]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
drm/i915/cx0_phy: Update HDMI TMDS C20 algorithm value
authorDnyaneshwar Bhadane <dnyaneshwar.bhadane@intel.com>
Tue, 17 Dec 2024 20:13:01 +0000 (01:43 +0530)
committerMatt Roper <matthew.d.roper@intel.com>
Thu, 16 Jan 2025 23:05:36 +0000 (15:05 -0800)
In the C20 algorithm for HDMI TMDS, certain fields have been updated
in the BSpec to set values for SRAM_GENERIC_<A/B>_TX_CNTX_CFG_1,
such as tx_misc and dac_ctrl_range for Xe2LPD, Xe2HPD and MTL/ARL.
This patch covers fields that need to be set based on the platform type.

Some ARLs SoCs cannot be directly distinguished by their GMD version Id,
Specifically to set value of tx_misc, so PCI Host Bridge IDs are used
for differentiation.

v2:
- Relocate defines and Restructure the code(Jani)

v3:
- Replace conditions with display.platform.<platform> (jani)
- Move host bridge check to new function (Jani)

v4:
- Identify/Replace arrowlake_u as meteorlake_u(Jani)

Bspec:74165,74491
Signed-off-by: Dnyaneshwar Bhadane <dnyaneshwar.bhadane@intel.com>
Reviewed-by: Suraj Kandpal <suraj.kandpal@intel.com>
Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20241217201301.3593054-3-dnyaneshwar.bhadane@intel.com
drivers/gpu/drm/i915/display/intel_cx0_phy.c
drivers/gpu/drm/i915/display/intel_cx0_phy_regs.h
drivers/gpu/drm/i915/display/intel_display_device.h

index 5ebc90d210d4747852af216425ba1b5c9c706c94..857262fcbac9f493cf1b254bf6c955673d1ea4bb 100644 (file)
@@ -2173,9 +2173,47 @@ static void intel_c10pll_dump_hw_state(struct intel_display *display,
                            i + 2, hw_state->pll[i + 2], i + 3, hw_state->pll[i + 3]);
 }
 
