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.kand...@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