drm/i915: Only recalculate wm's for planes part of the state, v2.

Only planes that are part of the state should be used for recalculating
watermarks. For planes not part of the state the previous patch allows
us to re-use the old values since they're calculated even for levels
that are not actively used.

Changes since v1:
- Remove big if from intel_crtc_atomic_check.
- Remove extra newline.
- Remove memset in ilk_compute_pipe_wm.

Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Cc: Matt Roper <matthew.d.roper@intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/1456826842-32553-2-git-send-email-maarten.lankhorst@linux.intel.com
Reviewed-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
This commit is contained in:
Maarten Lankhorst
2016-03-01 11:07:22 +01:00
parent d81f04c5ef
commit e3bddded40
4 changed files with 47 additions and 29 deletions

View File

@@ -1996,11 +1996,18 @@ static void ilk_compute_wm_level(const struct drm_i915_private *dev_priv,
cur_latency *= 5;
}
result->pri_val = ilk_compute_pri_wm(cstate, pristate,
pri_latency, level);
result->spr_val = ilk_compute_spr_wm(cstate, sprstate, spr_latency);
result->cur_val = ilk_compute_cur_wm(cstate, curstate, cur_latency);
result->fbc_val = ilk_compute_fbc_wm(cstate, pristate, result->pri_val);
if (pristate) {
result->pri_val = ilk_compute_pri_wm(cstate, pristate,
pri_latency, level);
result->fbc_val = ilk_compute_fbc_wm(cstate, pristate, result->pri_val);
}
if (sprstate)
result->spr_val = ilk_compute_spr_wm(cstate, sprstate, spr_latency);
if (curstate)
result->cur_val = ilk_compute_cur_wm(cstate, curstate, cur_latency);
result->enable = true;
}
@@ -2288,51 +2295,51 @@ static bool ilk_validate_pipe_wm(struct drm_device *dev,
}
/* Compute new watermarks for the pipe */
static int ilk_compute_pipe_wm(struct intel_crtc *intel_crtc,
struct drm_atomic_state *state)
static int ilk_compute_pipe_wm(struct intel_crtc_state *cstate)
{
struct drm_atomic_state *state = cstate->base.state;
struct intel_crtc *intel_crtc = to_intel_crtc(cstate->base.crtc);
struct intel_pipe_wm *pipe_wm;
struct drm_device *dev = intel_crtc->base.dev;
struct drm_device *dev = state->dev;
const struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_crtc_state *cstate = NULL;
struct intel_plane *intel_plane;
struct drm_plane_state *ps;
struct intel_plane_state *pristate = NULL;
struct intel_plane_state *sprstate = NULL;
struct intel_plane_state *curstate = NULL;
int level, max_level = ilk_wm_max_level(dev), usable_level;
struct ilk_wm_maximums max;
cstate = intel_atomic_get_crtc_state(state, intel_crtc);
if (IS_ERR(cstate))
return PTR_ERR(cstate);
pipe_wm = &cstate->wm.optimal.ilk;
for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane) {
ps = drm_atomic_get_plane_state(state,
&intel_plane->base);
if (IS_ERR(ps))
return PTR_ERR(ps);
struct intel_plane_state *ps;
ps = intel_atomic_get_existing_plane_state(state,
intel_plane);
if (!ps)
continue;
if (intel_plane->base.type == DRM_PLANE_TYPE_PRIMARY)
pristate = to_intel_plane_state(ps);
pristate = ps;
else if (intel_plane->base.type == DRM_PLANE_TYPE_OVERLAY)
sprstate = to_intel_plane_state(ps);
sprstate = ps;
else if (intel_plane->base.type == DRM_PLANE_TYPE_CURSOR)
curstate = to_intel_plane_state(ps);
curstate = ps;
}
pipe_wm->pipe_enabled = cstate->base.active;
pipe_wm->sprites_enabled = sprstate->visible;
pipe_wm->sprites_scaled = sprstate->visible &&
(drm_rect_width(&sprstate->dst) != drm_rect_width(&sprstate->src) >> 16 ||
drm_rect_height(&sprstate->dst) != drm_rect_height(&sprstate->src) >> 16);
if (sprstate) {
pipe_wm->sprites_enabled = sprstate->visible;
pipe_wm->sprites_scaled = sprstate->visible &&
(drm_rect_width(&sprstate->dst) != drm_rect_width(&sprstate->src) >> 16 ||
drm_rect_height(&sprstate->dst) != drm_rect_height(&sprstate->src) >> 16);
}
usable_level = max_level;
/* ILK/SNB: LP2+ watermarks only w/o sprites */
if (INTEL_INFO(dev)->gen <= 6 && sprstate->visible)
if (INTEL_INFO(dev)->gen <= 6 && pipe_wm->sprites_enabled)
usable_level = 1;
/* ILK/SNB/IVB: LP1+ watermarks only w/o scaling */