This should not be done this late when nothing changed. Signed-off-by: Maarten Lankhorst <maarten.lankhorst@xxxxxxxxxxxxxxx> --- drivers/gpu/drm/i915/intel_display.c | 3 +- drivers/gpu/drm/i915/intel_drv.h | 13 ++++++++ drivers/gpu/drm/i915/intel_pm.c | 59 +++++++++++++++++++++--------------- 3 files changed, 49 insertions(+), 26 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index c3aa1d5bd23f..a8285fe429e1 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -12029,7 +12029,8 @@ static int intel_crtc_atomic_check(struct drm_crtc *crtc, } ret = 0; - if (dev_priv->display.compute_pipe_wm) { + if (dev_priv->display.compute_pipe_wm && + (mode_changed || pipe_config->update_pipe || crtc_state->planes_changed)) { ret = dev_priv->display.compute_pipe_wm(intel_crtc, state); if (ret) { DRM_DEBUG_KMS("Target pipe watermarks are invalid\n"); diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index ec89659e5d0d..1fea7a1a3ed1 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -1606,6 +1606,19 @@ 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); diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 9df9e9a22f3c..482c684a116b 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -2005,11 +2005,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; } @@ -2305,7 +2312,6 @@ static int ilk_compute_pipe_wm(struct intel_crtc *intel_crtc, 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; @@ -2319,27 +2325,32 @@ static int ilk_compute_pipe_wm(struct intel_crtc *intel_crtc, 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); - else if (intel_plane->base.type == DRM_PLANE_TYPE_OVERLAY) - sprstate = to_intel_plane_state(ps); - else if (intel_plane->base.type == DRM_PLANE_TYPE_CURSOR) - curstate = to_intel_plane_state(ps); + pristate = ps; + else if (intel_plane->base.type == DRM_PLANE_TYPE_OVERLAY) { + sprstate = ps; + + if (ps) { + 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); + } + } else if (intel_plane->base.type == DRM_PLANE_TYPE_CURSOR) + 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); /* 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) max_level = 1; /* ILK/SNB/IVB: LP1+ watermarks only w/o scaling */ @@ -2358,20 +2369,18 @@ static int ilk_compute_pipe_wm(struct intel_crtc *intel_crtc, ilk_compute_wm_reg_maximums(dev, 1, &max); for (level = 1; level <= max_level; level++) { - struct intel_wm_level wm = {}; + struct intel_wm_level *wm = &pipe_wm->wm[level]; ilk_compute_wm_level(dev_priv, intel_crtc, level, cstate, - pristate, sprstate, curstate, &wm); + pristate, sprstate, curstate, wm); /* * Disable any watermark level that exceeds the * register maximums since such watermarks are * always invalid. */ - if (!ilk_validate_wm_level(level, &max, &wm)) + if (!ilk_validate_wm_level(level, &max, wm)) break; - - pipe_wm->wm[level] = wm; } return 0; -- 2.1.0 _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/intel-gfx