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

@ -631,8 +631,7 @@ struct drm_i915_display_funcs {
int target, int refclk,
struct dpll *match_clock,
struct dpll *best_clock);
int (*compute_pipe_wm)(struct intel_crtc *crtc,
struct drm_atomic_state *state);
int (*compute_pipe_wm)(struct intel_crtc_state *cstate);
int (*compute_intermediate_wm)(struct drm_device *dev,
struct intel_crtc *intel_crtc,
struct intel_crtc_state *newstate);

View File

@ -12106,7 +12106,7 @@ static int intel_crtc_atomic_check(struct drm_crtc *crtc,
ret = 0;
if (dev_priv->display.compute_pipe_wm) {
ret = dev_priv->display.compute_pipe_wm(intel_crtc, state);
ret = dev_priv->display.compute_pipe_wm(pipe_config);
if (ret) {
DRM_DEBUG_KMS("Target pipe watermarks are invalid\n");
return ret;

View File

@ -1628,6 +1628,18 @@ intel_atomic_get_crtc_state(struct drm_atomic_state *state,
return to_intel_crtc_state(crtc_state);
}
static inline struct intel_plane_state *
intel_atomic_get_existing_plane_state(struct drm_atomic_state *state,
struct intel_plane *plane)
{
struct drm_plane_state *plane_state;
plane_state = drm_atomic_get_existing_plane_state(state, &plane->base);
return to_intel_plane_state(plane_state);
}
int intel_atomic_setup_scalers(struct drm_device *dev,
struct intel_crtc *intel_crtc,
struct intel_crtc_state *crtc_state);

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 */