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
Cc: Dnyaneshwar Bhadane <[email protected]>
Signed-off-by: Gustavo Sousa <[email protected]>
---
Changes in v2:
- EDITME: describe what is new in this series revision.
- EDITME: use bulletpoints and terse descriptions.
- Link to v1: 
https://patch.msgid.link/[email protected]
---
 drivers/gpu/drm/i915/display/intel_cdclk.c | 29 +++++++++++++++++++++++------
 1 file changed, 23 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c 
b/drivers/gpu/drm/i915/display/intel_cdclk.c
index 7443e5285942..9bfbfbf34dc0 100644
--- a/drivers/gpu/drm/i915/display/intel_cdclk.c
+++ b/drivers/gpu/drm/i915/display/intel_cdclk.c
@@ -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,

---
base-commit: 3d6700a02638d446a4e8ad92a8212c3efef84ae0
change-id: 20251222-xe3_lpd-no-cd2x-divider-48f9f0972f98

Best regards,
--  
Gustavo Sousa <[email protected]>

Reply via email to