drm/i915: Only recalculate wm's for planes part of the state, v2.
authorMaarten Lankhorst <maarten.lankhorst@linux.intel.com>
Tue, 1 Mar 2016 10:07:22 +0000 (11:07 +0100)
committerMaarten Lankhorst <maarten.lankhorst@linux.intel.com>
Thu, 3 Mar 2016 08:20:39 +0000 (09:20 +0100)
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>
drivers/gpu/drm/i915/i915_drv.h
drivers/gpu/drm/i915/intel_display.c
drivers/gpu/drm/i915/intel_drv.h
drivers/gpu/drm/i915/intel_pm.c

index 2cb0a41..c8791f6 100644 (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);
index 44fcff0..08c3631 100644 (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;
index cb413e2..6c00854 100644 (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);
index 161c66b..f65e841 100644 (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 */