aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlan Cox <alan@linux.intel.com>2011-11-29 17:26:58 -0500
committerDave Airlie <airlied@redhat.com>2011-12-06 04:55:37 -0500
commit1f0d0b5183c8dd4d58678e8ba35553cabaf87390 (patch)
tree39627a64a010a1057097113be1298301f861edcf
parent2357f7e61f4ca5789ce2ecbe44367acfe078a841 (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.c2
-rw-r--r--drivers/gpu/drm/gma500/psb_intel_lvds.c60
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
303int psb_runtime_resume(struct device *dev) 303int psb_runtime_resume(struct device *dev)
304{ 304{
305 return 0; 305 return gma_power_resume(dev);;
306} 306}
307 307
308int psb_runtime_idle(struct device *dev) 308int 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 {
68static u32 psb_intel_lvds_get_max_backlight(struct drm_device *dev) 68static 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 */
163void psb_intel_lvds_set_brightness(struct drm_device *dev, int level) 170void 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,