Skip to content

Commit

Permalink
drm/i915: make sure eDP panel is turned on
Browse files Browse the repository at this point in the history
commit 9934c13 upstream.

When enabling the eDP port, we need to make sure the panel is turned on
after training the link.  If we don't, it likely won't come back after
suspend or may not come up at all.

For unknown reasons, unlocking the panel regs before initiating a power
on sequence is necessary.  There are known bugs in the PCH panel
sequencing logic, apparently this is one possible workaround.

Fixes https://bugs.freedesktop.org/show_bug.cgi?id=28739.

Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Tested-by: "Paulo J. S. Silva" <pjssilva@gmail.com>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
  • Loading branch information
Jesse Barnes authored and Greg Kroah-Hartman committed Aug 2, 2010
1 parent 4a501bb commit c9fcc5d
Showing 1 changed file with 51 additions and 2 deletions.
53 changes: 51 additions & 2 deletions drivers/gpu/drm/i915/intel_dp.c
Original file line number Diff line number Diff line change
Expand Up @@ -677,6 +677,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;
Expand Down Expand Up @@ -711,14 +756,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;
Expand Down

0 comments on commit c9fcc5d

Please sign in to comment.