From: ville.syrjala@linux.intel.com
To: intel-gfx@lists.freedesktop.org
Subject: [PATCH 06/18] drm/i915: Compute VLV/CHV FIFO sizes based on the PM2 watermarks
Date: Thu, 16 Feb 2017 20:07:39 +0200 [thread overview]
Message-ID: <20170216180751.3097-7-ville.syrjala@linux.intel.com> (raw)
In-Reply-To: <20170216180751.3097-1-ville.syrjala@linux.intel.com>
From: Ville Syrjälä <ville.syrjala@linux.intel.com>
Let's compute the watermarks first and the FIFO size second. This way we
can make sure the FIFO split is the most accommodating to the watermarks.
Previously we could have potentially computed a FIFO split that couldn't
accommodate the PM2 watermarks simply due to a bad split even if the
total FIFO size would have been sufficient.
It'll also allow us to avoid recomputing the wms for all planes whenever
the FIFO split would change. Thus we don't have to add any extra planes
to the state when the FIFO needs to be repartitioned.
To help with this we'll keep around copies of the non-inverted
watermarks in the crtc state. For now that doesn't help too much, but
once we start to do the watermark computation only for the planes
that change we'll need the non-inverted values around for the other
planes.
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Reviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
---
drivers/gpu/drm/i915/intel_drv.h | 2 +
drivers/gpu/drm/i915/intel_pm.c | 116 +++++++++++++++++++--------------------
2 files changed, 57 insertions(+), 61 deletions(-)
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 493a37b089fb..ada5fd3fdeab 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -534,6 +534,8 @@ struct intel_crtc_wm_state {
} skl;
struct {
+ /* non-inverted optimal watermarks */
+ struct vlv_pipe_wm noninverted[NUM_VLV_WM_LEVELS];
struct vlv_fifo_state fifo_state;
/* inverted optimal watermarks */
struct vlv_wm_state optimal;
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 9371b9645c9d..ad02edb11ca2 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -1018,73 +1018,70 @@ static uint16_t vlv_compute_wm_level(const struct intel_crtc_state *crtc_state,
return min_t(int, wm, USHRT_MAX);
}
-static void vlv_compute_fifo(struct intel_crtc_state *crtc_state)
+static int vlv_compute_fifo(struct intel_crtc_state *crtc_state)
{
struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
- struct vlv_wm_state *wm_state = &crtc_state->wm.vlv.optimal;
+ const struct vlv_pipe_wm *noninverted =
+ &crtc_state->wm.vlv.noninverted[VLV_WM_LEVEL_PM2];
struct vlv_fifo_state *fifo_state = &crtc_state->wm.vlv.fifo_state;
- struct drm_device *dev = crtc->base.dev;
- struct intel_plane *plane;
- unsigned int total_rate = 0;
- const int fifo_size = 512 - 1;
+ unsigned int active_planes = crtc_state->active_planes & ~BIT(PLANE_CURSOR);
+ int num_active_planes = hweight32(active_planes);
+ const int fifo_size = 511;
int fifo_extra, fifo_left = fifo_size;
+ unsigned int total_rate;
+ enum plane_id plane_id;
- for_each_intel_plane_on_crtc(dev, crtc, plane) {
- struct intel_plane_state *state =
- to_intel_plane_state(plane->base.state);
+ total_rate = noninverted->plane[PLANE_PRIMARY] +
+ noninverted->plane[PLANE_SPRITE0] +
+ noninverted->plane[PLANE_SPRITE1];
- if (plane->id == PLANE_CURSOR)
- continue;
+ if (total_rate > fifo_size)
+ return -EINVAL;
- if (state->base.visible) {
- wm_state->num_active_planes++;
- total_rate += state->base.fb->format->cpp[0];
- }
- }
+ if (total_rate == 0)
+ total_rate = 1;
- for_each_intel_plane_on_crtc(dev, crtc, plane) {
- struct intel_plane_state *state =
- to_intel_plane_state(plane->base.state);
+ for_each_plane_id_on_crtc(crtc, plane_id) {
unsigned int rate;
- if (plane->id == PLANE_CURSOR) {
- fifo_state->plane[plane->id] = 63;
+ if ((active_planes & BIT(plane_id)) == 0) {
+ fifo_state->plane[plane_id] = 0;
continue;
}
- if (!state->base.visible) {
- fifo_state->plane[plane->id] = 0;
- continue;
- }
-
- rate = state->base.fb->format->cpp[0];
- fifo_state->plane[plane->id] = fifo_size * rate / total_rate;
- fifo_left -= fifo_state->plane[plane->id];
+ rate = noninverted->plane[plane_id];
+ fifo_state->plane[plane_id] = fifo_size * rate / total_rate;
+ fifo_left -= fifo_state->plane[plane_id];
}
- fifo_extra = DIV_ROUND_UP(fifo_left, wm_state->num_active_planes ?: 1);
+ fifo_state->plane[PLANE_CURSOR] = 63;
+
+ fifo_extra = DIV_ROUND_UP(fifo_left, num_active_planes ?: 1);
/* spread the remainder evenly */
- for_each_intel_plane_on_crtc(dev, crtc, plane) {
+ for_each_plane_id_on_crtc(crtc, plane_id) {
int plane_extra;
if (fifo_left == 0)
break;
- if (plane->id == PLANE_CURSOR)
- continue;
-
- /* give it all to the first plane if none are active */
- if (fifo_state->plane[plane->id] == 0 &&
- wm_state->num_active_planes)
+ if ((active_planes & BIT(plane_id)) == 0)
continue;
plane_extra = min(fifo_extra, fifo_left);
- fifo_state->plane[plane->id] += plane_extra;
+ fifo_state->plane[plane_id] += plane_extra;
fifo_left -= plane_extra;
}
- WARN_ON(fifo_left != 0);
+ WARN_ON(active_planes != 0 && fifo_left != 0);
+
+ /* give it all to the first plane if none are active */
+ if (active_planes == 0) {
+ WARN_ON(fifo_left != fifo_size);
+ fifo_state->plane[PLANE_PRIMARY] = fifo_left;
+ }
+
+ return 0;
}
static u16 vlv_invert_wm_value(u16 wm, u16 fifo_size)
@@ -1129,35 +1126,33 @@ static void vlv_compute_wm(struct intel_crtc_state *crtc_state)
struct intel_crtc *crtc = to_intel_crtc(crtc_state->base.crtc);
struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
struct vlv_wm_state *wm_state = &crtc_state->wm.vlv.optimal;
- const struct vlv_fifo_state *fifo_state =
- &crtc_state->wm.vlv.fifo_state;
struct intel_plane *plane;
int level;
memset(wm_state, 0, sizeof(*wm_state));
+ memset(crtc_state->wm.vlv.noninverted, 0,
+ sizeof(crtc_state->wm.vlv.noninverted));
wm_state->cxsr = crtc->pipe != PIPE_C && crtc->wm.cxsr_allowed;
wm_state->num_levels = dev_priv->wm.max_level + 1;
wm_state->num_active_planes = 0;
- vlv_compute_fifo(crtc_state);
-
if (wm_state->num_active_planes != 1)
wm_state->cxsr = false;
for_each_intel_plane_on_crtc(&dev_priv->drm, crtc, plane) {
struct intel_plane_state *state =
to_intel_plane_state(plane->base.state);
- int level;
if (!state->base.visible)
continue;
- /* normal watermarks */
for (level = 0; level < wm_state->num_levels; level++) {
+ struct vlv_pipe_wm *noninverted =
+ &crtc_state->wm.vlv.noninverted[level];
int wm = vlv_compute_wm_level(crtc_state, state, level);
- int max_wm = fifo_state->plane[plane->id];
+ int max_wm = plane->id == PLANE_CURSOR ? 63 : 511;
/* hack */
if (WARN_ON(level == 0 && wm > max_wm))
@@ -1166,25 +1161,24 @@ static void vlv_compute_wm(struct intel_crtc_state *crtc_state)
if (wm > max_wm)
break;
- wm_state->wm[level].plane[plane->id] = wm;
+ noninverted->plane[plane->id] = wm;
}
wm_state->num_levels = level;
+ }
- if (!wm_state->cxsr)
- continue;
-
- /* maxfifo watermarks */
- if (plane->id == PLANE_CURSOR) {
- for (level = 0; level < wm_state->num_levels; level++)
- wm_state->sr[level].cursor =
- wm_state->wm[level].plane[PLANE_CURSOR];
- } else {
- for (level = 0; level < wm_state->num_levels; level++)
- wm_state->sr[level].plane =
- max(wm_state->sr[level].plane,
- wm_state->wm[level].plane[plane->id]);
- }
+ vlv_compute_fifo(crtc_state);
+
+ for (level = 0; level < wm_state->num_levels; level++) {
+ struct vlv_pipe_wm *noninverted =
+ &crtc_state->wm.vlv.noninverted[level];
+
+ wm_state->wm[level] = *noninverted;
+
+ wm_state->sr[level].plane = max3(noninverted->plane[PLANE_PRIMARY],
+ noninverted->plane[PLANE_SPRITE0],
+ noninverted->plane[PLANE_SPRITE1]);
+ wm_state->sr[level].cursor = noninverted->plane[PLANE_CURSOR];
}
/* clear any (partially) filled invalid levels */
--
2.10.2
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx
next prev parent reply other threads:[~2017-02-16 18:08 UTC|newest]
Thread overview: 21+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-02-16 18:07 [PATCH v2 00/18] drm/i915: VLV/CHV two-stage watermarks (v2) ville.syrjala
2017-02-16 18:07 ` [PATCH 01/18] drm/i915: Track visible planes in a bitmask ville.syrjala
2017-02-16 18:07 ` [PATCH v2 02/18] drm/i915: Track plane fifo sizes under intel_crtc ville.syrjala
2017-02-16 18:07 ` [PATCH 03/18] drm/i915: Move vlv wms from crtc->wm_state to crtc->wm.active.vlv ville.syrjala
2017-02-16 18:07 ` [PATCH 04/18] drm/i915: Plop vlv wm state into crtc_state ville.syrjala
2017-02-16 18:07 ` [PATCH 05/18] drm/i915: Plop vlv/chv fifo sizes into crtc state ville.syrjala
2017-02-16 18:07 ` ville.syrjala [this message]
2017-02-16 18:07 ` [PATCH 07/18] drm/i915: Compute vlv/chv wms the atomic way ville.syrjala
2017-02-16 18:07 ` [PATCH 08/18] drm/i915: Skip useless watermark/FIFO related work on VLV/CHV when not needed ville.syrjala
2017-02-16 18:07 ` [PATCH 09/18] drm/i915: Compute proper intermediate wms for vlv/cvh ville.syrjala
2017-02-16 18:07 ` [PATCH 10/18] drm/i915: Nuke crtc->wm.cxsr_allowed ville.syrjala
2017-02-16 18:07 ` [PATCH 11/18] drm/i915: Only use update_wm_{pre, post} for pre-ilk platforms ville.syrjala
2017-02-16 18:07 ` [PATCH 12/18] drm/i915: Sanitize VLV/CHV watermarks properly ville.syrjala
2017-02-16 18:07 ` [PATCH 13/18] drm/i915: Workaround VLV/CHV sprite1->sprite0 enable underrun ville.syrjala
2017-02-16 18:07 ` [PATCH 14/18] drm/i915: Kill level 0 wm hack for VLV/CHV ville.syrjala
2017-02-16 18:07 ` [PATCH 15/18] drm/i915: Add plane update/disable tracepoints ville.syrjala
2017-02-16 18:07 ` [PATCH 16/18] drm/i915: Add VLV/CHV watermark/FIFO programming tracepoints ville.syrjala
2017-02-16 18:07 ` [PATCH 17/18] drm/i915: Add cxsr toggle tracepoint ville.syrjala
2017-02-16 18:07 ` [PATCH 18/18] drm/i915: Add FIFO underrun tracepoints ville.syrjala
2017-03-01 15:15 ` Maarten Lankhorst
2017-02-16 22:22 ` ✓ Fi.CI.BAT: success for drm/i915: VLV/CHV two-stage watermarks (rev2) Patchwork
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=20170216180751.3097-7-ville.syrjala@linux.intel.com \
--to=ville.syrjala@linux.intel.com \
--cc=intel-gfx@lists.freedesktop.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox