diff --git a/src/i830_driver.c b/src/i830_driver.c index ca4544d..7818ee4 100644 --- a/src/i830_driver.c +++ b/src/i830_driver.c @@ -1991,13 +1991,6 @@ SaveHWState(ScrnInfoPtr pScrn) return TRUE; } -/* Wait for the PLL to settle down after programming */ -static void -i830_dpll_settle(void) -{ - usleep(10000); /* 10 ms *should* be plenty */ -} - static Bool RestoreHWState(ScrnInfoPtr pScrn) { @@ -2032,23 +2025,6 @@ RestoreHWState(ScrnInfoPtr pScrn) if (!IS_I830(pI830) && !IS_845G(pI830)) OUTREG(PFIT_CONTROL, pI830->savePFIT_CONTROL); - /* - * Pipe regs - * To restore the saved state, we first need to program the PLL regs, - * followed by the pipe configuration and finally the display plane - * configuration. The VGA registers can program one, both or neither - * of the PLL regs, depending on their VGA_MOD_DIS bit value. - */ - - /* - * Since either or both pipes may use the VGA clocks, make sure the - * regs are valid. - */ - OUTREG(VCLK_DIVISOR_VGA0, pI830->saveVCLK_DIVISOR_VGA0); - OUTREG(VCLK_DIVISOR_VGA1, pI830->saveVCLK_DIVISOR_VGA1); - OUTREG(VCLK_POST_DIV, pI830->saveVCLK_POST_DIV); - - /* If the pipe A PLL is active, we can restore the pipe & plane config */ if (pI830->saveDPLL_A & DPLL_VCO_ENABLE) { OUTREG(DPLL_A, pI830->saveDPLL_A & ~DPLL_VCO_ENABLE); @@ -2057,14 +2033,13 @@ RestoreHWState(ScrnInfoPtr pScrn) OUTREG(FPA0, pI830->saveFPA0); OUTREG(FPA1, pI830->saveFPA1); OUTREG(DPLL_A, pI830->saveDPLL_A); - i830_dpll_settle(); + usleep(150); if (IS_I965G(pI830)) OUTREG(DPLL_A_MD, pI830->saveDPLL_A_MD); else OUTREG(DPLL_A, pI830->saveDPLL_A); - i830_dpll_settle(); + usleep(150); - /* Restore mode config */ OUTREG(HTOTAL_A, pI830->saveHTOTAL_A); OUTREG(HBLANK_A, pI830->saveHBLANK_A); OUTREG(HSYNC_A, pI830->saveHSYNC_A); @@ -2083,31 +2058,20 @@ RestoreHWState(ScrnInfoPtr pScrn) OUTREG(DSPASURF, pI830->saveDSPASURF); OUTREG(DSPATILEOFF, pI830->saveDSPATILEOFF); } - - OUTREG(PIPEACONF, pI830->savePIPEACONF); - i830WaitForVblank(pScrn); - /* - * Program Pipe A's plane - * The corresponding display plane may be disabled, and should only be - * enabled if pipe A is actually on (otherwise we have a bug in the initial - * state). + * Make sure the DPLL is active and not in VGA mode or the + * write of PIPEnCONF may cause a crash */ - if (pI830->saveDSPACNTR & DISPPLANE_SEL_PIPE_A) { - OUTREG(DSPACNTR, pI830->saveDSPACNTR); - OUTREG(DSPABASE, INREG(DSPABASE)); - i830WaitForVblank(pScrn); - } - if (pI830->saveDSPBCNTR & DISPPLANE_SEL_PIPE_A) { - OUTREG(DSPBCNTR, pI830->saveDSPBCNTR); - OUTREG(DSPBBASE, INREG(DSPBBASE)); - i830WaitForVblank(pScrn); - } - - /* See note about pipe programming above */ + if ((pI830->saveDPLL_A & DPLL_VCO_ENABLE) && + (pI830->saveDPLL_A & DPLL_VGA_MODE_DIS)) + OUTREG(PIPEACONF, pI830->savePIPEACONF); + i830WaitForVblank(pScrn); + OUTREG(DSPACNTR, pI830->saveDSPACNTR); + OUTREG(DSPABASE, INREG(DSPABASE)); + i830WaitForVblank(pScrn); + if(xf86_config->num_crtc == 2) { - /* If the pipe B PLL is active, we can restore the pipe & plane config */ if (pI830->saveDPLL_B & DPLL_VCO_ENABLE) { OUTREG(DPLL_B, pI830->saveDPLL_B & ~DPLL_VCO_ENABLE); @@ -2116,14 +2080,13 @@ RestoreHWState(ScrnInfoPtr pScrn) OUTREG(FPB0, pI830->saveFPB0); OUTREG(FPB1, pI830->saveFPB1); OUTREG(DPLL_B, pI830->saveDPLL_B); - i830_dpll_settle(); + usleep(150); if (IS_I965G(pI830)) OUTREG(DPLL_B_MD, pI830->saveDPLL_B_MD); else OUTREG(DPLL_B, pI830->saveDPLL_B); - i830_dpll_settle(); + usleep(150); - /* Restore mode config */ OUTREG(HTOTAL_B, pI830->saveHTOTAL_B); OUTREG(HBLANK_B, pI830->saveHBLANK_B); OUTREG(HSYNC_B, pI830->saveHSYNC_B); @@ -2142,28 +2105,18 @@ RestoreHWState(ScrnInfoPtr pScrn) OUTREG(DSPBTILEOFF, pI830->saveDSPBTILEOFF); } - OUTREG(PIPEBCONF, pI830->savePIPEBCONF); - i830WaitForVblank(pScrn); - /* - * Program Pipe B's plane - * Note that pipe B may be disabled, and in that case, the plane - * should also be disabled or we must have had a bad initial state. + * See PIPEnCONF note above */ - if (pI830->saveDSPACNTR & DISPPLANE_SEL_PIPE_B) { - OUTREG(DSPACNTR, pI830->saveDSPACNTR); - OUTREG(DSPABASE, INREG(DSPABASE)); - i830WaitForVblank(pScrn); - } - if (pI830->saveDSPBCNTR & DISPPLANE_SEL_PIPE_B) { - OUTREG(DSPBCNTR, pI830->saveDSPBCNTR); - OUTREG(DSPBBASE, INREG(DSPBBASE)); - i830WaitForVblank(pScrn); - } + if ((pI830->saveDPLL_B & DPLL_VCO_ENABLE) && + (pI830->saveDPLL_B & DPLL_VGA_MODE_DIS)) + OUTREG(PIPEBCONF, pI830->savePIPEBCONF); + i830WaitForVblank(pScrn); + OUTREG(DSPBCNTR, pI830->saveDSPBCNTR); + OUTREG(DSPBBASE, INREG(DSPBBASE)); + i830WaitForVblank(pScrn); } - OUTREG(VGACNTRL, pI830->saveVGACNTRL); - /* Restore outputs */ for (i = 0; i < xf86_config->num_output; i++) { xf86OutputPtr output = xf86_config->output[i]; @@ -2171,6 +2124,12 @@ RestoreHWState(ScrnInfoPtr pScrn) output->funcs->restore(output); } + OUTREG(VGACNTRL, pI830->saveVGACNTRL); + + OUTREG(VCLK_DIVISOR_VGA0, pI830->saveVCLK_DIVISOR_VGA0); + OUTREG(VCLK_DIVISOR_VGA1, pI830->saveVCLK_DIVISOR_VGA1); + OUTREG(VCLK_POST_DIV, pI830->saveVCLK_POST_DIV); + i830_restore_palette(pI830, PIPE_A); i830_restore_palette(pI830, PIPE_B);