drm/i915: Only wait for required lanes in vlv_wait_port_ready()
authorVille Syrjälä <ville.syrjala@linux.intel.com>
Fri, 10 Apr 2015 15:21:31 +0000 (18:21 +0300)
committerDaniel Vetter <daniel.vetter@ffwll.ch>
Fri, 8 May 2015 15:26:02 +0000 (17:26 +0200)
Currently vlv_wait_port_ready() waits for all four lanes on the
appropriate channel. This no longer works on CHV when the unused
lanes may be power gated. So pass in a mask of lanes that the
caller is expecting to be ready.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Reviewed-by: Deepak S<deepak.s@linux.intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
drivers/gpu/drm/i915/intel_display.c
drivers/gpu/drm/i915/intel_dp.c
drivers/gpu/drm/i915/intel_drv.h
drivers/gpu/drm/i915/intel_hdmi.c

index fd228a27a7d0d5f9ba525bfc051d37d2b20da952..22e6644f755e4380aed8375f0cf4bc6768d08c12 100644 (file)
@@ -1844,7 +1844,8 @@ static void chv_disable_pll(struct drm_i915_private *dev_priv, enum pipe pipe)
 }
 
 void vlv_wait_port_ready(struct drm_i915_private *dev_priv,
-               struct intel_digital_port *dport)
+                        struct intel_digital_port *dport,
+                        unsigned int expected_mask)
 {
        u32 port_mask;
        int dpll_reg;
@@ -1857,6 +1858,7 @@ void vlv_wait_port_ready(struct drm_i915_private *dev_priv,
        case PORT_C:
                port_mask = DPLL_PORTC_READY_MASK;
                dpll_reg = DPLL(0);
+               expected_mask <<= 4;
                break;
        case PORT_D:
                port_mask = DPLL_PORTD_READY_MASK;
@@ -1866,9 +1868,9 @@ void vlv_wait_port_ready(struct drm_i915_private *dev_priv,
                BUG();
        }
 
-       if (wait_for((I915_READ(dpll_reg) & port_mask) == 0, 1000))
-               WARN(1, "timed out waiting for port %c ready: 0x%08x\n",
-                    port_name(dport->port), I915_READ(dpll_reg));
+       if (wait_for((I915_READ(dpll_reg) & port_mask) == expected_mask, 1000))
+               WARN(1, "timed out waiting for port %c ready: got 0x%x, expected 0x%x\n",
+                    port_name(dport->port), I915_READ(dpll_reg) & port_mask, expected_mask);
 }
 
 static void intel_prepare_shared_dpll(struct intel_crtc *crtc)
index 9cf9208aeaff5d14ae6fb959c203a48916aec769..82dcc6ed8b1d8c4a241497b4f8d0cb664fda032d 100644 (file)
@@ -2497,6 +2497,7 @@ static void intel_enable_dp(struct intel_encoder *encoder)
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc);
        uint32_t dp_reg = I915_READ(intel_dp->output_reg);
+       unsigned int lane_mask = 0x0;
 
        if (WARN_ON(dp_reg & DP_PORT_EN))
                return;
@@ -2515,7 +2516,8 @@ static void intel_enable_dp(struct intel_encoder *encoder)
        pps_unlock(intel_dp);
 
        if (IS_VALLEYVIEW(dev))
-               vlv_wait_port_ready(dev_priv, dp_to_dig_port(intel_dp));
+               vlv_wait_port_ready(dev_priv, dp_to_dig_port(intel_dp),
+                                   lane_mask);
 
        intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON);
        intel_dp_start_link_train(intel_dp);
index 930ea6916d9f17f0b47ee4c1417a1c7f2f3d6413..ea3368e836264876d1319bf652485b99226d6b1c 100644 (file)
@@ -1013,7 +1013,8 @@ intel_wait_for_vblank(struct drm_device *dev, int pipe)
 }
 int ironlake_get_lanes_required(int target_clock, int link_bw, int bpp);
 void vlv_wait_port_ready(struct drm_i915_private *dev_priv,
-                        struct intel_digital_port *dport);
+                        struct intel_digital_port *dport,
+                        unsigned int expected_mask);
 bool intel_get_load_detect_pipe(struct drm_connector *connector,
                                struct drm_display_mode *mode,
                                struct intel_load_detect_pipe *old,
index 86355f1c6f2172205d08c6eff35e8cb9a158d96c..d04e6dc97fe5ca5538bfaee254f42a78a1819938 100644 (file)
@@ -1324,7 +1324,7 @@ static void vlv_hdmi_pre_enable(struct intel_encoder *encoder)
 
        intel_enable_hdmi(encoder);
 
-       vlv_wait_port_ready(dev_priv, dport);
+       vlv_wait_port_ready(dev_priv, dport, 0x0);
 }
 
 static void vlv_hdmi_pre_pll_enable(struct intel_encoder *encoder)
@@ -1641,7 +1641,7 @@ static void chv_hdmi_pre_enable(struct intel_encoder *encoder)
 
        intel_enable_hdmi(encoder);
 
-       vlv_wait_port_ready(dev_priv, dport);
+       vlv_wait_port_ready(dev_priv, dport, 0x0);
 }
 
 static void intel_hdmi_destroy(struct drm_connector *connector)