On 13-05-2026 22:08, Animesh Manna wrote:
Program the CMTG Clock Select register based on the transcoder used.
v2:
- Correct mask for PHY B. [Jani]
- Use REG_FIELD_PREP() for enable value. [Dibin]
- Extend cmtg clock select for xe3plpd. [Dibin]
v3:
- CMTG support removed for old platform.
v4:
- Optimize further with else-if. [Uma]
- Correct CMTG_CLK_SEL_B_MASK. [Uma]
Signed-off-by: Animesh Manna <[email protected]>
Signed-off-by: Dibin Moolakadan Subrahmanian
<[email protected]>
---
drivers/gpu/drm/i915/display/intel_cmtg.c | 22 +++++++++++++++++++
drivers/gpu/drm/i915/display/intel_cmtg.h | 1 +
.../gpu/drm/i915/display/intel_cmtg_regs.h | 2 ++
drivers/gpu/drm/i915/display/intel_cx0_phy.c | 5 +++++
4 files changed, 30 insertions(+)
diff --git a/drivers/gpu/drm/i915/display/intel_cmtg.c
b/drivers/gpu/drm/i915/display/intel_cmtg.c
index dc039bea452c..cfe59c604506 100644
--- a/drivers/gpu/drm/i915/display/intel_cmtg.c
+++ b/drivers/gpu/drm/i915/display/intel_cmtg.c
@@ -198,3 +198,25 @@ bool intel_cmtg_is_allowed(const struct intel_crtc_state
*crtc_state)
return false;
}
+
+void intel_cmtg_set_clk_select(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 clk_sel_clr = 0;
+ u32 clk_sel_set = 0;
+
+ if (!intel_cmtg_is_allowed(crtc_state))
+ return;
+
+ if (cpu_transcoder == TRANSCODER_A) {
+ clk_sel_clr = CMTG_CLK_SEL_A_MASK;
+ clk_sel_set = CMTG_CLK_SELECT_PHYA_ENABLE;
+ } else if (cpu_transcoder == TRANSCODER_B) {
+ clk_sel_clr = CMTG_CLK_SEL_B_MASK;
+ clk_sel_set = CMTG_CLK_SELECT_PHYB_ENABLE;
+ }
+
+ if (clk_sel_set)
+ intel_de_rmw(display, CMTG_CLK_SEL, clk_sel_clr, clk_sel_set);
+}
This comment applies to the entire CMTG programming series, but adding it here
since this is the first
TRANSCODER/PHY programming step.
There are IGT cases where TRANSCODER_B is not mapped to PORT_B, so the
current|else if|
flow can fail because PHY B may not be enabled.
Please check whether the programming sequence here is correct and
what TRANSCODER/PORT/PHY combinations are supported for CMTG.
diff --git a/drivers/gpu/drm/i915/display/intel_cmtg.h
b/drivers/gpu/drm/i915/display/intel_cmtg.h
index ed540581738f..87092ce6d67b 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_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);
diff --git a/drivers/gpu/drm/i915/display/intel_cmtg_regs.h b/drivers/gpu/drm/i915/display/intel_cmtg_regs.h
index 945a35578284..4a80b88d88fd 100644
--- a/drivers/gpu/drm/i915/display/intel_cmtg_regs.h
+++ b/drivers/gpu/drm/i915/display/intel_cmtg_regs.h
@@ -10,8 +10,10 @@
#define CMTG_CLK_SEL _MMIO(0x46160)
#define CMTG_CLK_SEL_A_MASK REG_GENMASK(31, 29)
+#define CMTG_CLK_SELECT_PHYA_ENABLE REG_FIELD_PREP(CMTG_CLK_SEL_A_MASK, 0x4)
#define CMTG_CLK_SEL_A_DISABLED
REG_FIELD_PREP(CMTG_CLK_SEL_A_MASK, 0)
#define CMTG_CLK_SEL_B_MASK REG_GENMASK(15, 13)
+#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)
diff --git a/drivers/gpu/drm/i915/display/intel_cx0_phy.c
b/drivers/gpu/drm/i915/display/intel_cx0_phy.c
index d832e44ef62a..6a7481578e61 100644
--- a/drivers/gpu/drm/i915/display/intel_cx0_phy.c
+++ b/drivers/gpu/drm/i915/display/intel_cx0_phy.c
@@ -9,6 +9,7 @@
#include <drm/drm_print.h>
#include "intel_alpm.h"
+#include "intel_cmtg.h"
#include "intel_cx0_phy.h"
#include "intel_cx0_phy_regs.h"
#include "intel_display_regs.h"
@@ -3418,10 +3419,14 @@ void intel_mtl_pll_enable(struct intel_encoder *encoder,
void intel_mtl_pll_enable_clock(struct intel_encoder *encoder,
const struct intel_crtc_state *crtc_state)
{
+ struct intel_display *display = to_intel_display(encoder);
struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
if (intel_tc_port_in_tbt_alt_mode(dig_port))
intel_mtl_tbt_pll_enable_clock(encoder, crtc_state->port_clock);
+
+ if (HAS_LT_PHY(display))
+ intel_cmtg_set_clk_select(crtc_state);
}
/*