diff --git a/src/i810_reg.h b/src/i810_reg.h index 248df04..d1fed22 100644 --- a/src/i810_reg.h +++ b/src/i810_reg.h @@ -822,6 +822,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # define PP_SEQUENCE_MASK 0x30000000 #define PP_CONTROL 0x61204 +# define POWER_DOWN_ON_RESET (1 << 1) # define POWER_TARGET_ON (1 << 0) #define LVDSPP_ON 0x61208 @@ -1066,6 +1067,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define BLC_PWM_CTL 0x61254 #define BACKLIGHT_MODULATION_FREQ_SHIFT (17) +#define BACKLIGHT_MODULATION_FREQ_SHIFT2 (16) /** * This is the most significant 15 bits of the number of backlight cycles in a * complete cycle of the modulated backlight control. @@ -1073,7 +1075,9 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * The actual value is this field multiplied by two. */ #define BACKLIGHT_MODULATION_FREQ_MASK (0x7fff << 17) +#define BACKLIGHT_MODULATION_FREQ_MASK2 (0xffff << 16) #define BLM_LEGACY_MODE (1 << 16) + /** * This is the number of cycles out of the backlight modulation cycle for which * the backlight is on. @@ -1084,6 +1088,10 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define BACKLIGHT_DUTY_CYCLE_SHIFT (0) #define BACKLIGHT_DUTY_CYCLE_MASK (0xffff) +/* On 965+ backlight control is in another register */ +#define BLC_PWM_CTL2 0x61250 +#define BLM_LEGACY_MODE2 (1 << 30) + #define BLM_CTL 0x61260 #define BLM_THRESHOLD_0 0x61270 #define BLM_THRESHOLD_1 0x61274 diff --git a/src/i830.h b/src/i830.h index bf072a1..a8de0e6 100644 --- a/src/i830.h +++ b/src/i830.h @@ -532,6 +532,7 @@ typedef struct _I830Rec { 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; diff --git a/src/i830_driver.c b/src/i830_driver.c index f293bfd..a87b70d 100644 --- a/src/i830_driver.c +++ b/src/i830_driver.c @@ -2916,6 +2916,8 @@ I830EnterVT(int scrnIndex, int flags) pI830->leaving = FALSE; + RestoreHWState(pScrn); + if (I830IsPrimary(pScrn)) if (!i830_bind_all_memory(pScrn)) return FALSE; diff --git a/src/i830_lvds.c b/src/i830_lvds.c index 246008b..b38d0f8 100644 --- a/src/i830_lvds.c +++ b/src/i830_lvds.c @@ -46,6 +46,30 @@ struct i830_lvds_priv { int backlight_duty_cycle; }; +/** + * Use legacy backlight controls? + * + * \param pI830 device in question + * + * Returns TRUE if legacy backlight should be used, false otherwise. + */ +static int +i830_lvds_backlight_legacy(I830Ptr pI830) +{ + CARD32 blc_pwm_ctl, blc_pwm_ctl2; + + /* 965GM+ change the location of the legacy control bit */ + if (IS_I965GM(pI830)) { + blc_pwm_ctl2 = INREG(BLC_PWM_CTL2); + if (blc_pwm_ctl2 & BLM_LEGACY_MODE2) + return TRUE; + } else { + blc_pwm_ctl = INREG(BLC_PWM_CTL); + if (blc_pwm_ctl & BLM_LEGACY_MODE) + return TRUE; + } + return FALSE; +} /** * Sets the backlight level. @@ -59,18 +83,12 @@ i830_lvds_set_backlight(xf86OutputPtr output, int level) I830Ptr pI830 = I830PTR(pScrn); CARD32 blc_pwm_ctl; + if (i830_lvds_backlight_legacy(pI830)) + pciWriteByte(pI830->PciTag, LEGACY_BACKLIGHT_BRIGHTNESS, 0xfe); + blc_pwm_ctl = INREG(BLC_PWM_CTL); - if (blc_pwm_ctl & BLM_LEGACY_MODE) - { - pciWriteByte (pI830->PciTag, - LEGACY_BACKLIGHT_BRIGHTNESS, - level & 0xff); - } - else - { - blc_pwm_ctl &= ~BACKLIGHT_DUTY_CYCLE_MASK; - OUTREG(BLC_PWM_CTL, blc_pwm_ctl | (level << BACKLIGHT_DUTY_CYCLE_SHIFT)); - } + blc_pwm_ctl &= ~BACKLIGHT_DUTY_CYCLE_MASK; + OUTREG(BLC_PWM_CTL, blc_pwm_ctl | (level << BACKLIGHT_DUTY_CYCLE_SHIFT)); } /** @@ -82,12 +100,24 @@ i830_lvds_get_max_backlight(xf86OutputPtr output) ScrnInfoPtr pScrn = output->scrn; I830Ptr pI830 = I830PTR(pScrn); CARD32 pwm_ctl = INREG(BLC_PWM_CTL); + CARD32 val; + + if (IS_I965GM(pI830)) { + val = ((pwm_ctl & BACKLIGHT_MODULATION_FREQ_MASK2) >> + BACKLIGHT_MODULATION_FREQ_SHIFT2); + } else { + val = ((pwm_ctl & BACKLIGHT_MODULATION_FREQ_MASK) >> + BACKLIGHT_MODULATION_FREQ_SHIFT) * 2; + } - if (pwm_ctl & BLM_LEGACY_MODE) - return 0xff; - else - return ((pwm_ctl & BACKLIGHT_MODULATION_FREQ_MASK) >> - BACKLIGHT_MODULATION_FREQ_SHIFT) * 2; + /* + * In legacy control mode, backlight value is calculated: + * if (LBB[7:0] != 0xff) + * backlight = BLC_PWM_CTL[15:0] * BPC[7:0] + * else + * backlight = BLC_PWM_CTL[15:0] + */ + return val; } /** @@ -122,6 +152,8 @@ i830SetLVDSPanelPower(xf86OutputPtr output, Bool on) static void i830_lvds_dpms (xf86OutputPtr output, int mode) { + I830OutputPrivatePtr intel_output = output->driver_private; + if (mode == DPMSModeOn) i830SetLVDSPanelPower(output, TRUE); else @@ -138,21 +170,15 @@ i830_lvds_save (xf86OutputPtr output) ScrnInfoPtr pScrn = output->scrn; 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); - if (pI830->saveBLC_PWM_CTL & BLM_LEGACY_MODE) - { - dev_priv->backlight_duty_cycle = pciReadByte (pI830->PciTag, - LEGACY_BACKLIGHT_BRIGHTNESS); - } - else - { - dev_priv->backlight_duty_cycle = (pI830->saveBLC_PWM_CTL & - BACKLIGHT_DUTY_CYCLE_MASK); - } + dev_priv->backlight_duty_cycle = (pI830->saveBLC_PWM_CTL & + BACKLIGHT_DUTY_CYCLE_MASK); /* * If the light is off at server startup, just make it full brightness @@ -167,6 +193,8 @@ i830_lvds_restore(xf86OutputPtr output) ScrnInfoPtr pScrn = output->scrn; 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);