[PATCH v5 7/9] drm/i915/flipq: Implement Wa_16018781658 for LNL-A0
Ville Syrjala
ville.syrjala at linux.intel.com
Tue Jun 24 17:00:47 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)
Reviewed-by: Uma Shankar <uma.shankar at intel.com>
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 1b2e721d36a3..44835432a79f 100644
--- a/drivers/gpu/drm/i915/display/intel_dmc.c
+++ b/drivers/gpu/drm/i915/display/intel_dmc.c
@@ -1645,9 +1645,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 ee69b85cb104..7833423e8538 100644
--- a/drivers/gpu/drm/i915/display/intel_flipq.c
+++ b/drivers/gpu/drm/i915/display/intel_flipq.c
@@ -261,6 +261,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);
}
@@ -273,6 +281,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