[PATCH v3 10/12] drm/i915/flipq: Implement Wa_16018781658 for LNL-A0
Ville Syrjala
ville.syrjala at linux.intel.com
Tue Jun 3 14:08:34 UTC 2025
From: Ville Syrjälä <ville.syrjala at linux.intel.com>
The normal flip queue completion interrupt doesn't work on LNL-A0,
and instead the firmware implements a workaround via the delayed
vblank event handler. Implement said workaround on the driver side
by enabling the appropriate event and handling the result interrupt
vector value in the PIPEDMC irq handler.
Included here just for reference since LNL-A0 is pre-production
and we don't actually care about it anymore.
v2: Ignore INT_VECTOR if there is a real PIPEDMC interrupt
(nothing in the hw appears to clear INT_VECTOR)
Signed-off-by: Ville Syrjälä <ville.syrjala at linux.intel.com>
---
drivers/gpu/drm/i915/display/intel_dmc.c | 19 ++++++++++++++++++-
drivers/gpu/drm/i915/display/intel_flipq.c | 12 ++++++++++++
2 files changed, 30 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/i915/display/intel_dmc.c b/drivers/gpu/drm/i915/display/intel_dmc.c
index a23a726dea0d..469a51c5399d 100644
--- a/drivers/gpu/drm/i915/display/intel_dmc.c
+++ b/drivers/gpu/drm/i915/display/intel_dmc.c
@@ -1517,9 +1517,26 @@ void intel_pipedmc_irq_handler(struct intel_display *display, enum pipe pipe)
}
int_vector = intel_de_read(display, PIPEDMC_STATUS(pipe)) & PIPEDMC_INT_VECTOR_MASK;
- if (tmp == 0 && int_vector != 0)
+ /* Wa_16018781658 */
+ if (tmp == 0 && int_vector == PIPEDMC_INT_VECTOR_FLIPQ_PROG_DONE) {
+ spin_lock(&display->drm->event_lock);
+
+ if (crtc->flipq_event) {
+ /*
+ * Update vblank counter/timestamp in case it
+ * hasn't been done yet for this frame.
+ */
+ drm_crtc_accurate_vblank_count(&crtc->base);
+
+ drm_crtc_send_vblank_event(&crtc->base, crtc->flipq_event);
+ crtc->flipq_event = NULL;
+ }
+
+ spin_unlock(&display->drm->event_lock);
+ } else if (tmp == 0 && int_vector != 0) {
drm_err(display->drm, "[CRTC:%d:%s]] PIPEDMC interrupt vector 0x%x\n",
crtc->base.base.id, crtc->base.name, tmp);
+ }
}
void intel_pipedmc_enable_event(struct intel_crtc *crtc,
diff --git a/drivers/gpu/drm/i915/display/intel_flipq.c b/drivers/gpu/drm/i915/display/intel_flipq.c
index 434f9d854c40..37e5603c860e 100644
--- a/drivers/gpu/drm/i915/display/intel_flipq.c
+++ b/drivers/gpu/drm/i915/display/intel_flipq.c
@@ -245,6 +245,14 @@ void intel_flipq_enable(const struct intel_crtc_state *crtc_state)
intel_pipedmc_enable_event(crtc, flipq_event_id(display));
+ /*
+ * Wa_16018781658
+ * PIPEDMC_FPQ_CTL2 bit 1 isn't working, firmware implements
+ * a workaround via the delayed vblank handler.
+ */
+ if (display->platform.lunarlake && IS_DISPLAY_STEP(display, STEP_A0, STEP_B0))
+ intel_pipedmc_enable_event(crtc, PIPEDMC_EVENT_DELAYED_VBLANK);
+
intel_de_write(display, PIPEDMC_FQ_CTRL(crtc->pipe), PIPEDMC_FQ_CTRL_ENABLE);
}
@@ -255,6 +263,10 @@ void intel_flipq_disable(const struct intel_crtc_state *crtc_state)
intel_de_write(display, PIPEDMC_FQ_CTRL(crtc->pipe), 0);
+ /* Wa_16018781658 */
+ if (display->platform.lunarlake && IS_DISPLAY_STEP(display, STEP_A0, STEP_B0))
+ intel_pipedmc_disable_event(crtc, PIPEDMC_EVENT_DELAYED_VBLANK);
+
intel_pipedmc_disable_event(crtc, flipq_event_id(display));
intel_de_write(display, PIPEDMC_SCANLINECMPLOWER(crtc->pipe), 0);
--
2.49.0
More information about the Intel-xe
mailing list