Commit 83b84597 authored by Ville Syrjälä's avatar Ville Syrjälä Committed by Daniel Vetter

drm/i915: Clear PPS port select when giving up the power sequencer

VLV gets confused if two power sequencers have the same port selected.
It would seem the port doesn't start up properly in the is case and
vlv_wait_port_ready() will fail as will the link training. Clearing the
port select in the PP_ON_DELAYS register fixes this problem.

CHV doesn't seem to need this, but it doesn't seem to hurt either so
let's just do it for both to keep the code between the platforms as
uniform as possible.
Signed-off-by: default avatarVille Syrjälä <ville.syrjala@linux.intel.com>
Reviewed-by: default avatarImre Deak <imre.deak@intel.com>
Signed-off-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
parent 9a42356b
...@@ -2657,6 +2657,32 @@ static void g4x_pre_enable_dp(struct intel_encoder *encoder) ...@@ -2657,6 +2657,32 @@ static void g4x_pre_enable_dp(struct intel_encoder *encoder)
} }
} }
static void vlv_detach_power_sequencer(struct intel_dp *intel_dp)
{
struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
struct drm_i915_private *dev_priv = intel_dig_port->base.base.dev->dev_private;
enum pipe pipe = intel_dp->pps_pipe;
int pp_on_reg = VLV_PIPE_PP_ON_DELAYS(pipe);
edp_panel_vdd_off_sync(intel_dp);
/*
* VLV seems to get confused when multiple power seqeuencers
* have the same port selected (even if only one has power/vdd
* enabled). The failure manifests as vlv_wait_port_ready() failing
* CHV on the other hand doesn't seem to mind having the same port
* selected in multiple power seqeuencers, but let's clear the
* port select always when logically disconnecting a power sequencer
* from a port.
*/
DRM_DEBUG_KMS("detaching pipe %c power sequencer from port %c\n",
pipe_name(pipe), port_name(intel_dig_port->port));
I915_WRITE(pp_on_reg, 0);
POSTING_READ(pp_on_reg);
intel_dp->pps_pipe = INVALID_PIPE;
}
static void vlv_steal_power_sequencer(struct drm_device *dev, static void vlv_steal_power_sequencer(struct drm_device *dev,
enum pipe pipe) enum pipe pipe)
{ {
...@@ -2683,9 +2709,7 @@ static void vlv_steal_power_sequencer(struct drm_device *dev, ...@@ -2683,9 +2709,7 @@ static void vlv_steal_power_sequencer(struct drm_device *dev,
pipe_name(pipe), port_name(port)); pipe_name(pipe), port_name(port));
/* make sure vdd is off before we steal it */ /* make sure vdd is off before we steal it */
edp_panel_vdd_off_sync(intel_dp); vlv_detach_power_sequencer(intel_dp);
intel_dp->pps_pipe = INVALID_PIPE;
} }
} }
...@@ -2711,7 +2735,7 @@ static void vlv_init_panel_power_sequencer(struct intel_dp *intel_dp) ...@@ -2711,7 +2735,7 @@ static void vlv_init_panel_power_sequencer(struct intel_dp *intel_dp)
* we still have control of it. * we still have control of it.
*/ */
if (intel_dp->pps_pipe != INVALID_PIPE) if (intel_dp->pps_pipe != INVALID_PIPE)
edp_panel_vdd_off_sync(intel_dp); vlv_detach_power_sequencer(intel_dp);
/* /*
* We may be stealing the power * We may be stealing the power
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment