aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915
diff options
context:
space:
mode:
authorDaniel Vetter <daniel.vetter@ffwll.ch>2012-06-05 06:14:54 -0400
committerDaniel Vetter <daniel.vetter@ffwll.ch>2012-06-12 13:27:58 -0400
commit24ded204429fa0f5501d37c63ee35c555c0b75ee (patch)
tree0fcebac4835709b28ed26b30d02b64a88c0e158a /drivers/gpu/drm/i915
parent7cf4160148136deb31ee5f2802857dd935a38529 (diff)
drm/i915: properly enable the blc controller on the right pipe
On gen4+ we have a bitfield to specify from which pipe the backlight controller should take it's clock. For PCH split platforms we've already set these up, but only at initialization time. And without taking into account the 3rd pipe added with ivb. For gen4, we've completely ignored these. Although we do restrict lvds to the 2nd pipe, so this is only a problem on machines where we boot up with the lvds on the first pipe. So restructure the code to enable the backlight on the right pipe at modeset time. v2: For odd reasons panel_enable_backlight gets called twice in a modeset, so we can't WARN_ON in there if the backlight controller is switched on already. v3: backlight enable can also be called through dpms on, so the check in there is legit. Update the comment to reflect that. Tested-By: Kamal Mostafa <kamal@canonical.com> Bugzilla: https://bugs.launchpad.net/bugs/954661 Cc: Carsten Emde <C.Emde@osadl.org> Reviewed-by: Eugeni Dodonov <eugeni.dodonov@intel.com> Signed-Off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers/gpu/drm/i915')
-rw-r--r--drivers/gpu/drm/i915/intel_drv.h3
-rw-r--r--drivers/gpu/drm/i915/intel_lvds.c32
-rw-r--r--drivers/gpu/drm/i915/intel_panel.c38
3 files changed, 45 insertions, 28 deletions
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index c35edd7ca84d..1a1fdb088dda 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -379,7 +379,8 @@ extern u32 intel_panel_get_max_backlight(struct drm_device *dev);
379extern u32 intel_panel_get_backlight(struct drm_device *dev); 379extern u32 intel_panel_get_backlight(struct drm_device *dev);
380extern void intel_panel_set_backlight(struct drm_device *dev, u32 level); 380extern void intel_panel_set_backlight(struct drm_device *dev, u32 level);
381extern int intel_panel_setup_backlight(struct drm_device *dev); 381extern int intel_panel_setup_backlight(struct drm_device *dev);
382extern void intel_panel_enable_backlight(struct drm_device *dev); 382extern void intel_panel_enable_backlight(struct drm_device *dev,
383 enum pipe pipe);
383extern void intel_panel_disable_backlight(struct drm_device *dev); 384extern void intel_panel_disable_backlight(struct drm_device *dev);
384extern void intel_panel_destroy_backlight(struct drm_device *dev); 385extern void intel_panel_destroy_backlight(struct drm_device *dev);
385extern enum drm_connector_status intel_panel_detect(struct drm_device *dev); 386extern enum drm_connector_status intel_panel_detect(struct drm_device *dev);
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c
index a7269e6b4bf7..492db7740de2 100644
--- a/drivers/gpu/drm/i915/intel_lvds.c
+++ b/drivers/gpu/drm/i915/intel_lvds.c
@@ -71,6 +71,7 @@ static struct intel_lvds *intel_attached_lvds(struct drm_connector *connector)
71static void intel_lvds_enable(struct intel_lvds *intel_lvds) 71static void intel_lvds_enable(struct intel_lvds *intel_lvds)
72{ 72{
73 struct drm_device *dev = intel_lvds->base.base.dev; 73 struct drm_device *dev = intel_lvds->base.base.dev;
74 struct intel_crtc *intel_crtc = to_intel_crtc(intel_lvds->base.base.crtc);
74 struct drm_i915_private *dev_priv = dev->dev_private; 75 struct drm_i915_private *dev_priv = dev->dev_private;
75 u32 ctl_reg, lvds_reg, stat_reg; 76 u32 ctl_reg, lvds_reg, stat_reg;
76 77
@@ -107,7 +108,7 @@ static void intel_lvds_enable(struct intel_lvds *intel_lvds)
107 if (wait_for((I915_READ(stat_reg) & PP_ON) != 0, 1000)) 108 if (wait_for((I915_READ(stat_reg) & PP_ON) != 0, 1000))
108 DRM_ERROR("timed out waiting for panel to power on\n"); 109 DRM_ERROR("timed out waiting for panel to power on\n");
109 110
110 intel_panel_enable_backlight(dev); 111 intel_panel_enable_backlight(dev, intel_crtc->pipe);
111} 112}
112 113
113static void intel_lvds_disable(struct intel_lvds *intel_lvds) 114static void intel_lvds_disable(struct intel_lvds *intel_lvds)
@@ -1074,35 +1075,14 @@ bool intel_lvds_init(struct drm_device *dev)
1074 goto failed; 1075 goto failed;
1075 1076
1076out: 1077out:
1078 /*
1079 * Unlock registers and just
1080 * leave them unlocked
1081 */
1077 if (HAS_PCH_SPLIT(dev)) { 1082 if (HAS_PCH_SPLIT(dev)) {
1078 u32 pwm;
1079
1080 pipe = (I915_READ(PCH_LVDS) & LVDS_PIPEB_SELECT) ? 1 : 0;
1081
1082 /* make sure PWM is enabled and locked to the LVDS pipe */
1083 pwm = I915_READ(BLC_PWM_CPU_CTL2);
1084 if (pipe == 0 && (pwm & BLM_PIPE_B))
1085 I915_WRITE(BLC_PWM_CPU_CTL2, pwm & ~BLM_PWM_ENABLE);
1086 if (pipe)
1087 pwm |= BLM_PIPE_B;
1088 else
1089 pwm &= ~BLM_PIPE_B;
1090 I915_WRITE(BLC_PWM_CPU_CTL2, pwm | BLM_PWM_ENABLE);
1091
1092 pwm = I915_READ(BLC_PWM_PCH_CTL1);
1093 pwm |= BLM_PCH_PWM_ENABLE;
1094 I915_WRITE(BLC_PWM_PCH_CTL1, pwm);
1095 /*
1096 * Unlock registers and just
1097 * leave them unlocked
1098 */
1099 I915_WRITE(PCH_PP_CONTROL, 1083 I915_WRITE(PCH_PP_CONTROL,
1100 I915_READ(PCH_PP_CONTROL) | PANEL_UNLOCK_REGS); 1084 I915_READ(PCH_PP_CONTROL) | PANEL_UNLOCK_REGS);
1101 } else { 1085 } else {
1102 /*
1103 * Unlock registers and just
1104 * leave them unlocked
1105 */
1106 I915_WRITE(PP_CONTROL, 1086 I915_WRITE(PP_CONTROL,
1107 I915_READ(PP_CONTROL) | PANEL_UNLOCK_REGS); 1087 I915_READ(PP_CONTROL) | PANEL_UNLOCK_REGS);
1108 } 1088 }
diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c
index 7180cc828f94..58c7ee7238b8 100644
--- a/drivers/gpu/drm/i915/intel_panel.c
+++ b/drivers/gpu/drm/i915/intel_panel.c
@@ -287,9 +287,18 @@ void intel_panel_disable_backlight(struct drm_device *dev)
287 287
288 dev_priv->backlight_enabled = false; 288 dev_priv->backlight_enabled = false;
289 intel_panel_actually_set_backlight(dev, 0); 289 intel_panel_actually_set_backlight(dev, 0);
290
291 if (INTEL_INFO(dev)->gen >= 4) {
292 uint32_t reg;
293
294 reg = HAS_PCH_SPLIT(dev) ? BLC_PWM_CPU_CTL2 : BLC_PWM_CTL2;
295
296 I915_WRITE(reg, I915_READ(reg) & ~BLM_PWM_ENABLE);
297 }
290} 298}
291 299
292void intel_panel_enable_backlight(struct drm_device *dev) 300void intel_panel_enable_backlight(struct drm_device *dev,
301 enum pipe pipe)
293{ 302{
294 struct drm_i915_private *dev_priv = dev->dev_private; 303 struct drm_i915_private *dev_priv = dev->dev_private;
295 304
@@ -298,6 +307,33 @@ void intel_panel_enable_backlight(struct drm_device *dev)
298 307
299 dev_priv->backlight_enabled = true; 308 dev_priv->backlight_enabled = true;
300 intel_panel_actually_set_backlight(dev, dev_priv->backlight_level); 309 intel_panel_actually_set_backlight(dev, dev_priv->backlight_level);
310
311 if (INTEL_INFO(dev)->gen >= 4) {
312 uint32_t reg, tmp;
313
314 reg = HAS_PCH_SPLIT(dev) ? BLC_PWM_CPU_CTL2 : BLC_PWM_CTL2;
315
316
317 tmp = I915_READ(reg);
318
319 /* Note that this can also get called through dpms changes. And
320 * we don't track the backlight dpms state, hence check whether
321 * we have to do anything first. */
322 if (tmp & BLM_PWM_ENABLE)
323 return;
324
325 if (dev_priv->num_pipe == 3)
326 tmp &= ~BLM_PIPE_SELECT_IVB;
327 else
328 tmp &= ~BLM_PIPE_SELECT;
329
330 tmp |= BLM_PIPE(pipe);
331 tmp &= ~BLM_PWM_ENABLE;
332
333 I915_WRITE(reg, tmp);
334 POSTING_READ(reg);
335 I915_WRITE(reg, tmp | BLM_PWM_ENABLE);
336 }
301} 337}
302 338
303static void intel_panel_init_backlight(struct drm_device *dev) 339static void intel_panel_init_backlight(struct drm_device *dev)