| From 8777b927b92cf5b6c29f9f9d3c737addea9ac8a7 Mon Sep 17 00:00:00 2001 |
| From: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> |
| Date: Thu, 19 Oct 2017 17:13:40 +0200 |
| Subject: drm/i915: Do not rely on wm preservation for ILK watermarks |
| MIME-Version: 1.0 |
| Content-Type: text/plain; charset=UTF-8 |
| Content-Transfer-Encoding: 8bit |
| |
| From: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> |
| |
| commit 8777b927b92cf5b6c29f9f9d3c737addea9ac8a7 upstream. |
| |
| The original intent was to preserve watermarks as much as possible |
| in intel_pipe_wm.raw_wm, and put the validated ones in intel_pipe_wm.wm. |
| |
| It seems this approach is insufficient and we don't always preserve |
| the raw watermarks, so just use the atomic iterator we're already using |
| to get a const pointer to all bound planes on the crtc. |
| |
| Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=102373 |
| Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> |
| Acked-by: Ville Syrjälä <ville.syrjala@linux.intel.com> |
| Reviewed-by: Matt Roper <matthew.d.roper@intel.com> |
| Link: https://patchwork.freedesktop.org/patch/msgid/20171019151341.4579-1-maarten.lankhorst@linux.intel.com |
| (cherry picked from commit 28283f4f359cd7cfa9e65457bb98c507a2cd0cd0) |
| Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| drivers/gpu/drm/i915/intel_drv.h | 1 |
| drivers/gpu/drm/i915/intel_pm.c | 52 ++++++++++++++++----------------------- |
| 2 files changed, 22 insertions(+), 31 deletions(-) |
| |
| --- a/drivers/gpu/drm/i915/intel_drv.h |
| +++ b/drivers/gpu/drm/i915/intel_drv.h |
| @@ -457,7 +457,6 @@ 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,6 +27,7 @@ |
| |
| #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" |
| @@ -2017,9 +2018,9 @@ static void ilk_compute_wm_level(const s |
| const struct intel_crtc *intel_crtc, |
| int level, |
| struct intel_crtc_state *cstate, |
| - struct intel_plane_state *pristate, |
| - struct intel_plane_state *sprstate, |
| - struct intel_plane_state *curstate, |
| + const struct intel_plane_state *pristate, |
| + const struct intel_plane_state *sprstate, |
| + const struct intel_plane_state *curstate, |
| struct intel_wm_level *result) |
| { |
| uint16_t pri_latency = dev_priv->wm.pri_latency[level]; |
| @@ -2341,28 +2342,24 @@ 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 intel_plane *intel_plane; |
| - struct intel_plane_state *pristate = NULL; |
| - struct intel_plane_state *sprstate = NULL; |
| - struct intel_plane_state *curstate = NULL; |
| + 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; |
| int level, max_level = ilk_wm_max_level(dev), usable_level; |
| struct ilk_wm_maximums max; |
| |
| pipe_wm = &cstate->wm.ilk.optimal; |
| |
| - for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane) { |
| - struct intel_plane_state *ps; |
| + 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); |
| |
| - ps = intel_atomic_get_existing_plane_state(state, |
| - intel_plane); |
| - if (!ps) |
| - continue; |
| - |
| - if (intel_plane->base.type == DRM_PLANE_TYPE_PRIMARY) |
| + if (plane->type == DRM_PLANE_TYPE_PRIMARY) |
| pristate = ps; |
| - else if (intel_plane->base.type == DRM_PLANE_TYPE_OVERLAY) |
| + else if (plane->type == DRM_PLANE_TYPE_OVERLAY) |
| sprstate = ps; |
| - else if (intel_plane->base.type == DRM_PLANE_TYPE_CURSOR) |
| + else if (plane->type == DRM_PLANE_TYPE_CURSOR) |
| curstate = ps; |
| } |
| |
| @@ -2384,11 +2381,9 @@ static int ilk_compute_pipe_wm(struct in |
| if (pipe_wm->sprites_scaled) |
| usable_level = 0; |
| |
| - ilk_compute_wm_level(dev_priv, intel_crtc, 0, cstate, |
| - 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]; |
| + ilk_compute_wm_level(dev_priv, intel_crtc, 0, cstate, |
| + pristate, sprstate, curstate, &pipe_wm->wm[0]); |
| |
| if (IS_HASWELL(dev) || IS_BROADWELL(dev)) |
| pipe_wm->linetime = hsw_compute_linetime_wm(cstate); |
| @@ -2398,8 +2393,8 @@ static int ilk_compute_pipe_wm(struct in |
| |
| ilk_compute_wm_reg_maximums(dev, 1, &max); |
| |
| - for (level = 1; level <= max_level; level++) { |
| - struct intel_wm_level *wm = &pipe_wm->raw_wm[level]; |
| + for (level = 1; level <= usable_level; level++) { |
| + struct intel_wm_level *wm = &pipe_wm->wm[level]; |
| |
| ilk_compute_wm_level(dev_priv, intel_crtc, level, cstate, |
| pristate, sprstate, curstate, wm); |
| @@ -2409,13 +2404,10 @@ static int ilk_compute_pipe_wm(struct in |
| * register maximums since such watermarks are |
| * always invalid. |
| */ |
| - if (level > usable_level) |
| - continue; |
| - |
| - if (ilk_validate_wm_level(level, &max, wm)) |
| - pipe_wm->wm[level] = *wm; |
| - else |
| - usable_level = level; |
| + if (!ilk_validate_wm_level(level, &max, wm)) { |
| + memset(wm, 0, sizeof(*wm)); |
| + break; |
| + } |
| } |
| |
| return 0; |