Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

gma500: Fix backlight crash

Initial changes to get backlight behaviour we want and to fix backlight crashes
on suspend/resume paths.

[Note: on some boxes this will now produce a warning about the backlight, this
isn't a regression it's an unfixed but non harmful case I still need to nail]

Signed-off-by: Alan Cox <alan@linux.intel.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>

authored by

Alan Cox and committed by
Dave Airlie
1f0d0b51 2357f7e6

+33 -27
+1 -1
drivers/gpu/drm/gma500/power.c
··· 302 302 303 303 int psb_runtime_resume(struct device *dev) 304 304 { 305 - return 0; 305 + return gma_power_resume(dev);; 306 306 } 307 307 308 308 int psb_runtime_idle(struct device *dev)
+32 -26
drivers/gpu/drm/gma500/psb_intel_lvds.c
··· 68 68 static u32 psb_intel_lvds_get_max_backlight(struct drm_device *dev) 69 69 { 70 70 struct drm_psb_private *dev_priv = dev->dev_private; 71 - u32 retVal; 71 + u32 ret; 72 72 73 73 if (gma_power_begin(dev, false)) { 74 - retVal = ((REG_READ(BLC_PWM_CTL) & 75 - BACKLIGHT_MODULATION_FREQ_MASK) >> 76 - BACKLIGHT_MODULATION_FREQ_SHIFT) * 2; 77 - 74 + ret = REG_READ(BLC_PWM_CTL); 78 75 gma_power_end(dev); 79 - } else 80 - retVal = ((dev_priv->saveBLC_PWM_CTL & 81 - BACKLIGHT_MODULATION_FREQ_MASK) >> 82 - BACKLIGHT_MODULATION_FREQ_SHIFT) * 2; 76 + } else /* Powered off, use the saved value */ 77 + ret = dev_priv->saveBLC_PWM_CTL; 83 78 84 - return retVal; 79 + /* Top 15bits hold the frequency mask */ 80 + ret = (ret & BACKLIGHT_MODULATION_FREQ_MASK) >> 81 + BACKLIGHT_MODULATION_FREQ_SHIFT; 82 + 83 + ret *= 2; /* Return a 16bit range as needed for setting */ 84 + if (ret == 0) 85 + dev_err(dev->dev, "BL bug: Reg %08x save %08X\n", 86 + REG_READ(BLC_PWM_CTL), dev_priv->saveBLC_PWM_CTL); 87 + return ret; 85 88 } 86 89 87 90 /* ··· 145 142 max_pwm_blc = psb_intel_lvds_get_max_backlight(dev); 146 143 147 144 /*BLC_PWM_CTL Should be initiated while backlight device init*/ 148 - BUG_ON((max_pwm_blc & PSB_BLC_MAX_PWM_REG_FREQ) == 0); 145 + BUG_ON(max_pwm_blc == 0); 149 146 150 147 blc_pwm_duty_cycle = level * max_pwm_blc / BRIGHTNESS_MAX_LEVEL; 151 148 ··· 157 154 (max_pwm_blc << PSB_BACKLIGHT_PWM_CTL_SHIFT) | 158 155 (blc_pwm_duty_cycle)); 159 156 157 + dev_info(dev->dev, "Backlight lvds set brightness %08x\n", 158 + (max_pwm_blc << PSB_BACKLIGHT_PWM_CTL_SHIFT) | 159 + (blc_pwm_duty_cycle)); 160 + 160 161 return 0; 161 162 } 162 163 ··· 169 162 */ 170 163 void psb_intel_lvds_set_brightness(struct drm_device *dev, int level) 171 164 { 172 - /*u32 blc_pwm_ctl;*/ 173 - struct drm_psb_private *dev_priv = 174 - (struct drm_psb_private *)dev->dev_private; 165 + struct drm_psb_private *dev_priv = dev->dev_private; 175 166 176 167 dev_dbg(dev->dev, "backlight level is %d\n", level); 177 168 178 169 if (!dev_priv->lvds_bl) { 179 - dev_err(dev->dev, "NO LVDS Backlight Info\n"); 170 + dev_err(dev->dev, "NO LVDS backlight info\n"); 180 171 return; 181 172 } 182 173 ··· 195 190 u32 blc_pwm_ctl; 196 191 197 192 if (gma_power_begin(dev, false)) { 198 - blc_pwm_ctl = 199 - REG_READ(BLC_PWM_CTL) & ~BACKLIGHT_DUTY_CYCLE_MASK; 193 + blc_pwm_ctl = REG_READ(BLC_PWM_CTL); 194 + blc_pwm_ctl &= ~BACKLIGHT_DUTY_CYCLE_MASK; 200 195 REG_WRITE(BLC_PWM_CTL, 201 196 (blc_pwm_ctl | 202 197 (level << BACKLIGHT_DUTY_CYCLE_SHIFT))); 198 + dev_priv->saveBLC_PWM_CTL = (blc_pwm_ctl | 199 + (level << BACKLIGHT_DUTY_CYCLE_SHIFT)); 203 200 gma_power_end(dev); 204 201 } else { 205 202 blc_pwm_ctl = dev_priv->saveBLC_PWM_CTL & ··· 219 212 { 220 213 u32 pp_status; 221 214 222 - if (!gma_power_begin(dev, true)) 215 + if (!gma_power_begin(dev, true)) { 216 + dev_err(dev->dev, "set power, chip off!\n"); 223 217 return; 224 - 218 + } 219 + 225 220 if (on) { 226 221 REG_WRITE(PP_CONTROL, REG_READ(PP_CONTROL) | 227 222 POWER_TARGET_ON); ··· 305 296 { 306 297 struct drm_device *dev = connector->dev; 307 298 u32 pp_status; 308 - 309 - /*struct drm_psb_private *dev_priv = 310 - (struct drm_psb_private *)dev->dev_private;*/ 311 299 struct psb_intel_output *psb_intel_output = 312 300 to_psb_intel_output(connector); 313 301 struct psb_intel_lvds_priv *lvds_priv = ··· 627 621 goto set_prop_error; 628 622 else { 629 623 #ifdef CONFIG_BACKLIGHT_CLASS_DEVICE 630 - struct drm_psb_private *devp = encoder->dev->dev_private; 624 + struct drm_psb_private *devp = 625 + encoder->dev->dev_private; 631 626 struct backlight_device *bd = devp->backlight_device; 632 627 if (bd) { 633 628 bd->props.brightness = value; ··· 701 694 struct drm_encoder *encoder; 702 695 struct drm_display_mode *scan; /* *modes, *bios_mode; */ 703 696 struct drm_crtc *crtc; 704 - struct drm_psb_private *dev_priv = 705 - (struct drm_psb_private *)dev->dev_private; 697 + struct drm_psb_private *dev_priv = dev->dev_private; 706 698 u32 lvds; 707 699 int pipe; 708 700 ··· 717 711 } 718 712 719 713 psb_intel_output->dev_priv = lvds_priv; 720 - 721 714 psb_intel_output->mode_dev = mode_dev; 715 + 722 716 connector = &psb_intel_output->base; 723 717 encoder = &psb_intel_output->enc; 724 718 drm_connector_init(dev, &psb_intel_output->base,