drm/i915/cmtg: Modify existing hook to disable CMTG

Earlier cmtg_disable() used to disable all instances of CMTG
which cannot handle individual request for specific CMTG instance.
Introduce cmtg_disable_all() which will disable all cmtg instances
and cmtg_disable() only disable specific instance.

v2:
- Use intel_de_rmw to simplify. [Uma]

v3:
- Add a code comment describing when cpu_transcoder should be used
instead of cmtg_transcoder. [Uma]

Signed-off-by: Dibin Moolakadan Subrahmanian <dibin.moolakadan.subrahmanian@intel.com>
Signed-off-by: Animesh Manna <animesh.manna@intel.com>
Reviewed-by: Uma Shankar <uma.shankar@intel.com>
Link: https://patch.msgid.link/20260615200339.885190-18-animesh.manna@intel.com
This commit is contained in:
Dibin Moolakadan Subrahmanian
2026-06-16 17:20:47 +05:30
committed by Animesh Manna
parent 3c6b291c29
commit 3bb44e8d42
3 changed files with 45 additions and 3 deletions
+43 -3
View File
@@ -138,8 +138,8 @@ static bool intel_cmtg_disable_requires_modeset(struct intel_display *display,
return cmtg_config->trans_a_secondary || cmtg_config->trans_b_secondary;
}
static void intel_cmtg_disable(struct intel_display *display,
struct intel_cmtg_config *cmtg_config)
static void intel_cmtg_disable_all(struct intel_display *display,
struct intel_cmtg_config *cmtg_config)
{
u32 clk_sel_clr = 0;
u32 clk_sel_set = 0;
@@ -170,6 +170,46 @@ static void intel_cmtg_disable(struct intel_display *display,
intel_de_rmw(display, CMTG_CLK_SEL, clk_sel_clr, clk_sel_set);
}
void intel_cmtg_disable(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;
enum transcoder cmtg_transcoder = to_cmtg_transcoder(crtc_state->cpu_transcoder);
u32 clk_sel_clr = 0;
if (!crtc->cmtg.enabled)
return;
crtc->cmtg.enabled = false;
intel_de_rmw(display, TRANS_VRR_CTL(display, cmtg_transcoder),
VRR_CTL_VRR_ENABLE | VRR_CTL_FLIP_LINE_EN, 0);
/*
* Use cpu_transcoder for:
* 1. Exclusive CMTG registers that do not use the standard transcoder offset
* (e.g., TRANS_CMTG_CTL, CMTG_CLK_SEL).
* 2. Registers shared between the eDP and CMTG transcoders.
* (e.g., TRANS_DDI_FUNC_CTL2).
*/
intel_de_rmw(display, TRANS_DDI_FUNC_CTL2(display, cpu_transcoder),
CMTG_SECONDARY_MODE, 0);
intel_de_rmw(display, TRANS_CMTG_CTL(cpu_transcoder), CMTG_ENABLE, 0);
if (intel_de_wait_for_clear_ms(display, TRANS_CMTG_CTL(cpu_transcoder), CMTG_STATE, 50)) {
drm_WARN(display->drm, 1, "CMTG: %s disable timeout\n",
transcoder_name(cpu_transcoder));
return;
}
clk_sel_clr = cpu_transcoder == TRANSCODER_A ? CMTG_CLK_SEL_A_MASK : CMTG_CLK_SEL_B_MASK;
intel_de_rmw(display, CMTG_CLK_SEL, clk_sel_clr, 0);
drm_dbg_kms(display->drm, "CMTG: %s disabled\n", transcoder_name(cpu_transcoder));
}
/*
* Read out CMTG configuration and, on platforms that allow disabling it without
* a modeset, do it.
@@ -197,7 +237,7 @@ void intel_cmtg_sanitize(struct intel_display *display)
if (intel_cmtg_disable_requires_modeset(display, &cmtg_config))
return;
intel_cmtg_disable(display, &cmtg_config);
intel_cmtg_disable_all(display, &cmtg_config);
}
bool intel_cmtg_is_allowed(const struct intel_crtc_state *crtc_state)
@@ -16,6 +16,7 @@ enum set_timing_type {
LRR
};
void intel_cmtg_disable(const struct intel_crtc_state *crtc_state);
void intel_cmtg_enable_ddi(const struct intel_crtc_state *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);
@@ -22,5 +22,6 @@
_TRANS_CMTG_CTL_A, _TRANS_CMTG_CTL_B)
#define CMTG_ENABLE REG_BIT(31)
#define CMTG_SYNC_TO_PORT REG_BIT(29)
#define CMTG_STATE REG_BIT(23)
#endif /* __INTEL_CMTG_REGS_H__ */