Commit 7ee6f99d authored by Ville Syrjälä's avatar Ville Syrjälä Committed by Jani Nikula

drm/i915: Replace wm.max_levels with wm.num_levels and use it everywhere

Replaces wm.max_level with wm.num_levels, since that generally
results in nicer looking code (for-loops can be in standard
form etc.).

Also get rid of the two different wrappers we have for this
(ilk_wm_max_level() and intel_wm_num_levels()). They don't
really do anything for us other than potentially slow things
down if the compiler actually emits the function calls every
time (num_planes*num_wm_levels*higher_level_wm_function_calls
could be a big number). The watermark code already shows up
far too prominently in cpu profiles. Though I must admit that
I didn't look at the generated code this time.

v2: Fix the ilk_wm_merge() off-by-one (Jani)
Signed-off-by: default avatarVille Syrjälä <ville.syrjala@linux.intel.com>
Reviewed-by: default avatarJani Nikula <jani.nikula@intel.com>
Signed-off-by: default avatarJani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20230209222504.31478-1-ville.syrjala@linux.intel.com
parent 064b3eee
...@@ -243,7 +243,7 @@ struct intel_wm { ...@@ -243,7 +243,7 @@ struct intel_wm {
struct g4x_wm_values g4x; struct g4x_wm_values g4x;
}; };
u8 max_level; u8 num_levels;
/* /*
* Should be held around atomic WM register writing; also * Should be held around atomic WM register writing; also
......
...@@ -1286,13 +1286,10 @@ static void wm_latency_show(struct seq_file *m, const u16 wm[8]) ...@@ -1286,13 +1286,10 @@ static void wm_latency_show(struct seq_file *m, const u16 wm[8])
{ {
struct drm_i915_private *dev_priv = m->private; struct drm_i915_private *dev_priv = m->private;
int level; int level;
int num_levels;
num_levels = ilk_wm_max_level(dev_priv) + 1;
drm_modeset_lock_all(&dev_priv->drm); drm_modeset_lock_all(&dev_priv->drm);
for (level = 0; level < num_levels; level++) { for (level = 0; level < dev_priv->display.wm.num_levels; level++) {
unsigned int latency = wm[level]; unsigned int latency = wm[level];
/* /*
...@@ -1395,13 +1392,10 @@ static ssize_t wm_latency_write(struct file *file, const char __user *ubuf, ...@@ -1395,13 +1392,10 @@ static ssize_t wm_latency_write(struct file *file, const char __user *ubuf,
struct seq_file *m = file->private_data; struct seq_file *m = file->private_data;
struct drm_i915_private *dev_priv = m->private; struct drm_i915_private *dev_priv = m->private;
u16 new[8] = { 0 }; u16 new[8] = { 0 };
int num_levels;
int level; int level;
int ret; int ret;
char tmp[32]; char tmp[32];
num_levels = ilk_wm_max_level(dev_priv) + 1;
if (len >= sizeof(tmp)) if (len >= sizeof(tmp))
return -EINVAL; return -EINVAL;
...@@ -1413,12 +1407,12 @@ static ssize_t wm_latency_write(struct file *file, const char __user *ubuf, ...@@ -1413,12 +1407,12 @@ static ssize_t wm_latency_write(struct file *file, const char __user *ubuf,
ret = sscanf(tmp, "%hu %hu %hu %hu %hu %hu %hu %hu", ret = sscanf(tmp, "%hu %hu %hu %hu %hu %hu %hu %hu",
&new[0], &new[1], &new[2], &new[3], &new[0], &new[1], &new[2], &new[3],
&new[4], &new[5], &new[6], &new[7]); &new[4], &new[5], &new[6], &new[7]);
if (ret != num_levels) if (ret != dev_priv->display.wm.num_levels)
return -EINVAL; return -EINVAL;
drm_modeset_lock_all(&dev_priv->drm); drm_modeset_lock_all(&dev_priv->drm);
for (level = 0; level < num_levels; level++) for (level = 0; level < dev_priv->display.wm.num_levels; level++)
wm[level] = new[level]; wm[level] = new[level];
drm_modeset_unlock_all(&dev_priv->drm); drm_modeset_unlock_all(&dev_priv->drm);
......
...@@ -359,7 +359,7 @@ static bool skl_crtc_can_enable_sagv(const struct intel_crtc_state *crtc_state) ...@@ -359,7 +359,7 @@ static bool skl_crtc_can_enable_sagv(const struct intel_crtc_state *crtc_state)
continue; continue;
/* Find the highest enabled wm level for this plane */ /* Find the highest enabled wm level for this plane */
for (level = ilk_wm_max_level(i915); for (level = i915->display.wm.num_levels - 1;
!wm->wm[level].enable; --level) !wm->wm[level].enable; --level)
{ } { }
...@@ -710,10 +710,10 @@ skl_cursor_allocation(const struct intel_crtc_state *crtc_state, ...@@ -710,10 +710,10 @@ skl_cursor_allocation(const struct intel_crtc_state *crtc_state,
{ {
struct intel_plane *plane = to_intel_plane(crtc_state->uapi.crtc->cursor); struct intel_plane *plane = to_intel_plane(crtc_state->uapi.crtc->cursor);
struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev); struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
int level, max_level = ilk_wm_max_level(i915);
struct skl_wm_level wm = {}; struct skl_wm_level wm = {};
int ret, min_ddb_alloc = 0; int ret, min_ddb_alloc = 0;
struct skl_wm_params wp; struct skl_wm_params wp;
int level;
ret = skl_compute_wm_params(crtc_state, 256, ret = skl_compute_wm_params(crtc_state, 256,
drm_format_info(DRM_FORMAT_ARGB8888), drm_format_info(DRM_FORMAT_ARGB8888),
...@@ -722,7 +722,7 @@ skl_cursor_allocation(const struct intel_crtc_state *crtc_state, ...@@ -722,7 +722,7 @@ skl_cursor_allocation(const struct intel_crtc_state *crtc_state,
crtc_state->pixel_rate, &wp, 0); crtc_state->pixel_rate, &wp, 0);
drm_WARN_ON(&i915->drm, ret); drm_WARN_ON(&i915->drm, ret);
for (level = 0; level <= max_level; level++) { for (level = 0; level < i915->display.wm.num_levels; level++) {
unsigned int latency = i915->display.wm.skl_latency[level]; unsigned int latency = i915->display.wm.skl_latency[level];
skl_compute_plane_wm(crtc_state, plane, level, latency, &wp, &wm, &wm); skl_compute_plane_wm(crtc_state, plane, level, latency, &wp, &wm, &wm);
...@@ -1492,7 +1492,7 @@ skl_crtc_allocate_plane_ddb(struct intel_atomic_state *state, ...@@ -1492,7 +1492,7 @@ skl_crtc_allocate_plane_ddb(struct intel_atomic_state *state,
* Find the highest watermark level for which we can satisfy the block * Find the highest watermark level for which we can satisfy the block
* requirement of active planes. * requirement of active planes.
*/ */
for (level = ilk_wm_max_level(i915); level >= 0; level--) { for (level = i915->display.wm.num_levels - 1; level >= 0; level--) {
blocks = 0; blocks = 0;
for_each_plane_id_on_crtc(crtc, plane_id) { for_each_plane_id_on_crtc(crtc, plane_id) {
const struct skl_plane_wm *wm = const struct skl_plane_wm *wm =
...@@ -1568,7 +1568,7 @@ skl_crtc_allocate_plane_ddb(struct intel_atomic_state *state, ...@@ -1568,7 +1568,7 @@ skl_crtc_allocate_plane_ddb(struct intel_atomic_state *state,
* all levels as "enabled." Go back now and disable the ones * all levels as "enabled." Go back now and disable the ones
* that aren't actually possible. * that aren't actually possible.
*/ */
for (level++; level <= ilk_wm_max_level(i915); level++) { for (level++; level < i915->display.wm.num_levels; level++) {
for_each_plane_id_on_crtc(crtc, plane_id) { for_each_plane_id_on_crtc(crtc, plane_id) {
const struct skl_ddb_entry *ddb = const struct skl_ddb_entry *ddb =
&crtc_state->wm.skl.plane_ddb[plane_id]; &crtc_state->wm.skl.plane_ddb[plane_id];
...@@ -1967,10 +1967,10 @@ skl_compute_wm_levels(const struct intel_crtc_state *crtc_state, ...@@ -1967,10 +1967,10 @@ skl_compute_wm_levels(const struct intel_crtc_state *crtc_state,
struct skl_wm_level *levels) struct skl_wm_level *levels)
{ {
struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev); struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev);
int level, max_level = ilk_wm_max_level(i915);
struct skl_wm_level *result_prev = &levels[0]; struct skl_wm_level *result_prev = &levels[0];
int level;
for (level = 0; level <= max_level; level++) { for (level = 0; level < i915->display.wm.num_levels; level++) {
struct skl_wm_level *result = &levels[level]; struct skl_wm_level *result = &levels[level];
unsigned int latency = i915->display.wm.skl_latency[level]; unsigned int latency = i915->display.wm.skl_latency[level];
...@@ -2248,7 +2248,6 @@ void skl_write_plane_wm(struct intel_plane *plane, ...@@ -2248,7 +2248,6 @@ void skl_write_plane_wm(struct intel_plane *plane,
const struct intel_crtc_state *crtc_state) const struct intel_crtc_state *crtc_state)
{ {
struct drm_i915_private *i915 = to_i915(plane->base.dev); struct drm_i915_private *i915 = to_i915(plane->base.dev);
int level, max_level = ilk_wm_max_level(i915);
enum plane_id plane_id = plane->id; enum plane_id plane_id = plane->id;
enum pipe pipe = plane->pipe; enum pipe pipe = plane->pipe;
const struct skl_pipe_wm *pipe_wm = &crtc_state->wm.skl.optimal; const struct skl_pipe_wm *pipe_wm = &crtc_state->wm.skl.optimal;
...@@ -2256,8 +2255,9 @@ void skl_write_plane_wm(struct intel_plane *plane, ...@@ -2256,8 +2255,9 @@ void skl_write_plane_wm(struct intel_plane *plane,
&crtc_state->wm.skl.plane_ddb[plane_id]; &crtc_state->wm.skl.plane_ddb[plane_id];
const struct skl_ddb_entry *ddb_y = const struct skl_ddb_entry *ddb_y =
&crtc_state->wm.skl.plane_ddb_y[plane_id]; &crtc_state->wm.skl.plane_ddb_y[plane_id];
int level;
for (level = 0; level <= max_level; level++) for (level = 0; level < i915->display.wm.num_levels; level++)
skl_write_wm_level(i915, PLANE_WM(pipe, plane_id, level), skl_write_wm_level(i915, PLANE_WM(pipe, plane_id, level),
skl_plane_wm_level(pipe_wm, plane_id, level)); skl_plane_wm_level(pipe_wm, plane_id, level));
...@@ -2285,14 +2285,14 @@ void skl_write_cursor_wm(struct intel_plane *plane, ...@@ -2285,14 +2285,14 @@ void skl_write_cursor_wm(struct intel_plane *plane,
const struct intel_crtc_state *crtc_state) const struct intel_crtc_state *crtc_state)
{ {
struct drm_i915_private *i915 = to_i915(plane->base.dev); struct drm_i915_private *i915 = to_i915(plane->base.dev);
int level, max_level = ilk_wm_max_level(i915);
enum plane_id plane_id = plane->id; enum plane_id plane_id = plane->id;
enum pipe pipe = plane->pipe; enum pipe pipe = plane->pipe;
const struct skl_pipe_wm *pipe_wm = &crtc_state->wm.skl.optimal; const struct skl_pipe_wm *pipe_wm = &crtc_state->wm.skl.optimal;
const struct skl_ddb_entry *ddb = const struct skl_ddb_entry *ddb =
&crtc_state->wm.skl.plane_ddb[plane_id]; &crtc_state->wm.skl.plane_ddb[plane_id];
int level;
for (level = 0; level <= max_level; level++) for (level = 0; level < i915->display.wm.num_levels; level++)
skl_write_wm_level(i915, CUR_WM(pipe, level), skl_write_wm_level(i915, CUR_WM(pipe, level),
skl_plane_wm_level(pipe_wm, plane_id, level)); skl_plane_wm_level(pipe_wm, plane_id, level));
...@@ -2324,9 +2324,9 @@ static bool skl_plane_wm_equals(struct drm_i915_private *i915, ...@@ -2324,9 +2324,9 @@ static bool skl_plane_wm_equals(struct drm_i915_private *i915,
const struct skl_plane_wm *wm1, const struct skl_plane_wm *wm1,
const struct skl_plane_wm *wm2) const struct skl_plane_wm *wm2)
{ {
int level, max_level = ilk_wm_max_level(i915); int level;
for (level = 0; level <= max_level; level++) { for (level = 0; level < i915->display.wm.num_levels; level++) {
/* /*
* We don't check uv_wm as the hardware doesn't actually * We don't check uv_wm as the hardware doesn't actually
* use it. It only gets used for calculating the required * use it. It only gets used for calculating the required
...@@ -2676,9 +2676,9 @@ static bool skl_plane_selected_wm_equals(struct intel_plane *plane, ...@@ -2676,9 +2676,9 @@ static bool skl_plane_selected_wm_equals(struct intel_plane *plane,
const struct skl_pipe_wm *new_pipe_wm) const struct skl_pipe_wm *new_pipe_wm)
{ {
struct drm_i915_private *i915 = to_i915(plane->base.dev); struct drm_i915_private *i915 = to_i915(plane->base.dev);
int level, max_level = ilk_wm_max_level(i915); int level;
for (level = 0; level <= max_level; level++) { for (level = 0; level < i915->display.wm.num_levels; level++) {
/* /*
* We don't check uv_wm as the hardware doesn't actually * We don't check uv_wm as the hardware doesn't actually
* use it. It only gets used for calculating the required * use it. It only gets used for calculating the required
...@@ -2814,16 +2814,14 @@ static void skl_pipe_wm_get_hw_state(struct intel_crtc *crtc, ...@@ -2814,16 +2814,14 @@ static void skl_pipe_wm_get_hw_state(struct intel_crtc *crtc,
{ {
struct drm_i915_private *i915 = to_i915(crtc->base.dev); struct drm_i915_private *i915 = to_i915(crtc->base.dev);
enum pipe pipe = crtc->pipe; enum pipe pipe = crtc->pipe;
int level, max_level;
enum plane_id plane_id; enum plane_id plane_id;
int level;
u32 val; u32 val;
max_level = ilk_wm_max_level(i915);
for_each_plane_id_on_crtc(crtc, plane_id) { for_each_plane_id_on_crtc(crtc, plane_id) {
struct skl_plane_wm *wm = &out->planes[plane_id]; struct skl_plane_wm *wm = &out->planes[plane_id];
for (level = 0; level <= max_level; level++) { for (level = 0; level < i915->display.wm.num_levels; level++) {
if (plane_id != PLANE_CURSOR) if (plane_id != PLANE_CURSOR)
val = intel_de_read(i915, PLANE_WM(pipe, plane_id, level)); val = intel_de_read(i915, PLANE_WM(pipe, plane_id, level));
else else
...@@ -3006,9 +3004,9 @@ void intel_wm_state_verify(struct intel_crtc *crtc, ...@@ -3006,9 +3004,9 @@ void intel_wm_state_verify(struct intel_crtc *crtc,
struct skl_pipe_wm wm; struct skl_pipe_wm wm;
} *hw; } *hw;
const struct skl_pipe_wm *sw_wm = &new_crtc_state->wm.skl.optimal; const struct skl_pipe_wm *sw_wm = &new_crtc_state->wm.skl.optimal;
int level, max_level = ilk_wm_max_level(i915);
struct intel_plane *plane; struct intel_plane *plane;
u8 hw_enabled_slices; u8 hw_enabled_slices;
int level;
if (DISPLAY_VER(i915) < 9 || !new_crtc_state->hw.active) if (DISPLAY_VER(i915) < 9 || !new_crtc_state->hw.active)
return; return;
...@@ -3035,7 +3033,7 @@ void intel_wm_state_verify(struct intel_crtc *crtc, ...@@ -3035,7 +3033,7 @@ void intel_wm_state_verify(struct intel_crtc *crtc,
const struct skl_wm_level *hw_wm_level, *sw_wm_level; const struct skl_wm_level *hw_wm_level, *sw_wm_level;
/* Watermarks */ /* Watermarks */
for (level = 0; level <= max_level; level++) { for (level = 0; level < i915->display.wm.num_levels; level++) {
hw_wm_level = &hw->wm.planes[plane->id].wm[level]; hw_wm_level = &hw->wm.planes[plane->id].wm[level];
sw_wm_level = skl_plane_wm_level(sw_wm, plane->id, level); sw_wm_level = skl_plane_wm_level(sw_wm, plane->id, level);
...@@ -3157,7 +3155,7 @@ void skl_watermark_ipc_init(struct drm_i915_private *i915) ...@@ -3157,7 +3155,7 @@ void skl_watermark_ipc_init(struct drm_i915_private *i915)
static void static void
adjust_wm_latency(struct drm_i915_private *i915, adjust_wm_latency(struct drm_i915_private *i915,
u16 wm[], int max_level, int read_latency) u16 wm[], int num_levels, int read_latency)
{ {
bool wm_lv_0_adjust_needed = i915->dram_info.wm_lv_0_adjust_needed; bool wm_lv_0_adjust_needed = i915->dram_info.wm_lv_0_adjust_needed;
int i, level; int i, level;
...@@ -3167,12 +3165,12 @@ adjust_wm_latency(struct drm_i915_private *i915, ...@@ -3167,12 +3165,12 @@ adjust_wm_latency(struct drm_i915_private *i915,
* need to be disabled. We make sure to sanitize the values out * need to be disabled. We make sure to sanitize the values out
* of the punit to satisfy this requirement. * of the punit to satisfy this requirement.
*/ */
for (level = 1; level <= max_level; level++) { for (level = 1; level < num_levels; level++) {
if (wm[level] == 0) { if (wm[level] == 0) {
for (i = level + 1; i <= max_level; i++) for (i = level + 1; i < num_levels; i++)
wm[i] = 0; wm[i] = 0;
max_level = level - 1; num_levels = level;
break; break;
} }
} }
...@@ -3185,7 +3183,7 @@ adjust_wm_latency(struct drm_i915_private *i915, ...@@ -3185,7 +3183,7 @@ adjust_wm_latency(struct drm_i915_private *i915,
* from the punit when level 0 response data is 0us. * from the punit when level 0 response data is 0us.
*/ */
if (wm[0] == 0) { if (wm[0] == 0) {
for (level = 0; level <= max_level; level++) for (level = 0; level < num_levels; level++)
wm[level] += read_latency; wm[level] += read_latency;
} }
...@@ -3201,7 +3199,7 @@ adjust_wm_latency(struct drm_i915_private *i915, ...@@ -3201,7 +3199,7 @@ adjust_wm_latency(struct drm_i915_private *i915,
static void mtl_read_wm_latency(struct drm_i915_private *i915, u16 wm[]) static void mtl_read_wm_latency(struct drm_i915_private *i915, u16 wm[])
{ {
int max_level = ilk_wm_max_level(i915); int num_levels = i915->display.wm.num_levels;
u32 val; u32 val;
val = intel_de_read(i915, MTL_LATENCY_LP0_LP1); val = intel_de_read(i915, MTL_LATENCY_LP0_LP1);
...@@ -3216,12 +3214,12 @@ static void mtl_read_wm_latency(struct drm_i915_private *i915, u16 wm[]) ...@@ -3216,12 +3214,12 @@ static void mtl_read_wm_latency(struct drm_i915_private *i915, u16 wm[])
wm[4] = REG_FIELD_GET(MTL_LATENCY_LEVEL_EVEN_MASK, val); wm[4] = REG_FIELD_GET(MTL_LATENCY_LEVEL_EVEN_MASK, val);
wm[5] = REG_FIELD_GET(MTL_LATENCY_LEVEL_ODD_MASK, val); wm[5] = REG_FIELD_GET(MTL_LATENCY_LEVEL_ODD_MASK, val);
adjust_wm_latency(i915, wm, max_level, 6); adjust_wm_latency(i915, wm, num_levels, 6);
} }
static void skl_read_wm_latency(struct drm_i915_private *i915, u16 wm[]) static void skl_read_wm_latency(struct drm_i915_private *i915, u16 wm[])
{ {
int max_level = ilk_wm_max_level(i915); int num_levels = i915->display.wm.num_levels;
int read_latency = DISPLAY_VER(i915) >= 12 ? 3 : 2; int read_latency = DISPLAY_VER(i915) >= 12 ? 3 : 2;
int mult = IS_DG2(i915) ? 2 : 1; int mult = IS_DG2(i915) ? 2 : 1;
u32 val; u32 val;
...@@ -3253,15 +3251,15 @@ static void skl_read_wm_latency(struct drm_i915_private *i915, u16 wm[]) ...@@ -3253,15 +3251,15 @@ static void skl_read_wm_latency(struct drm_i915_private *i915, u16 wm[])
wm[6] = REG_FIELD_GET(GEN9_MEM_LATENCY_LEVEL_2_6_MASK, val) * mult; wm[6] = REG_FIELD_GET(GEN9_MEM_LATENCY_LEVEL_2_6_MASK, val) * mult;
wm[7] = REG_FIELD_GET(GEN9_MEM_LATENCY_LEVEL_3_7_MASK, val) * mult; wm[7] = REG_FIELD_GET(GEN9_MEM_LATENCY_LEVEL_3_7_MASK, val) * mult;
adjust_wm_latency(i915, wm, max_level, read_latency); adjust_wm_latency(i915, wm, num_levels, read_latency);
} }
static void skl_setup_wm_latency(struct drm_i915_private *i915) static void skl_setup_wm_latency(struct drm_i915_private *i915)
{ {
if (HAS_HW_SAGV_WM(i915)) if (HAS_HW_SAGV_WM(i915))
i915->display.wm.max_level = 5; i915->display.wm.num_levels = 6;
else else
i915->display.wm.max_level = 7; i915->display.wm.num_levels = 8;
if (DISPLAY_VER(i915) >= 14) if (DISPLAY_VER(i915) >= 14)
mtl_read_wm_latency(i915, i915->display.wm.skl_latency); mtl_read_wm_latency(i915, i915->display.wm.skl_latency);
......
This diff is collapsed.
...@@ -14,7 +14,6 @@ struct intel_plane_state; ...@@ -14,7 +14,6 @@ struct intel_plane_state;
void intel_init_clock_gating(struct drm_i915_private *dev_priv); void intel_init_clock_gating(struct drm_i915_private *dev_priv);
void intel_suspend_hw(struct drm_i915_private *dev_priv); void intel_suspend_hw(struct drm_i915_private *dev_priv);
int ilk_wm_max_level(const struct drm_i915_private *dev_priv);
void intel_init_pm(struct drm_i915_private *dev_priv); void intel_init_pm(struct drm_i915_private *dev_priv);
void intel_init_clock_gating_hooks(struct drm_i915_private *dev_priv); void intel_init_clock_gating_hooks(struct drm_i915_private *dev_priv);
void intel_pm_setup(struct drm_i915_private *dev_priv); void intel_pm_setup(struct drm_i915_private *dev_priv);
......
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