From: Animesh Manna <[email protected]>

Add support for the CMTG vblank interrupt, which is delivered
through the DE port interrupt block. Enable/disable the interrupt
via the DE port IMR around CMTG enable/disable, and dispatch the
CMTG_VBLANK_{A,B} bits to the corresponding pipe vblank handler in
the gen8 DE IRQ handler.

Wired up for DISPLAY_VER 35. The CMTG interrupt is not enabled via
IER today because CMTG is brought up together with the eDP
transcoder; this can be revisited later.

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]

v3:
- Enable only vblank interrupt. [Dibin]

v4:
- Keep irq related code to intel_display_irq.c. [Jani, Uma]

Signed-off-by: Animesh Manna <[email protected]>
---
 drivers/gpu/drm/i915/display/intel_cmtg.c     | 24 ++++++++++++++++++-
 .../gpu/drm/i915/display/intel_display_irq.c  | 19 +++++++++++++++
 .../gpu/drm/i915/display/intel_display_irq.h  |  2 ++
 .../gpu/drm/i915/display/intel_display_regs.h |  2 ++
 4 files changed, 46 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/display/intel_cmtg.c 
b/drivers/gpu/drm/i915/display/intel_cmtg.c
index ae59d7e755f3..6da28c185080 100644
--- a/drivers/gpu/drm/i915/display/intel_cmtg.c
+++ b/drivers/gpu/drm/i915/display/intel_cmtg.c
@@ -14,6 +14,7 @@
 #include "intel_de.h"
 #include "intel_display.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"
@@ -177,7 +178,7 @@ void intel_cmtg_disable(const struct intel_crtc_state 
*crtc_state)
        struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
        enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
        enum transcoder cmtg_transcoder = 
to_cmtg_transcoder(crtc_state->cpu_transcoder);
-       u32 clk_sel_clr = 0;
+       u32 clk_sel_clr = 0, interrupt_mask = 0;
 
        if (!crtc->cmtg.enabled)
                return;
@@ -210,6 +211,13 @@ void intel_cmtg_disable(const struct intel_crtc_state 
*crtc_state)
        intel_de_rmw(display, CMTG_CLK_SEL, clk_sel_clr, 0);
 
        drm_dbg_kms(display->drm, "CMTG: %s disabled\n", 
transcoder_name(cpu_transcoder));
+
+       if (cpu_transcoder == TRANSCODER_A)
+               interrupt_mask = CMTG_VBLANK_A;
+       else if (cpu_transcoder == TRANSCODER_B)
+               interrupt_mask = CMTG_VBLANK_B;
+
+       intel_display_irq_port_interrupt_mask(display, interrupt_mask, true);
 }
 
 /*
@@ -355,11 +363,25 @@ static void intel_cmtg_enable_ddi(const struct 
intel_crtc_state *crtc_state)
        struct intel_display *display = to_intel_display(crtc_state);
        struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
        enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
+       u32 interrupt_mask = 0;
 
        intel_de_rmw(display, TRANS_DDI_FUNC_CTL2(display, cpu_transcoder), 0, 
CMTG_SECONDARY_MODE);
        intel_de_rmw(display, CMTG_SCANLINE_GB1(cpu_transcoder), 0, 
CMTG_HW_GB_ENABLE);
        crtc->cmtg.enabled = true;
        drm_dbg_kms(display->drm, "CMTG: %s enabled\n", 
transcoder_name(cpu_transcoder));
+
+       /*
+        * TODO: Currently cmtg is enabled along with eDP transcoder so cmtg
+        * interrupt is not enabled through IER, need to do some fine
+        * tuning in future.
+        */
+
+       if (cpu_transcoder == TRANSCODER_A)
+               interrupt_mask = CMTG_VBLANK_A;
+       else if (cpu_transcoder == TRANSCODER_B)
+               interrupt_mask = CMTG_VBLANK_B;
+
+       intel_display_irq_port_interrupt_mask(display, interrupt_mask, false);
 }
 
 /* Bspec: 75253 */
diff --git a/drivers/gpu/drm/i915/display/intel_display_irq.c 
b/drivers/gpu/drm/i915/display/intel_display_irq.c
index 4a821b0674fd..bcb0ee22fb56 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) {
+                                       intel_handle_vblank(display, PIPE_A);
+                                       found = true;
+                               }
+
+                               if (iir & CMTG_VBLANK_B) {
+                                       intel_handle_vblank(display, PIPE_B);
+                                       found = true;
+                               }
+                       }
+
                        if (DISPLAY_VER(display) >= 11) {
                                u32 te_trigger = iir & (DSI0_TE | DSI1_TE);
 
@@ -2666,3 +2678,10 @@ void intel_display_irq_snapshot_print(const struct 
intel_display_irq_snapshot *s
        drm_printf(p, "DERRMR: 0x%08x\n", snapshot->derrmr);
        drm_printf(p, "ERR_INT: 0x%08x\n", snapshot->err_int);
 }
+
+void intel_display_irq_port_interrupt_mask(struct intel_display *display, u32 
bits, bool mask)
+{
+       spin_lock_irq(&display->irq.lock);
+       bdw_update_port_irq(display, bits, mask ? 0 : bits);
+       spin_unlock_irq(&display->irq.lock);
+}
diff --git a/drivers/gpu/drm/i915/display/intel_display_irq.h 
b/drivers/gpu/drm/i915/display/intel_display_irq.h
index a1227cee885a..84446bf53401 100644
--- a/drivers/gpu/drm/i915/display/intel_display_irq.h
+++ b/drivers/gpu/drm/i915/display/intel_display_irq.h
@@ -82,4 +82,6 @@ void i915gm_irq_cstate_wa(struct intel_display *display, bool 
enable);
 struct intel_display_irq_snapshot *intel_display_irq_snapshot_capture(struct 
intel_display *display);
 void intel_display_irq_snapshot_print(const struct intel_display_irq_snapshot 
*snapshot, struct drm_printer *p);
 
+void intel_display_irq_port_interrupt_mask(struct intel_display *display, u32 
bits, bool mask);
+
 #endif /* __INTEL_DISPLAY_IRQ_H__ */
diff --git a/drivers/gpu/drm/i915/display/intel_display_regs.h 
b/drivers/gpu/drm/i915/display/intel_display_regs.h
index 4321f8b529da..fe851fe39222 100644
--- a/drivers/gpu/drm/i915/display/intel_display_regs.h
+++ b/drivers/gpu/drm/i915/display/intel_display_regs.h
@@ -1458,6 +1458,8 @@
 #define  GEN9_AUX_CHANNEL_B            (1 << 25)
 #define  DSI1_TE                       (1 << 24)
 #define  DSI0_TE                       (1 << 23)
+#define  CMTG_VBLANK_B                 (1 << 17)
+#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) | \
-- 
2.43.0

Reply via email to