diff options
author | Alan Cox <alan@linux.intel.com> | 2011-11-29 17:26:58 -0500 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2011-12-06 04:55:37 -0500 |
commit | 1f0d0b5183c8dd4d58678e8ba35553cabaf87390 (patch) | |
tree | 39627a64a010a1057097113be1298301f861edcf | |
parent | 2357f7e61f4ca5789ce2ecbe44367acfe078a841 (diff) |
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>
-rw-r--r-- | drivers/gpu/drm/gma500/power.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/gma500/psb_intel_lvds.c | 60 |
2 files changed, 34 insertions, 28 deletions
diff --git a/drivers/gpu/drm/gma500/power.c b/drivers/gpu/drm/gma500/power.c index 972bea7c1af2..94025693bae1 100644 --- a/drivers/gpu/drm/gma500/power.c +++ b/drivers/gpu/drm/gma500/power.c | |||
@@ -302,7 +302,7 @@ int psb_runtime_suspend(struct device *dev) | |||
302 | 302 | ||
303 | int psb_runtime_resume(struct device *dev) | 303 | int psb_runtime_resume(struct device *dev) |
304 | { | 304 | { |
305 | return 0; | 305 | return gma_power_resume(dev);; |
306 | } | 306 | } |
307 | 307 | ||
308 | int psb_runtime_idle(struct device *dev) | 308 | int psb_runtime_idle(struct device *dev) |
diff --git a/drivers/gpu/drm/gma500/psb_intel_lvds.c b/drivers/gpu/drm/gma500/psb_intel_lvds.c index 8b951e3afd49..21022e1a977a 100644 --- a/drivers/gpu/drm/gma500/psb_intel_lvds.c +++ b/drivers/gpu/drm/gma500/psb_intel_lvds.c | |||
@@ -68,20 +68,23 @@ struct psb_intel_lvds_priv { | |||
68 | static u32 psb_intel_lvds_get_max_backlight(struct drm_device *dev) | 68 | static u32 psb_intel_lvds_get_max_backlight(struct drm_device *dev) |
69 | { | 69 | { |
70 | struct drm_psb_private *dev_priv = dev->dev_private; | 70 | struct drm_psb_private *dev_priv = dev->dev_private; |
71 | u32 retVal; | 71 | u32 ret; |
72 | 72 | ||
73 | if (gma_power_begin(dev, false)) { | 73 | if (gma_power_begin(dev, false)) { |
74 | retVal = ((REG_READ(BLC_PWM_CTL) & | 74 | ret = REG_READ(BLC_PWM_CTL); |
75 | BACKLIGHT_MODULATION_FREQ_MASK) >> | ||
76 | BACKLIGHT_MODULATION_FREQ_SHIFT) * 2; | ||
77 | |||
78 | gma_power_end(dev); | 75 | gma_power_end(dev); |
79 | } else | 76 | } else /* Powered off, use the saved value */ |
80 | retVal = ((dev_priv->saveBLC_PWM_CTL & | 77 | ret = dev_priv->saveBLC_PWM_CTL; |
81 | BACKLIGHT_MODULATION_FREQ_MASK) >> | 78 | |
82 | BACKLIGHT_MODULATION_FREQ_SHIFT) * 2; | 79 | /* Top 15bits hold the frequency mask */ |
83 | 80 | ret = (ret & BACKLIGHT_MODULATION_FREQ_MASK) >> | |
84 | return retVal; | 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 | /* |
@@ -142,7 +145,7 @@ static int psb_lvds_pwm_set_brightness(struct drm_device *dev, int level) | |||
142 | max_pwm_blc = psb_intel_lvds_get_max_backlight(dev); | 145 | max_pwm_blc = psb_intel_lvds_get_max_backlight(dev); |
143 | 146 | ||
144 | /*BLC_PWM_CTL Should be initiated while backlight device init*/ | 147 | /*BLC_PWM_CTL Should be initiated while backlight device init*/ |
145 | BUG_ON((max_pwm_blc & PSB_BLC_MAX_PWM_REG_FREQ) == 0); | 148 | BUG_ON(max_pwm_blc == 0); |
146 | 149 | ||
147 | blc_pwm_duty_cycle = level * max_pwm_blc / BRIGHTNESS_MAX_LEVEL; | 150 | blc_pwm_duty_cycle = level * max_pwm_blc / BRIGHTNESS_MAX_LEVEL; |
148 | 151 | ||
@@ -154,6 +157,10 @@ static int psb_lvds_pwm_set_brightness(struct drm_device *dev, int level) | |||
154 | (max_pwm_blc << PSB_BACKLIGHT_PWM_CTL_SHIFT) | | 157 | (max_pwm_blc << PSB_BACKLIGHT_PWM_CTL_SHIFT) | |
155 | (blc_pwm_duty_cycle)); | 158 | (blc_pwm_duty_cycle)); |
156 | 159 | ||
160 | dev_info(dev->dev, "Backlight lvds set brightness %08x\n", | ||
161 | (max_pwm_blc << PSB_BACKLIGHT_PWM_CTL_SHIFT) | | ||
162 | (blc_pwm_duty_cycle)); | ||
163 | |||
157 | return 0; | 164 | return 0; |
158 | } | 165 | } |
159 | 166 | ||
@@ -162,14 +169,12 @@ static int psb_lvds_pwm_set_brightness(struct drm_device *dev, int level) | |||
162 | */ | 169 | */ |
163 | void psb_intel_lvds_set_brightness(struct drm_device *dev, int level) | 170 | void psb_intel_lvds_set_brightness(struct drm_device *dev, int level) |
164 | { | 171 | { |
165 | /*u32 blc_pwm_ctl;*/ | 172 | struct drm_psb_private *dev_priv = dev->dev_private; |
166 | struct drm_psb_private *dev_priv = | ||
167 | (struct drm_psb_private *)dev->dev_private; | ||
168 | 173 | ||
169 | dev_dbg(dev->dev, "backlight level is %d\n", level); | 174 | dev_dbg(dev->dev, "backlight level is %d\n", level); |
170 | 175 | ||
171 | if (!dev_priv->lvds_bl) { | 176 | if (!dev_priv->lvds_bl) { |
172 | dev_err(dev->dev, "NO LVDS Backlight Info\n"); | 177 | dev_err(dev->dev, "NO LVDS backlight info\n"); |
173 | return; | 178 | return; |
174 | } | 179 | } |
175 | 180 | ||
@@ -190,11 +195,13 @@ static void psb_intel_lvds_set_backlight(struct drm_device *dev, int level) | |||
190 | u32 blc_pwm_ctl; | 195 | u32 blc_pwm_ctl; |
191 | 196 | ||
192 | if (gma_power_begin(dev, false)) { | 197 | if (gma_power_begin(dev, false)) { |
193 | blc_pwm_ctl = | 198 | blc_pwm_ctl = REG_READ(BLC_PWM_CTL); |
194 | REG_READ(BLC_PWM_CTL) & ~BACKLIGHT_DUTY_CYCLE_MASK; | 199 | blc_pwm_ctl &= ~BACKLIGHT_DUTY_CYCLE_MASK; |
195 | REG_WRITE(BLC_PWM_CTL, | 200 | REG_WRITE(BLC_PWM_CTL, |
196 | (blc_pwm_ctl | | 201 | (blc_pwm_ctl | |
197 | (level << BACKLIGHT_DUTY_CYCLE_SHIFT))); | 202 | (level << BACKLIGHT_DUTY_CYCLE_SHIFT))); |
203 | dev_priv->saveBLC_PWM_CTL = (blc_pwm_ctl | | ||
204 | (level << BACKLIGHT_DUTY_CYCLE_SHIFT)); | ||
198 | gma_power_end(dev); | 205 | gma_power_end(dev); |
199 | } else { | 206 | } else { |
200 | blc_pwm_ctl = dev_priv->saveBLC_PWM_CTL & | 207 | blc_pwm_ctl = dev_priv->saveBLC_PWM_CTL & |
@@ -212,9 +219,11 @@ static void psb_intel_lvds_set_power(struct drm_device *dev, | |||
212 | { | 219 | { |
213 | u32 pp_status; | 220 | u32 pp_status; |
214 | 221 | ||
215 | if (!gma_power_begin(dev, true)) | 222 | if (!gma_power_begin(dev, true)) { |
223 | dev_err(dev->dev, "set power, chip off!\n"); | ||
216 | return; | 224 | return; |
217 | 225 | } | |
226 | |||
218 | if (on) { | 227 | if (on) { |
219 | REG_WRITE(PP_CONTROL, REG_READ(PP_CONTROL) | | 228 | REG_WRITE(PP_CONTROL, REG_READ(PP_CONTROL) | |
220 | POWER_TARGET_ON); | 229 | POWER_TARGET_ON); |
@@ -296,9 +305,6 @@ static void psb_intel_lvds_restore(struct drm_connector *connector) | |||
296 | { | 305 | { |
297 | struct drm_device *dev = connector->dev; | 306 | struct drm_device *dev = connector->dev; |
298 | u32 pp_status; | 307 | u32 pp_status; |
299 | |||
300 | /*struct drm_psb_private *dev_priv = | ||
301 | (struct drm_psb_private *)dev->dev_private;*/ | ||
302 | struct psb_intel_output *psb_intel_output = | 308 | struct psb_intel_output *psb_intel_output = |
303 | to_psb_intel_output(connector); | 309 | to_psb_intel_output(connector); |
304 | struct psb_intel_lvds_priv *lvds_priv = | 310 | struct psb_intel_lvds_priv *lvds_priv = |
@@ -621,7 +627,8 @@ int psb_intel_lvds_set_property(struct drm_connector *connector, | |||
621 | goto set_prop_error; | 627 | goto set_prop_error; |
622 | else { | 628 | else { |
623 | #ifdef CONFIG_BACKLIGHT_CLASS_DEVICE | 629 | #ifdef CONFIG_BACKLIGHT_CLASS_DEVICE |
624 | struct drm_psb_private *devp = encoder->dev->dev_private; | 630 | struct drm_psb_private *devp = |
631 | encoder->dev->dev_private; | ||
625 | struct backlight_device *bd = devp->backlight_device; | 632 | struct backlight_device *bd = devp->backlight_device; |
626 | if (bd) { | 633 | if (bd) { |
627 | bd->props.brightness = value; | 634 | bd->props.brightness = value; |
@@ -694,8 +701,7 @@ void psb_intel_lvds_init(struct drm_device *dev, | |||
694 | struct drm_encoder *encoder; | 701 | struct drm_encoder *encoder; |
695 | struct drm_display_mode *scan; /* *modes, *bios_mode; */ | 702 | struct drm_display_mode *scan; /* *modes, *bios_mode; */ |
696 | struct drm_crtc *crtc; | 703 | struct drm_crtc *crtc; |
697 | struct drm_psb_private *dev_priv = | 704 | struct drm_psb_private *dev_priv = dev->dev_private; |
698 | (struct drm_psb_private *)dev->dev_private; | ||
699 | u32 lvds; | 705 | u32 lvds; |
700 | int pipe; | 706 | int pipe; |
701 | 707 | ||
@@ -711,8 +717,8 @@ void psb_intel_lvds_init(struct drm_device *dev, | |||
711 | } | 717 | } |
712 | 718 | ||
713 | psb_intel_output->dev_priv = lvds_priv; | 719 | psb_intel_output->dev_priv = lvds_priv; |
714 | |||
715 | psb_intel_output->mode_dev = mode_dev; | 720 | psb_intel_output->mode_dev = mode_dev; |
721 | |||
716 | connector = &psb_intel_output->base; | 722 | connector = &psb_intel_output->base; |
717 | encoder = &psb_intel_output->enc; | 723 | encoder = &psb_intel_output->enc; |
718 | drm_connector_init(dev, &psb_intel_output->base, | 724 | drm_connector_init(dev, &psb_intel_output->base, |