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:52:58 -0800
commit9d0a8c38f8210c9af6ade6af1375655170e0ab2e (patch)
tree9203cf32f1ef64f3b08d576ea778967b2a49548c
parent83d304c61ad5fdc58b0a9309dbd1e5a3f6cd9b01 (diff)
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 fe4d6c5c..8fea8c0f 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -834,6 +834,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 ca4544d8..d9f98ae4 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -296,6 +296,7 @@ typedef enum {
OPTION_INTELTEXPOOL,
#endif
OPTION_TRIPLEBUFFER,
+ OPTION_FORCEENABLEPIPEA
} I830Opts;
static OptionInfoRec I830Options[] = {
@@ -318,6 +319,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* */
@@ -1177,6 +1179,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 },
};