|
@@ -717,6 +717,51 @@ intel_dp_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode,
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+static void ironlake_edp_panel_on (struct drm_device *dev)
|
|
|
+{
|
|
|
+ struct drm_i915_private *dev_priv = dev->dev_private;
|
|
|
+ unsigned long timeout = jiffies + msecs_to_jiffies(5000);
|
|
|
+ u32 pp, pp_status;
|
|
|
+
|
|
|
+ pp_status = I915_READ(PCH_PP_STATUS);
|
|
|
+ if (pp_status & PP_ON)
|
|
|
+ return;
|
|
|
+
|
|
|
+ pp = I915_READ(PCH_PP_CONTROL);
|
|
|
+ pp |= PANEL_UNLOCK_REGS | POWER_TARGET_ON;
|
|
|
+ I915_WRITE(PCH_PP_CONTROL, pp);
|
|
|
+ do {
|
|
|
+ pp_status = I915_READ(PCH_PP_STATUS);
|
|
|
+ } while (((pp_status & PP_ON) == 0) && !time_after(jiffies, timeout));
|
|
|
+
|
|
|
+ if (time_after(jiffies, timeout))
|
|
|
+ DRM_DEBUG_KMS("panel on wait timed out: 0x%08x\n", pp_status);
|
|
|
+
|
|
|
+ pp &= ~(PANEL_UNLOCK_REGS | EDP_FORCE_VDD);
|
|
|
+ I915_WRITE(PCH_PP_CONTROL, pp);
|
|
|
+}
|
|
|
+
|
|
|
+static void ironlake_edp_panel_off (struct drm_device *dev)
|
|
|
+{
|
|
|
+ struct drm_i915_private *dev_priv = dev->dev_private;
|
|
|
+ unsigned long timeout = jiffies + msecs_to_jiffies(5000);
|
|
|
+ u32 pp, pp_status;
|
|
|
+
|
|
|
+ pp = I915_READ(PCH_PP_CONTROL);
|
|
|
+ pp &= ~POWER_TARGET_ON;
|
|
|
+ I915_WRITE(PCH_PP_CONTROL, pp);
|
|
|
+ do {
|
|
|
+ pp_status = I915_READ(PCH_PP_STATUS);
|
|
|
+ } while ((pp_status & PP_ON) && !time_after(jiffies, timeout));
|
|
|
+
|
|
|
+ if (time_after(jiffies, timeout))
|
|
|
+ DRM_DEBUG_KMS("panel off wait timed out\n");
|
|
|
+
|
|
|
+ /* Make sure VDD is enabled so DP AUX will work */
|
|
|
+ pp |= EDP_FORCE_VDD;
|
|
|
+ I915_WRITE(PCH_PP_CONTROL, pp);
|
|
|
+}
|
|
|
+
|
|
|
static void ironlake_edp_backlight_on (struct drm_device *dev)
|
|
|
{
|
|
|
struct drm_i915_private *dev_priv = dev->dev_private;
|
|
@@ -751,14 +796,18 @@ intel_dp_dpms(struct drm_encoder *encoder, int mode)
|
|
|
if (mode != DRM_MODE_DPMS_ON) {
|
|
|
if (dp_reg & DP_PORT_EN) {
|
|
|
intel_dp_link_down(intel_encoder, dp_priv->DP);
|
|
|
- if (IS_eDP(intel_encoder))
|
|
|
+ if (IS_eDP(intel_encoder)) {
|
|
|
ironlake_edp_backlight_off(dev);
|
|
|
+ ironlake_edp_backlight_off(dev);
|
|
|
+ }
|
|
|
}
|
|
|
} else {
|
|
|
if (!(dp_reg & DP_PORT_EN)) {
|
|
|
intel_dp_link_train(intel_encoder, dp_priv->DP, dp_priv->link_configuration);
|
|
|
- if (IS_eDP(intel_encoder))
|
|
|
+ if (IS_eDP(intel_encoder)) {
|
|
|
+ ironlake_edp_panel_on(dev);
|
|
|
ironlake_edp_backlight_on(dev);
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
dp_priv->dpms_mode = mode;
|