drm/i915/display: UHBR rates for Thunderbolt
authorMika Kahola <mika.kahola@intel.com>
Tue, 17 Dec 2024 14:34:40 +0000 (16:34 +0200)
committerMika Kahola <mika.kahola@intel.com>
Thu, 19 Dec 2024 07:24:58 +0000 (09:24 +0200)
tbt-alt mode is missing uhbr rates 10G and 20G. This requires
requires pll clock rates 312.5 MHz and 625 MHz to be added,
respectively. The uhbr rates are supported only form PTL+
platforms.

v2: Add drm_WARN_ON() to check if port clock is not supported by
    the platform (Imre)
    Combine forward ungate with mask parameter (Imre)
    Rename XE3LPDP_* to XE3D_* (Imre)

Signed-off-by: Mika Kahola <mika.kahola@intel.com>
Reviewed-by: Imre Deak <imre.deak@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20241217143440.572308-1-mika.kahola@intel.com
drivers/gpu/drm/i915/display/intel_cx0_phy.c
drivers/gpu/drm/i915/display/intel_cx0_phy_regs.h

index 71dc659228ab956ef759200446b809e4f0b7fcf9..6bcef6696deb7026a6a5a44e4da3e2cf48945428 100644 (file)
@@ -3070,7 +3070,10 @@ int intel_mtl_tbt_calc_port_clock(struct intel_encoder *encoder)
 
        val = intel_de_read(display, XELPDP_PORT_CLOCK_CTL(display, encoder->port));
 
-       clock = REG_FIELD_GET(XELPDP_DDI_CLOCK_SELECT_MASK, val);
+       if (DISPLAY_VER(display) >= 30)
+               clock = REG_FIELD_GET(XE3_DDI_CLOCK_SELECT_MASK, val);
+       else
+               clock = REG_FIELD_GET(XELPDP_DDI_CLOCK_SELECT_MASK, val);
 
        drm_WARN_ON(display->drm, !(val & XELPDP_FORWARD_CLOCK_UNGATE));
        drm_WARN_ON(display->drm, !(val & XELPDP_TBT_CLOCK_REQUEST));
@@ -3085,13 +3088,18 @@ int intel_mtl_tbt_calc_port_clock(struct intel_encoder *encoder)
                return 540000;
        case XELPDP_DDI_CLOCK_SELECT_TBT_810:
                return 810000;
+       case XELPDP_DDI_CLOCK_SELECT_TBT_312_5:
+               return 1000000;
+       case XELPDP_DDI_CLOCK_SELECT_TBT_625:
+               return 2000000;
        default:
                MISSING_CASE(clock);
                return 162000;
        }
 }
 
-static int intel_mtl_tbt_clock_select(int clock)
+static int intel_mtl_tbt_clock_select(struct intel_display *display,
+                                     int clock)
 {
        switch (clock) {
        case 162000:
@@ -3102,6 +3110,18 @@ static int intel_mtl_tbt_clock_select(int clock)
                return XELPDP_DDI_CLOCK_SELECT_TBT_540;
        case 810000:
                return XELPDP_DDI_CLOCK_SELECT_TBT_810;
+       case 1000000:
+               if (DISPLAY_VER(display) < 30) {
+                       drm_WARN_ON(display->drm, "UHBR10 not supported for the platform\n");
+                       return XELPDP_DDI_CLOCK_SELECT_TBT_162;
+               }
+               return XELPDP_DDI_CLOCK_SELECT_TBT_312_5;
+       case 2000000:
+               if (DISPLAY_VER(display) < 30) {
+                       drm_WARN_ON(display->drm, "UHBR20 not supported for the platform\n");
+                       return XELPDP_DDI_CLOCK_SELECT_TBT_162;
+               }
+               return XELPDP_DDI_CLOCK_SELECT_TBT_625;
        default:
                MISSING_CASE(clock);
                return XELPDP_DDI_CLOCK_SELECT_TBT_162;
@@ -3114,15 +3134,26 @@ static void intel_mtl_tbt_pll_enable(struct intel_encoder *encoder,
        struct intel_display *display = to_intel_display(encoder);
        enum phy phy = intel_encoder_to_phy(encoder);
        u32 val = 0;
+       u32 mask;
 
        /*
         * 1. Program PORT_CLOCK_CTL REGISTER to configure
         * clock muxes, gating and SSC
         */
-       val |= XELPDP_DDI_CLOCK_SELECT(intel_mtl_tbt_clock_select(crtc_state->port_clock));
+
+       if (DISPLAY_VER(display) >= 30) {
+               mask = XE3_DDI_CLOCK_SELECT_MASK;
+               val |= XE3_DDI_CLOCK_SELECT(intel_mtl_tbt_clock_select(display, crtc_state->port_clock));
+       } else {
+               mask = XELPDP_DDI_CLOCK_SELECT_MASK;
+               val |= XELPDP_DDI_CLOCK_SELECT(intel_mtl_tbt_clock_select(display, crtc_state->port_clock));
+       }
+
+       mask |= XELPDP_FORWARD_CLOCK_UNGATE;
        val |= XELPDP_FORWARD_CLOCK_UNGATE;
+
        intel_de_rmw(display, XELPDP_PORT_CLOCK_CTL(display, encoder->port),
-                    XELPDP_DDI_CLOCK_SELECT_MASK | XELPDP_FORWARD_CLOCK_UNGATE, val);
+                    mask, val);
 
        /* 2. Read back PORT_CLOCK_CTL REGISTER */
        val = intel_de_read(display, XELPDP_PORT_CLOCK_CTL(display, encoder->port));
index c685479c9756cecff087cf3c1c637374479ca7fd..59002fe651ef7150e7ad3f7690d4865c9eeeab83 100644 (file)
 #define   XELPDP_TBT_CLOCK_REQUEST                     REG_BIT(19)
 #define   XELPDP_TBT_CLOCK_ACK                         REG_BIT(18)
 #define   XELPDP_DDI_CLOCK_SELECT_MASK                 REG_GENMASK(15, 12)
+#define   XE3_DDI_CLOCK_SELECT_MASK                    REG_GENMASK(16, 12)
 #define   XELPDP_DDI_CLOCK_SELECT(val)                 REG_FIELD_PREP(XELPDP_DDI_CLOCK_SELECT_MASK, val)
+#define   XE3_DDI_CLOCK_SELECT(val)                    REG_FIELD_PREP(XE3_DDI_CLOCK_SELECT_MASK, val)
 #define   XELPDP_DDI_CLOCK_SELECT_NONE                 0x0
 #define   XELPDP_DDI_CLOCK_SELECT_MAXPCLK              0x8
 #define   XELPDP_DDI_CLOCK_SELECT_DIV18CLK             0x9
 #define   XELPDP_DDI_CLOCK_SELECT_TBT_270              0xd
 #define   XELPDP_DDI_CLOCK_SELECT_TBT_540              0xe
 #define   XELPDP_DDI_CLOCK_SELECT_TBT_810              0xf
+#define   XELPDP_DDI_CLOCK_SELECT_TBT_312_5            0x18
+#define   XELPDP_DDI_CLOCK_SELECT_TBT_625              0x19
 #define   XELPDP_FORWARD_CLOCK_UNGATE                  REG_BIT(10)
 #define   XELPDP_LANE1_PHY_CLOCK_SELECT                        REG_BIT(8)
 #define   XELPDP_SSC_ENABLE_PLLA                       REG_BIT(1)