Add a hook to enable CMTG by programming CMTG CTL with Sync to Port. When CMTG starts running, the Sync to Port bit will be cleared. Add a wait to check its running status and trigger WARN_ON() on timeout.
Reviewed-by: Uma Shankar <[email protected]> Signed-off-by: Animesh Manna <[email protected]> --- drivers/gpu/drm/i915/display/intel_cmtg.c | 27 ++++++++++++++++--- drivers/gpu/drm/i915/display/intel_cmtg.h | 1 + .../gpu/drm/i915/display/intel_cmtg_regs.h | 7 +++-- 3 files changed, 29 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_cmtg.c b/drivers/gpu/drm/i915/display/intel_cmtg.c index d490c57ba8b7..000b4957e546 100644 --- a/drivers/gpu/drm/i915/display/intel_cmtg.c +++ b/drivers/gpu/drm/i915/display/intel_cmtg.c @@ -104,11 +104,11 @@ static void intel_cmtg_get_config(struct intel_display *display, { u32 val; - val = intel_de_read(display, TRANS_CMTG_CTL_A); + val = intel_de_read(display, TRANS_CMTG_CTL(TRANSCODER_A)); cmtg_config->cmtg_a_enable = val & CMTG_ENABLE; if (intel_cmtg_has_cmtg_b(display)) { - val = intel_de_read(display, TRANS_CMTG_CTL_B); + val = intel_de_read(display, TRANS_CMTG_CTL(TRANSCODER_B)); cmtg_config->cmtg_b_enable = val & CMTG_ENABLE; } @@ -141,14 +141,14 @@ static void intel_cmtg_disable(struct intel_display *display, if (cmtg_config->cmtg_a_enable) { drm_dbg_kms(display->drm, "Disabling CMTG A\n"); - intel_de_rmw(display, TRANS_CMTG_CTL_A, CMTG_ENABLE, 0); + intel_de_rmw(display, TRANS_CMTG_CTL(TRANSCODER_A), CMTG_ENABLE, 0); clk_sel_clr |= CMTG_CLK_SEL_A_MASK; clk_sel_set |= CMTG_CLK_SEL_A_DISABLED; } if (cmtg_config->cmtg_b_enable) { drm_dbg_kms(display->drm, "Disabling CMTG B\n"); - intel_de_rmw(display, TRANS_CMTG_CTL_B, CMTG_ENABLE, 0); + intel_de_rmw(display, TRANS_CMTG_CTL(TRANSCODER_B), CMTG_ENABLE, 0); clk_sel_clr |= CMTG_CLK_SEL_B_MASK; clk_sel_set |= CMTG_CLK_SEL_B_DISABLED; } @@ -339,3 +339,22 @@ void intel_cmtg_set_m_n(const struct intel_crtc_state *crtc_state) intel_de_write(display, PIPE_DATA_M1(display, cmtg_transcoder), m_n->link_m); intel_de_write(display, PIPE_DATA_N1(display, cmtg_transcoder), m_n->link_n); } + +void intel_cmtg_enable_sync(const struct intel_crtc_state *crtc_state) +{ + struct intel_display *display = to_intel_display(crtc_state); + enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; + u32 cmtg_ctl; + + if (!intel_cmtg_is_allowed(crtc_state)) + return; + + cmtg_ctl = CMTG_SYNC_TO_PORT | CMTG_ENABLE; + + intel_de_rmw(display, TRANS_CMTG_CTL(cpu_transcoder), 0, cmtg_ctl); + if (intel_de_wait_for_clear_ms(display, TRANS_CMTG_CTL(cpu_transcoder), + CMTG_SYNC_TO_PORT, 50)) { + drm_WARN(display->drm, 1, "CMTG: %s enable timeout\n", + transcoder_name(cpu_transcoder)); + } +} diff --git a/drivers/gpu/drm/i915/display/intel_cmtg.h b/drivers/gpu/drm/i915/display/intel_cmtg.h index 6796eb727eef..64ff6a19948a 100644 --- a/drivers/gpu/drm/i915/display/intel_cmtg.h +++ b/drivers/gpu/drm/i915/display/intel_cmtg.h @@ -11,6 +11,7 @@ struct intel_display; struct intel_crtc_state; +void intel_cmtg_enable_sync(const struct intel_crtc_state *crtc_state); void intel_cmtg_set_m_n(const struct intel_crtc_state *crtc_state); void intel_cmtg_set_vrr_timings(const struct intel_crtc_state *crtc_state); void intel_cmtg_set_vrr_ctl(const struct intel_crtc_state *crtc_state); diff --git a/drivers/gpu/drm/i915/display/intel_cmtg_regs.h b/drivers/gpu/drm/i915/display/intel_cmtg_regs.h index 4a80b88d88fd..a93236bf7b75 100644 --- a/drivers/gpu/drm/i915/display/intel_cmtg_regs.h +++ b/drivers/gpu/drm/i915/display/intel_cmtg_regs.h @@ -16,8 +16,11 @@ #define CMTG_CLK_SELECT_PHYB_ENABLE REG_FIELD_PREP(CMTG_CLK_SEL_B_MASK, 0x6) #define CMTG_CLK_SEL_B_DISABLED REG_FIELD_PREP(CMTG_CLK_SEL_B_MASK, 0) -#define TRANS_CMTG_CTL_A _MMIO(0x6fa88) -#define TRANS_CMTG_CTL_B _MMIO(0x6fb88) +#define _TRANS_CMTG_CTL_A 0x6fa88 +#define _TRANS_CMTG_CTL_B 0x6fb88 +#define TRANS_CMTG_CTL(trans) _MMIO_TRANS((trans), \ + _TRANS_CMTG_CTL_A, _TRANS_CMTG_CTL_B) #define CMTG_ENABLE REG_BIT(31) +#define CMTG_SYNC_TO_PORT REG_BIT(29) #endif /* __INTEL_CMTG_REGS_H__ */ -- 2.29.0
