OSDN Git Service

drm/i915: Plumb crtc_state to PSR enable/disable
authorVille Syrjälä <ville.syrjala@linux.intel.com>
Fri, 18 Aug 2017 13:49:56 +0000 (16:49 +0300)
committerVille Syrjälä <ville.syrjala@linux.intel.com>
Tue, 22 Aug 2017 14:57:46 +0000 (17:57 +0300)
The PSR enable/disable need to know things about the crtc state, so
plumb it through. This will become even more important when we start
to reuse the generic infoframe code for the VSC DIP programming as the
infoframe code wants the crtc state as well.

v2: Fix kernel docs

Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20170818134958.15502-7-ville.syrjala@linux.intel.com
drivers/gpu/drm/i915/intel_ddi.c
drivers/gpu/drm/i915/intel_dp.c
drivers/gpu/drm/i915/intel_drv.h
drivers/gpu/drm/i915/intel_psr.c

index e13b720..b5db2ac 100644 (file)
@@ -2335,7 +2335,7 @@ static void intel_enable_ddi(struct intel_encoder *intel_encoder,
                        intel_dp_stop_link_train(intel_dp);
 
                intel_edp_backlight_on(pipe_config, conn_state);
-               intel_psr_enable(intel_dp);
+               intel_psr_enable(intel_dp, pipe_config);
                intel_edp_drrs_enable(intel_dp, pipe_config);
        }
 
@@ -2363,7 +2363,7 @@ static void intel_disable_ddi(struct intel_encoder *intel_encoder,
                struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
 
                intel_edp_drrs_disable(intel_dp, old_crtc_state);
-               intel_psr_disable(intel_dp);
+               intel_psr_disable(intel_dp, old_crtc_state);
                intel_edp_backlight_off(old_conn_state);
        }
 }
index caa8b1e..dc5b106 100644 (file)
@@ -2698,7 +2698,7 @@ static void intel_disable_dp(struct intel_encoder *encoder,
                intel_audio_codec_disable(encoder);
 
        if (HAS_PSR(dev_priv) && !HAS_DDI(dev_priv))
-               intel_psr_disable(intel_dp);
+               intel_psr_disable(intel_dp, old_crtc_state);
 
        /* Make sure the panel is off before trying to change the mode. But also
         * ensure that we have vdd while we switch off the panel. */
@@ -2928,7 +2928,7 @@ static void vlv_enable_dp(struct intel_encoder *encoder,
        struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
 
        intel_edp_backlight_on(pipe_config, conn_state);
-       intel_psr_enable(intel_dp);
+       intel_psr_enable(intel_dp, pipe_config);
 }
 
 static void g4x_pre_enable_dp(struct intel_encoder *encoder,
index d45f508..987db69 100644 (file)
@@ -1722,8 +1722,10 @@ static inline void intel_backlight_device_unregister(struct intel_connector *con
 
 
 /* intel_psr.c */
-void intel_psr_enable(struct intel_dp *intel_dp);
-void intel_psr_disable(struct intel_dp *intel_dp);
+void intel_psr_enable(struct intel_dp *intel_dp,
+                     const struct intel_crtc_state *crtc_state);
+void intel_psr_disable(struct intel_dp *intel_dp,
+                     const struct intel_crtc_state *old_crtc_state);
 void intel_psr_invalidate(struct drm_i915_private *dev_priv,
                          unsigned frontbuffer_bits);
 void intel_psr_flush(struct drm_i915_private *dev_priv,
index 1b31ab0..f62ab05 100644 (file)
@@ -103,28 +103,26 @@ static void intel_psr_write_vsc(struct intel_dp *intel_dp,
        POSTING_READ(ctl_reg);
 }
 
-static void vlv_psr_setup_vsc(struct intel_dp *intel_dp)
+static void vlv_psr_setup_vsc(struct intel_dp *intel_dp,
+                             const struct intel_crtc_state *crtc_state)
 {
-       struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
-       struct drm_device *dev = intel_dig_port->base.base.dev;
-       struct drm_i915_private *dev_priv = to_i915(dev);
-       struct drm_crtc *crtc = intel_dig_port->base.base.crtc;
-       enum pipe pipe = to_intel_crtc(crtc)->pipe;
+       struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
+       struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
        uint32_t val;
 
        /* VLV auto-generate VSC package as per EDP 1.3 spec, Table 3.10 */
-       val  = I915_READ(VLV_VSCSDP(pipe));
+       val  = I915_READ(VLV_VSCSDP(crtc->pipe));
        val &= ~VLV_EDP_PSR_SDP_FREQ_MASK;
        val |= VLV_EDP_PSR_SDP_FREQ_EVFRAME;
-       I915_WRITE(VLV_VSCSDP(pipe), val);
+       I915_WRITE(VLV_VSCSDP(crtc->pipe), val);
 }
 
-static void skl_psr_setup_su_vsc(struct intel_dp *intel_dp)
+static void skl_psr_setup_su_vsc(struct intel_dp *intel_dp,
+                                const struct intel_crtc_state *crtc_state)
 {
-       struct edp_vsc_psr psr_vsc;
        struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
-       struct drm_device *dev = intel_dig_port->base.base.dev;
-       struct drm_i915_private *dev_priv = to_i915(dev);
+       struct drm_i915_private *dev_priv = to_i915(intel_dig_port->base.base.dev);
+       struct edp_vsc_psr psr_vsc;
 
        /* Prepare VSC Header for SU as per EDP 1.4 spec, Table 6.11 */
        memset(&psr_vsc, 0, sizeof(psr_vsc));
@@ -145,7 +143,8 @@ static void skl_psr_setup_su_vsc(struct intel_dp *intel_dp)
        intel_psr_write_vsc(intel_dp, &psr_vsc);
 }
 
-static void hsw_psr_setup_vsc(struct intel_dp *intel_dp)
+static void hsw_psr_setup_vsc(struct intel_dp *intel_dp,
+                             const struct intel_crtc_state *crtc_state)
 {
        struct edp_vsc_psr psr_vsc;
 
@@ -233,16 +232,15 @@ static void hsw_psr_enable_sink(struct intel_dp *intel_dp)
        I915_WRITE(aux_ctl_reg, aux_ctl);
 }
 
-static void vlv_psr_enable_source(struct intel_dp *intel_dp)
+static void vlv_psr_enable_source(struct intel_dp *intel_dp,
+                                 const struct intel_crtc_state *crtc_state)
 {
        struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
-       struct drm_device *dev = dig_port->base.base.dev;
-       struct drm_i915_private *dev_priv = to_i915(dev);
-       struct drm_crtc *crtc = dig_port->base.base.crtc;
-       enum pipe pipe = to_intel_crtc(crtc)->pipe;
+       struct drm_i915_private *dev_priv = to_i915(dig_port->base.base.dev);
+       struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
 
        /* Transition from PSR_state 0 to PSR_state 1, i.e. PSR Inactive */
-       I915_WRITE(VLV_PSRCTL(pipe),
+       I915_WRITE(VLV_PSRCTL(crtc->pipe),
                   VLV_EDP_PSR_MODE_SW_TIMER |
                   VLV_EDP_PSR_SRC_TRANSMITTER_STATE |
                   VLV_EDP_PSR_ENABLE);
@@ -485,16 +483,17 @@ static void intel_psr_activate(struct intel_dp *intel_dp)
 /**
  * intel_psr_enable - Enable PSR
  * @intel_dp: Intel DP
+ * @crtc_state: new CRTC state
  *
  * This function can only be called after the pipe is fully trained and enabled.
  */
-void intel_psr_enable(struct intel_dp *intel_dp)
+void intel_psr_enable(struct intel_dp *intel_dp,
+                     const struct intel_crtc_state *crtc_state)
 {
        struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
        struct drm_device *dev = intel_dig_port->base.base.dev;
        struct drm_i915_private *dev_priv = to_i915(dev);
-       struct intel_crtc *crtc = to_intel_crtc(intel_dig_port->base.base.crtc);
-       enum transcoder cpu_transcoder = crtc->config->cpu_transcoder;
+       enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
        u32 chicken;
 
        if (!HAS_PSR(dev_priv)) {
@@ -520,11 +519,13 @@ void intel_psr_enable(struct intel_dp *intel_dp)
 
        if (HAS_DDI(dev_priv)) {
                if (dev_priv->psr.psr2_support) {
-                       skl_psr_setup_su_vsc(intel_dp);
+                       skl_psr_setup_su_vsc(intel_dp, crtc_state);
+
                        chicken = PSR2_VSC_ENABLE_PROG_HEADER;
                        if (dev_priv->psr.y_cord_support)
                                chicken |= PSR2_ADD_VERTICAL_LINE_COUNT;
                        I915_WRITE(CHICKEN_TRANS(cpu_transcoder), chicken);
+
                        I915_WRITE(EDP_PSR_DEBUG_CTL,
                                   EDP_PSR_DEBUG_MASK_MEMUP |
                                   EDP_PSR_DEBUG_MASK_HPD |
@@ -533,7 +534,8 @@ void intel_psr_enable(struct intel_dp *intel_dp)
                                   EDP_PSR_DEBUG_MASK_DISP_REG_WRITE);
                } else {
                        /* set up vsc header for psr1 */
-                       hsw_psr_setup_vsc(intel_dp);
+                       hsw_psr_setup_vsc(intel_dp, crtc_state);
+
                        /*
                         * Per Spec: Avoid continuous PSR exit by masking MEMUP
                         * and HPD. also mask LPSP to avoid dependency on other
@@ -553,7 +555,7 @@ void intel_psr_enable(struct intel_dp *intel_dp)
                if (INTEL_GEN(dev_priv) >= 9)
                        intel_psr_activate(intel_dp);
        } else {
-               vlv_psr_setup_vsc(intel_dp);
+               vlv_psr_setup_vsc(intel_dp, crtc_state);
 
                /* Enable PSR on the panel */
                vlv_psr_enable_sink(intel_dp);
@@ -564,7 +566,7 @@ void intel_psr_enable(struct intel_dp *intel_dp)
                 * but let it on inactive state. So we might do this prior
                 * to active transition, i.e. here.
                 */
-               vlv_psr_enable_source(intel_dp);
+               vlv_psr_enable_source(intel_dp, crtc_state);
        }
 
        /*
@@ -585,37 +587,38 @@ unlock:
        mutex_unlock(&dev_priv->psr.lock);
 }
 
-static void vlv_psr_disable(struct intel_dp *intel_dp)
+static void vlv_psr_disable(struct intel_dp *intel_dp,
+                           const struct intel_crtc_state *old_crtc_state)
 {
        struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
        struct drm_device *dev = intel_dig_port->base.base.dev;
        struct drm_i915_private *dev_priv = to_i915(dev);
-       struct intel_crtc *intel_crtc =
-               to_intel_crtc(intel_dig_port->base.base.crtc);
+       struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->base.crtc);
        uint32_t val;
 
        if (dev_priv->psr.active) {
                /* Put VLV PSR back to PSR_state 0 that is PSR Disabled. */
                if (intel_wait_for_register(dev_priv,
-                                           VLV_PSRSTAT(intel_crtc->pipe),
+                                           VLV_PSRSTAT(crtc->pipe),
                                            VLV_EDP_PSR_IN_TRANS,
                                            0,
                                            1))
                        WARN(1, "PSR transition took longer than expected\n");
 
-               val = I915_READ(VLV_PSRCTL(intel_crtc->pipe));
+               val = I915_READ(VLV_PSRCTL(crtc->pipe));
                val &= ~VLV_EDP_PSR_ACTIVE_ENTRY;
                val &= ~VLV_EDP_PSR_ENABLE;
                val &= ~VLV_EDP_PSR_MODE_MASK;
-               I915_WRITE(VLV_PSRCTL(intel_crtc->pipe), val);
+               I915_WRITE(VLV_PSRCTL(crtc->pipe), val);
 
                dev_priv->psr.active = false;
        } else {
-               WARN_ON(vlv_is_psr_active_on_pipe(dev, intel_crtc->pipe));
+               WARN_ON(vlv_is_psr_active_on_pipe(dev, crtc->pipe));
        }
 }
 
-static void hsw_psr_disable(struct intel_dp *intel_dp)
+static void hsw_psr_disable(struct intel_dp *intel_dp,
+                           const struct intel_crtc_state *old_crtc_state)
 {
        struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
        struct drm_device *dev = intel_dig_port->base.base.dev;
@@ -664,10 +667,12 @@ static void hsw_psr_disable(struct intel_dp *intel_dp)
 /**
  * intel_psr_disable - Disable PSR
  * @intel_dp: Intel DP
+ * @old_crtc_state: old CRTC state
  *
  * This function needs to be called before disabling pipe.
  */
-void intel_psr_disable(struct intel_dp *intel_dp)
+void intel_psr_disable(struct intel_dp *intel_dp,
+                      const struct intel_crtc_state *old_crtc_state)
 {
        struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
        struct drm_device *dev = intel_dig_port->base.base.dev;
@@ -681,9 +686,9 @@ void intel_psr_disable(struct intel_dp *intel_dp)
 
        /* Disable PSR on Source */
        if (HAS_DDI(dev_priv))
-               hsw_psr_disable(intel_dp);
+               hsw_psr_disable(intel_dp, old_crtc_state);
        else
-               vlv_psr_disable(intel_dp);
+               vlv_psr_disable(intel_dp, old_crtc_state);
 
        /* Disable PSR on Sink */
        drm_dp_dpcd_writeb(&intel_dp->aux, DP_PSR_EN_CFG, 0);