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: Lyude <cpaul@redhat.com> Reviewed-by: Paulo Zanoni <paulo.r.zanoni@intel.com> Reviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
This commit is contained in:
parent
b707aa5041
commit
a62163e97b
|
@ -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 {
|
||||||
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
|
||||||
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;
|
ddb_blocks = skl_ddb_entry_size(&ddb->plane[pipe][i]);
|
||||||
intel_pstate = NULL;
|
|
||||||
if (state)
|
|
||||||
intel_pstate =
|
|
||||||
intel_atomic_get_existing_plane_state(state,
|
|
||||||
intel_plane);
|
|
||||||
|
|
||||||
/*
|
ret = skl_compute_plane_wm(dev_priv,
|
||||||
* Note: If we start supporting multiple pending atomic commits
|
cstate,
|
||||||
* against the same planes/CRTC's in the future, plane->state
|
intel_pstate,
|
||||||
* will no longer be the correct pre-state to use for the
|
ddb_blocks,
|
||||||
* calculations here and we'll need to change where we get the
|
level,
|
||||||
* 'unchanged' plane data from.
|
&result->plane_res_b,
|
||||||
*
|
&result->plane_res_l,
|
||||||
* For now this is fine because we only allow one queued commit
|
&result->plane_en);
|
||||||
* against a CRTC. Even if the plane isn't modified by this
|
if (ret)
|
||||||
* transaction and we don't have a plane lock, we still have
|
return ret;
|
||||||
* 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);
|
|
||||||
|
|
||||||
ddb_blocks = skl_ddb_entry_size(&ddb->plane[pipe][i]);
|
|
||||||
|
|
||||||
ret = skl_compute_plane_wm(dev_priv,
|
|
||||||
cstate,
|
|
||||||
intel_pstate,
|
|
||||||
ddb_blocks,
|
|
||||||
level,
|
|
||||||
&result->plane_res_b[i],
|
|
||||||
&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)
|
||||||
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,
|
||||||
{
|
{
|
||||||
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,
|
||||||
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,
|
||||||
|
|
||||||
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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue