@@ -40,6 +40,7 @@
#include "intel_psr.h"
#include "intel_vdsc.h"
#include "skl_watermark.h"
+#include "skl_watermark_regs.h"
#include "vlv_sideband.h"
/**
@@ -1860,6 +1861,47 @@ static int get_mdclk_cdclk_ratio(struct drm_i915_private *i915,
return 1;
}
+static void lnl_prog_mbus_dbuf_ctrl(struct drm_i915_private *i915,
+ const struct intel_cdclk_config *cdclk_config)
+{
+ int min_throttle_val;
+ int min_tracker_state;
+ enum dbuf_slice slice;
+ int mdclk_cdclk_div_ratio;
+ int mbus_join = intel_de_read(i915, MBUS_CTL) & MBUS_JOIN;
+
+ mdclk_cdclk_div_ratio = get_mdclk_cdclk_ratio(i915, cdclk_config);
+
+ min_throttle_val = MBUS_TRANS_THROTTLE_MIN_SELECT(mdclk_cdclk_div_ratio);
+
+ intel_de_rmw(i915, MBUS_CTL, MBUS_TRANS_THROTTLE_MIN_MASK, min_throttle_val);
+
+ if (mbus_join)
+ mdclk_cdclk_div_ratio = (mdclk_cdclk_div_ratio << 1) + 1;
+
+ min_tracker_state = DBUF_MIN_TRACKER_STATE_SERVICE(mdclk_cdclk_div_ratio);
+
+ for_each_dbuf_slice(i915, slice)
+ intel_de_rmw(i915, DBUF_CTL_S(slice),
+ DBUF_MIN_TRACKER_STATE_SERVICE_MASK,
+ min_tracker_state);
+}
+
+static void lnl_cdclk_squash_program(struct drm_i915_private *i915,
+ const struct intel_cdclk_config *cdclk_config,
+ u16 waveform)
+{
+ if (cdclk_config->cdclk < i915->display.cdclk.hw.cdclk)
+ /* Program mbus_ctrl and dbuf_ctrl registers as Pre hook */
+ lnl_prog_mbus_dbuf_ctrl(i915, cdclk_config);
+
+ dg2_cdclk_squash_program(i915, waveform);
+
+ if (cdclk_config->cdclk > i915->display.cdclk.hw.cdclk)
+ /* Program mbus_ctrl and dbuf_ctrl registers as Post hook */
+ lnl_prog_mbus_dbuf_ctrl(i915, cdclk_config);
+}
+
static bool cdclk_compute_crawl_and_squash_midpoint(struct drm_i915_private *i915,
const struct intel_cdclk_config *old_cdclk_config,
const struct intel_cdclk_config *new_cdclk_config,
@@ -1994,7 +2036,9 @@ static void _bxt_set_cdclk(struct drm_i915_private *dev_priv,
waveform = cdclk_squash_waveform(dev_priv, cdclk);
- if (HAS_CDCLK_SQUASH(dev_priv))
+ if (DISPLAY_VER(dev_priv) >= 20)
+ lnl_cdclk_squash_program(dev_priv, cdclk_config, waveform);
+ else if (HAS_CDCLK_SQUASH(dev_priv))
dg2_cdclk_squash_program(dev_priv, waveform);
intel_de_write(dev_priv, CDCLK_CTL, bxt_cdclk_ctl(dev_priv, cdclk_config, pipe));