From: Ville Syrjälä <ville.syrj...@linux.intel.com>

Clean up the DP pipe select bits. To make the whole situation a bit
less ugly we'll start to share the same code between .get_hw_state(),
the port state asserts, and the VLV power sequencer code.

v2: Return PIPE_A for cpt/ppt when the port isn't selected by
    any transcoder. Returning INVALID_PIPE explodes *somewhere*
    on some machines (can't immediately see where though). This
    now matches the old behaviour.

Signed-off-by: Ville Syrjälä <ville.syrj...@linux.intel.com>
---
 drivers/gpu/drm/i915/i915_reg.h      |  24 +++-----
 drivers/gpu/drm/i915/intel_display.c |  46 +++++----------
 drivers/gpu/drm/i915/intel_dp.c      | 110 ++++++++++++++++++++---------------
 drivers/gpu/drm/i915/intel_drv.h     |   3 +
 4 files changed, 90 insertions(+), 93 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index dc9fc6220509..9548e0bee7db 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -5248,10 +5248,15 @@ enum {
 #define CHV_DP_D               _MMIO(VLV_DISPLAY_BASE + 0x64300)
 
 #define   DP_PORT_EN                   (1 << 31)
-#define   DP_PIPEB_SELECT              (1 << 30)
-#define   DP_PIPE_MASK                 (1 << 30)
-#define   DP_PIPE_SELECT_CHV(pipe)     ((pipe) << 16)
-#define   DP_PIPE_MASK_CHV             (3 << 16)
+#define   DP_PIPE_SEL(pipe)            ((pipe) << 30)
+#define   DP_PIPE_SEL_MASK             (1 << 30)
+#define   DP_PIPE_SEL_SHIFT            30
+#define   DP_PIPE_SEL_IVB(pipe)                ((pipe) << 29)
+#define   DP_PIPE_SEL_MASK_IVB         (3 << 29)
+#define   DP_PIPE_SEL_SHIFT_IVB                29
+#define   DP_PIPE_SEL_CHV(pipe)                ((pipe) << 16)
+#define   DP_PIPE_SEL_MASK_CHV         (3 << 16)
+#define   DP_PIPE_SEL_SHIFT_CHV                16
 
 /* Link training mode - select a suitable mode for each stage */
 #define   DP_LINK_TRAIN_PAT_1          (0 << 28)
@@ -7921,16 +7926,6 @@ enum {
 #define PCH_DP_AUX_CH_DATA(aux_ch, i)  _MMIO(_PORT((aux_ch) - AUX_CH_B, 
_PCH_DPB_AUX_CH_DATA1, _PCH_DPC_AUX_CH_DATA1) + (i) * 4) /* 5 registers */
 
 /* CPT */
-#define  PORT_TRANS_A_SEL_CPT  0
-#define  PORT_TRANS_B_SEL_CPT  (1<<29)
-#define  PORT_TRANS_C_SEL_CPT  (2<<29)
-#define  PORT_TRANS_SEL_MASK   (3<<29)
-#define  PORT_TRANS_SEL_CPT(pipe)      ((pipe) << 29)
-#define  PORT_TO_PIPE(val)     (((val) & (1<<30)) >> 30)
-#define  PORT_TO_PIPE_CPT(val) (((val) & PORT_TRANS_SEL_MASK) >> 29)
-#define  SDVO_PORT_TO_PIPE_CHV(val)    (((val) & (3<<24)) >> 24)
-#define  DP_PORT_TO_PIPE_CHV(val)      (((val) & (3<<16)) >> 16)
-
 #define _TRANS_DP_CTL_A                0xe0300
 #define _TRANS_DP_CTL_B                0xe1300
 #define _TRANS_DP_CTL_C                0xe2300
@@ -7939,7 +7934,6 @@ enum {
 #define  TRANS_DP_PORT_SEL(port)       (((port) - PORT_B) << 29)
 #define  TRANS_DP_PORT_SEL_NONE                (3 << 29)
 #define  TRANS_DP_PORT_SEL_MASK                (3 << 29)
-#define  TRANS_DP_PIPE_TO_PORT(val)    ((((val) & TRANS_DP_PORT_SEL_MASK) >> 
29) + PORT_B)
 #define  TRANS_DP_AUDIO_ONLY   (1<<26)
 #define  TRANS_DP_ENH_FRAMING  (1<<18)
 #define  TRANS_DP_8BPC         (0<<9)
diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index 43b589dfe71f..dfe3a17b86d1 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -1261,38 +1261,22 @@ void assert_pch_transcoder_disabled(struct 
drm_i915_private *dev_priv,
             pipe_name(pipe));
 }
 
-static bool dp_pipe_enabled(struct drm_i915_private *dev_priv,
-                           enum pipe pipe, u32 port_sel, u32 val)
+static void assert_pch_dp_disabled(struct drm_i915_private *dev_priv,
+                                  enum pipe pipe, enum port port,
+                                  i915_reg_t dp_reg)
 {
-       if ((val & DP_PORT_EN) == 0)
-               return false;
+       enum pipe port_pipe;
+       bool state;
 
-       if (HAS_PCH_CPT(dev_priv)) {
-               u32 trans_dp_ctl = I915_READ(TRANS_DP_CTL(pipe));
-               if ((trans_dp_ctl & TRANS_DP_PORT_SEL_MASK) != port_sel)
-                       return false;
-       } else if (IS_CHERRYVIEW(dev_priv)) {
-               if ((val & DP_PIPE_MASK_CHV) != DP_PIPE_SELECT_CHV(pipe))
-                       return false;
-       } else {
-               if ((val & DP_PIPE_MASK) != (pipe << 30))
-                       return false;
-       }
-       return true;
-}
+       state = intel_dp_port_enabled(dev_priv, dp_reg, port, &port_pipe);
 
