mirror of
https://github.com/torvalds/linux.git
synced 2026-10-14 11:54:03 +02:00
drm/i915/cmtg: Add CMTG interrupt handling
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 <animesh.manna@intel.com>
Reviewed-by: Uma Shankar <uma.shankar@intel.com>
Link: https://patch.msgid.link/20260615200339.885190-23-animesh.manna@intel.com
This commit is contained in:
parent
f9360ef054
commit
481fe84b73
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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__ */
|
||||
|
|
|
|||
|
|
@ -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) | \
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user