> -----Original Message-----
> From: Dibin Moolakadan Subrahmanian
> <[email protected]>
> Sent: Friday, May 29, 2026 7:46 PM
> To: Manna, Animesh <[email protected]>; intel-
> [email protected]; [email protected]
> Cc: Shankar, Uma <[email protected]>; [email protected];
> Nikula, Jani <[email protected]>
> Subject: Re: [PATCH v7 10/15] drm/i915/cmtg: Add CMTG interrupt handling
>
>
> On 26-05-2026 19:08, Animesh Manna wrote:
> > Add support for vsync, vblank, and delayed vblank interrupts of CMTG
> > which are part of DE port interrupt.
> >
> > v2:
> > - Use consistent DC3co check as used in earlier patches. [Uma]
> > - Use else-if instead of separate if block. [Uma]
> > - Merge mask and unmask function as it is similar. [Uma]
> > - Modify DISPLAY_VER() check. [Uma]
> >
> > Signed-off-by: Animesh Manna <[email protected]>
> > ---
> > drivers/gpu/drm/i915/display/intel_cmtg.c | 42 +++++++++++++++++++
> > drivers/gpu/drm/i915/display/intel_cmtg.h | 2 +
> > .../gpu/drm/i915/display/intel_display_irq.c | 12 ++++++
> > .../gpu/drm/i915/display/intel_display_regs.h | 6 +++
> > 4 files changed, 62 insertions(+)
> >
> > diff --git a/drivers/gpu/drm/i915/display/intel_cmtg.c
> > b/drivers/gpu/drm/i915/display/intel_cmtg.c
> > index 643e2e846d25..17e8da4fa7ee 100644
> > --- a/drivers/gpu/drm/i915/display/intel_cmtg.c
> > +++ b/drivers/gpu/drm/i915/display/intel_cmtg.c
> > @@ -13,6 +13,7 @@
> > #include "intel_crtc.h"
> > #include "intel_de.h"
> > #include "intel_display_device.h"
> > +#include "intel_display_irq.h"
> > #include "intel_display_power.h"
> > #include "intel_display_regs.h"
> > #include "intel_display_types.h"
> > @@ -402,3 +403,44 @@ void intel_cmtg_enable_ddi(const struct
> > intel_crtc_state *crtc_state)
> >
> > drm_dbg_kms(display->drm, "CMTG: %s enabled\n",
> transcoder_name(cpu_transcoder));
> > }
> > +
> > +static void intel_cmtg_mask_interrupt(const struct intel_crtc_state
> > +*crtc_state, bool mask) {
> > + struct intel_display *display = to_intel_display(crtc_state);
> > + enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
> > + u32 interrupt_mask = 0;
> > +
> > + if (cpu_transcoder == TRANSCODER_A)
> > + interrupt_mask = CMTG_VBLANK_A |
> CMTG_DELAYED_VBLANK_A | CMTG_VSYNC_A;
> > + else if (cpu_transcoder == TRANSCODER_B)
> > + interrupt_mask = CMTG_VBLANK_B |
> CMTG_DELAYED_VBLANK_B |
> > +CMTG_VSYNC_B;
> > +
> > + if (mask)
> > + bdw_update_port_irq(display, interrupt_mask, 0);
> > + else
> > + bdw_update_port_irq(display, interrupt_mask,
> interrupt_mask); }
> > +
> > +void intel_cmtg_enable_interrupt(const struct intel_crtc_state
> > +*crtc_state) {
> > + struct intel_display *display = to_intel_display(crtc_state);
> > +
> > + if (!intel_cmtg_is_allowed(crtc_state))
> > + return;
> > +
> > + spin_lock_irq(&display->irq.lock);
> > + intel_cmtg_mask_interrupt(crtc_state, false);
> > + spin_unlock_irq(&display->irq.lock);
> > +}
>
> Is this interrupt getting enabled through `GEN8_DE_PORT_IRQ` IER ?
Currently transcoder interrupt is used, will check on this.
>
> > +
> > +void intel_cmtg_disable_interrupt(const struct intel_crtc_state
> > +*crtc_state) {
> > + struct intel_display *display = to_intel_display(crtc_state);
> > +
> > + if (!intel_cmtg_is_allowed(crtc_state))
> > + return;
> > +
> > + spin_lock_irq(&display->irq.lock);
> > + intel_cmtg_mask_interrupt(crtc_state, true);
> > + spin_unlock_irq(&display->irq.lock);
> > +}
> > diff --git a/drivers/gpu/drm/i915/display/intel_cmtg.h
> > b/drivers/gpu/drm/i915/display/intel_cmtg.h
> > index 79785afccc51..8fcb44d6398f 100644
> > --- a/drivers/gpu/drm/i915/display/intel_cmtg.h
> > +++ b/drivers/gpu/drm/i915/display/intel_cmtg.h
> > @@ -21,5 +21,7 @@ void intel_cmtg_set_timings(const struct
> intel_crtc_state *crtc_state, bool lrr)
> > void intel_cmtg_set_clk_select(const struct intel_crtc_state *crtc_state);
> > void intel_cmtg_sanitize(struct intel_display *display);
> > bool intel_cmtg_is_allowed(const struct intel_crtc_state
> > *crtc_state);
> > +void intel_cmtg_enable_interrupt(const struct intel_crtc_state
> > +*crtc_state); void intel_cmtg_disable_interrupt(const struct
> > +intel_crtc_state *crtc_state);
> >
> > #endif /* __INTEL_CMTG_H__ */
> > diff --git a/drivers/gpu/drm/i915/display/intel_display_irq.c
> > b/drivers/gpu/drm/i915/display/intel_display_irq.c
> > index 899a38c0a7b7..f7f670dd5900 100644
> > --- a/drivers/gpu/drm/i915/display/intel_display_irq.c
> > +++ b/drivers/gpu/drm/i915/display/intel_display_irq.c
> > @@ -1469,6 +1469,18 @@ static void gen8_de_irq_handler(struct
> intel_display *display, u32 master_ctl)
> > found = true;
> > }
> >
> > + if (DISPLAY_VER(display) == 35) {
> > + if (iir & (CMTG_VBLANK_A | CMTG_VSYNC_A
> | CMTG_DELAYED_VBLANK_A)) {
> > + intel_handle_vblank(display, PIPE_A);
> > + found = true;
> > + }
> > +
> > + if (iir & (CMTG_VBLANK_B | CMTG_VSYNC_B
> | CMTG_DELAYED_VBLANK_B)) {
> > + intel_handle_vblank(display, PIPE_B);
> > + found = true;
> > + }
> > + }
>
> I could see `intel_handle_vblank()` getting called only for
> `GEN8_PIPE_VBLANK` interrupts. Does it need to be called for all three
> interrupts here?
You are right, only CMTG_VBLANK will be sufficient.
Regards,
Animesh
>
> > +
> > if (DISPLAY_VER(display) >= 11) {
> > u32 te_trigger = iir & (DSI0_TE | DSI1_TE);
> >
> > diff --git a/drivers/gpu/drm/i915/display/intel_display_regs.h
> > b/drivers/gpu/drm/i915/display/intel_display_regs.h
> > index 4321f8b529da..f38dcd9b6c48 100644
> > --- a/drivers/gpu/drm/i915/display/intel_display_regs.h
> > +++ b/drivers/gpu/drm/i915/display/intel_display_regs.h
> > @@ -1458,6 +1458,12 @@
> > #define GEN9_AUX_CHANNEL_B (1 << 25)
> > #define DSI1_TE (1 << 24)
> > #define DSI0_TE (1 << 23)
> > +#define CMTG_VSYNC_B (1 << 19)
> > +#define CMTG_DELAYED_VBLANK_B (1 << 18)
> > +#define CMTG_VBLANK_B (1 << 17)
> > +#define CMTG_VSYNC_A (1 << 16)
> > +#define CMTG_DELAYED_VBLANK_A (1 << 15)
> > +#define CMTG_VBLANK_A (1 << 14)
> > #define GEN8_DE_PORT_HOTPLUG(hpd_pin) REG_BIT(3 +
> _HPD_PIN_DDI(hpd_pin))
> > #define BXT_DE_PORT_HOTPLUG_MASK
> (GEN8_DE_PORT_HOTPLUG(HPD_PORT_A) | \
> >
> GEN8_DE_PORT_HOTPLUG(HPD_PORT_B) | \