[PATCH v2 05/10] drm/i915/psr: Ensure SFF/CFF bits are not written at their sample point
Jouni Högander
jouni.hogander at intel.com
Mon Dec 30 13:29:22 UTC 2024
Bspec says this for SFF/CFF:
"Hardware samples this bit on the start of every V. Blank Guardband
region. For deterministic behavior, Software should ensure it is not
changing this bit around the sample point."
This can be achieved by using intel_vblank_evade.
v2: take drm modeset lock
Signed-off-by: Jouni Högander <jouni.hogander at intel.com>
---
drivers/gpu/drm/i915/display/intel_psr.c | 46 +++++++++++++++++++-----
1 file changed, 38 insertions(+), 8 deletions(-)
diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c
index e6f96a8b4fb0..69fb2ce2fbfa 100644
--- a/drivers/gpu/drm/i915/display/intel_psr.c
+++ b/drivers/gpu/drm/i915/display/intel_psr.c
@@ -26,6 +26,7 @@
#include <drm/drm_atomic_helper.h>
#include <drm/drm_damage_helper.h>
#include <drm/drm_debugfs.h>
+#include <drm/drm_vblank.h>
#include "i915_drv.h"
#include "i915_reg.h"
@@ -44,6 +45,7 @@
#include "intel_psr.h"
#include "intel_psr_regs.h"
#include "intel_snps_phy.h"
+#include "intel_vblank.h"
#include "skl_universal_plane.h"
/**
@@ -3114,16 +3116,31 @@ static void intel_psr_configure_full_frame_update(struct intel_dp *intel_dp)
{
struct intel_display *display = to_intel_display(intel_dp);
enum transcoder cpu_transcoder = intel_dp->psr.transcoder;
+ struct intel_crtc *crtc = intel_crtc_for_pipe(display, intel_dp->psr.pipe);
+ struct intel_crtc_state *crtc_state = to_intel_crtc_state(crtc->base.state);
+ struct intel_vblank_evade_ctx evade;
if (!intel_dp->psr.psr2_sel_fetch_enabled)
return;
+ intel_vblank_evade_init(crtc_state, crtc_state, &evade);
+
+ drm_crtc_vblank_get(&crtc->base);
+
+ local_irq_disable();
+
+ intel_vblank_evade(&evade);
+
+ drm_crtc_vblank_put(&crtc->base);
+
intel_de_write(display,
PSR2_MAN_TRK_CTL(display, cpu_transcoder),
man_trk_ctl_enable_bit_get(display) |
man_trk_ctl_partial_frame_bit_get(display) |
man_trk_ctl_single_full_frame_bit_get(display) |
man_trk_ctl_continuos_full_frame(display));
+
+ local_irq_enable();
}
static void _psr_invalidate_handle(struct intel_dp *intel_dp)
@@ -3164,12 +3181,14 @@ void intel_psr_invalidate(struct intel_display *display,
for_each_intel_encoder_with_psr(display->drm, encoder) {
unsigned int pipe_frontbuffer_bits = frontbuffer_bits;
struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
+ struct intel_crtc *crtc = intel_crtc_for_pipe(display,
+ intel_dp->psr.pipe);
+
+ drm_modeset_lock(&crtc->base.mutex, NULL);
mutex_lock(&intel_dp->psr.lock);
- if (!intel_dp->psr.enabled) {
- mutex_unlock(&intel_dp->psr.lock);
- continue;
- }
+ if (!intel_dp->psr.enabled)
+ goto unlock;
pipe_frontbuffer_bits &=
INTEL_FRONTBUFFER_ALL_MASK(intel_dp->psr.pipe);
@@ -3178,7 +3197,10 @@ void intel_psr_invalidate(struct intel_display *display,
if (pipe_frontbuffer_bits)
_psr_invalidate_handle(intel_dp);
+unlock:
mutex_unlock(&intel_dp->psr.lock);
+
+ drm_modeset_unlock(&crtc->base.mutex);
}
}
/*
@@ -3259,12 +3281,16 @@ void intel_psr_flush(struct intel_display *display,
for_each_intel_encoder_with_psr(display->drm, encoder) {
unsigned int pipe_frontbuffer_bits = frontbuffer_bits;
struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
+ struct intel_crtc *crtc = intel_crtc_for_pipe(display,
+ intel_dp->psr.pipe);
+
+ if (origin != ORIGIN_FLIP &&
+ origin != ORIGIN_CURSOR_UPDATE)
+ drm_modeset_lock(&crtc->base.mutex, NULL);
mutex_lock(&intel_dp->psr.lock);
- if (!intel_dp->psr.enabled) {
- mutex_unlock(&intel_dp->psr.lock);
- continue;
- }
+ if (!intel_dp->psr.enabled)
+ goto unlock;
pipe_frontbuffer_bits &=
INTEL_FRONTBUFFER_ALL_MASK(intel_dp->psr.pipe);
@@ -3292,6 +3318,10 @@ void intel_psr_flush(struct intel_display *display,
_psr_flush_handle(intel_dp);
unlock:
mutex_unlock(&intel_dp->psr.lock);
+
+ if (origin != ORIGIN_FLIP &&
+ origin != ORIGIN_CURSOR_UPDATE)
+ drm_modeset_unlock(&crtc->base.mutex);
}
}
--
2.43.0
More information about the Intel-gfx-trybot
mailing list