Commit a62163e9 authored by Lyude's avatar Lyude

drm/i915/gen9: Make skl_wm_level per-plane

Having skl_wm_level contain all of the watermarks for each plane is
annoying since it prevents us from having any sort of object to
represent a single watermark level, something we take advantage of in
the next commit to cut down on all of the copy paste code in here.

Changes since v1:
- Style nitpicks
- Fix accidental usage of i vs. PLANE_CURSOR
- Split out skl_pipe_wm_active_state simplification into separate patch
Signed-off-by: default avatarLyude <cpaul@redhat.com>
Reviewed-by: default avatarPaulo Zanoni <paulo.r.zanoni@intel.com>
Reviewed-by: default avatarMaarten Lankhorst <maarten.lankhorst@linux.intel.com>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
parent b707aa50
...@@ -1653,9 +1653,9 @@ struct skl_wm_values { ...@@ -1653,9 +1653,9 @@ struct skl_wm_values {
}; };
struct skl_wm_level { struct skl_wm_level {
bool plane_en[I915_MAX_PLANES]; bool plane_en;
uint16_t plane_res_b[I915_MAX_PLANES]; uint16_t plane_res_b;
uint8_t plane_res_l[I915_MAX_PLANES]; uint8_t plane_res_l;
}; };
/* /*
......
...@@ -468,9 +468,13 @@ struct intel_pipe_wm { ...@@ -468,9 +468,13 @@ struct intel_pipe_wm {
bool sprites_scaled; bool sprites_scaled;
}; };
struct skl_pipe_wm { struct skl_plane_wm {
struct skl_wm_level wm[8]; struct skl_wm_level wm[8];
struct skl_wm_level trans_wm; struct skl_wm_level trans_wm;
};
struct skl_pipe_wm {
struct skl_plane_wm planes[I915_MAX_PLANES];
uint32_t linetime; uint32_t linetime;
}; };
......
...@@ -3674,67 +3674,52 @@ static int ...@@ -3674,67 +3674,52 @@ static int
skl_compute_wm_level(const struct drm_i915_private *dev_priv, skl_compute_wm_level(const struct drm_i915_private *dev_priv,
struct skl_ddb_allocation *ddb, struct skl_ddb_allocation *ddb,
struct intel_crtc_state *cstate, struct intel_crtc_state *cstate,
struct intel_plane *intel_plane,
int level, int level,
struct skl_wm_level *result) struct skl_wm_level *result)
{ {
struct drm_atomic_state *state = cstate->base.state; struct drm_atomic_state *state = cstate->base.state;
struct intel_crtc *intel_crtc = to_intel_crtc(cstate->base.crtc); struct intel_crtc *intel_crtc = to_intel_crtc(cstate->base.crtc);
struct drm_plane *plane; struct drm_plane *plane = &intel_plane->base;
struct intel_plane *intel_plane; struct intel_plane_state *intel_pstate = NULL;
struct intel_plane_state *intel_pstate;
uint16_t ddb_blocks; uint16_t ddb_blocks;
enum pipe pipe = intel_crtc->pipe; enum pipe pipe = intel_crtc->pipe;
int ret; int ret;
int i = skl_wm_plane_id(intel_plane);
if (state)
intel_pstate =
intel_atomic_get_existing_plane_state(state,
intel_plane);
/* /*
* We'll only calculate watermarks for planes that are actually * Note: If we start supporting multiple pending atomic commits against
* enabled, so make sure all other planes are set as disabled. * the same planes/CRTC's in the future, plane->state will no longer be
* the correct pre-state to use for the calculations here and we'll
* need to change where we get the 'unchanged' plane data from.
*
* For now this is fine because we only allow one queued commit against
* a CRTC. Even if the plane isn't modified by this transaction and we
* don't have a plane lock, we still have the CRTC's lock, so we know
* that no other transactions are racing with us to update it.
*/ */
memset(result, 0, sizeof(*result)); if (!intel_pstate)
intel_pstate = to_intel_plane_state(plane->state);
for_each_intel_plane_mask(&dev_priv->drm, WARN_ON(!intel_pstate->base.fb);
intel_plane,
cstate->base.plane_mask) {
int i = skl_wm_plane_id(intel_plane);
plane = &intel_plane->base;
intel_pstate = NULL;
if (state)
intel_pstate =
intel_atomic_get_existing_plane_state(state,
intel_plane);
/* ddb_blocks = skl_ddb_entry_size(&ddb->plane[pipe][i]);
* Note: If we start supporting multiple pending atomic commits
* against the same planes/CRTC's in the future, plane->state
* will no longer be the correct pre-state to use for the
* calculations here and we'll need to change where we get the
* 'unchanged' plane data from.
*
* For now this is fine because we only allow one queued commit
* against a CRTC. Even if the plane isn't modified by this
* transaction and we don't have a plane lock, we still have
* the CRTC's lock, so we know that no other transactions are
* racing with us to update it.
*/
if (!intel_pstate)
intel_pstate = to_intel_plane_state(plane->state);
WARN_ON(!intel_pstate->base.fb); ret = skl_compute_plane_wm(dev_priv,
cstate,
ddb_blocks = skl_ddb_entry_size(&ddb->plane[pipe][i]); intel_pstate,
ddb_blocks,
ret = skl_compute_plane_wm(dev_priv, level,
cstate, &result->plane_res_b,
intel_pstate, &result->plane_res_l,
ddb_blocks, &result->plane_en);
level, if (ret)
&result->plane_res_b[i], return ret;
&result->plane_res_l[i],
&result->plane_en[i]);
if (ret)
return ret;
}
return 0; return 0;
} }
...@@ -3755,19 +3740,11 @@ skl_compute_linetime_wm(struct intel_crtc_state *cstate) ...@@ -3755,19 +3740,11 @@ skl_compute_linetime_wm(struct intel_crtc_state *cstate)
static void skl_compute_transition_wm(struct intel_crtc_state *cstate, static void skl_compute_transition_wm(struct intel_crtc_state *cstate,
struct skl_wm_level *trans_wm /* out */) struct skl_wm_level *trans_wm /* out */)
{ {
struct drm_crtc *crtc = cstate->base.crtc;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
struct intel_plane *intel_plane;
if (!cstate->base.active) if (!cstate->base.active)
return; return;
/* Until we know more, just disable transition WMs */ /* Until we know more, just disable transition WMs */
for_each_intel_plane_on_crtc(crtc->dev, intel_crtc, intel_plane) { trans_wm->plane_en = false;
int i = skl_wm_plane_id(intel_plane);
trans_wm->plane_en[i] = false;
}
} }
static int skl_build_pipe_wm(struct intel_crtc_state *cstate, static int skl_build_pipe_wm(struct intel_crtc_state *cstate,
...@@ -3776,19 +3753,33 @@ static int skl_build_pipe_wm(struct intel_crtc_state *cstate, ...@@ -3776,19 +3753,33 @@ static int skl_build_pipe_wm(struct intel_crtc_state *cstate,
{ {
struct drm_device *dev = cstate->base.crtc->dev; struct drm_device *dev = cstate->base.crtc->dev;
const struct drm_i915_private *dev_priv = to_i915(dev); const struct drm_i915_private *dev_priv = to_i915(dev);
struct intel_plane *intel_plane;
struct skl_plane_wm *wm;
int level, max_level = ilk_wm_max_level(dev_priv); int level, max_level = ilk_wm_max_level(dev_priv);
int ret; int ret;
for (level = 0; level <= max_level; level++) { /*
ret = skl_compute_wm_level(dev_priv, ddb, cstate, * We'll only calculate watermarks for planes that are actually
level, &pipe_wm->wm[level]); * enabled, so make sure all other planes are set as disabled.
if (ret) */
return ret; memset(pipe_wm->planes, 0, sizeof(pipe_wm->planes));
for_each_intel_plane_mask(&dev_priv->drm,
intel_plane,
cstate->base.plane_mask) {
wm = &pipe_wm->planes[skl_wm_plane_id(intel_plane)];
for (level = 0; level <= max_level; level++) {
ret = skl_compute_wm_level(dev_priv, ddb, cstate,
intel_plane, level,
&wm->wm[level]);
if (ret)
return ret;
}
skl_compute_transition_wm(cstate, &wm->trans_wm);
} }
pipe_wm->linetime = skl_compute_linetime_wm(cstate); pipe_wm->linetime = skl_compute_linetime_wm(cstate);
skl_compute_transition_wm(cstate, &pipe_wm->trans_wm);
return 0; return 0;
} }
...@@ -3798,50 +3789,55 @@ static void skl_compute_wm_results(struct drm_device *dev, ...@@ -3798,50 +3789,55 @@ static void skl_compute_wm_results(struct drm_device *dev,
struct intel_crtc *intel_crtc) struct intel_crtc *intel_crtc)
{ {
int level, max_level = ilk_wm_max_level(to_i915(dev)); int level, max_level = ilk_wm_max_level(to_i915(dev));
struct skl_plane_wm *plane_wm;
enum pipe pipe = intel_crtc->pipe; enum pipe pipe = intel_crtc->pipe;
uint32_t temp; uint32_t temp;
int i; int i;
for (level = 0; level <= max_level; level++) { for (i = 0; i < intel_num_planes(intel_crtc); i++) {
for (i = 0; i < intel_num_planes(intel_crtc); i++) { plane_wm = &p_wm->planes[i];
for (level = 0; level <= max_level; level++) {
temp = 0; temp = 0;
temp |= p_wm->wm[level].plane_res_l[i] << temp |= plane_wm->wm[level].plane_res_l <<
PLANE_WM_LINES_SHIFT; PLANE_WM_LINES_SHIFT;
temp |= p_wm->wm[level].plane_res_b[i]; temp |= plane_wm->wm[level].plane_res_b;
if (p_wm->wm[level].plane_en[i]) if (plane_wm->wm[level].plane_en)
temp |= PLANE_WM_EN; temp |= PLANE_WM_EN;
r->plane[pipe][i][level] = temp; r->plane[pipe][i][level] = temp;
} }
}
for (level = 0; level <= max_level; level++) {
plane_wm = &p_wm->planes[PLANE_CURSOR];
temp = 0; temp = 0;
temp |= plane_wm->wm[level].plane_res_l << PLANE_WM_LINES_SHIFT;
temp |= p_wm->wm[level].plane_res_l[PLANE_CURSOR] << PLANE_WM_LINES_SHIFT; temp |= plane_wm->wm[level].plane_res_b;
temp |= p_wm->wm[level].plane_res_b[PLANE_CURSOR]; if (plane_wm->wm[level].plane_en)
if (p_wm->wm[level].plane_en[PLANE_CURSOR])
temp |= PLANE_WM_EN; temp |= PLANE_WM_EN;
r->plane[pipe][PLANE_CURSOR][level] = temp; r->plane[pipe][PLANE_CURSOR][level] = temp;
} }
/* transition WMs */ /* transition WMs */
for (i = 0; i < intel_num_planes(intel_crtc); i++) { for (i = 0; i < intel_num_planes(intel_crtc); i++) {
plane_wm = &p_wm->planes[i];
temp = 0; temp = 0;
temp |= p_wm->trans_wm.plane_res_l[i] << PLANE_WM_LINES_SHIFT; temp |= plane_wm->trans_wm.plane_res_l << PLANE_WM_LINES_SHIFT;
temp |= p_wm->trans_wm.plane_res_b[i]; temp |= plane_wm->trans_wm.plane_res_b;
if (p_wm->trans_wm.plane_en[i]) if (plane_wm->trans_wm.plane_en)
temp |= PLANE_WM_EN; temp |= PLANE_WM_EN;
r->plane_trans[pipe][i] = temp; r->plane_trans[pipe][i] = temp;
} }
plane_wm = &p_wm->planes[PLANE_CURSOR];
temp = 0; temp = 0;
temp |= p_wm->trans_wm.plane_res_l[PLANE_CURSOR] << PLANE_WM_LINES_SHIFT; temp |= plane_wm->trans_wm.plane_res_l << PLANE_WM_LINES_SHIFT;
temp |= p_wm->trans_wm.plane_res_b[PLANE_CURSOR]; temp |= plane_wm->trans_wm.plane_res_b;
if (p_wm->trans_wm.plane_en[PLANE_CURSOR]) if (plane_wm->trans_wm.plane_en)
temp |= PLANE_WM_EN; temp |= PLANE_WM_EN;
r->plane_trans[pipe][PLANE_CURSOR] = temp; r->plane_trans[pipe][PLANE_CURSOR] = temp;
...@@ -4282,35 +4278,37 @@ static void skl_pipe_wm_active_state(uint32_t val, ...@@ -4282,35 +4278,37 @@ static void skl_pipe_wm_active_state(uint32_t val,
if (!is_transwm) { if (!is_transwm) {
if (!is_cursor) { if (!is_cursor) {
active->wm[level].plane_en[i] = is_enabled; active->planes[i].wm[level].plane_en = is_enabled;
active->wm[level].plane_res_b[i] = active->planes[i].wm[level].plane_res_b =
val & PLANE_WM_BLOCKS_MASK; val & PLANE_WM_BLOCKS_MASK;
active->wm[level].plane_res_l[i] = active->planes[i].wm[level].plane_res_l =
(val >> PLANE_WM_LINES_SHIFT) & (val >> PLANE_WM_LINES_SHIFT) &
PLANE_WM_LINES_MASK; PLANE_WM_LINES_MASK;
} else { } else {
active->wm[level].plane_en[PLANE_CURSOR] = is_enabled; active->planes[PLANE_CURSOR].wm[level].plane_en =
active->wm[level].plane_res_b[PLANE_CURSOR] = is_enabled;
val & PLANE_WM_BLOCKS_MASK; active->planes[PLANE_CURSOR].wm[level].plane_res_b =
active->wm[level].plane_res_l[PLANE_CURSOR] = val & PLANE_WM_BLOCKS_MASK;
(val >> PLANE_WM_LINES_SHIFT) & active->planes[PLANE_CURSOR].wm[level].plane_res_l =
PLANE_WM_LINES_MASK; (val >> PLANE_WM_LINES_SHIFT) &
PLANE_WM_LINES_MASK;
} }
} else { } else {
if (!is_cursor) { if (!is_cursor) {
active->trans_wm.plane_en[i] = is_enabled; active->planes[i].trans_wm.plane_en = is_enabled;
active->trans_wm.plane_res_b[i] = active->planes[i].trans_wm.plane_res_b =
val & PLANE_WM_BLOCKS_MASK; val & PLANE_WM_BLOCKS_MASK;
active->trans_wm.plane_res_l[i] = active->planes[i].trans_wm.plane_res_l =
(val >> PLANE_WM_LINES_SHIFT) & (val >> PLANE_WM_LINES_SHIFT) &
PLANE_WM_LINES_MASK; PLANE_WM_LINES_MASK;
} else { } else {
active->trans_wm.plane_en[PLANE_CURSOR] = is_enabled; active->planes[PLANE_CURSOR].trans_wm.plane_en =
active->trans_wm.plane_res_b[PLANE_CURSOR] = is_enabled;
val & PLANE_WM_BLOCKS_MASK; active->planes[PLANE_CURSOR].trans_wm.plane_res_b =
active->trans_wm.plane_res_l[PLANE_CURSOR] = val & PLANE_WM_BLOCKS_MASK;
(val >> PLANE_WM_LINES_SHIFT) & active->planes[PLANE_CURSOR].trans_wm.plane_res_l =
PLANE_WM_LINES_MASK; (val >> PLANE_WM_LINES_SHIFT) &
PLANE_WM_LINES_MASK;
} }
} }
} }
......
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