drm/i915/cmtg: Set timings for CMTG by using transcoder timing helpers

Expose intel_set_transcoder_timings() & intel_set_transcoder_timings_lrr()
so that they can program timings on any transcoder, and use them from a
new intel_cmtg_set_timings() helper instead of duplicating the timing
register write sequence for CMTG.

intel_cmtg_set_timings() maps the CPU transcoder to the corresponding
CMTG transcoder (TRANSCODER_A->TRANSCODER_CMTG0, TRANSCODER_B->
TRANSCODER_CMTG1) and calls the shared helper, gated by
intel_cmtg_is_allowed(). It is invoked from hsw_configure_cpu_transcoder()
for the full modeset path and from intel_pipe_fastset() for the LRR
update path.

v2:
- Use sw state instead of reading directly from hardware. [Jani]
- Move set_timing later after encoder enable. [Dibin]

v3:
- Replace id with trans. [Jani]
- Program cmtg set_timing() along with primary transcoder timing.

v4:
- Use _MMIO_TRANS() for cmtg registers instead of direct
multiplication. [Jani]

v5:
- Modify register definition approach and match existing
transcoder definition. [Ville]

v6:
- Reuse transcoder timing helpers. [Ville]

v7:
- Introduce enum for set_timing_type. [Uma]
- Add check for INVALID_TRANSCODER. [Uma]

Bspec: 68989
Reviewed-by: Uma Shankar <uma.shankar@intel.com>
Signed-off-by: Animesh Manna <animesh.manna@intel.com>
Link: https://patch.msgid.link/20260615200339.885190-10-animesh.manna@intel.com
This commit is contained in:
Animesh Manna 2026-06-16 01:33:26 +05:30
parent 61f1ed0d71
commit 3269980141
4 changed files with 45 additions and 6 deletions

View File

@ -81,6 +81,18 @@ static void intel_cmtg_dump_config(struct intel_display *display,
str_yes_no(cmtg_config->trans_b_secondary));
}
static inline enum transcoder to_cmtg_transcoder(enum transcoder cpu_transcoder)
{
switch (cpu_transcoder) {
case TRANSCODER_A:
return TRANSCODER_CMTG0;
case TRANSCODER_B:
return TRANSCODER_CMTG1;
default:
return INVALID_TRANSCODER;
}
}
static bool intel_cmtg_transcoder_is_secondary(struct intel_display *display,
enum transcoder trans)
{
@ -219,3 +231,19 @@ void intel_cmtg_set_clk_select(const struct intel_crtc_state *crtc_state)
if (clk_sel_set)
intel_de_rmw(display, CMTG_CLK_SEL, clk_sel_clr, clk_sel_set);
}
void intel_cmtg_set_timings(const struct intel_crtc_state *crtc_state, enum set_timing_type type)
{
enum transcoder cmtg_transcoder = to_cmtg_transcoder(crtc_state->cpu_transcoder);
if (cmtg_transcoder == INVALID_TRANSCODER)
return;
if (!intel_cmtg_is_allowed(crtc_state))
return;
if (type == LRR)
intel_set_transcoder_timings_lrr(crtc_state, cmtg_transcoder);
else
intel_set_transcoder_timings(crtc_state, cmtg_transcoder);
}

View File

@ -11,6 +11,12 @@
struct intel_display;
struct intel_crtc_state;
enum set_timing_type {
MODESET = 0,
LRR
};
void intel_cmtg_set_timings(const struct intel_crtc_state *crtc_state, enum set_timing_type type);
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);

View File

@ -60,6 +60,7 @@
#include "intel_bw.h"
#include "intel_cdclk.h"
#include "intel_clock_gating.h"
#include "intel_cmtg.h"
#include "intel_color.h"
#include "intel_crt.h"
#include "intel_crtc.h"
@ -132,8 +133,6 @@
#include "vlv_dsi_pll.h"
#include "vlv_dsi_regs.h"
static void intel_set_transcoder_timings(const struct intel_crtc_state *crtc_state,
enum transcoder transcoder);
static void intel_set_pipe_src_size(const struct intel_crtc_state *crtc_state);
static void hsw_set_transconf(const struct intel_crtc_state *crtc_state);
static void bdw_set_pipe_misc(struct intel_dsb *dsb,
@ -1637,6 +1636,7 @@ static void hsw_configure_cpu_transcoder(const struct intel_crtc_state *crtc_sta
}
intel_set_transcoder_timings(crtc_state, crtc_state->cpu_transcoder);
intel_cmtg_set_timings(crtc_state, MODESET);
if (cpu_transcoder != TRANSCODER_EDP)
intel_de_write(display, TRANS_MULT(display, cpu_transcoder),
@ -2665,8 +2665,8 @@ transcoder_has_vrr(const struct intel_crtc_state *crtc_state)
return HAS_VRR(display) && !transcoder_is_dsi(cpu_transcoder);
}
static void intel_set_transcoder_timings(const struct intel_crtc_state *crtc_state,
enum transcoder transcoder)
void intel_set_transcoder_timings(const struct intel_crtc_state *crtc_state,
enum transcoder transcoder)
{
struct intel_display *display = to_intel_display(crtc_state);
struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
@ -2777,8 +2777,8 @@ static void intel_set_transcoder_timings(const struct intel_crtc_state *crtc_sta
}
}
static void intel_set_transcoder_timings_lrr(const struct intel_crtc_state *crtc_state,
enum transcoder transcoder)
void intel_set_transcoder_timings_lrr(const struct intel_crtc_state *crtc_state,
enum transcoder transcoder)
{
struct intel_display *display = to_intel_display(crtc_state);
const struct drm_display_mode *adjusted_mode = &crtc_state->hw.adjusted_mode;
@ -6693,6 +6693,7 @@ static void intel_pipe_fastset(const struct intel_crtc_state *old_crtc_state,
if (new_crtc_state->update_lrr) {
intel_set_transcoder_timings_lrr(new_crtc_state, new_crtc_state->cpu_transcoder);
intel_cmtg_set_timings(new_crtc_state, LRR);
intel_vrr_set_fixed_rr_timings(new_crtc_state);
intel_vrr_transcoder_enable(new_crtc_state);
}

View File

@ -424,6 +424,10 @@ void intel_set_m_n(struct intel_display *display,
const struct intel_link_m_n *m_n,
intel_reg_t data_m_reg, intel_reg_t data_n_reg,
intel_reg_t link_m_reg, intel_reg_t link_n_reg);
void intel_set_transcoder_timings(const struct intel_crtc_state *crtc_state,
enum transcoder transcoder);
void intel_set_transcoder_timings_lrr(const struct intel_crtc_state *crtc_state,
enum transcoder transcoder);
void intel_get_m_n(struct intel_display *display,
struct intel_link_m_n *m_n,
intel_reg_t data_m_reg, intel_reg_t data_n_reg,