summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJesse Barnes <jbarnes@hobbes.virtuousgeek.org>2008-01-09 09:47:38 -0800
committerJesse Barnes <jbarnes@hobbes.virtuousgeek.org>2008-01-09 09:47:38 -0800
commit3c22ed633be2ac96eea7bc533839e956f1f31b84 (patch)
tree42d41b357f1e035f20a94a621b94d85c95c0f380
parentd3b41bcf231a6ffd289c128c06aa619f554a776c (diff)
downloadxorg-driver-xf86-video-intel-3c22ed633be2ac96eea7bc533839e956f1f31b84.tar.gz
Add pipe A force enable quirk
On some platforms, the firmware may read & write GPU registers on lid close, suspend/resume time or during various SMM events. If one of the graphics pipes is disabled at that time, the GPU may hang due to the programming dependencies of the various registers. This patch adds a quirk to force the driver to keep pipe A enabled if necessary, through user configuration in xorg.conf or via a platform specific quirk. Leaving the pipe enabled comes at a power cost however, so the quirk should only be enabled when strictly necessary. Fixes https://bugs.freedesktop.org/show_bug.cgi?id=11432.
-rw-r--r--man/intel.man7
-rw-r--r--src/i830.h1
-rw-r--r--src/i830_crt.c8
-rw-r--r--src/i830_display.c20
-rw-r--r--src/i830_driver.c5
-rw-r--r--src/i830_quirks.c9
6 files changed, 42 insertions, 8 deletions
diff --git a/man/intel.man b/man/intel.man
index d46e3f9c..e5736e57 100644
--- a/man/intel.man
+++ b/man/intel.man
@@ -175,6 +175,13 @@ Default: "EXA".
.BI "Option \*qModeDebug\*q \*q" boolean \*q
Enable printing of additional debugging information about modesetting to
the server log.
+.TP
+.BI "Option \*qForceEnablePipeA\*q \*q" boolean \*q
+Force the driver to leave pipe A enabled. May be necessary in configurations
+where the BIOS accesses pipe registers during display hotswitch or lid close,
+causing a crash. If you find that your platform needs this option, please file
+a bug against xf86-video-intel at http://bugs.freedesktop.org which includes
+the output of 'lspci -v' and 'lspci -vn'.
.SH OUTPUT CONFIGURATION
On 830M and better chipsets, the driver supports runtime configuration of
diff --git a/src/i830.h b/src/i830.h
index dcb87cc6..9adbaf7d 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -836,6 +836,7 @@ extern const int I830CopyROP[16];
#define QUIRK_IGNORE_TV 0x00000001
#define QUIRK_IGNORE_LVDS 0x00000002
#define QUIRK_IGNORE_MACMINI_LVDS 0x00000004
+#define QUIRK_PIPEA_FORCE 0x00000008
extern void i830_fixup_devices(ScrnInfoPtr);
#endif /* _I830_H_ */
diff --git a/src/i830_crt.c b/src/i830_crt.c
index cd71dc59..3f0fc463 100644
--- a/src/i830_crt.c
+++ b/src/i830_crt.c
@@ -380,6 +380,14 @@ i830_crt_detect(xf86OutputPtr output)
out:
i830ReleaseLoadDetectPipe (output, dpms_mode);
+
+ /* Needed for some machines where the BIOS pokes at pipe A */
+ if (pI830->quirk_flag & QUIRK_PIPEA_FORCE) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Overriding VGA detection, "
+ "forcing pipe A on.\n");
+ status = XF86OutputStatusConnected;
+ }
+
return status;
}
diff --git a/src/i830_display.c b/src/i830_display.c
index 0e426249..d16871d4 100644
--- a/src/i830_display.c
+++ b/src/i830_display.c
@@ -724,6 +724,10 @@ i830_crtc_dpms(xf86CrtcPtr crtc, int mode)
/* Give the overlay scaler a chance to disable if it's on this pipe */
i830_crtc_dpms_video(crtc, FALSE);
+ /* May need to leave pipe A on */
+ if ((pipe == 0) && (pI830->quirk_flag & QUIRK_PIPEA_FORCE))
+ return;
+
/* Disable the VGA plane that we never use */
OUTREG(VGACNTRL, VGA_DISP_DISABLE);
@@ -1176,14 +1180,6 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode,
i830PrintPll("chosen", &clock);
}
- if (dpll & DPLL_VCO_ENABLE)
- {
- OUTREG(fp_reg, fp);
- OUTREG(dpll_reg, dpll & ~DPLL_VCO_ENABLE);
- POSTING_READ(dpll_reg);
- usleep(150);
- }
-
/* The LVDS pin pair needs to be on before the DPLLs are enabled.
* This is an exception to the general rule that mode_set doesn't turn
* things on.
@@ -1192,6 +1188,14 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode,
{
CARD32 lvds = INREG(LVDS);
+ if (dpll & DPLL_VCO_ENABLE)
+ {
+ OUTREG(fp_reg, fp);
+ OUTREG(dpll_reg, dpll & ~DPLL_VCO_ENABLE);
+ POSTING_READ(dpll_reg);
+ usleep(150);
+ }
+
lvds |= LVDS_PORT_EN | LVDS_A0A2_CLKA_POWER_UP | LVDS_PIPEB_SELECT;
/* Set the B0-B3 data pairs corresponding to whether we're going to
* set the DPLLs for dual-channel mode or not.
diff --git a/src/i830_driver.c b/src/i830_driver.c
index 32d46027..32cecff1 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -298,6 +298,7 @@ typedef enum {
OPTION_INTELTEXPOOL,
#endif
OPTION_TRIPLEBUFFER,
+ OPTION_FORCEENABLEPIPEA
} I830Opts;
static OptionInfoRec I830Options[] = {
@@ -320,6 +321,7 @@ static OptionInfoRec I830Options[] = {
{OPTION_INTELTEXPOOL,"Legacy3D", OPTV_BOOLEAN, {0}, FALSE},
#endif
{OPTION_TRIPLEBUFFER, "TripleBuffer", OPTV_BOOLEAN, {0}, FALSE},
+ {OPTION_FORCEENABLEPIPEA, "ForceEnablePipeA", OPTV_BOOLEAN, {0}, FALSE},
{-1, NULL, OPTV_NONE, {0}, FALSE}
};
/* *INDENT-ON* */
@@ -1193,6 +1195,9 @@ I830PreInit(ScrnInfoPtr pScrn, int flags)
pI830->debug_modes = FALSE;
}
+ if (xf86ReturnOptValBool(pI830->Options, OPTION_FORCEENABLEPIPEA, FALSE))
+ pI830->quirk_flag |= QUIRK_PIPEA_FORCE;
+
/* We have to use PIO to probe, because we haven't mapped yet. */
I830SetPIOAccess(pI830);
diff --git a/src/i830_quirks.c b/src/i830_quirks.c
index 323962c7..8fbdbfe8 100644
--- a/src/i830_quirks.c
+++ b/src/i830_quirks.c
@@ -39,6 +39,11 @@ typedef struct {
void (*hook)(I830Ptr);
} i830_quirk, *i830_quirk_ptr;
+static void quirk_pipea_force (I830Ptr pI830)
+{
+ pI830->quirk_flag |= QUIRK_PIPEA_FORCE;
+}
+
static void quirk_ignore_tv (I830Ptr pI830)
{
pI830->quirk_flag |= QUIRK_IGNORE_TV;
@@ -86,6 +91,10 @@ static i830_quirk i830_quirk_list[] = {
/* Samsung Q35 has no TV output */
{ PCI_CHIP_I945_GM, 0x144d, 0xc504, quirk_ignore_tv },
+
+ /* Dell Inspiron 510m needs pipe A force quirk */
+ { PCI_CHIP_I855_GM, 0x1028, 0x0164, quirk_pipea_force },
+
{ 0, 0, 0, NULL },
};