diff --git a/man/intel.man b/man/intel.man index d46e3f9..2698b76 100644 --- a/man/intel.man +++ b/man/intel.man @@ -175,6 +175,11 @@ 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 +unconditionally. .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 fe4d6c5..8fea8c0 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 cd71dc5..3f0fc46 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 0e42624..d16871d 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 7818ee4..e656bd5 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 87d9a8a..041c993 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;