Greg Kroah-Hartman wrote: > 4.9-stable review patch. If anyone has any objections, please let me know. > > ------------------ > > This reverts commit 7de694782cbe7840f2c0de6f1e70f41fc1b8b6e8 which is > commit 8777b927b92cf5b6c29f9f9d3c737addea9ac8a7 upstream. > > It was reported to cause flickering and other regressions. > > Reported-by: Rainer Fiebig <jrf@xxxxxxxxxxx> > Cc: Maarten Lankhorst <maarten.lankhorst@xxxxxxxxxxxxxxx> > Cc: Ville Syrjälä <ville.syrjala@xxxxxxxxxxxxxxx> > Cc: Matt Roper <matthew.d.roper@xxxxxxxxx> > Cc: Rodrigo Vivi <rodrigo.vivi@xxxxxxxxx> > Cc: Jani Nikula <jani.nikula@xxxxxxxxxxxxxxx> > Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx> > > reverted: > --- > drivers/gpu/drm/i915/intel_drv.h | 1 > drivers/gpu/drm/i915/intel_pm.c | 52 ++++++++++++++++++++++----------------- > 2 files changed, 31 insertions(+), 22 deletions(-) > > --- a/drivers/gpu/drm/i915/intel_drv.h > +++ b/drivers/gpu/drm/i915/intel_drv.h > @@ -457,6 +457,7 @@ struct intel_crtc_scaler_state { > > struct intel_pipe_wm { > struct intel_wm_level wm[5]; > + struct intel_wm_level raw_wm[5]; > uint32_t linetime; > bool fbc_wm_enabled; > bool pipe_enabled; > --- a/drivers/gpu/drm/i915/intel_pm.c > +++ b/drivers/gpu/drm/i915/intel_pm.c > @@ -27,7 +27,6 @@ > > #include <linux/cpufreq.h> > #include <drm/drm_plane_helper.h> > -#include <drm/drm_atomic_helper.h> > #include "i915_drv.h" > #include "intel_drv.h" > #include "../../../platform/x86/intel_ips.h" > @@ -2018,9 +2017,9 @@ static void ilk_compute_wm_level(const s > const struct intel_crtc *intel_crtc, > int level, > struct intel_crtc_state *cstate, > - const struct intel_plane_state *pristate, > - const struct intel_plane_state *sprstate, > - const struct intel_plane_state *curstate, > + struct intel_plane_state *pristate, > + struct intel_plane_state *sprstate, > + struct intel_plane_state *curstate, > struct intel_wm_level *result) > { > uint16_t pri_latency = dev_priv->wm.pri_latency[level]; > @@ -2342,24 +2341,28 @@ static int ilk_compute_pipe_wm(struct in > struct intel_pipe_wm *pipe_wm; > struct drm_device *dev = state->dev; > const struct drm_i915_private *dev_priv = to_i915(dev); > - struct drm_plane *plane; > - const struct drm_plane_state *plane_state; > - const struct intel_plane_state *pristate = NULL; > - const struct intel_plane_state *sprstate = NULL; > - const struct intel_plane_state *curstate = NULL; > + struct intel_plane *intel_plane; > + 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; > > pipe_wm = &cstate->wm.ilk.optimal; > > - drm_atomic_crtc_state_for_each_plane_state(plane, plane_state, &cstate->base) { > - const struct intel_plane_state *ps = to_intel_plane_state(plane_state); > + for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane) { > + struct intel_plane_state *ps; > > - if (plane->type == DRM_PLANE_TYPE_PRIMARY) > + ps = intel_atomic_get_existing_plane_state(state, > + intel_plane); > + if (!ps) > + continue; > + > + if (intel_plane->base.type == DRM_PLANE_TYPE_PRIMARY) > pristate = ps; > - else if (plane->type == DRM_PLANE_TYPE_OVERLAY) > + else if (intel_plane->base.type == DRM_PLANE_TYPE_OVERLAY) > sprstate = ps; > - else if (plane->type == DRM_PLANE_TYPE_CURSOR) > + else if (intel_plane->base.type == DRM_PLANE_TYPE_CURSOR) > curstate = ps; > } > > @@ -2381,9 +2384,11 @@ static int ilk_compute_pipe_wm(struct in > if (pipe_wm->sprites_scaled) > usable_level = 0; > > - memset(&pipe_wm->wm, 0, sizeof(pipe_wm->wm)); > ilk_compute_wm_level(dev_priv, intel_crtc, 0, cstate, > - pristate, sprstate, curstate, &pipe_wm->wm[0]); > + pristate, sprstate, curstate, &pipe_wm->raw_wm[0]); > + > + memset(&pipe_wm->wm, 0, sizeof(pipe_wm->wm)); > + pipe_wm->wm[0] = pipe_wm->raw_wm[0]; > > if (IS_HASWELL(dev) || IS_BROADWELL(dev)) > pipe_wm->linetime = hsw_compute_linetime_wm(cstate); > @@ -2393,8 +2398,8 @@ static int ilk_compute_pipe_wm(struct in > > ilk_compute_wm_reg_maximums(dev, 1, &max); > > - for (level = 1; level <= usable_level; level++) { > - struct intel_wm_level *wm = &pipe_wm->wm[level]; > + for (level = 1; level <= max_level; level++) { > + struct intel_wm_level *wm = &pipe_wm->raw_wm[level]; > > ilk_compute_wm_level(dev_priv, intel_crtc, level, cstate, > pristate, sprstate, curstate, wm); > @@ -2404,10 +2409,13 @@ static int ilk_compute_pipe_wm(struct in > * register maximums since such watermarks are > * always invalid. > */ > - if (!ilk_validate_wm_level(level, &max, wm)) { > - memset(wm, 0, sizeof(*wm)); > - break; > - } > + if (level > usable_level) > + continue; > + > + if (ilk_validate_wm_level(level, &max, wm)) > + pipe_wm->wm[level] = *wm; > + else > + usable_level = level; > } > > return 0; > > Applied it to 4.9.65 and all's nice again. Thanks. Rainer Fiebig