drm/i915: Clean up SDVO pipe select bits
authorVille Syrjälä <ville.syrjala@linux.intel.com>
Mon, 14 May 2018 17:24:21 +0000 (20:24 +0300)
committerVille Syrjälä <ville.syrjala@linux.intel.com>
Thu, 17 May 2018 16:33:38 +0000 (19:33 +0300)
Clean up the SDVO pipe select bits. To make the whole situation a bit
less ugly we'll start to share the same code between .get_hw_state()
and the port state asserts.

v2: Order the defines shift,mask,value (Jani)

Reviewed-by: Jani Nikula <jani.nikula@intel.com>
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20180514172423.9302-3-ville.syrjala@linux.intel.com
drivers/gpu/drm/i915/i915_reg.h
drivers/gpu/drm/i915/intel_display.c
drivers/gpu/drm/i915/intel_drv.h
drivers/gpu/drm/i915/intel_hdmi.c
drivers/gpu/drm/i915/intel_sdvo.c

index 753b8f1..f1c8323 100644 (file)
@@ -4297,9 +4297,9 @@ enum {
 
 /* Gen 3 SDVO bits: */
 #define   SDVO_ENABLE                          (1 << 31)
-#define   SDVO_PIPE_SEL(pipe)                  ((pipe) << 30)
+#define   SDVO_PIPE_SEL_SHIFT                  30
 #define   SDVO_PIPE_SEL_MASK                   (1 << 30)
-#define   SDVO_PIPE_B_SELECT                   (1 << 30)
+#define   SDVO_PIPE_SEL(pipe)                  ((pipe) << 30)
 #define   SDVO_STALL_SELECT                    (1 << 29)
 #define   SDVO_INTERRUPT_ENABLE                        (1 << 26)
 /*
@@ -4339,12 +4339,14 @@ enum {
 #define   SDVOB_HOTPLUG_ENABLE                 (1 << 23) /* SDVO only */
 
 /* Gen 6 (CPT) SDVO/HDMI bits: */
-#define   SDVO_PIPE_SEL_CPT(pipe)              ((pipe) << 29)
+#define   SDVO_PIPE_SEL_SHIFT_CPT              29
 #define   SDVO_PIPE_SEL_MASK_CPT               (3 << 29)
+#define   SDVO_PIPE_SEL_CPT(pipe)              ((pipe) << 29)
 
 /* CHV SDVO/HDMI bits: */
-#define   SDVO_PIPE_SEL_CHV(pipe)              ((pipe) << 24)
+#define   SDVO_PIPE_SEL_SHIFT_CHV              24
 #define   SDVO_PIPE_SEL_MASK_CHV               (3 << 24)
+#define   SDVO_PIPE_SEL_CHV(pipe)              ((pipe) << 24)
 
 
 /* DVO port control */
index a1c6cc7..817d5d3 100644 (file)
@@ -1323,25 +1323,6 @@ static bool dp_pipe_enabled(struct drm_i915_private *dev_priv,
        return true;
 }
 
-static bool hdmi_pipe_enabled(struct drm_i915_private *dev_priv,
-                             enum pipe pipe, u32 val)
-{
-       if ((val & SDVO_ENABLE) == 0)
-               return false;
-
-       if (HAS_PCH_CPT(dev_priv)) {
-               if ((val & SDVO_PIPE_SEL_MASK_CPT) != SDVO_PIPE_SEL_CPT(pipe))
-                       return false;
-       } else if (IS_CHERRYVIEW(dev_priv)) {
-               if ((val & SDVO_PIPE_SEL_MASK_CHV) != SDVO_PIPE_SEL_CHV(pipe))
-                       return false;
-       } else {
-               if ((val & SDVO_PIPE_SEL_MASK) != SDVO_PIPE_SEL(pipe))
-                       return false;
-       }
-       return true;
-}
-
 static void assert_pch_dp_disabled(struct drm_i915_private *dev_priv,
                                   enum pipe pipe, i915_reg_t reg,
                                   u32 port_sel)
@@ -1357,16 +1338,21 @@ static void assert_pch_dp_disabled(struct drm_i915_private *dev_priv,
 }
 
 static void assert_pch_hdmi_disabled(struct drm_i915_private *dev_priv,
-                                    enum pipe pipe, i915_reg_t reg)
+                                    enum pipe pipe, enum port port,
+                                    i915_reg_t hdmi_reg)
 {
-       u32 val = I915_READ(reg);
-       I915_STATE_WARN(hdmi_pipe_enabled(dev_priv, pipe, val),
-            "PCH HDMI (0x%08x) enabled on transcoder %c, should be disabled\n",
-            i915_mmio_reg_offset(reg), pipe_name(pipe));
+       enum pipe port_pipe;
+       bool state;
+
+       state = intel_sdvo_port_enabled(dev_priv, hdmi_reg, &port_pipe);
+
+       I915_STATE_WARN(state && port_pipe == pipe,
+                       "PCH HDMI %c enabled on transcoder %c, should be disabled\n",
+                       port_name(port), pipe_name(pipe));
 
-       I915_STATE_WARN(HAS_PCH_IBX(dev_priv) && (val & SDVO_ENABLE) == 0
-            && (val & SDVO_PIPE_B_SELECT),
-            "IBX PCH hdmi port still using transcoder B\n");
+       I915_STATE_WARN(HAS_PCH_IBX(dev_priv) && !state && port_pipe == PIPE_B,
+                       "IBX PCH HDMI %c still using transcoder B\n",
+                       port_name(port));
 }
 
 static void assert_pch_ports_disabled(struct drm_i915_private *dev_priv,
@@ -1388,9 +1374,9 @@ static void assert_pch_ports_disabled(struct drm_i915_private *dev_priv,
                        "PCH LVDS enabled on transcoder %c, should be disabled\n",
                        pipe_name(pipe));
 
-       assert_pch_hdmi_disabled(dev_priv, pipe, PCH_HDMIB);
-       assert_pch_hdmi_disabled(dev_priv, pipe, PCH_HDMIC);
-       assert_pch_hdmi_disabled(dev_priv, pipe, PCH_HDMID);
+       assert_pch_hdmi_disabled(dev_priv, pipe, PORT_B, PCH_HDMIB);
+       assert_pch_hdmi_disabled(dev_priv, pipe, PORT_C, PCH_HDMIC);
+       assert_pch_hdmi_disabled(dev_priv, pipe, PORT_D, PCH_HDMID);
 }
 
 static void _vlv_enable_pll(struct intel_crtc *crtc,
index 911d496..12002fc 100644 (file)
@@ -2064,6 +2064,8 @@ void intel_init_ipc(struct drm_i915_private *dev_priv);
 void intel_enable_ipc(struct drm_i915_private *dev_priv);
 
 /* intel_sdvo.c */
+bool intel_sdvo_port_enabled(struct drm_i915_private *dev_priv,
+                            i915_reg_t sdvo_reg, enum pipe *pipe);
 bool intel_sdvo_init(struct drm_i915_private *dev_priv,
                     i915_reg_t reg, enum port port);
 
index ee929f3..ba5ea61 100644 (file)
@@ -1161,33 +1161,16 @@ static void intel_hdmi_prepare(struct intel_encoder *encoder,
 static bool intel_hdmi_get_hw_state(struct intel_encoder *encoder,
                                    enum pipe *pipe)
 {
-       struct drm_device *dev = encoder->base.dev;
-       struct drm_i915_private *dev_priv = to_i915(dev);
+       struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
        struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(&encoder->base);
-       u32 tmp;
        bool ret;
 
        if (!intel_display_power_get_if_enabled(dev_priv,
                                                encoder->power_domain))
                return false;
 
-       ret = false;
-
-       tmp = I915_READ(intel_hdmi->hdmi_reg);
-
-       if (!(tmp & SDVO_ENABLE))
-               goto out;
-
-       if (HAS_PCH_CPT(dev_priv))
-               *pipe = PORT_TO_PIPE_CPT(tmp);
-       else if (IS_CHERRYVIEW(dev_priv))
-               *pipe = SDVO_PORT_TO_PIPE_CHV(tmp);
-       else
-               *pipe = PORT_TO_PIPE(tmp);
-
-       ret = true;
+       ret = intel_sdvo_port_enabled(dev_priv, intel_hdmi->hdmi_reg, pipe);
 
-out:
        intel_display_power_put(dev_priv, encoder->power_domain);
 
        return ret;
@@ -1421,8 +1404,8 @@ static void intel_disable_hdmi(struct intel_encoder *encoder,
                intel_set_cpu_fifo_underrun_reporting(dev_priv, PIPE_A, false);
                intel_set_pch_fifo_underrun_reporting(dev_priv, PIPE_A, false);
 
-               temp &= ~SDVO_PIPE_B_SELECT;
-               temp |= SDVO_ENABLE;
+               temp &= ~SDVO_PIPE_SEL_MASK;
+               temp |= SDVO_ENABLE | SDVO_PIPE_SEL(PIPE_A);
                /*
                 * HW workaround, need to write this twice for issue
                 * that may result in first write getting masked.
index 96e213e..848b03a 100644 (file)
@@ -1403,27 +1403,37 @@ static bool intel_sdvo_connector_get_hw_state(struct intel_connector *connector)
                return false;
 }
 
+bool intel_sdvo_port_enabled(struct drm_i915_private *dev_priv,
+                            i915_reg_t sdvo_reg, enum pipe *pipe)
+{
+       u32 val;
+
+       val = I915_READ(sdvo_reg);
+
+       /* asserts want to know the pipe even if the port is disabled */
+       if (HAS_PCH_CPT(dev_priv))
+               *pipe = (val & SDVO_PIPE_SEL_MASK_CPT) >> SDVO_PIPE_SEL_SHIFT_CPT;
+       else if (IS_CHERRYVIEW(dev_priv))
+               *pipe = (val & SDVO_PIPE_SEL_MASK_CHV) >> SDVO_PIPE_SEL_SHIFT_CHV;
+       else
+               *pipe = (val & SDVO_PIPE_SEL_MASK) >> SDVO_PIPE_SEL_SHIFT;
+
+       return val & SDVO_ENABLE;
+}
+
 static bool intel_sdvo_get_hw_state(struct intel_encoder *encoder,
                                    enum pipe *pipe)
 {
-       struct drm_device *dev = encoder->base.dev;
-       struct drm_i915_private *dev_priv = to_i915(dev);
+       struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
        struct intel_sdvo *intel_sdvo = to_sdvo(encoder);
        u16 active_outputs = 0;
-       u32 tmp;
+       bool ret;
 
-       tmp = I915_READ(intel_sdvo->sdvo_reg);
        intel_sdvo_get_active_outputs(intel_sdvo, &active_outputs);
 
-       if (!(tmp & SDVO_ENABLE) && (active_outputs == 0))
-               return false;
-
-       if (HAS_PCH_CPT(dev_priv))
-               *pipe = PORT_TO_PIPE_CPT(tmp);
-       else
-               *pipe = PORT_TO_PIPE(tmp);
+       ret = intel_sdvo_port_enabled(dev_priv, intel_sdvo->sdvo_reg, pipe);
 
-       return true;
+       return ret || active_outputs;
 }
 
 static void intel_sdvo_get_config(struct intel_encoder *encoder,
@@ -1550,8 +1560,8 @@ static void intel_disable_sdvo(struct intel_encoder *encoder,
                intel_set_cpu_fifo_underrun_reporting(dev_priv, PIPE_A, false);
                intel_set_pch_fifo_underrun_reporting(dev_priv, PIPE_A, false);
 
-               temp &= ~SDVO_PIPE_B_SELECT;
-               temp |= SDVO_ENABLE;
+               temp &= ~SDVO_PIPE_SEL_MASK;
+               temp |= SDVO_ENABLE | SDVO_PIPE_SEL(PIPE_A);
                intel_sdvo_write_sdvox(intel_sdvo, temp);
 
                temp &= ~SDVO_ENABLE;