From: Paulo Zanoni <paulo.r.zanoni@intel.com>
To: Lyude <cpaul@redhat.com>, intel-gfx@lists.freedesktop.org
Cc: David Airlie <airlied@linux.ie>,
Daniel Vetter <daniel.vetter@intel.com>,
linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org
Subject: Re: [PATCH 5/6] drm/i915/gen9: Get rid of redundant watermark values
Date: Wed, 05 Oct 2016 18:44:04 -0300 [thread overview]
Message-ID: <1475703844.2381.74.camel@intel.com> (raw)
In-Reply-To: <1475681598-12081-6-git-send-email-cpaul@redhat.com>
Em Qua, 2016-10-05 às 11:33 -0400, Lyude escreveu:
> Now that we've make skl_wm_levels make a little more sense, we can
> remove all of the redundant wm information. Up until now we'd been
> storing two copies of all of the skl watermarks: one being the
> skl_pipe_wm structs, the other being the global wm struct in
> drm_i915_private containing the raw register values. This is
> confusing
> and problematic, since it means we're prone to accidentally letting
> the
> two copies go out of sync. So, get rid of all of the functions
> responsible for computing the register values and just use a single
> helper, skl_write_wm_level(), to convert and write the new watermarks
> on
> the fly.
I like the direction of this patch too, but there are some small
possible problems. See below.
>
> Signed-off-by: Lyude <cpaul@redhat.com>
> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> Cc: Matt Roper <matthew.d.roper@intel.com>
> ---
> drivers/gpu/drm/i915/i915_drv.h | 2 -
> drivers/gpu/drm/i915/intel_display.c | 14 ++-
> drivers/gpu/drm/i915/intel_drv.h | 6 +-
> drivers/gpu/drm/i915/intel_pm.c | 203 ++++++++++++-------------
> ----------
> drivers/gpu/drm/i915/intel_sprite.c | 8 +-
> 5 files changed, 88 insertions(+), 145 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_drv.h
> b/drivers/gpu/drm/i915/i915_drv.h
> index 0f97d43..63519ac 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -1643,8 +1643,6 @@ struct skl_ddb_allocation {
> struct skl_wm_values {
> unsigned dirty_pipes;
> struct skl_ddb_allocation ddb;
> - uint32_t plane[I915_MAX_PIPES][I915_MAX_PLANES][8];
> - uint32_t plane_trans[I915_MAX_PIPES][I915_MAX_PLANES];
> };
>
> struct skl_wm_level {
> diff --git a/drivers/gpu/drm/i915/intel_display.c
> b/drivers/gpu/drm/i915/intel_display.c
> index dd15ae2..c580d3d 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -3378,6 +3378,8 @@ static void skylake_update_primary_plane(struct
> drm_plane *plane,
> struct intel_crtc *intel_crtc = to_intel_crtc(crtc_state-
> >base.crtc);
> struct drm_framebuffer *fb = plane_state->base.fb;
> const struct skl_wm_values *wm = &dev_priv->wm.skl_results;
> + const struct skl_plane_wm *p_wm =
> + &crtc_state->wm.skl.optimal.planes[0];
I wish someone would do a patch to convert all these hardcoded values
to PLANE_X, and convert "int"s to "enum plane"s everywhere.
> int pipe = intel_crtc->pipe;
> u32 plane_ctl;
> unsigned int rotation = plane_state->base.rotation;
> @@ -3414,7 +3416,7 @@ static void skylake_update_primary_plane(struct
> drm_plane *plane,
> intel_crtc->adjusted_y = src_y;
>
> if (wm->dirty_pipes & drm_crtc_mask(&intel_crtc->base))
> - skl_write_plane_wm(intel_crtc, wm, 0);
> + skl_write_plane_wm(intel_crtc, p_wm, &wm->ddb, 0);
>
> I915_WRITE(PLANE_CTL(pipe, 0), plane_ctl);
> I915_WRITE(PLANE_OFFSET(pipe, 0), (src_y << 16) | src_x);
> @@ -3448,6 +3450,8 @@ static void
> skylake_disable_primary_plane(struct drm_plane *primary,
> struct drm_device *dev = crtc->dev;
> struct drm_i915_private *dev_priv = to_i915(dev);
> struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> + struct intel_crtc_state *cstate = to_intel_crtc_state(crtc-
> >state);
> + const struct skl_plane_wm *p_wm = &cstate-
> >wm.skl.optimal.planes[0];
> int pipe = intel_crtc->pipe;
>
> /*
> @@ -3455,7 +3459,8 @@ static void
> skylake_disable_primary_plane(struct drm_plane *primary,
> * plane's visiblity isn't actually changing neither is its
> watermarks.
> */
> if (!crtc->primary->state->visible)
> - skl_write_plane_wm(intel_crtc, &dev_priv-
> >wm.skl_results, 0);
> + skl_write_plane_wm(intel_crtc, p_wm,
> + &dev_priv->wm.skl_results.ddb,
> 0);
>
> I915_WRITE(PLANE_CTL(pipe, 0), 0);
> I915_WRITE(PLANE_SURF(pipe, 0), 0);
> @@ -10819,12 +10824,15 @@ static void i9xx_update_cursor(struct
> drm_crtc *crtc, u32 base,
> struct drm_device *dev = crtc->dev;
> struct drm_i915_private *dev_priv = to_i915(dev);
> struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> + struct intel_crtc_state *cstate = to_intel_crtc_state(crtc-
> >state);
> const struct skl_wm_values *wm = &dev_priv->wm.skl_results;
> + const struct skl_plane_wm *p_wm =
> + &cstate->wm.skl.optimal.planes[PLANE_CURSOR];
> int pipe = intel_crtc->pipe;
> uint32_t cntl = 0;
>
> if (INTEL_GEN(dev_priv) >= 9 && wm->dirty_pipes &
> drm_crtc_mask(crtc))
> - skl_write_cursor_wm(intel_crtc, wm);
> + skl_write_cursor_wm(intel_crtc, p_wm, &wm->ddb);
>
> if (plane_state && plane_state->base.visible) {
> cntl = MCURSOR_GAMMA_ENABLE;
> diff --git a/drivers/gpu/drm/i915/intel_drv.h
> b/drivers/gpu/drm/i915/intel_drv.h
> index d684f4f..958dc72 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -1765,9 +1765,11 @@ bool skl_ddb_allocation_equals(const struct
> skl_ddb_allocation *old,
> bool skl_ddb_allocation_overlaps(struct drm_atomic_state *state,
> struct intel_crtc *intel_crtc);
> void skl_write_cursor_wm(struct intel_crtc *intel_crtc,
> - const struct skl_wm_values *wm);
> + const struct skl_plane_wm *wm,
> + const struct skl_ddb_allocation *ddb);
> void skl_write_plane_wm(struct intel_crtc *intel_crtc,
> - const struct skl_wm_values *wm,
> + const struct skl_plane_wm *wm,
> + const struct skl_ddb_allocation *ddb,
> int plane);
> uint32_t ilk_pipe_pixel_rate(const struct intel_crtc_state
> *pipe_config);
> bool ilk_disable_lp_wm(struct drm_device *dev);
> diff --git a/drivers/gpu/drm/i915/intel_pm.c
> b/drivers/gpu/drm/i915/intel_pm.c
> index 250f12d..7708646 100644
> --- a/drivers/gpu/drm/i915/intel_pm.c
> +++ b/drivers/gpu/drm/i915/intel_pm.c
> @@ -3000,6 +3000,8 @@ bool intel_can_enable_sagv(struct
> drm_atomic_state *state)
> struct drm_i915_private *dev_priv = to_i915(dev);
> struct intel_atomic_state *intel_state =
> to_intel_atomic_state(state);
> struct drm_crtc *crtc;
> + struct intel_crtc_state *cstate;
> + struct skl_plane_wm *wm;
> enum pipe pipe;
> int level, plane;
>
> @@ -3020,18 +3022,21 @@ bool intel_can_enable_sagv(struct
> drm_atomic_state *state)
> /* Since we're now guaranteed to only have one active
> CRTC... */
> pipe = ffs(intel_state->active_crtcs) - 1;
> crtc = dev_priv->pipe_to_crtc_mapping[pipe];
> + cstate = intel_atomic_get_crtc_state(state,
> to_intel_crtc(crtc));
>
> if (crtc->state->mode.flags & DRM_MODE_FLAG_INTERLACE)
> return false;
>
> for_each_plane(dev_priv, pipe, plane) {
> + wm = &cstate->wm.skl.optimal.planes[plane];
> +
> /* Skip this plane if it's not enabled */
> - if (intel_state->wm_results.plane[pipe][plane][0] ==
> 0)
> + if (!wm->wm[0].plane_en)
> continue;
>
> /* Find the highest enabled wm level for this plane
> */
> - for (level = ilk_wm_max_level(dev);
> - intel_state-
> >wm_results.plane[pipe][plane][level] == 0; --level)
> + for (level = ilk_wm_max_level(dev); !wm-
> >wm[level].plane_en;
> + --level)
> { }
>
> /*
> @@ -3777,67 +3782,6 @@ static int skl_build_pipe_wm(struct
> intel_crtc_state *cstate,
> return 0;
> }
>
> -static void skl_compute_wm_results(struct drm_device *dev,
> - struct skl_pipe_wm *p_wm,
> - struct skl_wm_values *r,
> - struct intel_crtc *intel_crtc)
> -{
> - int level, max_level = ilk_wm_max_level(dev);
> - struct skl_plane_wm *plane_wm;
> - enum pipe pipe = intel_crtc->pipe;
> - uint32_t temp;
> - int 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 |= 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][i][level] = temp;
> - }
> -
> - }
> -
> - for (level = 0; level <= max_level; level++) {
> - plane_wm = &p_wm->planes[PLANE_CURSOR];
> - temp = 0;
> - 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 |= 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 |= 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;
> -}
> -
> static void skl_ddb_entry_write(struct drm_i915_private *dev_priv,
> i915_reg_t reg,
> const struct skl_ddb_entry *entry)
> @@ -3848,8 +3792,22 @@ static void skl_ddb_entry_write(struct
> drm_i915_private *dev_priv,
> I915_WRITE(reg, 0);
> }
>
> +static void skl_write_wm_level(struct drm_i915_private *dev_priv,
> + i915_reg_t reg,
> + const struct skl_wm_level *level)
> +{
> + uint32_t val = 0;
> +
> + val |= level->plane_res_b;
> + val |= level->plane_res_l << PLANE_WM_LINES_SHIFT;
> + val |= level->plane_en;
The line above seems wrong, you should check for plane_en and then set
PLANE_WM_EN.
IMHO it would even better if we completely zeroed the register in case
plane_en is false, so we could have:
uint32_t val = 0;
if (level->plane_en) {
val |= PLANE_WM_EN;
val |= level->plane_res_b;
val |= level->plane_res_l << PLANE_WM_LINES_SHIFT;
}
> +
> + I915_WRITE(reg, val);
> +}
> +
> void skl_write_plane_wm(struct intel_crtc *intel_crtc,
> - const struct skl_wm_values *wm,
> + const struct skl_plane_wm *wm,
> + const struct skl_ddb_allocation *ddb,
> int plane)
> {
> struct drm_crtc *crtc = &intel_crtc->base;
> @@ -3859,19 +3817,21 @@ void skl_write_plane_wm(struct intel_crtc
> *intel_crtc,
> enum pipe pipe = intel_crtc->pipe;
>
> for (level = 0; level <= max_level; level++) {
> - I915_WRITE(PLANE_WM(pipe, plane, level),
> - wm->plane[pipe][plane][level]);
> + skl_write_wm_level(dev_priv, PLANE_WM(pipe, plane,
> level),
> + &wm->wm[level]);
> }
> - I915_WRITE(PLANE_WM_TRANS(pipe, plane), wm-
> >plane_trans[pipe][plane]);
> + skl_write_wm_level(dev_priv, PLANE_WM_TRANS(pipe, plane),
> + &wm->trans_wm);
>
> skl_ddb_entry_write(dev_priv, PLANE_BUF_CFG(pipe, plane),
> - &wm->ddb.plane[pipe][plane]);
> + &ddb->plane[pipe][plane]);
> skl_ddb_entry_write(dev_priv, PLANE_NV12_BUF_CFG(pipe,
> plane),
> - &wm->ddb.y_plane[pipe][plane]);
> + &ddb->y_plane[pipe][plane]);
> }
>
> void skl_write_cursor_wm(struct intel_crtc *intel_crtc,
> - const struct skl_wm_values *wm)
> + const struct skl_plane_wm *wm,
> + const struct skl_ddb_allocation *ddb)
> {
> struct drm_crtc *crtc = &intel_crtc->base;
> struct drm_device *dev = crtc->dev;
> @@ -3880,13 +3840,13 @@ void skl_write_cursor_wm(struct intel_crtc
> *intel_crtc,
> enum pipe pipe = intel_crtc->pipe;
>
> for (level = 0; level <= max_level; level++) {
> - I915_WRITE(CUR_WM(pipe, level),
> - wm->plane[pipe][PLANE_CURSOR][level]);
> + skl_write_wm_level(dev_priv, CUR_WM(pipe, level),
> + &wm->wm[level]);
> }
> - I915_WRITE(CUR_WM_TRANS(pipe), wm-
> >plane_trans[pipe][PLANE_CURSOR]);
> + skl_write_wm_level(dev_priv, CUR_WM_TRANS(pipe), &wm-
> >trans_wm);
>
> skl_ddb_entry_write(dev_priv, CUR_BUF_CFG(pipe),
> - &wm->ddb.plane[pipe][PLANE_CURSOR]);
> + &ddb->plane[pipe][PLANE_CURSOR]);
> }
>
> static inline bool skl_ddb_entries_overlap(const struct
> skl_ddb_entry *a,
> @@ -4064,11 +4024,6 @@ skl_copy_wm_for_pipe(struct skl_wm_values
> *dst,
> struct skl_wm_values *src,
> enum pipe pipe)
> {
> - memcpy(dst->plane[pipe], src->plane[pipe],
> - sizeof(dst->plane[pipe]));
> - memcpy(dst->plane_trans[pipe], src->plane_trans[pipe],
> - sizeof(dst->plane_trans[pipe]));
> -
> memcpy(dst->ddb.y_plane[pipe], src->ddb.y_plane[pipe],
> sizeof(dst->ddb.y_plane[pipe]));
> memcpy(dst->ddb.plane[pipe], src->ddb.plane[pipe],
> @@ -4117,7 +4072,6 @@ skl_compute_wm(struct drm_atomic_state *state)
> * no suitable watermark values can be found.
> */
> for_each_crtc_in_state(state, crtc, cstate, i) {
> - struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> struct intel_crtc_state *intel_cstate =
> to_intel_crtc_state(cstate);
>
> @@ -4135,7 +4089,6 @@ skl_compute_wm(struct drm_atomic_state *state)
> continue;
>
> intel_cstate->update_wm_pre = true;
> - skl_compute_wm_results(crtc->dev, pipe_wm, results,
> intel_crtc);
> }
>
> return 0;
> @@ -4169,9 +4122,11 @@ static void skl_update_wm(struct drm_crtc
> *crtc)
> int plane;
>
> for (plane = 0; plane <
> intel_num_planes(intel_crtc); plane++)
> - skl_write_plane_wm(intel_crtc, results,
> plane);
> + skl_write_plane_wm(intel_crtc, &pipe_wm-
> >planes[plane],
> + &results->ddb, plane);
>
> - skl_write_cursor_wm(intel_crtc, results);
> + skl_write_cursor_wm(intel_crtc, &pipe_wm-
> >planes[PLANE_CURSOR],
> + &results->ddb);
> }
>
> skl_copy_wm_for_pipe(hw_vals, results, pipe);
> @@ -4256,28 +4211,13 @@ static void ilk_optimize_watermarks(struct
> intel_crtc_state *cstate)
> mutex_unlock(&dev_priv->wm.wm_mutex);
> }
>
> -static void skl_pipe_wm_active_state(uint32_t val,
> - struct skl_pipe_wm *active,
> - bool is_transwm,
> - int i,
> - int level)
> +static inline void skl_wm_level_from_reg_val(uint32_t val,
> + struct skl_wm_level
> *level)
> {
> - struct skl_plane_wm *plane_wm = &active->planes[i];
> - bool is_enabled = (val & PLANE_WM_EN) != 0;
> -
> - if (!is_transwm) {
> - plane_wm->wm[level].plane_en = is_enabled;
> - plane_wm->wm[level].plane_res_b = val &
> PLANE_WM_BLOCKS_MASK;
> - plane_wm->wm[level].plane_res_l =
> - (val >> PLANE_WM_LINES_SHIFT) &
> - PLANE_WM_LINES_MASK;
> - } else {
> - plane_wm->trans_wm.plane_en = is_enabled;
> - plane_wm->trans_wm.plane_res_b = val &
> PLANE_WM_BLOCKS_MASK;
> - plane_wm->trans_wm.plane_res_l =
> - (val >> PLANE_WM_LINES_SHIFT) &
> - PLANE_WM_LINES_MASK;
> - }
> + level->plane_en = val & PLANE_WM_EN;
> + level->plane_res_b = val & PLANE_WM_BLOCKS_MASK;
> + level->plane_res_l = (val & PLANE_WM_LINES_MASK) >>
> + PLANE_WM_LINES_SHIFT;
This also looks wrong, since PLANE_WM_LINES_MASK is 0x1f. We should do
like the original code did: shifting before masking.
> }
>
> static void skl_pipe_wm_get_hw_state(struct drm_crtc *crtc)
> @@ -4287,23 +4227,33 @@ static void skl_pipe_wm_get_hw_state(struct
> drm_crtc *crtc)
> struct skl_wm_values *hw = &dev_priv->wm.skl_hw;
> struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> struct intel_crtc_state *cstate = to_intel_crtc_state(crtc-
> >state);
> + struct intel_plane *intel_plane;
> struct skl_pipe_wm *active = &cstate->wm.skl.optimal;
> + struct skl_plane_wm *wm;
> enum pipe pipe = intel_crtc->pipe;
> - int level, i, max_level;
> - uint32_t temp;
> + int level, id, max_level = ilk_wm_max_level(dev);
> + uint32_t val;
>
> - max_level = ilk_wm_max_level(dev);
> + for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane) {
> + id = skl_wm_plane_id(intel_plane);
> + wm = &cstate->wm.skl.optimal.planes[id];
>
> - for (level = 0; level <= max_level; level++) {
> - for (i = 0; i < intel_num_planes(intel_crtc); i++)
> - hw->plane[pipe][i][level] =
> - I915_READ(PLANE_WM(pipe, i,
> level));
> - hw->plane[pipe][PLANE_CURSOR][level] =
> I915_READ(CUR_WM(pipe, level));
> - }
> + for (level = 0; level <= max_level; level++) {
> + if (id != PLANE_CURSOR)
> + val = I915_READ(PLANE_WM(pipe, id,
> level));
> + else
> + val = I915_READ(CUR_WM(pipe,
> level));
> +
> + skl_wm_level_from_reg_val(val, &wm-
> >wm[level]);
> + }
>
> - for (i = 0; i < intel_num_planes(intel_crtc); i++)
> - hw->plane_trans[pipe][i] =
> I915_READ(PLANE_WM_TRANS(pipe, i));
> - hw->plane_trans[pipe][PLANE_CURSOR] =
> I915_READ(CUR_WM_TRANS(pipe));
> + if (id != PLANE_CURSOR)
> + val = I915_READ(PLANE_WM_TRANS(pipe, id));
> + else
> + val = I915_READ(CUR_WM_TRANS(pipe));
> +
> + skl_wm_level_from_reg_val(val, &wm->trans_wm);
> + }
>
> if (!intel_crtc->active)
> return;
> @@ -4311,25 +4261,6 @@ static void skl_pipe_wm_get_hw_state(struct
> drm_crtc *crtc)
> hw->dirty_pipes |= drm_crtc_mask(crtc);
>
> active->linetime = I915_READ(PIPE_WM_LINETIME(pipe));
> -
> - for (level = 0; level <= max_level; level++) {
> - for (i = 0; i < intel_num_planes(intel_crtc); i++) {
> - temp = hw->plane[pipe][i][level];
> - skl_pipe_wm_active_state(temp, active,
> false, i, level);
> - }
> - temp = hw->plane[pipe][PLANE_CURSOR][level];
> - skl_pipe_wm_active_state(temp, active, false, i,
> level);
> - }
> -
> - for (i = 0; i < intel_num_planes(intel_crtc); i++) {
> - temp = hw->plane_trans[pipe][i];
> - skl_pipe_wm_active_state(temp, active, true, i, 0);
> - }
> -
> - temp = hw->plane_trans[pipe][PLANE_CURSOR];
> - skl_pipe_wm_active_state(temp, active, true, i, 0);
> -
> - intel_crtc->wm.active.skl = *active;
As far as I understood, we should still be setting intel_crtc-
>wm.active.skl. Shouldn't we? If not, why?
Now, due to the problems above, weren't you getting some WARNs about
the hw state not matching what it should? In case not, maybe you could
investigate why.
> }
>
> void skl_wm_get_hw_state(struct drm_device *dev)
> diff --git a/drivers/gpu/drm/i915/intel_sprite.c
> b/drivers/gpu/drm/i915/intel_sprite.c
> index 73a521f..0fb775b 100644
> --- a/drivers/gpu/drm/i915/intel_sprite.c
> +++ b/drivers/gpu/drm/i915/intel_sprite.c
> @@ -208,6 +208,8 @@ skl_update_plane(struct drm_plane *drm_plane,
> struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> const int pipe = intel_plane->pipe;
> const int plane = intel_plane->plane + 1;
> + const struct skl_plane_wm *p_wm =
> + &crtc_state->wm.skl.optimal.planes[plane];
> u32 plane_ctl;
> const struct drm_intel_sprite_colorkey *key = &plane_state-
> >ckey;
> u32 surf_addr = plane_state->main.offset;
> @@ -232,7 +234,7 @@ skl_update_plane(struct drm_plane *drm_plane,
> plane_ctl |= skl_plane_ctl_rotation(rotation);
>
> if (wm->dirty_pipes & drm_crtc_mask(crtc))
> - skl_write_plane_wm(intel_crtc, wm, plane);
> + skl_write_plane_wm(intel_crtc, p_wm, &wm->ddb,
> plane);
>
> if (key->flags) {
> I915_WRITE(PLANE_KEYVAL(pipe, plane), key-
> >min_value);
> @@ -289,6 +291,7 @@ skl_disable_plane(struct drm_plane *dplane,
> struct drm_crtc *crtc)
> struct drm_device *dev = dplane->dev;
> struct drm_i915_private *dev_priv = to_i915(dev);
> struct intel_plane *intel_plane = to_intel_plane(dplane);
> + struct intel_crtc_state *cstate = to_intel_crtc_state(crtc-
> >state);
> const int pipe = intel_plane->pipe;
> const int plane = intel_plane->plane + 1;
>
> @@ -298,7 +301,8 @@ skl_disable_plane(struct drm_plane *dplane,
> struct drm_crtc *crtc)
> */
> if (!dplane->state->visible)
> skl_write_plane_wm(to_intel_crtc(crtc),
> - &dev_priv->wm.skl_results,
> plane);
> + &cstate-
> >wm.skl.optimal.planes[plane],
> + &dev_priv->wm.skl_results.ddb,
> plane);
>
> I915_WRITE(PLANE_CTL(pipe, plane), 0);
>
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
WARNING: multiple messages have this Message-ID (diff)
From: Paulo Zanoni <paulo.r.zanoni@intel.com>
To: Lyude <cpaul@redhat.com>, intel-gfx@lists.freedesktop.org
Cc: David Airlie <airlied@linux.ie>,
linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org,
Daniel Vetter <daniel.vetter@intel.com>
Subject: Re: [Intel-gfx] [PATCH 5/6] drm/i915/gen9: Get rid of redundant watermark values
Date: Wed, 05 Oct 2016 18:44:04 -0300 [thread overview]
Message-ID: <1475703844.2381.74.camel@intel.com> (raw)
In-Reply-To: <1475681598-12081-6-git-send-email-cpaul@redhat.com>
Em Qua, 2016-10-05 às 11:33 -0400, Lyude escreveu:
> Now that we've make skl_wm_levels make a little more sense, we can
> remove all of the redundant wm information. Up until now we'd been
> storing two copies of all of the skl watermarks: one being the
> skl_pipe_wm structs, the other being the global wm struct in
> drm_i915_private containing the raw register values. This is
> confusing
> and problematic, since it means we're prone to accidentally letting
> the
> two copies go out of sync. So, get rid of all of the functions
> responsible for computing the register values and just use a single
> helper, skl_write_wm_level(), to convert and write the new watermarks
> on
> the fly.
I like the direction of this patch too, but there are some small
possible problems. See below.
>
> Signed-off-by: Lyude <cpaul@redhat.com>
> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
> Cc: Matt Roper <matthew.d.roper@intel.com>
> ---
> drivers/gpu/drm/i915/i915_drv.h | 2 -
> drivers/gpu/drm/i915/intel_display.c | 14 ++-
> drivers/gpu/drm/i915/intel_drv.h | 6 +-
> drivers/gpu/drm/i915/intel_pm.c | 203 ++++++++++++-------------
> ----------
> drivers/gpu/drm/i915/intel_sprite.c | 8 +-
> 5 files changed, 88 insertions(+), 145 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_drv.h
> b/drivers/gpu/drm/i915/i915_drv.h
> index 0f97d43..63519ac 100644
> --- a/drivers/gpu/drm/i915/i915_drv.h
> +++ b/drivers/gpu/drm/i915/i915_drv.h
> @@ -1643,8 +1643,6 @@ struct skl_ddb_allocation {
> struct skl_wm_values {
> unsigned dirty_pipes;
> struct skl_ddb_allocation ddb;
> - uint32_t plane[I915_MAX_PIPES][I915_MAX_PLANES][8];
> - uint32_t plane_trans[I915_MAX_PIPES][I915_MAX_PLANES];
> };
>
> struct skl_wm_level {
> diff --git a/drivers/gpu/drm/i915/intel_display.c
> b/drivers/gpu/drm/i915/intel_display.c
> index dd15ae2..c580d3d 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -3378,6 +3378,8 @@ static void skylake_update_primary_plane(struct
> drm_plane *plane,
> struct intel_crtc *intel_crtc = to_intel_crtc(crtc_state-
> >base.crtc);
> struct drm_framebuffer *fb = plane_state->base.fb;
> const struct skl_wm_values *wm = &dev_priv->wm.skl_results;
> + const struct skl_plane_wm *p_wm =
> + &crtc_state->wm.skl.optimal.planes[0];
I wish someone would do a patch to convert all these hardcoded values
to PLANE_X, and convert "int"s to "enum plane"s everywhere.
> int pipe = intel_crtc->pipe;
> u32 plane_ctl;
> unsigned int rotation = plane_state->base.rotation;
> @@ -3414,7 +3416,7 @@ static void skylake_update_primary_plane(struct
> drm_plane *plane,
> intel_crtc->adjusted_y = src_y;
>
> if (wm->dirty_pipes & drm_crtc_mask(&intel_crtc->base))
> - skl_write_plane_wm(intel_crtc, wm, 0);
> + skl_write_plane_wm(intel_crtc, p_wm, &wm->ddb, 0);
>
> I915_WRITE(PLANE_CTL(pipe, 0), plane_ctl);
> I915_WRITE(PLANE_OFFSET(pipe, 0), (src_y << 16) | src_x);
> @@ -3448,6 +3450,8 @@ static void
> skylake_disable_primary_plane(struct drm_plane *primary,
> struct drm_device *dev = crtc->dev;
> struct drm_i915_private *dev_priv = to_i915(dev);
> struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> + struct intel_crtc_state *cstate = to_intel_crtc_state(crtc-
> >state);
> + const struct skl_plane_wm *p_wm = &cstate-
> >wm.skl.optimal.planes[0];
> int pipe = intel_crtc->pipe;
>
> /*
> @@ -3455,7 +3459,8 @@ static void
> skylake_disable_primary_plane(struct drm_plane *primary,
> * plane's visiblity isn't actually changing neither is its
> watermarks.
> */
> if (!crtc->primary->state->visible)
> - skl_write_plane_wm(intel_crtc, &dev_priv-
> >wm.skl_results, 0);
> + skl_write_plane_wm(intel_crtc, p_wm,
> + &dev_priv->wm.skl_results.ddb,
> 0);
>
> I915_WRITE(PLANE_CTL(pipe, 0), 0);
> I915_WRITE(PLANE_SURF(pipe, 0), 0);
> @@ -10819,12 +10824,15 @@ static void i9xx_update_cursor(struct
> drm_crtc *crtc, u32 base,
> struct drm_device *dev = crtc->dev;
> struct drm_i915_private *dev_priv = to_i915(dev);
> struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> + struct intel_crtc_state *cstate = to_intel_crtc_state(crtc-
> >state);
> const struct skl_wm_values *wm = &dev_priv->wm.skl_results;
> + const struct skl_plane_wm *p_wm =
> + &cstate->wm.skl.optimal.planes[PLANE_CURSOR];
> int pipe = intel_crtc->pipe;
> uint32_t cntl = 0;
>
> if (INTEL_GEN(dev_priv) >= 9 && wm->dirty_pipes &
> drm_crtc_mask(crtc))
> - skl_write_cursor_wm(intel_crtc, wm);
> + skl_write_cursor_wm(intel_crtc, p_wm, &wm->ddb);
>
> if (plane_state && plane_state->base.visible) {
> cntl = MCURSOR_GAMMA_ENABLE;
> diff --git a/drivers/gpu/drm/i915/intel_drv.h
> b/drivers/gpu/drm/i915/intel_drv.h
> index d684f4f..958dc72 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -1765,9 +1765,11 @@ bool skl_ddb_allocation_equals(const struct
> skl_ddb_allocation *old,
> bool skl_ddb_allocation_overlaps(struct drm_atomic_state *state,
> struct intel_crtc *intel_crtc);
> void skl_write_cursor_wm(struct intel_crtc *intel_crtc,
> - const struct skl_wm_values *wm);
> + const struct skl_plane_wm *wm,
> + const struct skl_ddb_allocation *ddb);
> void skl_write_plane_wm(struct intel_crtc *intel_crtc,
> - const struct skl_wm_values *wm,
> + const struct skl_plane_wm *wm,
> + const struct skl_ddb_allocation *ddb,
> int plane);
> uint32_t ilk_pipe_pixel_rate(const struct intel_crtc_state
> *pipe_config);
> bool ilk_disable_lp_wm(struct drm_device *dev);
> diff --git a/drivers/gpu/drm/i915/intel_pm.c
> b/drivers/gpu/drm/i915/intel_pm.c
> index 250f12d..7708646 100644
> --- a/drivers/gpu/drm/i915/intel_pm.c
> +++ b/drivers/gpu/drm/i915/intel_pm.c
> @@ -3000,6 +3000,8 @@ bool intel_can_enable_sagv(struct
> drm_atomic_state *state)
> struct drm_i915_private *dev_priv = to_i915(dev);
> struct intel_atomic_state *intel_state =
> to_intel_atomic_state(state);
> struct drm_crtc *crtc;
> + struct intel_crtc_state *cstate;
> + struct skl_plane_wm *wm;
> enum pipe pipe;
> int level, plane;
>
> @@ -3020,18 +3022,21 @@ bool intel_can_enable_sagv(struct
> drm_atomic_state *state)
> /* Since we're now guaranteed to only have one active
> CRTC... */
> pipe = ffs(intel_state->active_crtcs) - 1;
> crtc = dev_priv->pipe_to_crtc_mapping[pipe];
> + cstate = intel_atomic_get_crtc_state(state,
> to_intel_crtc(crtc));
>
> if (crtc->state->mode.flags & DRM_MODE_FLAG_INTERLACE)
> return false;
>
> for_each_plane(dev_priv, pipe, plane) {
> + wm = &cstate->wm.skl.optimal.planes[plane];
> +
> /* Skip this plane if it's not enabled */
> - if (intel_state->wm_results.plane[pipe][plane][0] ==
> 0)
> + if (!wm->wm[0].plane_en)
> continue;
>
> /* Find the highest enabled wm level for this plane
> */
> - for (level = ilk_wm_max_level(dev);
> - intel_state-
> >wm_results.plane[pipe][plane][level] == 0; --level)
> + for (level = ilk_wm_max_level(dev); !wm-
> >wm[level].plane_en;
> + --level)
> { }
>
> /*
> @@ -3777,67 +3782,6 @@ static int skl_build_pipe_wm(struct
> intel_crtc_state *cstate,
> return 0;
> }
>
> -static void skl_compute_wm_results(struct drm_device *dev,
> - struct skl_pipe_wm *p_wm,
> - struct skl_wm_values *r,
> - struct intel_crtc *intel_crtc)
> -{
> - int level, max_level = ilk_wm_max_level(dev);
> - struct skl_plane_wm *plane_wm;
> - enum pipe pipe = intel_crtc->pipe;
> - uint32_t temp;
> - int 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 |= 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][i][level] = temp;
> - }
> -
> - }
> -
> - for (level = 0; level <= max_level; level++) {
> - plane_wm = &p_wm->planes[PLANE_CURSOR];
> - temp = 0;
> - 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 |= 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 |= 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;
> -}
> -
> static void skl_ddb_entry_write(struct drm_i915_private *dev_priv,
> i915_reg_t reg,
> const struct skl_ddb_entry *entry)
> @@ -3848,8 +3792,22 @@ static void skl_ddb_entry_write(struct
> drm_i915_private *dev_priv,
> I915_WRITE(reg, 0);
> }
>
> +static void skl_write_wm_level(struct drm_i915_private *dev_priv,
> + i915_reg_t reg,
> + const struct skl_wm_level *level)
> +{
> + uint32_t val = 0;
> +
> + val |= level->plane_res_b;
> + val |= level->plane_res_l << PLANE_WM_LINES_SHIFT;
> + val |= level->plane_en;
The line above seems wrong, you should check for plane_en and then set
PLANE_WM_EN.
IMHO it would even better if we completely zeroed the register in case
plane_en is false, so we could have:
uint32_t val = 0;
if (level->plane_en) {
val |= PLANE_WM_EN;
val |= level->plane_res_b;
val |= level->plane_res_l << PLANE_WM_LINES_SHIFT;
}
> +
> + I915_WRITE(reg, val);
> +}
> +
> void skl_write_plane_wm(struct intel_crtc *intel_crtc,
> - const struct skl_wm_values *wm,
> + const struct skl_plane_wm *wm,
> + const struct skl_ddb_allocation *ddb,
> int plane)
> {
> struct drm_crtc *crtc = &intel_crtc->base;
> @@ -3859,19 +3817,21 @@ void skl_write_plane_wm(struct intel_crtc
> *intel_crtc,
> enum pipe pipe = intel_crtc->pipe;
>
> for (level = 0; level <= max_level; level++) {
> - I915_WRITE(PLANE_WM(pipe, plane, level),
> - wm->plane[pipe][plane][level]);
> + skl_write_wm_level(dev_priv, PLANE_WM(pipe, plane,
> level),
> + &wm->wm[level]);
> }
> - I915_WRITE(PLANE_WM_TRANS(pipe, plane), wm-
> >plane_trans[pipe][plane]);
> + skl_write_wm_level(dev_priv, PLANE_WM_TRANS(pipe, plane),
> + &wm->trans_wm);
>
> skl_ddb_entry_write(dev_priv, PLANE_BUF_CFG(pipe, plane),
> - &wm->ddb.plane[pipe][plane]);
> + &ddb->plane[pipe][plane]);
> skl_ddb_entry_write(dev_priv, PLANE_NV12_BUF_CFG(pipe,
> plane),
> - &wm->ddb.y_plane[pipe][plane]);
> + &ddb->y_plane[pipe][plane]);
> }
>
> void skl_write_cursor_wm(struct intel_crtc *intel_crtc,
> - const struct skl_wm_values *wm)
> + const struct skl_plane_wm *wm,
> + const struct skl_ddb_allocation *ddb)
> {
> struct drm_crtc *crtc = &intel_crtc->base;
> struct drm_device *dev = crtc->dev;
> @@ -3880,13 +3840,13 @@ void skl_write_cursor_wm(struct intel_crtc
> *intel_crtc,
> enum pipe pipe = intel_crtc->pipe;
>
> for (level = 0; level <= max_level; level++) {
> - I915_WRITE(CUR_WM(pipe, level),
> - wm->plane[pipe][PLANE_CURSOR][level]);
> + skl_write_wm_level(dev_priv, CUR_WM(pipe, level),
> + &wm->wm[level]);
> }
> - I915_WRITE(CUR_WM_TRANS(pipe), wm-
> >plane_trans[pipe][PLANE_CURSOR]);
> + skl_write_wm_level(dev_priv, CUR_WM_TRANS(pipe), &wm-
> >trans_wm);
>
> skl_ddb_entry_write(dev_priv, CUR_BUF_CFG(pipe),
> - &wm->ddb.plane[pipe][PLANE_CURSOR]);
> + &ddb->plane[pipe][PLANE_CURSOR]);
> }
>
> static inline bool skl_ddb_entries_overlap(const struct
> skl_ddb_entry *a,
> @@ -4064,11 +4024,6 @@ skl_copy_wm_for_pipe(struct skl_wm_values
> *dst,
> struct skl_wm_values *src,
> enum pipe pipe)
> {
> - memcpy(dst->plane[pipe], src->plane[pipe],
> - sizeof(dst->plane[pipe]));
> - memcpy(dst->plane_trans[pipe], src->plane_trans[pipe],
> - sizeof(dst->plane_trans[pipe]));
> -
> memcpy(dst->ddb.y_plane[pipe], src->ddb.y_plane[pipe],
> sizeof(dst->ddb.y_plane[pipe]));
> memcpy(dst->ddb.plane[pipe], src->ddb.plane[pipe],
> @@ -4117,7 +4072,6 @@ skl_compute_wm(struct drm_atomic_state *state)
> * no suitable watermark values can be found.
> */
> for_each_crtc_in_state(state, crtc, cstate, i) {
> - struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> struct intel_crtc_state *intel_cstate =
> to_intel_crtc_state(cstate);
>
> @@ -4135,7 +4089,6 @@ skl_compute_wm(struct drm_atomic_state *state)
> continue;
>
> intel_cstate->update_wm_pre = true;
> - skl_compute_wm_results(crtc->dev, pipe_wm, results,
> intel_crtc);
> }
>
> return 0;
> @@ -4169,9 +4122,11 @@ static void skl_update_wm(struct drm_crtc
> *crtc)
> int plane;
>
> for (plane = 0; plane <
> intel_num_planes(intel_crtc); plane++)
> - skl_write_plane_wm(intel_crtc, results,
> plane);
> + skl_write_plane_wm(intel_crtc, &pipe_wm-
> >planes[plane],
> + &results->ddb, plane);
>
> - skl_write_cursor_wm(intel_crtc, results);
> + skl_write_cursor_wm(intel_crtc, &pipe_wm-
> >planes[PLANE_CURSOR],
> + &results->ddb);
> }
>
> skl_copy_wm_for_pipe(hw_vals, results, pipe);
> @@ -4256,28 +4211,13 @@ static void ilk_optimize_watermarks(struct
> intel_crtc_state *cstate)
> mutex_unlock(&dev_priv->wm.wm_mutex);
> }
>
> -static void skl_pipe_wm_active_state(uint32_t val,
> - struct skl_pipe_wm *active,
> - bool is_transwm,
> - int i,
> - int level)
> +static inline void skl_wm_level_from_reg_val(uint32_t val,
> + struct skl_wm_level
> *level)
> {
> - struct skl_plane_wm *plane_wm = &active->planes[i];
> - bool is_enabled = (val & PLANE_WM_EN) != 0;
> -
> - if (!is_transwm) {
> - plane_wm->wm[level].plane_en = is_enabled;
> - plane_wm->wm[level].plane_res_b = val &
> PLANE_WM_BLOCKS_MASK;
> - plane_wm->wm[level].plane_res_l =
> - (val >> PLANE_WM_LINES_SHIFT) &
> - PLANE_WM_LINES_MASK;
> - } else {
> - plane_wm->trans_wm.plane_en = is_enabled;
> - plane_wm->trans_wm.plane_res_b = val &
> PLANE_WM_BLOCKS_MASK;
> - plane_wm->trans_wm.plane_res_l =
> - (val >> PLANE_WM_LINES_SHIFT) &
> - PLANE_WM_LINES_MASK;
> - }
> + level->plane_en = val & PLANE_WM_EN;
> + level->plane_res_b = val & PLANE_WM_BLOCKS_MASK;
> + level->plane_res_l = (val & PLANE_WM_LINES_MASK) >>
> + PLANE_WM_LINES_SHIFT;
This also looks wrong, since PLANE_WM_LINES_MASK is 0x1f. We should do
like the original code did: shifting before masking.
> }
>
> static void skl_pipe_wm_get_hw_state(struct drm_crtc *crtc)
> @@ -4287,23 +4227,33 @@ static void skl_pipe_wm_get_hw_state(struct
> drm_crtc *crtc)
> struct skl_wm_values *hw = &dev_priv->wm.skl_hw;
> struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> struct intel_crtc_state *cstate = to_intel_crtc_state(crtc-
> >state);
> + struct intel_plane *intel_plane;
> struct skl_pipe_wm *active = &cstate->wm.skl.optimal;
> + struct skl_plane_wm *wm;
> enum pipe pipe = intel_crtc->pipe;
> - int level, i, max_level;
> - uint32_t temp;
> + int level, id, max_level = ilk_wm_max_level(dev);
> + uint32_t val;
>
> - max_level = ilk_wm_max_level(dev);
> + for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane) {
> + id = skl_wm_plane_id(intel_plane);
> + wm = &cstate->wm.skl.optimal.planes[id];
>
> - for (level = 0; level <= max_level; level++) {
> - for (i = 0; i < intel_num_planes(intel_crtc); i++)
> - hw->plane[pipe][i][level] =
> - I915_READ(PLANE_WM(pipe, i,
> level));
> - hw->plane[pipe][PLANE_CURSOR][level] =
> I915_READ(CUR_WM(pipe, level));
> - }
> + for (level = 0; level <= max_level; level++) {
> + if (id != PLANE_CURSOR)
> + val = I915_READ(PLANE_WM(pipe, id,
> level));
> + else
> + val = I915_READ(CUR_WM(pipe,
> level));
> +
> + skl_wm_level_from_reg_val(val, &wm-
> >wm[level]);
> + }
>
> - for (i = 0; i < intel_num_planes(intel_crtc); i++)
> - hw->plane_trans[pipe][i] =
> I915_READ(PLANE_WM_TRANS(pipe, i));
> - hw->plane_trans[pipe][PLANE_CURSOR] =
> I915_READ(CUR_WM_TRANS(pipe));
> + if (id != PLANE_CURSOR)
> + val = I915_READ(PLANE_WM_TRANS(pipe, id));
> + else
> + val = I915_READ(CUR_WM_TRANS(pipe));
> +
> + skl_wm_level_from_reg_val(val, &wm->trans_wm);
> + }
>
> if (!intel_crtc->active)
> return;
> @@ -4311,25 +4261,6 @@ static void skl_pipe_wm_get_hw_state(struct
> drm_crtc *crtc)
> hw->dirty_pipes |= drm_crtc_mask(crtc);
>
> active->linetime = I915_READ(PIPE_WM_LINETIME(pipe));
> -
> - for (level = 0; level <= max_level; level++) {
> - for (i = 0; i < intel_num_planes(intel_crtc); i++) {
> - temp = hw->plane[pipe][i][level];
> - skl_pipe_wm_active_state(temp, active,
> false, i, level);
> - }
> - temp = hw->plane[pipe][PLANE_CURSOR][level];
> - skl_pipe_wm_active_state(temp, active, false, i,
> level);
> - }
> -
> - for (i = 0; i < intel_num_planes(intel_crtc); i++) {
> - temp = hw->plane_trans[pipe][i];
> - skl_pipe_wm_active_state(temp, active, true, i, 0);
> - }
> -
> - temp = hw->plane_trans[pipe][PLANE_CURSOR];
> - skl_pipe_wm_active_state(temp, active, true, i, 0);
> -
> - intel_crtc->wm.active.skl = *active;
As far as I understood, we should still be setting intel_crtc-
>wm.active.skl. Shouldn't we? If not, why?
Now, due to the problems above, weren't you getting some WARNs about
the hw state not matching what it should? In case not, maybe you could
investigate why.
> }
>
> void skl_wm_get_hw_state(struct drm_device *dev)
> diff --git a/drivers/gpu/drm/i915/intel_sprite.c
> b/drivers/gpu/drm/i915/intel_sprite.c
> index 73a521f..0fb775b 100644
> --- a/drivers/gpu/drm/i915/intel_sprite.c
> +++ b/drivers/gpu/drm/i915/intel_sprite.c
> @@ -208,6 +208,8 @@ skl_update_plane(struct drm_plane *drm_plane,
> struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> const int pipe = intel_plane->pipe;
> const int plane = intel_plane->plane + 1;
> + const struct skl_plane_wm *p_wm =
> + &crtc_state->wm.skl.optimal.planes[plane];
> u32 plane_ctl;
> const struct drm_intel_sprite_colorkey *key = &plane_state-
> >ckey;
> u32 surf_addr = plane_state->main.offset;
> @@ -232,7 +234,7 @@ skl_update_plane(struct drm_plane *drm_plane,
> plane_ctl |= skl_plane_ctl_rotation(rotation);
>
> if (wm->dirty_pipes & drm_crtc_mask(crtc))
> - skl_write_plane_wm(intel_crtc, wm, plane);
> + skl_write_plane_wm(intel_crtc, p_wm, &wm->ddb,
> plane);
>
> if (key->flags) {
> I915_WRITE(PLANE_KEYVAL(pipe, plane), key-
> >min_value);
> @@ -289,6 +291,7 @@ skl_disable_plane(struct drm_plane *dplane,
> struct drm_crtc *crtc)
> struct drm_device *dev = dplane->dev;
> struct drm_i915_private *dev_priv = to_i915(dev);
> struct intel_plane *intel_plane = to_intel_plane(dplane);
> + struct intel_crtc_state *cstate = to_intel_crtc_state(crtc-
> >state);
> const int pipe = intel_plane->pipe;
> const int plane = intel_plane->plane + 1;
>
> @@ -298,7 +301,8 @@ skl_disable_plane(struct drm_plane *dplane,
> struct drm_crtc *crtc)
> */
> if (!dplane->state->visible)
> skl_write_plane_wm(to_intel_crtc(crtc),
> - &dev_priv->wm.skl_results,
> plane);
> + &cstate-
> >wm.skl.optimal.planes[plane],
> + &dev_priv->wm.skl_results.ddb,
> plane);
>
> I915_WRITE(PLANE_CTL(pipe, plane), 0);
>
next prev parent reply other threads:[~2016-10-05 21:44 UTC|newest]
Thread overview: 28+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-10-05 15:33 [PATCH 0/6] Start of skl watermark cleanup Lyude
2016-10-05 15:33 ` Lyude
2016-10-05 15:33 ` [PATCH 1/6] drm/i915/skl: Move per-pipe ddb allocations into crtc states Lyude
2016-10-05 15:33 ` Lyude
2016-10-05 20:23 ` Paulo Zanoni
2016-10-05 20:23 ` [Intel-gfx] " Paulo Zanoni
2016-10-05 15:33 ` [PATCH 2/6] drm/i915/skl: Remove linetime from skl_wm_values Lyude
2016-10-05 15:33 ` Lyude
2016-10-05 20:24 ` [Intel-gfx] " Paulo Zanoni
2016-10-05 15:33 ` [PATCH 3/6] drm/i915: Add enable_sagv option Lyude
2016-10-05 15:33 ` Lyude
2016-10-05 19:32 ` Paulo Zanoni
2016-10-05 19:32 ` [Intel-gfx] " Paulo Zanoni
2016-10-05 15:33 ` [PATCH 4/6] drm/i915/gen9: Make skl_wm_level per-plane Lyude
2016-10-05 15:33 ` Lyude
2016-10-05 20:33 ` Paulo Zanoni
2016-10-05 20:33 ` [Intel-gfx] " Paulo Zanoni
2016-10-06 10:38 ` Maarten Lankhorst
2016-10-06 10:38 ` [Intel-gfx] " Maarten Lankhorst
2016-10-05 15:33 ` [PATCH 5/6] drm/i915/gen9: Get rid of redundant watermark values Lyude
2016-10-05 21:44 ` Paulo Zanoni [this message]
2016-10-05 21:44 ` [Intel-gfx] " Paulo Zanoni
2016-10-05 21:53 ` Chris Wilson
2016-10-05 15:33 ` [PATCH 6/6] drm/i915/gen9: Add ddb changes to atomic debug output Lyude
2016-10-05 15:33 ` Lyude
2016-10-05 16:26 ` ✗ Fi.CI.BAT: warning for Start of skl watermark cleanup Patchwork
2016-10-06 11:25 ` [PATCH 0/6] " Maarten Lankhorst
2016-10-06 11:25 ` Maarten Lankhorst
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1475703844.2381.74.camel@intel.com \
--to=paulo.r.zanoni@intel.com \
--cc=airlied@linux.ie \
--cc=cpaul@redhat.com \
--cc=daniel.vetter@intel.com \
--cc=dri-devel@lists.freedesktop.org \
--cc=intel-gfx@lists.freedesktop.org \
--cc=linux-kernel@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.