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 {
};
struct skl_wm_level {
bool plane_en[I915_MAX_PLANES];
uint16_t plane_res_b[I915_MAX_PLANES];
uint8_t plane_res_l[I915_MAX_PLANES];
bool plane_en;
uint16_t plane_res_b;
uint8_t plane_res_l;
};
/*
......
......@@ -468,9 +468,13 @@ struct intel_pipe_wm {
bool sprites_scaled;
};
struct skl_pipe_wm {
struct skl_plane_wm {
struct skl_wm_level wm[8];
struct skl_wm_level trans_wm;
};
struct skl_pipe_wm {
struct skl_plane_wm planes[I915_MAX_PLANES];
uint32_t linetime;
};
......
......@@ -3674,48 +3674,34 @@ static int
skl_compute_wm_level(const struct drm_i915_private *dev_priv,
struct skl_ddb_allocation *ddb,
struct intel_crtc_state *cstate,
struct intel_plane *intel_plane,
int level,
struct skl_wm_level *result)
{
struct drm_atomic_state *state = cstate->base.state;
struct intel_crtc *intel_crtc = to_intel_crtc(cstate->base.crtc);
struct drm_plane *plane;
struct intel_plane *intel_plane;
struct intel_plane_state *intel_pstate;
struct drm_plane *plane = &intel_plane->base;
struct intel_plane_state *intel_pstate = NULL;
uint16_t ddb_blocks;
enum pipe pipe = intel_crtc->pipe;
int ret;
/*
* We'll only calculate watermarks for planes that are actually
* enabled, so make sure all other planes are set as disabled.
*/
memset(result, 0, sizeof(*result));
for_each_intel_plane_mask(&dev_priv->drm,
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);
/*
* 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.
* 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.
* 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);
......@@ -3729,12 +3715,11 @@ skl_compute_wm_level(const struct drm_i915_private *dev_priv,
intel_pstate,
ddb_blocks,
level,
&result->plane_res_b[i],
&result->plane_res_l[i],
&result->plane_en[i]);
&result->plane_res_b,
&result->plane_res_l,
&result->plane_en);
if (ret)
return ret;
}
return 0;
}
......@@ -3755,19 +3740,11 @@ skl_compute_linetime_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 drm_crtc *crtc = cstate->base.crtc;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
struct intel_plane *intel_plane;
if (!cstate->base.active)
return;
/* Until we know more, just disable transition WMs */
for_each_intel_plane_on_crtc(crtc->dev, intel_crtc, intel_plane) {
int i = skl_wm_plane_id(intel_plane);
trans_wm->plane_en[i] = false;
}
trans_wm->plane_en = false;
}
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;
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 ret;
/*
* We'll only calculate watermarks for planes that are actually
* enabled, so make sure all other planes are set as disabled.
*/
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,
level, &pipe_wm->wm[level]);
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);
skl_compute_transition_wm(cstate, &pipe_wm->trans_wm);
return 0;
}
......@@ -3798,50 +3789,55 @@ static void skl_compute_wm_results(struct drm_device *dev,
struct intel_crtc *intel_crtc)
{
int level, max_level = ilk_wm_max_level(to_i915(dev));
struct skl_plane_wm *plane_wm;
enum pipe pipe = intel_crtc->pipe;
uint32_t temp;
int i;
for (level = 0; level <= max_level; level++) {
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 |= p_wm->wm[level].plane_res_l[i] <<
temp |= plane_wm->wm[level].plane_res_l <<
PLANE_WM_LINES_SHIFT;
temp |= p_wm->wm[level].plane_res_b[i];
if (p_wm->wm[level].plane_en[i])
temp |= plane_wm->wm[level].plane_res_b;
if (plane_wm->wm[level].plane_en)
temp |= PLANE_WM_EN;
r->plane[pipe][i][level] = temp;
}
}
for (level = 0; level <= max_level; level++) {
plane_wm = &p_wm->planes[PLANE_CURSOR];
temp = 0;
temp |= p_wm->wm[level].plane_res_l[PLANE_CURSOR] << PLANE_WM_LINES_SHIFT;
temp |= p_wm->wm[level].plane_res_b[PLANE_CURSOR];
if (p_wm->wm[level].plane_en[PLANE_CURSOR])
temp |= plane_wm->wm[level].plane_res_l << PLANE_WM_LINES_SHIFT;
temp |= plane_wm->wm[level].plane_res_b;
if (plane_wm->wm[level].plane_en)
temp |= PLANE_WM_EN;
r->plane[pipe][PLANE_CURSOR][level] = temp;
}
/* transition WMs */
for (i = 0; i < intel_num_planes(intel_crtc); i++) {
plane_wm = &p_wm->planes[i];
temp = 0;
temp |= p_wm->trans_wm.plane_res_l[i] << PLANE_WM_LINES_SHIFT;
temp |= p_wm->trans_wm.plane_res_b[i];
if (p_wm->trans_wm.plane_en[i])
temp |= plane_wm->trans_wm.plane_res_l << PLANE_WM_LINES_SHIFT;
temp |= plane_wm->trans_wm.plane_res_b;
if (plane_wm->trans_wm.plane_en)
temp |= PLANE_WM_EN;
r->plane_trans[pipe][i] = temp;
}
plane_wm = &p_wm->planes[PLANE_CURSOR];
temp = 0;
temp |= p_wm->trans_wm.plane_res_l[PLANE_CURSOR] << PLANE_WM_LINES_SHIFT;
temp |= p_wm->trans_wm.plane_res_b[PLANE_CURSOR];
if (p_wm->trans_wm.plane_en[PLANE_CURSOR])
temp |= plane_wm->trans_wm.plane_res_l << PLANE_WM_LINES_SHIFT;
temp |= plane_wm->trans_wm.plane_res_b;
if (plane_wm->trans_wm.plane_en)
temp |= PLANE_WM_EN;
r->plane_trans[pipe][PLANE_CURSOR] = temp;
......@@ -4282,33 +4278,35 @@ static void skl_pipe_wm_active_state(uint32_t val,
if (!is_transwm) {
if (!is_cursor) {
active->wm[level].plane_en[i] = is_enabled;
active->wm[level].plane_res_b[i] =
active->planes[i].wm[level].plane_en = is_enabled;
active->planes[i].wm[level].plane_res_b =
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) &
PLANE_WM_LINES_MASK;
} else {
active->wm[level].plane_en[PLANE_CURSOR] = is_enabled;
active->wm[level].plane_res_b[PLANE_CURSOR] =
active->planes[PLANE_CURSOR].wm[level].plane_en =
is_enabled;
active->planes[PLANE_CURSOR].wm[level].plane_res_b =
val & PLANE_WM_BLOCKS_MASK;
active->wm[level].plane_res_l[PLANE_CURSOR] =
active->planes[PLANE_CURSOR].wm[level].plane_res_l =
(val >> PLANE_WM_LINES_SHIFT) &
PLANE_WM_LINES_MASK;
}
} else {
if (!is_cursor) {
active->trans_wm.plane_en[i] = is_enabled;
active->trans_wm.plane_res_b[i] =
active->planes[i].trans_wm.plane_en = is_enabled;
active->planes[i].trans_wm.plane_res_b =
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) &
PLANE_WM_LINES_MASK;
} else {
active->trans_wm.plane_en[PLANE_CURSOR] = is_enabled;
active->trans_wm.plane_res_b[PLANE_CURSOR] =
active->planes[PLANE_CURSOR].trans_wm.plane_en =
is_enabled;
active->planes[PLANE_CURSOR].trans_wm.plane_res_b =
val & PLANE_WM_BLOCKS_MASK;
active->trans_wm.plane_res_l[PLANE_CURSOR] =
active->planes[PLANE_CURSOR].trans_wm.plane_res_l =
(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