diff --git a/src/i830.h b/src/i830.h index 4f176f8..1bdb517 100644 --- a/src/i830.h +++ b/src/i830.h @@ -275,6 +275,72 @@ enum last_3d { LAST_3D_ROTATION }; +struct i830_hw_state { + CARD32 REG_DSPACNTR; + CARD32 REG_DSPBCNTR; + CARD32 REG_PIPEACONF; + CARD32 REG_PIPEBCONF; + CARD32 REG_PIPEASRC; + CARD32 REG_PIPEBSRC; + CARD32 REG_FPA0; + CARD32 REG_FPA1; + CARD32 REG_DPLL_A; + CARD32 REG_DPLL_A_MD; + CARD32 REG_HTOTAL_A; + CARD32 REG_HBLANK_A; + CARD32 REG_HSYNC_A; + CARD32 REG_VTOTAL_A; + CARD32 REG_VBLANK_A; + CARD32 REG_VSYNC_A; + CARD32 REG_BCLRPAT_A; + CARD32 REG_DSPASTRIDE; + CARD32 REG_DSPASIZE; + CARD32 REG_DSPAPOS; + CARD32 REG_DSPABASE; + CARD32 REG_DSPASURF; + CARD32 REG_DSPATILEOFF; + CARD32 REG_FPB0; + CARD32 REG_FPB1; + CARD32 REG_DPLL_B; + CARD32 REG_DPLL_B_MD; + CARD32 REG_HTOTAL_B; + CARD32 REG_HBLANK_B; + CARD32 REG_HSYNC_B; + CARD32 REG_VTOTAL_B; + CARD32 REG_VBLANK_B; + CARD32 REG_VSYNC_B; + CARD32 REG_BCLRPAT_B; + CARD32 REG_DSPBSTRIDE; + CARD32 REG_DSPBSIZE; + CARD32 REG_DSPBPOS; + CARD32 REG_DSPBBASE; + CARD32 REG_DSPBSURF; + CARD32 REG_DSPBTILEOFF; + CARD32 REG_VCLK_DIVISOR_VGA0; + CARD32 REG_VCLK_DIVISOR_VGA1; + CARD32 REG_VCLK_POST_DIV; + CARD32 REG_VGACNTRL; + CARD32 REG_ADPA; + CARD32 REG_LVDS; + CARD32 REG_DVOA; + CARD32 REG_DVOB; + CARD32 REG_DVOC; + CARD32 REG_PP_ON; + CARD32 REG_PP_OFF; + CARD32 REG_PP_CONTROL; + CARD32 REG_PP_CYCLE; + CARD32 REG_PFIT_CONTROL; + CARD32 REG_PaletteA[256]; + CARD32 REG_PaletteB[256]; + CARD32 REG_SWF[17]; + CARD32 REG_BLC_PWM_CTL; + CARD32 REG_BLC_PWM_CTL2; + CARD32 REG_FBC_CFB_BASE; + CARD32 REG_FBC_LL_BASE; + CARD32 REG_FBC_CONTROL2; + CARD32 REG_FBC_CONTROL; +}; + typedef struct _I830Rec { unsigned char *MMIOBase; unsigned char *GTTBase; @@ -485,75 +551,14 @@ typedef struct _I830Rec { int ddc2; - CARD32 saveDSPACNTR; - CARD32 saveDSPBCNTR; - CARD32 savePIPEACONF; - CARD32 savePIPEBCONF; - CARD32 savePIPEASRC; - CARD32 savePIPEBSRC; - CARD32 saveFPA0; - CARD32 saveFPA1; - CARD32 saveDPLL_A; - CARD32 saveDPLL_A_MD; - CARD32 saveHTOTAL_A; - CARD32 saveHBLANK_A; - CARD32 saveHSYNC_A; - CARD32 saveVTOTAL_A; - CARD32 saveVBLANK_A; - CARD32 saveVSYNC_A; - CARD32 saveBCLRPAT_A; - CARD32 saveDSPASTRIDE; - CARD32 saveDSPASIZE; - CARD32 saveDSPAPOS; - CARD32 saveDSPABASE; - CARD32 saveDSPASURF; - CARD32 saveDSPATILEOFF; - CARD32 saveFPB0; - CARD32 saveFPB1; - CARD32 saveDPLL_B; - CARD32 saveDPLL_B_MD; - CARD32 saveHTOTAL_B; - CARD32 saveHBLANK_B; - CARD32 saveHSYNC_B; - CARD32 saveVTOTAL_B; - CARD32 saveVBLANK_B; - CARD32 saveVSYNC_B; - CARD32 saveBCLRPAT_B; - CARD32 saveDSPBSTRIDE; - CARD32 saveDSPBSIZE; - CARD32 saveDSPBPOS; - CARD32 saveDSPBBASE; - CARD32 saveDSPBSURF; - CARD32 saveDSPBTILEOFF; - CARD32 saveVCLK_DIVISOR_VGA0; - CARD32 saveVCLK_DIVISOR_VGA1; - CARD32 saveVCLK_POST_DIV; - CARD32 saveVGACNTRL; - CARD32 saveADPA; - CARD32 saveLVDS; - CARD32 saveDVOA; - CARD32 saveDVOB; - CARD32 saveDVOC; - CARD32 savePP_ON; - CARD32 savePP_OFF; - CARD32 savePP_CONTROL; - CARD32 savePP_CYCLE; - CARD32 savePFIT_CONTROL; - CARD32 savePaletteA[256]; - CARD32 savePaletteB[256]; - CARD32 saveSWF[17]; - CARD32 saveBLC_PWM_CTL; - CARD32 saveBLC_PWM_CTL2; - CARD32 saveFBC_CFB_BASE; - CARD32 saveFBC_LL_BASE; - CARD32 saveFBC_CONTROL2; - CARD32 saveFBC_CONTROL; - enum last_3d *last_3d; /** Enables logging of debug output related to mode switching. */ Bool debug_modes; unsigned int quirk_flag; + + struct i830_hw_state initial_state; /* hw state at PreInit time */ + struct i830_hw_state last_state; /* hw state at last VT switch */ } I830Rec; #define I830PTR(p) ((I830Ptr)((p)->driverPrivate)) diff --git a/src/i830_crt.c b/src/i830_crt.c index d7762a0..608c4b4 100644 --- a/src/i830_crt.c +++ b/src/i830_crt.c @@ -69,7 +69,7 @@ i830_crt_save (xf86OutputPtr output) ScrnInfoPtr pScrn = output->scrn; I830Ptr pI830 = I830PTR(pScrn); - pI830->saveADPA = INREG(ADPA); + pI830->last_state.REG_ADPA = INREG(ADPA); } static void @@ -78,7 +78,7 @@ i830_crt_restore (xf86OutputPtr output) ScrnInfoPtr pScrn = output->scrn; I830Ptr pI830 = I830PTR(pScrn); - OUTREG(ADPA, pI830->saveADPA); + OUTREG(ADPA, pI830->last_state.REG_ADPA); } static int diff --git a/src/i830_driver.c b/src/i830_driver.c index 9fa231d..10af5b3 100644 --- a/src/i830_driver.c +++ b/src/i830_driver.c @@ -336,8 +336,8 @@ static void i830AdjustFrame(int scrnIndex, int x, int y, int flags); static Bool I830CloseScreen(int scrnIndex, ScreenPtr pScreen); static Bool I830EnterVT(int scrnIndex, int flags); static CARD32 I830CheckDevicesTimer(OsTimerPtr timer, CARD32 now, pointer arg); -static Bool SaveHWState(ScrnInfoPtr pScrn); -static Bool RestoreHWState(ScrnInfoPtr pScrn); +static Bool SaveHWState(ScrnInfoPtr pScrn, struct i830_hw_state *state); +static Bool RestoreHWState(ScrnInfoPtr pScrn, struct i830_hw_state *state); /* temporary */ extern void xf86SetCursor(ScreenPtr pScreen, CursorPtr pCurs, int x, int y); @@ -1520,15 +1520,22 @@ I830PreInit(ScrnInfoPtr pScrn, int flags) } I830SetupOutputs(pScrn); - SaveHWState(pScrn); - if (!xf86InitialConfiguration (pScrn, FALSE)) + SaveHWState(pScrn, &pI830->initial_state); + SaveHWState(pScrn, &pI830->last_state); + { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes.\n"); - RestoreHWState(pScrn); - PreInitCleanup(pScrn); - return FALSE; + struct i830_hw_state tmp; + + SaveHWState(pScrn, &tmp); + if (!xf86InitialConfiguration (pScrn, FALSE)) + { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes.\n"); + RestoreHWState(pScrn, &tmp); + PreInitCleanup(pScrn); + return FALSE; + } + RestoreHWState(pScrn, &tmp); } - RestoreHWState(pScrn); /* XXX This should go away, replaced by xf86Crtc.c support for it */ pI830->rotation = RR_Rotate_0; @@ -1894,7 +1901,7 @@ SetHWOperatingState(ScrnInfoPtr pScrn) } static Bool -SaveHWState(ScrnInfoPtr pScrn) +SaveHWState(ScrnInfoPtr pScrn, struct i830_hw_state *state) { xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); I830Ptr pI830 = I830PTR(pScrn); @@ -1903,85 +1910,85 @@ SaveHWState(ScrnInfoPtr pScrn) int i; if (pI830->fb_compression) { - pI830->saveFBC_CFB_BASE = INREG(FBC_CFB_BASE); - pI830->saveFBC_LL_BASE = INREG(FBC_LL_BASE); - pI830->saveFBC_CONTROL2 = INREG(FBC_CONTROL2); - pI830->saveFBC_CONTROL = INREG(FBC_CONTROL); + state->REG_FBC_CFB_BASE = INREG(FBC_CFB_BASE); + state->REG_FBC_LL_BASE = INREG(FBC_LL_BASE); + state->REG_FBC_CONTROL2 = INREG(FBC_CONTROL2); + state->REG_FBC_CONTROL = INREG(FBC_CONTROL); } /* Save video mode information for native mode-setting. */ - pI830->saveDSPACNTR = INREG(DSPACNTR); - pI830->savePIPEACONF = INREG(PIPEACONF); - pI830->savePIPEASRC = INREG(PIPEASRC); - pI830->saveFPA0 = INREG(FPA0); - pI830->saveFPA1 = INREG(FPA1); - pI830->saveDPLL_A = INREG(DPLL_A); + state->REG_DSPACNTR = INREG(DSPACNTR); + state->REG_PIPEACONF = INREG(PIPEACONF); + state->REG_PIPEASRC = INREG(PIPEASRC); + state->REG_FPA0 = INREG(FPA0); + state->REG_FPA1 = INREG(FPA1); + state->REG_DPLL_A = INREG(DPLL_A); if (IS_I965G(pI830)) - pI830->saveDPLL_A_MD = INREG(DPLL_A_MD); - pI830->saveHTOTAL_A = INREG(HTOTAL_A); - pI830->saveHBLANK_A = INREG(HBLANK_A); - pI830->saveHSYNC_A = INREG(HSYNC_A); - pI830->saveVTOTAL_A = INREG(VTOTAL_A); - pI830->saveVBLANK_A = INREG(VBLANK_A); - pI830->saveVSYNC_A = INREG(VSYNC_A); - pI830->saveBCLRPAT_A = INREG(BCLRPAT_A); - pI830->saveDSPASTRIDE = INREG(DSPASTRIDE); - pI830->saveDSPASIZE = INREG(DSPASIZE); - pI830->saveDSPAPOS = INREG(DSPAPOS); - pI830->saveDSPABASE = INREG(DSPABASE); + state->REG_DPLL_A_MD = INREG(DPLL_A_MD); + state->REG_HTOTAL_A = INREG(HTOTAL_A); + state->REG_HBLANK_A = INREG(HBLANK_A); + state->REG_HSYNC_A = INREG(HSYNC_A); + state->REG_VTOTAL_A = INREG(VTOTAL_A); + state->REG_VBLANK_A = INREG(VBLANK_A); + state->REG_VSYNC_A = INREG(VSYNC_A); + state->REG_BCLRPAT_A = INREG(BCLRPAT_A); + state->REG_DSPASTRIDE = INREG(DSPASTRIDE); + state->REG_DSPASIZE = INREG(DSPASIZE); + state->REG_DSPAPOS = INREG(DSPAPOS); + state->REG_DSPABASE = INREG(DSPABASE); for(i= 0; i < 256; i++) { - pI830->savePaletteA[i] = INREG(PALETTE_A + (i << 2)); + state->REG_PaletteA[i] = INREG(PALETTE_A + (i << 2)); } if(xf86_config->num_crtc == 2) { - pI830->savePIPEBCONF = INREG(PIPEBCONF); - pI830->savePIPEBSRC = INREG(PIPEBSRC); - pI830->saveDSPBCNTR = INREG(DSPBCNTR); - pI830->saveFPB0 = INREG(FPB0); - pI830->saveFPB1 = INREG(FPB1); - pI830->saveDPLL_B = INREG(DPLL_B); + state->REG_PIPEBCONF = INREG(PIPEBCONF); + state->REG_PIPEBSRC = INREG(PIPEBSRC); + state->REG_DSPBCNTR = INREG(DSPBCNTR); + state->REG_FPB0 = INREG(FPB0); + state->REG_FPB1 = INREG(FPB1); + state->REG_DPLL_B = INREG(DPLL_B); if (IS_I965G(pI830)) - pI830->saveDPLL_B_MD = INREG(DPLL_B_MD); - pI830->saveHTOTAL_B = INREG(HTOTAL_B); - pI830->saveHBLANK_B = INREG(HBLANK_B); - pI830->saveHSYNC_B = INREG(HSYNC_B); - pI830->saveVTOTAL_B = INREG(VTOTAL_B); - pI830->saveVBLANK_B = INREG(VBLANK_B); - pI830->saveVSYNC_B = INREG(VSYNC_B); - pI830->saveBCLRPAT_B = INREG(BCLRPAT_B); - pI830->saveDSPBSTRIDE = INREG(DSPBSTRIDE); - pI830->saveDSPBSIZE = INREG(DSPBSIZE); - pI830->saveDSPBPOS = INREG(DSPBPOS); - pI830->saveDSPBBASE = INREG(DSPBBASE); + state->REG_DPLL_B_MD = INREG(DPLL_B_MD); + state->REG_HTOTAL_B = INREG(HTOTAL_B); + state->REG_HBLANK_B = INREG(HBLANK_B); + state->REG_HSYNC_B = INREG(HSYNC_B); + state->REG_VTOTAL_B = INREG(VTOTAL_B); + state->REG_VBLANK_B = INREG(VBLANK_B); + state->REG_VSYNC_B = INREG(VSYNC_B); + state->REG_BCLRPAT_B = INREG(BCLRPAT_B); + state->REG_DSPBSTRIDE = INREG(DSPBSTRIDE); + state->REG_DSPBSIZE = INREG(DSPBSIZE); + state->REG_DSPBPOS = INREG(DSPBPOS); + state->REG_DSPBBASE = INREG(DSPBBASE); for(i= 0; i < 256; i++) { - pI830->savePaletteB[i] = INREG(PALETTE_B + (i << 2)); + state->REG_PaletteB[i] = INREG(PALETTE_B + (i << 2)); } } if (IS_I965G(pI830)) { - pI830->saveDSPASURF = INREG(DSPASURF); - pI830->saveDSPBSURF = INREG(DSPBSURF); - pI830->saveDSPATILEOFF = INREG(DSPATILEOFF); - pI830->saveDSPBTILEOFF = INREG(DSPBTILEOFF); + state->REG_DSPASURF = INREG(DSPASURF); + state->REG_DSPBSURF = INREG(DSPBSURF); + state->REG_DSPATILEOFF = INREG(DSPATILEOFF); + state->REG_DSPBTILEOFF = INREG(DSPBTILEOFF); } - pI830->saveVCLK_DIVISOR_VGA0 = INREG(VCLK_DIVISOR_VGA0); - pI830->saveVCLK_DIVISOR_VGA1 = INREG(VCLK_DIVISOR_VGA1); - pI830->saveVCLK_POST_DIV = INREG(VCLK_POST_DIV); - pI830->saveVGACNTRL = INREG(VGACNTRL); + state->REG_VCLK_DIVISOR_VGA0 = INREG(VCLK_DIVISOR_VGA0); + state->REG_VCLK_DIVISOR_VGA1 = INREG(VCLK_DIVISOR_VGA1); + state->REG_VCLK_POST_DIV = INREG(VCLK_POST_DIV); + state->REG_VGACNTRL = INREG(VGACNTRL); for(i = 0; i < 7; i++) { - pI830->saveSWF[i] = INREG(SWF0 + (i << 2)); - pI830->saveSWF[i+7] = INREG(SWF00 + (i << 2)); + state->REG_SWF[i] = INREG(SWF0 + (i << 2)); + state->REG_SWF[i+7] = INREG(SWF00 + (i << 2)); } - pI830->saveSWF[14] = INREG(SWF30); - pI830->saveSWF[15] = INREG(SWF31); - pI830->saveSWF[16] = INREG(SWF32); + state->REG_SWF[14] = INREG(SWF30); + state->REG_SWF[15] = INREG(SWF31); + state->REG_SWF[16] = INREG(SWF32); if (IS_MOBILE(pI830) && !IS_I830(pI830)) - pI830->saveLVDS = INREG(LVDS); - pI830->savePFIT_CONTROL = INREG(PFIT_CONTROL); + state->REG_LVDS = INREG(LVDS); + state->REG_PFIT_CONTROL = INREG(PFIT_CONTROL); for (i = 0; i < xf86_config->num_output; i++) { xf86OutputPtr output = xf86_config->output[i]; @@ -1996,7 +2003,7 @@ SaveHWState(ScrnInfoPtr pScrn) } static Bool -RestoreHWState(ScrnInfoPtr pScrn) +RestoreHWState(ScrnInfoPtr pScrn, struct i830_hw_state *state) { xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); I830Ptr pI830 = I830PTR(pScrn); @@ -2024,87 +2031,87 @@ RestoreHWState(ScrnInfoPtr pScrn) i830WaitForVblank(pScrn); if (IS_MOBILE(pI830) && !IS_I830(pI830)) - OUTREG(LVDS, pI830->saveLVDS); + OUTREG(LVDS, state->REG_LVDS); if (!IS_I830(pI830) && !IS_845G(pI830)) - OUTREG(PFIT_CONTROL, pI830->savePFIT_CONTROL); + OUTREG(PFIT_CONTROL, state->REG_PFIT_CONTROL); - if (pI830->saveDPLL_A & DPLL_VCO_ENABLE) + if (state->REG_DPLL_A & DPLL_VCO_ENABLE) { - OUTREG(DPLL_A, pI830->saveDPLL_A & ~DPLL_VCO_ENABLE); + OUTREG(DPLL_A, state->REG_DPLL_A & ~DPLL_VCO_ENABLE); usleep(150); } - OUTREG(FPA0, pI830->saveFPA0); - OUTREG(FPA1, pI830->saveFPA1); - OUTREG(DPLL_A, pI830->saveDPLL_A); + OUTREG(FPA0, state->REG_FPA0); + OUTREG(FPA1, state->REG_FPA1); + OUTREG(DPLL_A, state->REG_DPLL_A); usleep(150); if (IS_I965G(pI830)) - OUTREG(DPLL_A_MD, pI830->saveDPLL_A_MD); + OUTREG(DPLL_A_MD, state->REG_DPLL_A_MD); else - OUTREG(DPLL_A, pI830->saveDPLL_A); + OUTREG(DPLL_A, state->REG_DPLL_A); usleep(150); - OUTREG(HTOTAL_A, pI830->saveHTOTAL_A); - OUTREG(HBLANK_A, pI830->saveHBLANK_A); - OUTREG(HSYNC_A, pI830->saveHSYNC_A); - OUTREG(VTOTAL_A, pI830->saveVTOTAL_A); - OUTREG(VBLANK_A, pI830->saveVBLANK_A); - OUTREG(VSYNC_A, pI830->saveVSYNC_A); - OUTREG(BCLRPAT_A, pI830->saveBCLRPAT_A); + OUTREG(HTOTAL_A, state->REG_HTOTAL_A); + OUTREG(HBLANK_A, state->REG_HBLANK_A); + OUTREG(HSYNC_A, state->REG_HSYNC_A); + OUTREG(VTOTAL_A, state->REG_VTOTAL_A); + OUTREG(VBLANK_A, state->REG_VBLANK_A); + OUTREG(VSYNC_A, state->REG_VSYNC_A); + OUTREG(BCLRPAT_A, state->REG_BCLRPAT_A); - OUTREG(DSPASTRIDE, pI830->saveDSPASTRIDE); - OUTREG(DSPASIZE, pI830->saveDSPASIZE); - OUTREG(DSPAPOS, pI830->saveDSPAPOS); - OUTREG(PIPEASRC, pI830->savePIPEASRC); - OUTREG(DSPABASE, pI830->saveDSPABASE); + OUTREG(DSPASTRIDE, state->REG_DSPASTRIDE); + OUTREG(DSPASIZE, state->REG_DSPASIZE); + OUTREG(DSPAPOS, state->REG_DSPAPOS); + OUTREG(PIPEASRC, state->REG_PIPEASRC); + OUTREG(DSPABASE, state->REG_DSPABASE); if (IS_I965G(pI830)) { - OUTREG(DSPASURF, pI830->saveDSPASURF); - OUTREG(DSPATILEOFF, pI830->saveDSPATILEOFF); + OUTREG(DSPASURF, state->REG_DSPASURF); + OUTREG(DSPATILEOFF, state->REG_DSPATILEOFF); } - OUTREG(PIPEACONF, pI830->savePIPEACONF); + OUTREG(PIPEACONF, state->REG_PIPEACONF); i830WaitForVblank(pScrn); - OUTREG(DSPACNTR, pI830->saveDSPACNTR); + OUTREG(DSPACNTR, state->REG_DSPACNTR); OUTREG(DSPABASE, INREG(DSPABASE)); i830WaitForVblank(pScrn); if(xf86_config->num_crtc == 2) { - if (pI830->saveDPLL_B & DPLL_VCO_ENABLE) + if (state->REG_DPLL_B & DPLL_VCO_ENABLE) { - OUTREG(DPLL_B, pI830->saveDPLL_B & ~DPLL_VCO_ENABLE); + OUTREG(DPLL_B, state->REG_DPLL_B & ~DPLL_VCO_ENABLE); usleep(150); } - OUTREG(FPB0, pI830->saveFPB0); - OUTREG(FPB1, pI830->saveFPB1); - OUTREG(DPLL_B, pI830->saveDPLL_B); + OUTREG(FPB0, state->REG_FPB0); + OUTREG(FPB1, state->REG_FPB1); + OUTREG(DPLL_B, state->REG_DPLL_B); usleep(150); if (IS_I965G(pI830)) - OUTREG(DPLL_B_MD, pI830->saveDPLL_B_MD); + OUTREG(DPLL_B_MD, state->REG_DPLL_B_MD); else - OUTREG(DPLL_B, pI830->saveDPLL_B); + OUTREG(DPLL_B, state->REG_DPLL_B); usleep(150); - OUTREG(HTOTAL_B, pI830->saveHTOTAL_B); - OUTREG(HBLANK_B, pI830->saveHBLANK_B); - OUTREG(HSYNC_B, pI830->saveHSYNC_B); - OUTREG(VTOTAL_B, pI830->saveVTOTAL_B); - OUTREG(VBLANK_B, pI830->saveVBLANK_B); - OUTREG(VSYNC_B, pI830->saveVSYNC_B); - OUTREG(BCLRPAT_B, pI830->saveBCLRPAT_B); - OUTREG(DSPBSTRIDE, pI830->saveDSPBSTRIDE); - OUTREG(DSPBSIZE, pI830->saveDSPBSIZE); - OUTREG(DSPBPOS, pI830->saveDSPBPOS); - OUTREG(PIPEBSRC, pI830->savePIPEBSRC); - OUTREG(DSPBBASE, pI830->saveDSPBBASE); + OUTREG(HTOTAL_B, state->REG_HTOTAL_B); + OUTREG(HBLANK_B, state->REG_HBLANK_B); + OUTREG(HSYNC_B, state->REG_HSYNC_B); + OUTREG(VTOTAL_B, state->REG_VTOTAL_B); + OUTREG(VBLANK_B, state->REG_VBLANK_B); + OUTREG(VSYNC_B, state->REG_VSYNC_B); + OUTREG(BCLRPAT_B, state->REG_BCLRPAT_B); + OUTREG(DSPBSTRIDE, state->REG_DSPBSTRIDE); + OUTREG(DSPBSIZE, state->REG_DSPBSIZE); + OUTREG(DSPBPOS, state->REG_DSPBPOS); + OUTREG(PIPEBSRC, state->REG_PIPEBSRC); + OUTREG(DSPBBASE, state->REG_DSPBBASE); if (IS_I965G(pI830)) { - OUTREG(DSPBSURF, pI830->saveDSPBSURF); - OUTREG(DSPBTILEOFF, pI830->saveDSPBTILEOFF); + OUTREG(DSPBSURF, state->REG_DSPBSURF); + OUTREG(DSPBTILEOFF, state->REG_DSPBTILEOFF); } - OUTREG(PIPEBCONF, pI830->savePIPEBCONF); + OUTREG(PIPEBCONF, state->REG_PIPEBCONF); i830WaitForVblank(pScrn); - OUTREG(DSPBCNTR, pI830->saveDSPBCNTR); + OUTREG(DSPBCNTR, state->REG_DSPBCNTR); OUTREG(DSPBBASE, INREG(DSPBBASE)); i830WaitForVblank(pScrn); } @@ -2116,36 +2123,36 @@ RestoreHWState(ScrnInfoPtr pScrn) output->funcs->restore(output); } - OUTREG(VGACNTRL, pI830->saveVGACNTRL); + OUTREG(VGACNTRL, state->REG_VGACNTRL); - OUTREG(VCLK_DIVISOR_VGA0, pI830->saveVCLK_DIVISOR_VGA0); - OUTREG(VCLK_DIVISOR_VGA1, pI830->saveVCLK_DIVISOR_VGA1); - OUTREG(VCLK_POST_DIV, pI830->saveVCLK_POST_DIV); + OUTREG(VCLK_DIVISOR_VGA0, state->REG_VCLK_DIVISOR_VGA0); + OUTREG(VCLK_DIVISOR_VGA1, state->REG_VCLK_DIVISOR_VGA1); + OUTREG(VCLK_POST_DIV, state->REG_VCLK_POST_DIV); for(i = 0; i < 256; i++) { - OUTREG(PALETTE_A + (i << 2), pI830->savePaletteA[i]); + OUTREG(PALETTE_A + (i << 2), state->REG_PaletteA[i]); } if(xf86_config->num_crtc == 2) { for(i= 0; i < 256; i++) { - OUTREG(PALETTE_B + (i << 2), pI830->savePaletteB[i]); + OUTREG(PALETTE_B + (i << 2), state->REG_PaletteB[i]); } } for(i = 0; i < 7; i++) { - OUTREG(SWF0 + (i << 2), pI830->saveSWF[i]); - OUTREG(SWF00 + (i << 2), pI830->saveSWF[i+7]); + OUTREG(SWF0 + (i << 2), state->REG_SWF[i]); + OUTREG(SWF00 + (i << 2), state->REG_SWF[i+7]); } - OUTREG(SWF30, pI830->saveSWF[14]); - OUTREG(SWF31, pI830->saveSWF[15]); - OUTREG(SWF32, pI830->saveSWF[16]); + OUTREG(SWF30, state->REG_SWF[14]); + OUTREG(SWF31, state->REG_SWF[15]); + OUTREG(SWF32, state->REG_SWF[16]); if (pI830->fb_compression) { - OUTREG(FBC_CFB_BASE, pI830->saveFBC_CFB_BASE); - OUTREG(FBC_LL_BASE, pI830->saveFBC_LL_BASE); - OUTREG(FBC_CONTROL2, pI830->saveFBC_CONTROL2); - OUTREG(FBC_CONTROL, pI830->saveFBC_CONTROL); + OUTREG(FBC_CFB_BASE, state->REG_FBC_CFB_BASE); + OUTREG(FBC_LL_BASE, state->REG_FBC_LL_BASE); + OUTREG(FBC_CONTROL2, state->REG_FBC_CONTROL2); + OUTREG(FBC_CONTROL, state->REG_FBC_CONTROL); } vgaHWRestore(pScrn, vgaReg, VGA_SR_FONTS); @@ -2991,6 +2998,9 @@ I830LeaveVT(int scrnIndex, int flags) DPRINTF(PFX, "Leave VT\n"); + ErrorF("*** saving last state\n"); + SaveHWState(pScrn, &pI830->last_state); + pI830->leaving = TRUE; if (pI830->devicesTimer) @@ -3024,7 +3034,9 @@ I830LeaveVT(int scrnIndex, int flags) ResetState(pScrn, TRUE); - RestoreHWState(pScrn); + /* Restore state from server startup, VT should be just as we left it */ + ErrorF("*** restoring initial state\n"); + RestoreHWState(pScrn, &pI830->initial_state); if (pI830->debug_modes) { i830CompareRegsToSnapshot(pScrn, "After LeaveVT"); @@ -3055,10 +3067,18 @@ I830EnterVT(int scrnIndex, int flags) * drivers do. Could change this to save state at each VT enter. */ if (pI830->SaveGeneration != serverGeneration) { + /* + * At server startup time, + */ pI830->SaveGeneration = serverGeneration; - SaveHWState(pScrn); + ErrorF("*** saving initial state\n"); + SaveHWState(pScrn, &pI830->initial_state); } + /* Get back to state we were in prior to VT switch */ + ErrorF("*** restoring last state\n"); + RestoreHWState(pScrn, &pI830->last_state); + pI830->leaving = FALSE; if (I830IsPrimary(pScrn)) diff --git a/src/i830_dvo.c b/src/i830_dvo.c index cb461d7..aa5c60d 100644 --- a/src/i830_dvo.c +++ b/src/i830_dvo.c @@ -137,9 +137,9 @@ i830_dvo_save(xf86OutputPtr output) /* Each output should probably just save the registers it touches, but for * now, use more overkill. */ - pI830->saveDVOA = INREG(DVOA); - pI830->saveDVOB = INREG(DVOB); - pI830->saveDVOC = INREG(DVOC); + pI830->last_state.REG_DVOA = INREG(DVOA); + pI830->last_state.REG_DVOB = INREG(DVOB); + pI830->last_state.REG_DVOC = INREG(DVOC); (*intel_output->i2c_drv->vid_rec->save)(dev_priv); } @@ -154,9 +154,9 @@ i830_dvo_restore(xf86OutputPtr output) (*intel_output->i2c_drv->vid_rec->restore)(dev_priv); - OUTREG(DVOA, pI830->saveDVOA); - OUTREG(DVOB, pI830->saveDVOB); - OUTREG(DVOC, pI830->saveDVOC); + OUTREG(DVOA, pI830->last_state.REG_DVOA); + OUTREG(DVOB, pI830->last_state.REG_DVOB); + OUTREG(DVOC, pI830->last_state.REG_DVOC); } static int diff --git a/src/i830_lvds.c b/src/i830_lvds.c index 0b6b192..23b4854 100644 --- a/src/i830_lvds.c +++ b/src/i830_lvds.c @@ -83,16 +83,44 @@ i830_lvds_set_backlight(xf86OutputPtr output, int level) I830Ptr pI830 = I830PTR(pScrn); CARD32 blc_pwm_ctl; - if (i830_lvds_backlight_legacy(pI830)) + if (i830_lvds_backlight_legacy(pI830)) { #if XSERVER_LIBPCIACCESS - pci_device_cfg_write_u8 (pI830->PciInfo, 0xfe, LEGACY_BACKLIGHT_BRIGHTNESS); + pci_device_cfg_write_u8 (pI830->PciInfo, level, LEGACY_BACKLIGHT_BRIGHTNESS); #else - pciWriteByte(pI830->PciTag, LEGACY_BACKLIGHT_BRIGHTNESS, 0xfe); + pciWriteByte(pI830->PciTag, LEGACY_BACKLIGHT_BRIGHTNESS, level); #endif + } else { + blc_pwm_ctl = INREG(BLC_PWM_CTL); + blc_pwm_ctl &= ~BACKLIGHT_DUTY_CYCLE_MASK; + OUTREG(BLC_PWM_CTL, blc_pwm_ctl | (level << BACKLIGHT_DUTY_CYCLE_SHIFT)); + } +} - blc_pwm_ctl = INREG(BLC_PWM_CTL); - blc_pwm_ctl &= ~BACKLIGHT_DUTY_CYCLE_MASK; - OUTREG(BLC_PWM_CTL, blc_pwm_ctl | (level << BACKLIGHT_DUTY_CYCLE_SHIFT)); +/** + * Gets current backlight level. + * + * Returns current backlight level. + */ +static int +i830_lvds_get_backlight(xf86OutputPtr output) +{ + ScrnInfoPtr pScrn = output->scrn; + I830Ptr pI830 = I830PTR(pScrn); + + if (i830_lvds_backlight_legacy(pI830)) { + CARD8 val; +#if XSERVER_LIBPCIACCESS + pci_device_cfg_read_u8 (pI830->PciInfo, &val, LEGACY_BACKLIGHT_BRIGHTNESS); +#else + val = pciReadByte(pI830->PciTag, LEGACY_BACKLIGHT_BRIGHTNESS); + return val; +#endif + } else { + CARD32 blc_pwm_ctl; + blc_pwm_ctl = INREG(BLC_PWM_CTL); + blc_pwm_ctl &= BACKLIGHT_DUTY_CYCLE_MASK; + return blc_pwm_ctl; + } } /** @@ -106,6 +134,9 @@ i830_lvds_get_max_backlight(xf86OutputPtr output) CARD32 pwm_ctl = INREG(BLC_PWM_CTL); CARD32 val; + if (i830_lvds_backlight_legacy(pI830)) + return 0xff; + if (IS_I965GM(pI830)) { val = ((pwm_ctl & BACKLIGHT_MODULATION_FREQ_MASK2) >> BACKLIGHT_MODULATION_FREQ_SHIFT2); @@ -173,14 +204,13 @@ i830_lvds_save (xf86OutputPtr output) I830Ptr pI830 = I830PTR(pScrn); if (IS_I965GM(pI830)) - pI830->saveBLC_PWM_CTL2 = INREG(BLC_PWM_CTL2); - pI830->savePP_ON = INREG(LVDSPP_ON); - pI830->savePP_OFF = INREG(LVDSPP_OFF); - pI830->savePP_CONTROL = INREG(PP_CONTROL); - pI830->savePP_CYCLE = INREG(PP_CYCLE); - pI830->saveBLC_PWM_CTL = INREG(BLC_PWM_CTL); - dev_priv->backlight_duty_cycle = (pI830->saveBLC_PWM_CTL & - BACKLIGHT_DUTY_CYCLE_MASK); + pI830->last_state.REG_BLC_PWM_CTL2 = INREG(BLC_PWM_CTL2); + pI830->last_state.REG_PP_ON = INREG(LVDSPP_ON); + pI830->last_state.REG_PP_OFF = INREG(LVDSPP_OFF); + pI830->last_state.REG_PP_CONTROL = INREG(PP_CONTROL); + pI830->last_state.REG_PP_CYCLE = INREG(PP_CYCLE); + pI830->last_state.REG_BLC_PWM_CTL = INREG(BLC_PWM_CTL); + dev_priv->backlight_duty_cycle = i830_lvds_get_backlight(output); /* * If the light is off at server startup, just make it full brightness @@ -196,13 +226,13 @@ i830_lvds_restore(xf86OutputPtr output) I830Ptr pI830 = I830PTR(pScrn); if (IS_I965GM(pI830)) - OUTREG(BLC_PWM_CTL2, pI830->saveBLC_PWM_CTL2); - OUTREG(BLC_PWM_CTL, pI830->saveBLC_PWM_CTL); - OUTREG(LVDSPP_ON, pI830->savePP_ON); - OUTREG(LVDSPP_OFF, pI830->savePP_OFF); - OUTREG(PP_CYCLE, pI830->savePP_CYCLE); - OUTREG(PP_CONTROL, pI830->savePP_CONTROL); - if (pI830->savePP_CONTROL & POWER_TARGET_ON) + OUTREG(BLC_PWM_CTL2, pI830->last_state.REG_BLC_PWM_CTL2); + OUTREG(BLC_PWM_CTL, pI830->last_state.REG_BLC_PWM_CTL); + OUTREG(LVDSPP_ON, pI830->last_state.REG_PP_ON); + OUTREG(LVDSPP_OFF, pI830->last_state.REG_PP_OFF); + OUTREG(PP_CYCLE, pI830->last_state.REG_PP_CYCLE); + OUTREG(PP_CONTROL, pI830->last_state.REG_PP_CONTROL); + if (pI830->last_state.REG_PP_CONTROL & POWER_TARGET_ON) i830SetLVDSPanelPower(output, TRUE); else i830SetLVDSPanelPower(output, FALSE);