summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/i915/display/intel_psr.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/i915/display/intel_psr.c')
-rw-r--r--drivers/gpu/drm/i915/display/intel_psr.c95
1 files changed, 77 insertions, 18 deletions
diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c
index 8ada4f829cab..acaf3d459821 100644
--- a/drivers/gpu/drm/i915/display/intel_psr.c
+++ b/drivers/gpu/drm/i915/display/intel_psr.c
@@ -27,6 +27,7 @@
#include "i915_drv.h"
#include "intel_atomic.h"
+#include "intel_de.h"
#include "intel_display_types.h"
#include "intel_dp_aux.h"
#include "intel_hdmi.h"
@@ -524,7 +525,7 @@ static void hsw_activate_psr2(struct intel_dp *intel_dp)
val = psr_compute_idle_frames(intel_dp) << EDP_PSR2_IDLE_FRAME_SHIFT;
val |= EDP_PSR2_ENABLE | EDP_SU_TRACK_ENABLE;
- if (DISPLAY_VER(dev_priv) >= 10)
+ if (DISPLAY_VER(dev_priv) >= 10 && DISPLAY_VER(dev_priv) <= 12)
val |= EDP_Y_COORDINATE_ENABLE;
val |= EDP_PSR2_FRAME_BEFORE_SU(intel_dp->psr.sink_sync_latency + 1);
@@ -655,6 +656,13 @@ tgl_dc3co_exitline_compute_config(struct intel_dp *intel_dp,
u32 exit_scanlines;
/*
+ * FIXME: Due to the changed sequence of activating/deactivating DC3CO,
+ * disable DC3CO until the changed dc3co activating/deactivating sequence
+ * is applied. B.Specs:49196
+ */
+ return;
+
+ /*
* DMC's DC3CO exit mechanism has an issue with Selective Fecth
* TODO: when the issue is addressed, this restriction should be removed.
*/
@@ -712,6 +720,13 @@ static bool intel_psr2_sel_fetch_config_valid(struct intel_dp *intel_dp,
}
}
+ /* Wa_14010254185 Wa_14010103792 */
+ if (IS_TGL_DISPLAY_STEP(dev_priv, STEP_A0, STEP_B1)) {
+ drm_dbg_kms(&dev_priv->drm,
+ "PSR2 sel fetch not enabled, missing the implementation of WAs\n");
+ return false;
+ }
+
return crtc_state->enable_psr2_sel_fetch = true;
}
@@ -732,6 +747,12 @@ static bool intel_psr2_config_valid(struct intel_dp *intel_dp,
return false;
}
+ /* Wa_16011181250 */
+ if (IS_ROCKETLAKE(dev_priv) || IS_ALDERLAKE_S(dev_priv)) {
+ drm_dbg_kms(&dev_priv->drm, "PSR2 is defeatured for this platform\n");
+ return false;
+ }
+
if (!transcoder_has_psr2(dev_priv, crtc_state->cpu_transcoder)) {
drm_dbg_kms(&dev_priv->drm,
"PSR2 not supported in transcoder %s\n",
@@ -769,7 +790,7 @@ static bool intel_psr2_config_valid(struct intel_dp *intel_dp,
psr_max_h = 4096;
psr_max_v = 2304;
max_bpp = 24;
- } else if (IS_DISPLAY_VER(dev_priv, 9)) {
+ } else if (DISPLAY_VER(dev_priv) == 9) {
psr_max_h = 3640;
psr_max_v = 2304;
max_bpp = 24;
@@ -804,6 +825,13 @@ static bool intel_psr2_config_valid(struct intel_dp *intel_dp,
}
}
+ /* Wa_2209313811 */
+ if (!crtc_state->enable_psr2_sel_fetch &&
+ IS_TGL_DISPLAY_STEP(dev_priv, STEP_A0, STEP_B1)) {
+ drm_dbg_kms(&dev_priv->drm, "PSR2 HW tracking is not supported this Display stepping\n");
+ return false;
+ }
+
if (!crtc_state->enable_psr2_sel_fetch &&
(crtc_hdisplay > psr_max_h || crtc_vdisplay > psr_max_v)) {
drm_dbg_kms(&dev_priv->drm,
@@ -873,6 +901,51 @@ void intel_psr_compute_config(struct intel_dp *intel_dp,
crtc_state->infoframes.enable |= intel_hdmi_infoframe_enable(DP_SDP_VSC);
}
+void intel_psr_get_config(struct intel_encoder *encoder,
+ struct intel_crtc_state *pipe_config)
+{
+ struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
+ struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
+ struct intel_dp *intel_dp;
+ u32 val;
+
+ if (!dig_port)
+ return;
+
+ intel_dp = &dig_port->dp;
+ if (!CAN_PSR(intel_dp))
+ return;
+
+ mutex_lock(&intel_dp->psr.lock);
+ if (!intel_dp->psr.enabled)
+ goto unlock;
+
+ /*
+ * Not possible to read EDP_PSR/PSR2_CTL registers as it is
+ * enabled/disabled because of frontbuffer tracking and others.
+ */
+ pipe_config->has_psr = true;
+ pipe_config->has_psr2 = intel_dp->psr.psr2_enabled;
+ pipe_config->infoframes.enable |= intel_hdmi_infoframe_enable(DP_SDP_VSC);
+
+ if (!intel_dp->psr.psr2_enabled)
+ goto unlock;
+
+ if (HAS_PSR2_SEL_FETCH(dev_priv)) {
+ val = intel_de_read(dev_priv, PSR2_MAN_TRK_CTL(intel_dp->psr.transcoder));
+ if (val & PSR2_MAN_TRK_CTL_ENABLE)
+ pipe_config->enable_psr2_sel_fetch = true;
+ }
+
+ if (DISPLAY_VER(dev_priv) >= 12) {
+ val = intel_de_read(dev_priv, EXITLINE(intel_dp->psr.transcoder));
+ val &= EXITLINE_MASK;
+ pipe_config->dc3co_exitline = val;
+ }
+unlock:
+ mutex_unlock(&intel_dp->psr.lock);
+}
+
static void intel_psr_activate(struct intel_dp *intel_dp)
{
struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
@@ -909,7 +982,7 @@ static void intel_psr_enable_source(struct intel_dp *intel_dp,
if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv))
hsw_psr_setup_aux(intel_dp);
- if (intel_dp->psr.psr2_enabled && IS_DISPLAY_VER(dev_priv, 9)) {
+ if (intel_dp->psr.psr2_enabled && DISPLAY_VER(dev_priv) == 9) {
i915_reg_t reg = CHICKEN_TRANS(cpu_transcoder);
u32 chicken = intel_de_read(dev_priv, reg);
@@ -1154,21 +1227,7 @@ static void psr_force_hw_tracking_exit(struct intel_dp *intel_dp)
{
struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
- if (IS_TIGERLAKE(dev_priv))
- /*
- * Writes to CURSURFLIVE in TGL are causing IOMMU errors and
- * visual glitches that are often reproduced when executing
- * CPU intensive workloads while a eDP 4K panel is attached.
- *
- * Manually exiting PSR causes the frontbuffer to be updated
- * without glitches and the IOMMU errors are also gone but
- * this comes at the cost of less time with PSR active.
- *
- * So using this workaround until this issue is root caused
- * and a better fix is found.
- */
- intel_psr_exit(intel_dp);
- else if (DISPLAY_VER(dev_priv) >= 9)
+ if (DISPLAY_VER(dev_priv) >= 9)
/*
* Display WA #0884: skl+
* This documented WA for bxt can be safely applied