Commit e3bddded authored by Maarten Lankhorst's avatar Maarten Lankhorst

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: default avatarMaarten 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.comReviewed-by: default avatarPaulo Zanoni <paulo.r.zanoni@intel.com>
parent d81f04c5
......@@ -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);
......
......@@ -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;
......
......@@ -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);
......
......@@ -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 */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment