]> git.baikalelectronics.ru Git - kernel.git/commitdiff
drm/i915/xelpd: Handle PSR2 SDP indication in the prior scanline
authorJosé Roberto de Souza <jose.souza@intel.com>
Wed, 16 Jun 2021 20:31:56 +0000 (13:31 -0700)
committerJosé Roberto de Souza <jose.souza@intel.com>
Thu, 24 Jun 2021 23:01:43 +0000 (16:01 -0700)
In some modes there is not enough time during hblank to transmit PSR2
SDP plus the pixels CRC SDP, if such case happens PSR2 needs to be
disabled.
But eDP spec 1.4b allows to transmit PSR2 SDP in a prior scanline
alone and than later the CRC SDP, allowing PSR2 to be enabled in
those hblank constrained modes.

BSpec: 49274
Cc: Gwan-gyeong Mun <gwan-gyeong.mun@intel.com>
Signed-off-by: José Roberto de Souza <jose.souza@intel.com>
Reviewed-by: Gwan-gyeong Mun <gwan-gyeong.mun@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20210616203158.118111-4-jose.souza@intel.com
drivers/gpu/drm/i915/display/intel_display_types.h
drivers/gpu/drm/i915/display/intel_psr.c
drivers/gpu/drm/i915/i915_reg.h

index 7ea73420bcf962efd33cac58187b74163ac9ce6f..d7b5e26e13949ef1b8c0bc2cd11bdee9b22eec5e 100644 (file)
@@ -1044,6 +1044,7 @@ struct intel_crtc_state {
        bool has_psr;
        bool has_psr2;
        bool enable_psr2_sel_fetch;
+       bool req_psr2_sdp_prior_scanline;
        u32 dc3co_exitline;
        u16 su_y_granularity;
 
@@ -1498,6 +1499,7 @@ struct intel_psr {
        bool colorimetry_support;
        bool psr2_enabled;
        bool psr2_sel_fetch_enabled;
+       bool req_psr2_sdp_prior_scanline;
        u8 sink_sync_latency;
        ktime_t last_entry_attempt;
        ktime_t last_exit;
index e508816911fad43f52bc3daa48c472892674aaab..3cb8758be4042a9905037c78d39e6c979e53ead1 100644 (file)
@@ -418,6 +418,9 @@ static void intel_psr_enable_sink(struct intel_dp *intel_dp)
                        dpcd_val |= DP_PSR_CRC_VERIFICATION;
        }
 
+       if (intel_dp->psr.req_psr2_sdp_prior_scanline)
+               dpcd_val |= DP_PSR_SU_REGION_SCANLINE_CAPTURE;
+
        drm_dp_dpcd_writeb(&intel_dp->aux, DP_PSR_EN_CFG, dpcd_val);
 
        drm_dp_dpcd_writeb(&intel_dp->aux, DP_SET_POWER, DP_SET_POWER_D0);
@@ -585,6 +588,9 @@ static void hsw_activate_psr2(struct intel_dp *intel_dp)
                val |= EDP_PSR2_FAST_WAKE(7);
        }
 
+       if (intel_dp->psr.req_psr2_sdp_prior_scanline)
+               val |= EDP_PSR2_SU_SDP_SCANLINE;
+
        if (intel_dp->psr.psr2_sel_fetch_enabled) {
                /* WA 1408330847 */
                if (IS_TGL_DISPLAY_STEP(dev_priv, STEP_A0, STEP_A0) ||
@@ -814,6 +820,29 @@ static bool psr2_granularity_check(struct intel_dp *intel_dp,
        return true;
 }
 
+static bool _compute_psr2_sdp_prior_scanline_indication(struct intel_dp *intel_dp,
+                                                       struct intel_crtc_state *crtc_state)
+{
+       const struct drm_display_mode *adjusted_mode = &crtc_state->uapi.adjusted_mode;
+       struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
+       u32 hblank_total, hblank_ns, req_ns;
+
+       hblank_total = adjusted_mode->crtc_hblank_end - adjusted_mode->crtc_hblank_start;
+       hblank_ns = div_u64(1000000ULL * hblank_total, adjusted_mode->crtc_clock);
+
+       /* From spec: (72 / number of lanes) * 1000 / symbol clock frequency MHz */
+       req_ns = (72 / crtc_state->lane_count) * 1000 / (crtc_state->port_clock / 1000);
+
+       if ((hblank_ns - req_ns) > 100)
+               return true;
+
+       if (DISPLAY_VER(dev_priv) < 13 || intel_dp->edp_dpcd[0] < DP_EDP_14b)
+               return false;
+
+       crtc_state->req_psr2_sdp_prior_scanline = true;
+       return true;
+}
+
 static bool intel_psr2_config_valid(struct intel_dp *intel_dp,
                                    struct intel_crtc_state *crtc_state)
 {
@@ -926,6 +955,12 @@ static bool intel_psr2_config_valid(struct intel_dp *intel_dp,
                return false;
        }
 
+       if (!_compute_psr2_sdp_prior_scanline_indication(intel_dp, crtc_state)) {
+               drm_dbg_kms(&dev_priv->drm,
+                           "PSR2 not enabled, PSR2 SDP indication do not fit in hblank\n");
+               return false;
+       }
+
        tgl_dc3co_exitline_compute_config(intel_dp, crtc_state);
        return true;
 }
@@ -1173,6 +1208,8 @@ static void intel_psr_enable_locked(struct intel_dp *intel_dp,
        intel_dp->psr.dc3co_exit_delay = val;
        intel_dp->psr.dc3co_exitline = crtc_state->dc3co_exitline;
        intel_dp->psr.psr2_sel_fetch_enabled = crtc_state->enable_psr2_sel_fetch;
+       intel_dp->psr.req_psr2_sdp_prior_scanline =
+               crtc_state->req_psr2_sdp_prior_scanline;
 
        if (!psr_interrupt_error_check(intel_dp))
                return;
index a22c20444bca4418e87a0d1b59e9f002486334f9..10856e356be0b505447ef48d298078cfcad51007 100644 (file)
@@ -4578,6 +4578,7 @@ enum {
 #define   TGL_EDP_PSR2_BLOCK_COUNT_NUM_2       (0 << 28)
 #define   TGL_EDP_PSR2_BLOCK_COUNT_NUM_3       (1 << 28)
 #define   EDP_Y_COORDINATE_ENABLE              REG_BIT(25) /* display 10, 11 and 12 */
+#define   EDP_PSR2_SU_SDP_SCANLINE             REG_BIT(25) /* display 13+ */
 #define   EDP_MAX_SU_DISABLE_TIME(t)           ((t) << 20)
 #define   EDP_MAX_SU_DISABLE_TIME_MASK         (0x1f << 20)
 #define   EDP_PSR2_IO_BUFFER_WAKE_MAX_LINES    8