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);
  }
/*

Reply via email to