summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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 },
};