[PATCH 24/28] drm/i915/writeback: Enable writeback interrupts
Suraj Kandpal
suraj.kandpal at intel.com
Fri Jul 25 05:04:05 UTC 2025
Enable writeback interrupts while enabling writeback
and define the isr handler and schedule work for later
to signal completion job.
Signed-off-by: Suraj Kandpal <suraj.kandpal at intel.com>
---
.../gpu/drm/i915/display/intel_display_irq.c | 10 ++++
.../gpu/drm/i915/display/intel_display_regs.h | 1 +
.../gpu/drm/i915/display/intel_writeback.c | 51 +++++++++++++++++++
.../gpu/drm/i915/display/intel_writeback.h | 1 +
4 files changed, 63 insertions(+)
diff --git a/drivers/gpu/drm/i915/display/intel_display_irq.c b/drivers/gpu/drm/i915/display/intel_display_irq.c
index fb25ec8adae3..0874afe839b2 100644
--- a/drivers/gpu/drm/i915/display/intel_display_irq.c
+++ b/drivers/gpu/drm/i915/display/intel_display_irq.c
@@ -31,6 +31,8 @@
#include "intel_psr.h"
#include "intel_psr_regs.h"
#include "intel_uncore.h"
+#include "intel_writeback.h"
+#include "intel_writeback_reg.h"
static void
intel_display_irq_regs_init(struct intel_display *display, struct i915_irq_regs regs,
@@ -1215,6 +1217,11 @@ gen8_de_misc_irq_handler(struct intel_display *display, u32 iir)
found = true;
}
+ if (iir & (GEN8_DE_MISC_WD0)) {
+ intel_writeback_isr_handler(display);
+ found = true;
+ }
+
if (iir & GEN8_DE_EDP_PSR) {
struct intel_encoder *encoder;
u32 psr_iir;
@@ -2251,6 +2258,9 @@ void gen8_de_irq_postinstall(struct intel_display *display)
if (DISPLAY_VER(display) < 11)
de_misc_masked |= GEN8_DE_MISC_GSE;
+ if (DISPLAY_VER(display) >= 13)
+ de_misc_masked |= GEN8_DE_MISC_WD0;
+
if (display->platform.geminilake || display->platform.broxton)
de_port_masked |= BXT_DE_PORT_GMBUS;
diff --git a/drivers/gpu/drm/i915/display/intel_display_regs.h b/drivers/gpu/drm/i915/display/intel_display_regs.h
index 7bd09d981cd2..fb748ae0634f 100644
--- a/drivers/gpu/drm/i915/display/intel_display_regs.h
+++ b/drivers/gpu/drm/i915/display/intel_display_regs.h
@@ -1325,6 +1325,7 @@
#define XELPDP_RM_TIMEOUT REG_BIT(29)
#define XELPDP_PMDEMAND_RSPTOUT_ERR REG_BIT(27)
#define GEN8_DE_MISC_GSE REG_BIT(27)
+#define GEN8_DE_MISC_WD0 REG_BIT(23)
#define GEN8_DE_EDP_PSR REG_BIT(19)
#define XELPDP_PMDEMAND_RSP REG_BIT(3)
#define XE2LPD_DBUF_OVERLAP_DETECTED REG_BIT(1)
diff --git a/drivers/gpu/drm/i915/display/intel_writeback.c b/drivers/gpu/drm/i915/display/intel_writeback.c
index 0f26134beacd..d66843fecd9a 100644
--- a/drivers/gpu/drm/i915/display/intel_writeback.c
+++ b/drivers/gpu/drm/i915/display/intel_writeback.c
@@ -13,6 +13,7 @@
#include <drm/drm_encoder.h>
#include <drm/drm_edid.h>
#include <drm/drm_gem_framebuffer_helper.h>
+#include <drm/drm_vblank.h>
#include "i915_drv.h"
#include "i915_reg.h"
@@ -23,6 +24,7 @@
#include "intel_display_types.h"
#include "intel_display_regs.h"
#include "intel_display_driver.h"
+#include "intel_display_regs.h"
#include "intel_connector.h"
#include "intel_fb_pin.h"
#include "intel_writeback.h"
@@ -335,6 +337,20 @@ void intel_writeback_atomic_commit(struct intel_atomic_state *state)
}
}
+static void
+intel_writeback_enable_interrupts(struct intel_display *display,
+ enum transcoder trans)
+{
+ u32 tmp;
+
+ tmp = intel_de_read(display, WD_IIR(trans));
+ intel_de_write_fw(display, WD_IIR(trans), tmp);
+
+ tmp = ~(WD_GTT_FAULT_INT | WD_WRITE_COMPLETE_INT |
+ WD_VBLANK_INT | WD_CAPTURING_INT);
+ intel_de_write(display, WD_IMR(trans), tmp);
+}
+
static void intel_writeback_enable_encoder(struct intel_atomic_state *state,
struct intel_encoder *encoder,
const struct intel_crtc_state *crtc_state,
@@ -360,6 +376,7 @@ static void intel_writeback_enable_encoder(struct intel_atomic_state *state,
fb = job->fb;
hactive = adjusted_mode->hdisplay;
vactive = adjusted_mode->vdisplay;
+ intel_writeback_enable_interrupts(display, trans);
/* Configure WD_STRIDE, WD_SURF and WD_TAIL_CFG */
/* Enable Planes, Pipes and Transcoder */
@@ -545,6 +562,40 @@ intel_writeback_get_hw_state(struct intel_encoder *encoder,
return true;
}
+void intel_writeback_isr_handler(struct intel_display *display)
+{
+ struct intel_encoder *encoder;
+ struct intel_writeback_connector *wb_conn;
+ struct intel_crtc *crtc;
+ u32 iir;
+
+ for_each_intel_encoder(display->drm, encoder) {
+ if (encoder->type != INTEL_OUTPUT_WRITEBACK)
+ continue;
+
+ wb_conn = enc_to_intel_writeback_connector(encoder);
+ if (!wb_conn->job) {
+ drm_err(display->drm, "No writeback job for the connector\n");
+ continue;
+ }
+
+ crtc = intel_crtc_for_pipe(display, wb_conn->pipe);
+ iir = intel_de_read(display, WD_IIR(wb_conn->trans));
+ if (iir & WD_GTT_FAULT_INT)
+ drm_err(display->drm, " GTT fault during writeback\n");
+ if (iir & WD_WRITE_COMPLETE_INT)
+ drm_dbg_kms(display->drm, "Writeback job write completed\n");
+ if (iir & WD_VBLANK_INT) {
+ drm_crtc_handle_vblank(&crtc->base);
+ drm_dbg_kms(display->drm, "Writeback vblank raised\n");
+ }
+ if (iir & WD_CAPTURING_INT)
+ drm_dbg_kms(display->drm, "Writeback job capture has started\n");
+
+ intel_de_write(display, WD_IIR(wb_conn->trans), iir);
+ }
+}
+
int intel_writeback_init(struct intel_display *display)
{
struct intel_encoder *encoder;
diff --git a/drivers/gpu/drm/i915/display/intel_writeback.h b/drivers/gpu/drm/i915/display/intel_writeback.h
index 3c145cf73e20..83a986753c4c 100644
--- a/drivers/gpu/drm/i915/display/intel_writeback.h
+++ b/drivers/gpu/drm/i915/display/intel_writeback.h
@@ -16,6 +16,7 @@ struct intel_writeback_connector;
int intel_writeback_init(struct intel_display *display);
void intel_writeback_atomic_commit(struct intel_atomic_state *state);
+void intel_writeback_isr_handler(struct intel_display *display);
#endif /* __INTEL_WRITEBACK_H__ */
--
2.34.1
More information about the Intel-xe
mailing list