aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/intel_dp.c
diff options
context:
space:
mode:
authorVille Syrjälä <ville.syrjala@linux.intel.com>2014-08-18 22:16:06 +0300
committerDaniel Vetter <daniel.vetter@ffwll.ch>2014-09-04 14:58:52 +0200
commit6491ab27caa2d802b02bfa620a53476ffae5fa3e (patch)
tree6a057f6b185a9814c2dc3019ee33392fcf41ec8d /drivers/gpu/drm/i915/intel_dp.c
parentdrm/i915: Reset power sequencer pipe tracking when disp2d is off (diff)
downloadlinux-dev-6491ab27caa2d802b02bfa620a53476ffae5fa3e.tar.xz
linux-dev-6491ab27caa2d802b02bfa620a53476ffae5fa3e.zip
drm/i915: Be more careful when picking the initial power sequencer pipe
Try to make sure we find the power sequencer that the BIOS used by first looking for one which has the panel power enabled, then fall back to one with VDD force bit enabled, and finally look at just the port select bits. This should make us pick the correct power sequencer when the BIOS has already enabled the panel. Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Reviewed-by: Imre Deak <imre.deak@intel.com> [danvet: Shorten the vlv_intial_pps_pipe to make lines fit into 80 chars.] Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers/gpu/drm/i915/intel_dp.c')
-rw-r--r--drivers/gpu/drm/i915/intel_dp.c41
1 files changed, 38 insertions, 3 deletions
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 83d2f76cf3e2..b036465e3aa2 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -375,9 +375,31 @@ vlv_power_sequencer_pipe(struct intel_dp *intel_dp)
return intel_dp->pps_pipe;
}
+typedef bool (*vlv_pipe_check)(struct drm_i915_private *dev_priv,
+ enum pipe pipe);
+
+static bool vlv_pipe_has_pp_on(struct drm_i915_private *dev_priv,
+ enum pipe pipe)
+{
+ return I915_READ(VLV_PIPE_PP_STATUS(pipe)) & PP_ON;
+}
+
+static bool vlv_pipe_has_vdd_on(struct drm_i915_private *dev_priv,
+ enum pipe pipe)
+{
+ return I915_READ(VLV_PIPE_PP_CONTROL(pipe)) & EDP_FORCE_VDD;
+}
+
+static bool vlv_pipe_any(struct drm_i915_private *dev_priv,
+ enum pipe pipe)
+{
+ return true;
+}
+
static enum pipe
-vlv_initial_power_sequencer_pipe(struct drm_i915_private *dev_priv,
- enum port port)
+vlv_initial_pps_pipe(struct drm_i915_private *dev_priv,
+ enum port port,
+ vlv_pipe_check pipe_check)
{
enum pipe pipe;
@@ -388,6 +410,9 @@ vlv_initial_power_sequencer_pipe(struct drm_i915_private *dev_priv,
if (port_sel != PANEL_PORT_SELECT_VLV(port))
continue;
+ if (!pipe_check(dev_priv, pipe))
+ continue;
+
return pipe;
}
@@ -406,7 +431,17 @@ vlv_initial_power_sequencer_setup(struct intel_dp *intel_dp)
lockdep_assert_held(&dev_priv->pps_mutex);
/* try to find a pipe with this port selected */
- intel_dp->pps_pipe = vlv_initial_power_sequencer_pipe(dev_priv, port);
+ /* first pick one where the panel is on */
+ intel_dp->pps_pipe = vlv_initial_pps_pipe(dev_priv, port,
+ vlv_pipe_has_pp_on);
+ /* didn't find one? pick one where vdd is on */
+ if (intel_dp->pps_pipe == INVALID_PIPE)
+ intel_dp->pps_pipe = vlv_initial_pps_pipe(dev_priv, port,
+ vlv_pipe_has_vdd_on);
+ /* didn't find one? pick one with just the correct port */
+ if (intel_dp->pps_pipe == INVALID_PIPE)
+ intel_dp->pps_pipe = vlv_initial_pps_pipe(dev_priv, port,
+ vlv_pipe_any);
/* didn't find one? just let vlv_power_sequencer_pipe() pick one when needed */
if (intel_dp->pps_pipe == INVALID_PIPE) {