diff --git a/src/i810_reg.h b/src/i810_reg.h index 248df04..b89fb6d 100644 --- a/src/i810_reg.h +++ b/src/i810_reg.h @@ -1074,6 +1074,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #define BACKLIGHT_MODULATION_FREQ_MASK (0x7fff << 17) #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 +1085,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 aa2b240..1a8ceaf 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_lvds.c b/src/i830_lvds.c index e2c6e3c..20a2888 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; + + /* G33 conveniently changed the location... */ + if (IS_G33CLASS(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. @@ -60,14 +84,9 @@ i830_lvds_set_backlight(xf86OutputPtr output, int level) CARD32 blc_pwm_ctl; blc_pwm_ctl = INREG(BLC_PWM_CTL); - if (blc_pwm_ctl & BLM_LEGACY_MODE) - { - pciWriteByte (pI830->PciTag, - LEGACY_BACKLIGHT_BRIGHTNESS, - level & 0xff); - } - else - { + if (i830_lvds_backlight_legacy(pI830)) { + 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)); } @@ -81,9 +100,9 @@ i830_lvds_get_max_backlight(xf86OutputPtr output) { ScrnInfoPtr pScrn = output->scrn; I830Ptr pI830 = I830PTR(pScrn); - CARD32 pwm_ctl = INREG(BLC_PWM_CTL); + CARD32 pwm_ctl = INREG(BLC_PWM_CTL), pwm_ctl2 = INREG(BLC_PWM_CTL2); - if (pwm_ctl & BLM_LEGACY_MODE) + if (pwm_ctl2 & BLM_LEGACY_MODE) return 0xff; else return ((pwm_ctl & BACKLIGHT_MODULATION_FREQ_MASK) >> @@ -143,13 +162,12 @@ i830_lvds_save (xf86OutputPtr output) 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 - { + if (IS_I965G(pI830)) + pI830->saveBLC_PWM_CTL2 = INREG(BLC_PWM_CTL2); + if (i830_lvds_backlight_legacy(pI830)) { + 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); } @@ -168,6 +186,8 @@ i830_lvds_restore(xf86OutputPtr output) I830Ptr pI830 = I830PTR(pScrn); OUTREG(BLC_PWM_CTL, pI830->saveBLC_PWM_CTL); + if (IS_I965G(pI830)) + OUTREG(BLC_PWM_CTL2, pI830->saveBLC_PWM_CTL2); OUTREG(LVDSPP_ON, pI830->savePP_ON); OUTREG(LVDSPP_OFF, pI830->savePP_OFF); OUTREG(PP_CYCLE, pI830->savePP_CYCLE);