-static int intel_c20_compute_hdmi_tmds_pll(struct intel_crtc_state *crtc_state)
+/*
+ * Some ARLs SoCs have the same drm PCI IDs, so need a helper to differentiate based
+ * on the host bridge device ID to get the correct txx_mics value.
+ */
+static bool is_arrowlake_s_by_host_bridge(void)
+{
+       struct pci_dev *pdev = NULL;
+       u16 host_bridge_pci_dev_id;
+
+       while ((pdev = pci_get_class(PCI_CLASS_BRIDGE_HOST << 8, pdev)))
+               host_bridge_pci_dev_id = pdev->device;
+
+       return pdev && IS_ARROWLAKE_S_BY_HOST_BRIDGE_ID(host_bridge_pci_dev_id);
+}
+
+static u16 intel_c20_hdmi_tmds_tx_cgf_1(struct intel_crtc_state *crtc_state)
 {
        struct intel_display *display = to_intel_display(crtc_state);
+       u16 tx_misc;
+       u16 tx_dcc_cal_dac_ctrl_range = 8;
+       u16 tx_term_ctrl = 2;
+
+       if (DISPLAY_VER(display) >= 20) {
+               tx_misc = 5;
+               tx_term_ctrl = 4;
+       } else if (display->platform.battlemage) {
+               tx_misc = 0;
+       } else if (display->platform.meteorlake_u ||
+                  is_arrowlake_s_by_host_bridge()) {
+               tx_misc = 3;
+       } else {
+               tx_misc = 7;
+       }
+
+       return (C20_PHY_TX_MISC(tx_misc) |
+               C20_PHY_TX_DCC_CAL_RANGE(tx_dcc_cal_dac_ctrl_range) |
+               C20_PHY_TX_DCC_BYPASS | C20_PHY_TX_TERM_CTL(tx_term_ctrl));
+}
+
+static int intel_c20_compute_hdmi_tmds_pll(struct intel_crtc_state *crtc_state)
+{
        struct intel_c20pll_state *pll_state = &crtc_state->dpll_hw_state.cx0pll.c20;
        u64 datarate;
        u64 mpll_tx_clk_div;
@@ -2185,7 +2223,6 @@ static int intel_c20_compute_hdmi_tmds_pll(struct intel_crtc_state *crtc_state)
        u64 mpll_multiplier;
        u64 mpll_fracn_quot;
        u64 mpll_fracn_rem;
-       u16 tx_misc;
        u8  mpllb_ana_freq_vco;
        u8  mpll_div_multiplier;
 
@@ -2205,11 +2242,6 @@ static int intel_c20_compute_hdmi_tmds_pll(struct intel_crtc_state *crtc_state)
        mpll_div_multiplier = min_t(u8, div64_u64((vco_freq * 16 + (datarate >> 1)),
                                                  datarate), 255);
 
-       if (DISPLAY_VER(display) >= 20)
-               tx_misc = 0x5;
-       else
-               tx_misc = 0x0;
-
        if (vco_freq <= DATARATE_3000000000)
                mpllb_ana_freq_vco = MPLLB_ANA_FREQ_VCO_3;
        else if (vco_freq <= DATARATE_3500000000)
@@ -2221,7 +2253,7 @@ static int intel_c20_compute_hdmi_tmds_pll(struct intel_crtc_state *crtc_state)
 
        pll_state->clock        = crtc_state->port_clock;
        pll_state->tx[0]        = 0xbe88;
-       pll_state->tx[1]        = 0x9800 | C20_PHY_TX_MISC(tx_misc);
+       pll_state->tx[1]        = intel_c20_hdmi_tmds_tx_cgf_1(crtc_state);
        pll_state->tx[2]        = 0x0000;
        pll_state->cmn[0]       = 0x0500;
        pll_state->cmn[1]       = 0x0005;
index 4dc6e179a7741bb8cd65b17f497eccf245d0041d..a47fd1aef9f0f57683f00a2869966342b285cbe5 100644 (file)
 #define   C20_PHY_TX_RATE              REG_GENMASK(2, 0)
 #define   C20_PHY_TX_MISC_MASK         REG_GENMASK16(7, 0)
 #define   C20_PHY_TX_MISC(val)         REG_FIELD_PREP16(C20_PHY_TX_MISC_MASK, (val))
+#define   C20_PHY_TX_DCC_CAL_RANGE_MASK        REG_GENMASK16(11, 8)
+#define   C20_PHY_TX_DCC_CAL_RANGE(val) \
+               REG_FIELD_PREP16(C20_PHY_TX_DCC_CAL_RANGE_MASK, (val))
+#define   C20_PHY_TX_DCC_BYPASS        REG_BIT(12)
+#define   C20_PHY_TX_TERM_CTL_MASK     REG_GENMASK16(15, 13)
+#define   C20_PHY_TX_TERM_CTL(val)     REG_FIELD_PREP16(C20_PHY_TX_TERM_CTL_MASK, (val))
 
 #define PHY_C20_A_CMN_CNTX_CFG(i915, idx) \
                ((_IS_XE2HPD_C20(i915) ? _XE2HPD_C20_A_CMN_CNTX_CFG : _MTL_C20_A_CMN_CNTX_CFG) - (idx))
index 5853472bb9c22645cd326026d2e4b0ec50adb65f..a7b5ce69cf17d4a799d8becaf5729ea2ede4102f 100644 (file)
@@ -234,6 +234,17 @@ struct intel_display_platforms {
        (drm_WARN_ON(__to_intel_display(__display)->drm, INTEL_DISPLAY_STEP(__display) == STEP_NONE), \
         INTEL_DISPLAY_STEP(__display) >= (since) && INTEL_DISPLAY_STEP(__display) < (until))
 
+#define ARLS_HOST_BRIDGE_PCI_ID1 0x7D1C
+#define ARLS_HOST_BRIDGE_PCI_ID2 0x7D2D
+#define ARLS_HOST_BRIDGE_PCI_ID3 0x7D2E
+#define ARLS_HOST_BRIDGE_PCI_ID4 0x7D2F
+
+#define IS_ARROWLAKE_S_BY_HOST_BRIDGE_ID(id)  \
+       (((id) == ARLS_HOST_BRIDGE_PCI_ID1) || \
+        ((id) == ARLS_HOST_BRIDGE_PCI_ID2) || \
+        ((id) == ARLS_HOST_BRIDGE_PCI_ID3) || \
+        ((id) == ARLS_HOST_BRIDGE_PCI_ID4))
+
 struct intel_display_runtime_info {
        struct intel_display_ip_ver {
                u16 ver;