-static void assert_pch_dp_disabled(struct drm_i915_private *dev_priv,
-                                  enum pipe pipe, i915_reg_t reg,
-                                  u32 port_sel)
-{
-       u32 val = I915_READ(reg);
-       I915_STATE_WARN(dp_pipe_enabled(dev_priv, pipe, port_sel, val),
-            "PCH DP (0x%08x) enabled on transcoder %c, should be disabled\n",
-            i915_mmio_reg_offset(reg), pipe_name(pipe));
+       I915_STATE_WARN(state && port_pipe == pipe,
+                       "PCH DP %c enabled on transcoder %c, should be 
disabled\n",
+                       port_name(port), pipe_name(pipe));
 
-       I915_STATE_WARN(HAS_PCH_IBX(dev_priv) && (val & DP_PORT_EN) == 0
-            && (val & DP_PIPEB_SELECT),
-            "IBX PCH dp port still using transcoder B\n");
+       I915_STATE_WARN(HAS_PCH_IBX(dev_priv) && !state && port_pipe == PIPE_B,
+                       "IBX PCH DP %c still using transcoder B\n",
+                       port_name(port));
 }
 
 static void assert_pch_hdmi_disabled(struct drm_i915_private *dev_priv,
@@ -1318,9 +1302,9 @@ static void assert_pch_ports_disabled(struct 
drm_i915_private *dev_priv,
 {
        enum pipe port_pipe;
 
-       assert_pch_dp_disabled(dev_priv, pipe, PCH_DP_B, 
TRANS_DP_PORT_SEL(PORT_B));
-       assert_pch_dp_disabled(dev_priv, pipe, PCH_DP_C, 
TRANS_DP_PORT_SEL(PORT_C));
-       assert_pch_dp_disabled(dev_priv, pipe, PCH_DP_D, 
TRANS_DP_PORT_SEL(PORT_D));
+       assert_pch_dp_disabled(dev_priv, pipe, PORT_B, PCH_DP_B);
+       assert_pch_dp_disabled(dev_priv, pipe, PORT_C, PCH_DP_C);
+       assert_pch_dp_disabled(dev_priv, pipe, PORT_D, PCH_DP_D);
 
        I915_STATE_WARN(intel_crt_port_enabled(dev_priv, PCH_ADPA, &port_pipe) 
&&
                        port_pipe == pipe,
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 2a82eccffe54..638a9dd05592 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -532,9 +532,9 @@ vlv_power_sequencer_kick(struct intel_dp *intel_dp)
        DP |= DP_LINK_TRAIN_PAT_1;
 
        if (IS_CHERRYVIEW(dev_priv))
-               DP |= DP_PIPE_SELECT_CHV(pipe);
-       else if (pipe == PIPE_B)
-               DP |= DP_PIPEB_SELECT;
+               DP |= DP_PIPE_SEL_CHV(pipe);
+       else
+               DP |= DP_PIPE_SEL(pipe);
 
        pll_enabled = I915_READ(DPLL(pipe)) & DPLL_VCO_ENABLE;
 
@@ -1980,7 +1980,7 @@ static void intel_dp_prepare(struct intel_encoder 
*encoder,
                if (drm_dp_enhanced_frame_cap(intel_dp->dpcd))
                        intel_dp->DP |= DP_ENHANCED_FRAMING;
 
-               intel_dp->DP |= crtc->pipe << 29;
+               intel_dp->DP |= DP_PIPE_SEL_IVB(crtc->pipe);
        } else if (HAS_PCH_CPT(dev_priv) && port != PORT_A) {
                u32 trans_dp;
 
@@ -2006,9 +2006,9 @@ static void intel_dp_prepare(struct intel_encoder 
*encoder,
                        intel_dp->DP |= DP_ENHANCED_FRAMING;
 
                if (IS_CHERRYVIEW(dev_priv))
-                       intel_dp->DP |= DP_PIPE_SELECT_CHV(crtc->pipe);
-               else if (crtc->pipe == PIPE_B)
-                       intel_dp->DP |= DP_PIPEB_SELECT;
+                       intel_dp->DP |= DP_PIPE_SEL_CHV(crtc->pipe);
+               else
+                       intel_dp->DP |= DP_PIPE_SEL(crtc->pipe);
        }
 }
 
@@ -2630,52 +2630,67 @@ void intel_dp_sink_dpms(struct intel_dp *intel_dp, int 
mode)
                              mode == DRM_MODE_DPMS_ON ? "enable" : "disable");
 }
 
-static bool intel_dp_get_hw_state(struct intel_encoder *encoder,
-                                 enum pipe *pipe)
+static bool cpt_dp_port_selected(struct drm_i915_private *dev_priv,
+                                enum port port, enum pipe *pipe)
 {
-       struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
-       struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
-       enum port port = encoder->port;
-       u32 tmp;
-       bool ret;
+       enum pipe p;
 
-       if (!intel_display_power_get_if_enabled(dev_priv,
-                                               encoder->power_domain))
-               return false;
+       for_each_pipe(dev_priv, p) {
+               u32 val = I915_READ(TRANS_DP_CTL(p));
+
+               if ((val & TRANS_DP_PORT_SEL_MASK) == TRANS_DP_PORT_SEL(port)) {
+                       *pipe = p;
+                       return true;
+               }
+       }
 
-       ret = false;
+       DRM_DEBUG_KMS("No pipe for DP port %c found\n", port_name(port));
 
-       tmp = I915_READ(intel_dp->output_reg);
+       /* must initialize pipe to something for the asserts */
+       *pipe = PIPE_A;
 
-       if (!(tmp & DP_PORT_EN))
-               goto out;
+       return false;
+}
 
-       if (IS_IVYBRIDGE(dev_priv) && port == PORT_A) {
-               *pipe = PORT_TO_PIPE_CPT(tmp);
-       } else if (HAS_PCH_CPT(dev_priv) && port != PORT_A) {
-               enum pipe p;
+bool intel_dp_port_enabled(struct drm_i915_private *dev_priv,
+                          i915_reg_t dp_reg, enum port port,
+                          enum pipe *pipe)
+{
+       bool ret;
+       u32 val;
 
-               for_each_pipe(dev_priv, p) {
-                       u32 trans_dp = I915_READ(TRANS_DP_CTL(p));
-                       if (TRANS_DP_PIPE_TO_PORT(trans_dp) == port) {
-                               *pipe = p;
-                               ret = true;
+       val = I915_READ(dp_reg);
 
-                               goto out;
-                       }
-               }
+       ret = val & DP_PORT_EN;
 
-               DRM_DEBUG_KMS("No pipe for dp port 0x%x found\n",
-                             i915_mmio_reg_offset(intel_dp->output_reg));
+       /* asserts want to know the pipe even if the port is disabled */
+       if (IS_IVYBRIDGE(dev_priv) && port == PORT_A) {
+               *pipe = (val & DP_PIPE_SEL_MASK_IVB) >> DP_PIPE_SEL_SHIFT_IVB;
+       } else if (HAS_PCH_CPT(dev_priv) && port != PORT_A) {
+               ret &= cpt_dp_port_selected(dev_priv, port, pipe);
        } else if (IS_CHERRYVIEW(dev_priv)) {
-               *pipe = DP_PORT_TO_PIPE_CHV(tmp);
+               *pipe = (val & DP_PIPE_SEL_MASK_CHV) >> DP_PIPE_SEL_SHIFT_CHV;
        } else {
-               *pipe = PORT_TO_PIPE(tmp);
+               *pipe = (val & DP_PIPE_SEL_MASK) >> DP_PIPE_SEL_SHIFT;
        }
 
-       ret = true;
+       return ret;
+}
+
+static bool intel_dp_get_hw_state(struct intel_encoder *encoder,
+                                 enum pipe *pipe)
+{
+       struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
+       struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
+       bool ret;
+
+       if (!intel_display_power_get_if_enabled(dev_priv,
+                                               encoder->power_domain))
+               return false;
+
+       ret = intel_dp_port_enabled(dev_priv, intel_dp->output_reg,
+                                   encoder->port, pipe);
 
-out:
        intel_display_power_put(dev_priv, encoder->power_domain);
 
        return ret;
@@ -3673,8 +3688,9 @@ intel_dp_link_down(struct intel_encoder *encoder,
                intel_set_pch_fifo_underrun_reporting(dev_priv, PIPE_A, false);
 
                /* always enable with pattern 1 (as per spec) */
-               DP &= ~(DP_PIPEB_SELECT | DP_LINK_TRAIN_MASK);
-               DP |= DP_PORT_EN | DP_LINK_TRAIN_PAT_1;
+               DP &= ~(DP_PIPE_SEL_MASK | DP_LINK_TRAIN_MASK);
+               DP |= DP_PORT_EN | DP_PIPE_SEL(PIPE_A) |
+                       DP_LINK_TRAIN_PAT_1;
                I915_WRITE(intel_dp->output_reg, DP);
                POSTING_READ(intel_dp->output_reg);
 
@@ -5248,14 +5264,14 @@ static void intel_edp_panel_vdd_sanitize(struct 
intel_dp *intel_dp)
 static enum pipe vlv_active_pipe(struct intel_dp *intel_dp)
 {
        struct drm_i915_private *dev_priv = to_i915(intel_dp_to_dev(intel_dp));
+       struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base;
+       enum pipe pipe;
 
-       if ((intel_dp->DP & DP_PORT_EN) == 0)
-               return INVALID_PIPE;
+       if (intel_dp_port_enabled(dev_priv, intel_dp->output_reg,
+                                 encoder->port, &pipe))
+               return pipe;
 
-       if (IS_CHERRYVIEW(dev_priv))
-               return DP_PORT_TO_PIPE_CHV(intel_dp->DP);
-       else
-               return PORT_TO_PIPE(intel_dp->DP);
+       return INVALID_PIPE;
 }
 
 void intel_dp_encoder_reset(struct drm_encoder *encoder)
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 11c0f3785f59..fd64016476a4 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -1617,6 +1617,9 @@ void intel_csr_ucode_suspend(struct drm_i915_private *);
 void intel_csr_ucode_resume(struct drm_i915_private *);
 
 /* intel_dp.c */
+bool intel_dp_port_enabled(struct drm_i915_private *dev_priv,
+                          i915_reg_t dp_reg, enum port port,
+                          enum pipe *pipe);
 bool intel_dp_init(struct drm_i915_private *dev_priv, i915_reg_t output_reg,
                   enum port port);
 bool intel_dp_init_connector(struct intel_digital_port *intel_dig_port,
-- 
2.16.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

Reply via email to