]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
drm/i915/cdclk: Incorporate Xe3_LPD changes for CD2X divider
authorGustavo Sousa <gustavo.sousa@intel.com>
Tue, 6 Jan 2026 21:40:21 +0000 (18:40 -0300)
committerGustavo Sousa <gustavo.sousa@intel.com>
Fri, 9 Jan 2026 14:32:06 +0000 (11:32 -0300)
On Xe3_LPD, there is no instruction to program the CD2X divider anymore
and the hardware is expected to always use the default value of 0b00,
meaning "divide by 1".

With that, the CDCLK_CTL register was changed so that:

  (1) The field "CD2X Divider Select" became a debug-only field.
      Because we are programming CDCLK_CTL with a direct write instead
      of read-modify-write operation, we still need to program "CD2X
      Divider Select" in order to keep the field from deviating from its
      default value.  Let's, however, throw a warning if we encounter a
      CDCLK value that would result in an unexpected value for that
      field.

  (2) The field "CD2X Pipe Select" has been removed. In fact, some
      debugging in a PTL machine showed that such field comes back as
      zero after writing a non-zero value to it.  As such, do not
      program it starting with Xe3_LPD.

v2:
  - Add missing "val |= " when calling bxt_cdclk_cd2x_pipe().
    (Dnyaneshwar)

Bspec: 68864, 69090
Reviewed-by: Dnyaneshwar Bhadane <dnyaneshwar.bhadane@intel.com>
Link: https://patch.msgid.link/20260106-xe3_lpd-no-cd2x-divider-v2-1-06e5cbc9dabb@intel.com
Signed-off-by: Gustavo Sousa <gustavo.sousa@intel.com>
drivers/gpu/drm/i915/display/intel_cdclk.c

index 7443e52859426b047472206d19b808145bd06908..9bfbfbf34dc0cbf77f1b90e79f868f29639fbe52 100644 (file)
@@ -1948,6 +1948,8 @@ static u32 bxt_cdclk_cd2x_pipe(struct intel_display *display, enum pipe pipe)
 static u32 bxt_cdclk_cd2x_div_sel(struct intel_display *display,
                                  int cdclk, int vco, u16 waveform)
 {
+       u32 ret;
+
        /* cdclk = vco / 2 / div{1,1.5,2,4} */
        switch (cdclk_divider(cdclk, vco, waveform)) {
        default:
@@ -1956,14 +1958,27 @@ static u32 bxt_cdclk_cd2x_div_sel(struct intel_display *display,
                drm_WARN_ON(display->drm, vco != 0);
                fallthrough;
        case 2:
-               return BXT_CDCLK_CD2X_DIV_SEL_1;
+               ret = BXT_CDCLK_CD2X_DIV_SEL_1;
+               break;
        case 3:
-               return BXT_CDCLK_CD2X_DIV_SEL_1_5;
+               ret = BXT_CDCLK_CD2X_DIV_SEL_1_5;
+               break;
        case 4:
-               return BXT_CDCLK_CD2X_DIV_SEL_2;
+               ret = BXT_CDCLK_CD2X_DIV_SEL_2;
+               break;
        case 8:
-               return BXT_CDCLK_CD2X_DIV_SEL_4;
+               ret = BXT_CDCLK_CD2X_DIV_SEL_4;
+               break;
        }
+
+       /*
+        * On Xe3_LPD onward, the expectation is to always have
+        * BXT_CDCLK_CD2X_DIV_SEL_1 as the default.
+        */
+       if (DISPLAY_VER(display) >= 30)
+               drm_WARN_ON(display->drm, ret != BXT_CDCLK_CD2X_DIV_SEL_1);
+
+       return ret;
 }
 
 static u16 cdclk_squash_waveform(struct intel_display *display,
@@ -2151,8 +2166,10 @@ static u32 bxt_cdclk_ctl(struct intel_display *display,
 
        waveform = cdclk_squash_waveform(display, cdclk);
 
-       val = bxt_cdclk_cd2x_div_sel(display, cdclk, vco, waveform) |
-               bxt_cdclk_cd2x_pipe(display, pipe);
+       val = bxt_cdclk_cd2x_div_sel(display, cdclk, vco, waveform);
+
+       if (DISPLAY_VER(display) < 30)
+               val |= bxt_cdclk_cd2x_pipe(display, pipe);
 
        /*
         * Disable SSA Precharge when CD clock frequency < 500 MHz,