diff --git a/src/i830_driver.c b/src/i830_driver.c index a19c8eb..6c3df4b 100644 --- a/src/i830_driver.c +++ b/src/i830_driver.c @@ -2116,7 +2116,17 @@ RestoreHWState(ScrnInfoPtr pScrn) OUTREG(DPLL_A, pI830->saveDPLL_A); i830_dpll_settle(); - /* Restore mode config */ + /* + * Restore mode config + * Ordering rules: + * - LVDS must be enabled before DPLLs are programmed + * - pipe timing regs must be valid before pipes are enabled + * - pipes must be enabled before corresponding planes + * - planes are enabled/disabled at next vblank after "trigger" register + * is written (either DSP*CNTR enable bit if 0->1 or DSP*BASE reg) + * - if VGA plane is active, corresponding bit in DSP*CNTR enable + * bit should be off + */ OUTREG(HTOTAL_A, pI830->saveHTOTAL_A); OUTREG(HBLANK_A, pI830->saveHBLANK_A); OUTREG(HSYNC_A, pI830->saveHSYNC_A); @@ -2124,21 +2134,20 @@ RestoreHWState(ScrnInfoPtr pScrn) OUTREG(VBLANK_A, pI830->saveVBLANK_A); OUTREG(VSYNC_A, pI830->saveVSYNC_A); OUTREG(BCLRPAT_A, pI830->saveBCLRPAT_A); - + OUTREG(PIPEASRC, pI830->savePIPEASRC); + OUTREG(PIPEACONF, pI830->savePIPEACONF); + i830WaitForVblank(pScrn); /* wait for pipe update */ + OUTREG(DSPASTRIDE, pI830->saveDSPASTRIDE); OUTREG(DSPASIZE, pI830->saveDSPASIZE); OUTREG(DSPAPOS, pI830->saveDSPAPOS); - OUTREG(PIPEASRC, pI830->savePIPEASRC); - OUTREG(DSPABASE, pI830->saveDSPABASE); if (IS_I965G(pI830)) { OUTREG(DSPASURF, pI830->saveDSPASURF); OUTREG(DSPATILEOFF, pI830->saveDSPATILEOFF); } - OUTREG(PIPEACONF, pI830->savePIPEACONF); - i830WaitForVblank(pScrn); - + OUTREG(DSPABASE, pI830->saveDSPABASE); /* * Program Pipe A's plane * The corresponding display plane may be disabled, and should only be @@ -2149,14 +2158,13 @@ RestoreHWState(ScrnInfoPtr pScrn) DISPPLANE_SEL_PIPE_A) { OUTREG(DSPACNTR, pI830->saveDSPACNTR); OUTREG(DSPABASE, INREG(DSPABASE)); - i830WaitForVblank(pScrn); } if ((pI830->saveDSPBCNTR & DISPPLANE_SEL_PIPE_MASK) == DISPPLANE_SEL_PIPE_A) { OUTREG(DSPBCNTR, pI830->saveDSPBCNTR); OUTREG(DSPBBASE, INREG(DSPBBASE)); - i830WaitForVblank(pScrn); } + i830WaitForVblank(pScrn); /* wait for plane update */ /* See note about pipe programming above */ if(xf86_config->num_crtc == 2) @@ -2185,20 +2193,21 @@ RestoreHWState(ScrnInfoPtr pScrn) OUTREG(VBLANK_B, pI830->saveVBLANK_B); OUTREG(VSYNC_B, pI830->saveVSYNC_B); OUTREG(BCLRPAT_B, pI830->saveBCLRPAT_B); + OUTREG(PIPEBSRC, pI830->savePIPEBSRC); + OUTREG(PIPEBCONF, pI830->savePIPEBCONF); + i830WaitForVblank(pScrn); /* wait for pipe update */ + OUTREG(DSPBSTRIDE, pI830->saveDSPBSTRIDE); OUTREG(DSPBSIZE, pI830->saveDSPBSIZE); OUTREG(DSPBPOS, pI830->saveDSPBPOS); - OUTREG(PIPEBSRC, pI830->savePIPEBSRC); - OUTREG(DSPBBASE, pI830->saveDSPBBASE); if (IS_I965G(pI830)) { OUTREG(DSPBSURF, pI830->saveDSPBSURF); OUTREG(DSPBTILEOFF, pI830->saveDSPBTILEOFF); } - OUTREG(PIPEBCONF, pI830->savePIPEBCONF); - i830WaitForVblank(pScrn); + OUTREG(DSPBBASE, pI830->saveDSPBBASE); /* * Program Pipe B's plane * Note that pipe B may be disabled, and in that case, the plane @@ -2208,14 +2217,13 @@ RestoreHWState(ScrnInfoPtr pScrn) DISPPLANE_SEL_PIPE_B) { OUTREG(DSPACNTR, pI830->saveDSPACNTR); OUTREG(DSPABASE, INREG(DSPABASE)); - i830WaitForVblank(pScrn); } if ((pI830->saveDSPBCNTR & DISPPLANE_SEL_PIPE_MASK) == DISPPLANE_SEL_PIPE_B) { OUTREG(DSPBCNTR, pI830->saveDSPBCNTR); OUTREG(DSPBBASE, INREG(DSPBBASE)); - i830WaitForVblank(pScrn); } + i830WaitForVblank(pScrn); /* wait for plane update */ } OUTREG(VGACNTRL, pI830->saveVGACNTRL);