]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
drm/i915/display: Fix PHY_C20_VDR_CUSTOM_SERDES_RATE programming
authorImre Deak <imre.deak@intel.com>
Wed, 15 Oct 2025 12:54:44 +0000 (15:54 +0300)
committerMika Kahola <mika.kahola@intel.com>
Thu, 16 Oct 2025 08:46:15 +0000 (11:46 +0300)
Make sure all the DP/HDMI/HDMI-FRL flags are programmed in all the modes
the PLL is configured.

Atm the DP mode flag is not programmed in case the PLL is configured for
HDMI mode for instance. This is incorrect after HW reset, since the DP
mode flag is asserted after reset, hence would need to be cleared for
HDMI, but also incorrect because of the same reason after configuring
the PLL to HDMI mode after it was used in DP mode (for instance on a
DP++ connector).

There is a similar issue with the HDMI-FRL flag, potentially remaining
set when configuring the PLL in DP mode.

Reviewed-by: Luca Coelho <luciano.coelho@intel.com>
Signed-off-by: Imre Deak <imre.deak@intel.com>
Signed-off-by: Mika Kahola <mika.kahola@intel.com>
Link: https://lore.kernel.org/r/20251015125446.3931198-6-mika.kahola@intel.com
drivers/gpu/drm/i915/display/intel_cx0_phy.c

index 9be7e155a584b13077eabd2f27da5cca18bfe528..6e49659d2f170be305a08131f56ecdbf335265ad 100644 (file)
@@ -2624,6 +2624,7 @@ static void intel_c20_pll_program(struct intel_display *display,
                                  bool is_dp, int port_clock)
 {
        u8 owned_lane_mask = intel_cx0_get_owned_lane_mask(encoder);
+       u8 serdes;
        bool cntx;
        int i;
 
@@ -2699,21 +2700,23 @@ static void intel_c20_pll_program(struct intel_display *display,
                      MB_WRITE_COMMITTED);
 
        /* 5. For DP or 6. For HDMI */
-       if (is_dp) {
-               intel_cx0_rmw(encoder, owned_lane_mask, PHY_C20_VDR_CUSTOM_SERDES_RATE,
-                             PHY_C20_IS_DP | PHY_C20_DP_RATE_MASK,
-                             PHY_C20_IS_DP | PHY_C20_DP_RATE(intel_c20_get_dp_rate(port_clock)),
-                             MB_WRITE_COMMITTED);
-       } else {
-               intel_cx0_rmw(encoder, owned_lane_mask, PHY_C20_VDR_CUSTOM_SERDES_RATE,
-                             PHY_C20_IS_HDMI_FRL | PHY_C20_DP_RATE_MASK,
-                             is_hdmi_frl(port_clock) ? PHY_C20_IS_HDMI_FRL : 0,
-                             MB_WRITE_COMMITTED);
+       serdes = 0;
+
+       if (is_dp)
+               serdes = PHY_C20_IS_DP |
+                        PHY_C20_DP_RATE(intel_c20_get_dp_rate(port_clock));
+       else if (is_hdmi_frl(port_clock))
+               serdes = PHY_C20_IS_HDMI_FRL;
 
+       intel_cx0_rmw(encoder, owned_lane_mask, PHY_C20_VDR_CUSTOM_SERDES_RATE,
+                     PHY_C20_IS_DP | PHY_C20_DP_RATE_MASK | PHY_C20_IS_HDMI_FRL,
+                     serdes,
+                     MB_WRITE_COMMITTED);
+
+       if (!is_dp)
                intel_cx0_write(encoder, INTEL_CX0_BOTH_LANES, PHY_C20_VDR_HDMI_RATE,
                                intel_c20_get_hdmi_rate(port_clock),
                                MB_WRITE_COMMITTED);
-       }
 
        /*
         * 7. Write Vendor specific registers to toggle context setting to load