Commit a2b4cefa authored by Radhakrishna Sripada's avatar Radhakrishna Sripada

drm/i915: Extract wm latency adjustment to its own function

Watermark latency is adjusted in cases when latency is 0us for level
greater than 1, the subsequent levels are disabled. Extract this logic
into its own function.

v2: Pass dev_priv to the extracted function(MattR)
Suggested-by: default avatarMatt Roper <matthew.d.roper@intel.com>
Signed-off-by: default avatarRadhakrishna Sripada <radhakrishna.sripada@intel.com>
Reviewed-by: default avatarMatt Roper <matthew.d.roper@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20220818234202.451742-14-radhakrishna.sripada@intel.com
parent dc35583b
...@@ -2862,15 +2862,60 @@ static void ilk_compute_wm_level(const struct drm_i915_private *dev_priv, ...@@ -2862,15 +2862,60 @@ static void ilk_compute_wm_level(const struct drm_i915_private *dev_priv,
result->enable = true; result->enable = true;
} }
static void
adjust_wm_latency(struct drm_i915_private *i915,
u16 wm[], int max_level, int read_latency)
{
bool wm_lv_0_adjust_needed = i915->dram_info.wm_lv_0_adjust_needed;
int i, level;
/*
* If a level n (n > 1) has a 0us latency, all levels m (m >= n)
* need to be disabled. We make sure to sanitize the values out
* of the punit to satisfy this requirement.
*/
for (level = 1; level <= max_level; level++) {
if (wm[level] == 0) {
for (i = level + 1; i <= max_level; i++)
wm[i] = 0;
max_level = level - 1;
break;
}
}
/*
* WaWmMemoryReadLatency
*
* punit doesn't take into account the read latency so we need
* to add proper adjustement to each valid level we retrieve
* from the punit when level 0 response data is 0us.
*/
if (wm[0] == 0) {
for (level = 0; level <= max_level; level++)
wm[level] += read_latency;
}
/*
* WA Level-0 adjustment for 16GB DIMMs: SKL+
* If we could not get dimm info enable this WA to prevent from
* any underrun. If not able to get Dimm info assume 16GB dimm
* to avoid any underrun.
*/
if (wm_lv_0_adjust_needed)
wm[0] += 1;
}
static void intel_read_wm_latency(struct drm_i915_private *dev_priv, static void intel_read_wm_latency(struct drm_i915_private *dev_priv,
u16 wm[]) u16 wm[])
{ {
struct intel_uncore *uncore = &dev_priv->uncore; struct intel_uncore *uncore = &dev_priv->uncore;
if (DISPLAY_VER(dev_priv) >= 9) { if (DISPLAY_VER(dev_priv) >= 9) {
int read_latency = DISPLAY_VER(dev_priv) >= 12 ? 3 : 2;
u32 val; u32 val;
int ret, i; int ret;
int level, max_level = ilk_wm_max_level(dev_priv); int max_level = ilk_wm_max_level(dev_priv);
int mult = IS_DG2(dev_priv) ? 2 : 1; int mult = IS_DG2(dev_priv) ? 2 : 1;
/* read the first set of memory latencies[0:3] */ /* read the first set of memory latencies[0:3] */
...@@ -2910,44 +2955,7 @@ static void intel_read_wm_latency(struct drm_i915_private *dev_priv, ...@@ -2910,44 +2955,7 @@ static void intel_read_wm_latency(struct drm_i915_private *dev_priv,
wm[7] = ((val >> GEN9_MEM_LATENCY_LEVEL_3_7_SHIFT) & wm[7] = ((val >> GEN9_MEM_LATENCY_LEVEL_3_7_SHIFT) &
GEN9_MEM_LATENCY_LEVEL_MASK) * mult; GEN9_MEM_LATENCY_LEVEL_MASK) * mult;
/* adjust_wm_latency(dev_priv, wm, max_level, read_latency);
* If a level n (n > 1) has a 0us latency, all levels m (m >= n)
* need to be disabled. We make sure to sanitize the values out
* of the punit to satisfy this requirement.
*/
for (level = 1; level <= max_level; level++) {
if (wm[level] == 0) {
for (i = level + 1; i <= max_level; i++)
wm[i] = 0;
max_level = level - 1;
break;
}
}
/*
* WaWmMemoryReadLatency
*
* punit doesn't take into account the read latency so we need
* to add proper adjustement to each valid level we retrieve
* from the punit when level 0 response data is 0us.
*/
if (wm[0] == 0) {
u8 adjust = DISPLAY_VER(dev_priv) >= 12 ? 3 : 2;
for (level = 0; level <= max_level; level++)
wm[level] += adjust;
}
/*
* WA Level-0 adjustment for 16GB DIMMs: SKL+
* If we could not get dimm info enable this WA to prevent from
* any underrun. If not able to get Dimm info assume 16GB dimm
* to avoid any underrun.
*/
if (dev_priv->dram_info.wm_lv_0_adjust_needed)
wm[0] += 1;
} else if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) { } else if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) {
u64 sskpd = intel_uncore_read64(uncore, MCH_SSKPD); u64 sskpd = intel_uncore_read64(uncore, MCH_SSKPD);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment