In preparation for refactoring watermark computation out to the atomic
'check' phase, we need to allow that computation to operate on the
in-flight state stored in a drm_atomic_state, rather than
already-committed CRTC and plane states (eventually the drm_atomic_state
should be the only source, but we allow both approaches at the moment as
we transition).

While we're at it, s/intel_compute_pipe_wm/ilk_compute_pipe_wm/ since
this function only applies to ILK-style watermarks and we have a
completely different function for SKL-style watermarks.

Signed-off-by: Matt Roper <matthew.d.ro...@intel.com>
---
 drivers/gpu/drm/i915/intel_pm.c | 102 +++++++++++++++++++++++++---------------
 1 file changed, 64 insertions(+), 38 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index dbff278..c3b9f99 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -1772,9 +1772,11 @@ static void ilk_compute_wm_level(const struct 
drm_i915_private *dev_priv,
                                 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,
                                 struct intel_wm_level *result)
 {
-       struct intel_plane *intel_plane;
        uint16_t pri_latency = dev_priv->wm.pri_latency[level];
        uint16_t spr_latency = dev_priv->wm.spr_latency[level];
        uint16_t cur_latency = dev_priv->wm.cur_latency[level];
@@ -1786,29 +1788,11 @@ static void ilk_compute_wm_level(const struct 
drm_i915_private *dev_priv,
                cur_latency *= 5;
        }
 
-       for_each_intel_plane_of_crtc(intel_crtc, intel_plane) {
-               struct intel_plane_state *pstate =
-                       to_intel_plane_state(intel_plane->base.state);
-
-               switch (intel_plane->base.type) {
-               case DRM_PLANE_TYPE_PRIMARY:
-                       result->pri_val = ilk_compute_pri_wm(cstate, pstate,
-                                                            pri_latency,
-                                                            level);
-                       result->fbc_val = ilk_compute_fbc_wm(cstate, pstate,
-                                                            result->pri_val);
-                       break;
-               case DRM_PLANE_TYPE_OVERLAY:
-                       result->spr_val = ilk_compute_spr_wm(cstate, pstate,
-                                                            spr_latency);
-                       break;
-               case DRM_PLANE_TYPE_CURSOR:
-                       result->cur_val = ilk_compute_cur_wm(cstate, pstate,
-                                                            cur_latency);
-                       break;
-               }
-       }
-
+       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);
        result->enable = true;
 }
 
@@ -2086,15 +2070,20 @@ static void ilk_compute_wm_config(struct drm_device 
*dev,
 }
 
 /* Compute new watermarks for the pipe */
-static bool intel_compute_pipe_wm(struct intel_crtc_state *cstate,
-                                 struct intel_pipe_wm *pipe_wm)
+static int ilk_compute_pipe_wm(struct drm_crtc *crtc,
+                              struct drm_atomic_state *state,
+                              struct intel_pipe_wm *pipe_wm)
 {
-       struct drm_crtc *crtc = cstate->base.crtc;
        struct drm_device *dev = crtc->dev;
        const struct drm_i915_private *dev_priv = dev->dev_private;
        struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+       struct drm_crtc_state *cs;
+       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);
        /* LP0 watermark maximums depend on this pipe alone */
        struct intel_wm_config config = {
@@ -2102,11 +2091,47 @@ static bool intel_compute_pipe_wm(struct 
intel_crtc_state *cstate,
        };
        struct ilk_wm_maximums max;
 
-       for_each_intel_plane_of_crtc(intel_crtc, intel_plane) {
-               if (intel_plane->base.type == DRM_PLANE_TYPE_OVERLAY) {
-                       sprstate = 
to_intel_plane_state(intel_plane->base.state);
-                       break;
+       /*
+        * FIXME: In an upcoming patch, we'll *only* be calling this from the
+        * atomic 'check' codepath and thus will always have a top-level atomic
+        * transaction.  However at the moment we still call this in the legacy
+        * 'ilk_update_wm' function, which means we need to be able to also
+        * operate on already-committed state which has been detached from any
+        * top-level transaction.
+        *
+        * Drop the 'else' block here once we only do atomic-style watermarks.
+        */
+       if (state) {
+               cs = drm_atomic_get_crtc_state(state, crtc);
+               if (IS_ERR(cs))
+                       return PTR_ERR(cs);
+               else
+                       cstate = to_intel_crtc_state(cs);
+
+               for_each_intel_plane_of_crtc(intel_crtc, intel_plane) {
+                       ps = drm_atomic_get_plane_state(state,
+                                                       &intel_plane->base);
+                       if (IS_ERR(ps))
+                               return PTR_ERR(ps);
+
+                       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);
+               }
+       } else {
+               /* Use already-committed state */
+               cstate = to_intel_crtc_state(crtc->state);
+               for_each_intel_plane_of_crtc(intel_crtc, intel_plane) {
+                       if (intel_plane->base.type == DRM_PLANE_TYPE_OVERLAY) {
+                               sprstate = 
to_intel_plane_state(intel_plane->base.state);
+                               break;
+                       }
                }
+               pristate = to_intel_plane_state(crtc->primary->state);
+               curstate = to_intel_plane_state(crtc->cursor->state);
        }
 
        config.sprites_enabled = sprstate->visible;
@@ -2115,7 +2140,7 @@ static bool intel_compute_pipe_wm(struct intel_crtc_state 
*cstate,
                drm_rect_height(&sprstate->dst) != 
drm_rect_height(&sprstate->src) >> 16;
 
        pipe_wm->pipe_enabled = cstate->base.active;
-       pipe_wm->sprites_enabled = sprstate->visible;
+       pipe_wm->sprites_enabled = config.sprites_enabled;
        pipe_wm->sprites_scaled = config.sprites_scaled;
 
        /* ILK/SNB: LP2+ watermarks only w/o sprites */
@@ -2126,7 +2151,8 @@ static bool intel_compute_pipe_wm(struct intel_crtc_state 
*cstate,
        if (config.sprites_scaled)
                max_level = 0;
 
-       ilk_compute_wm_level(dev_priv, intel_crtc, 0, cstate, &pipe_wm->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(dev, crtc);
@@ -2136,14 +2162,15 @@ static bool intel_compute_pipe_wm(struct 
intel_crtc_state *cstate,
 
        /* At least LP0 must be valid */
        if (!ilk_validate_wm_level(0, &max, &pipe_wm->wm[0]))
-               return false;
+               return -EINVAL;
 
        ilk_compute_wm_reg_maximums(dev, 1, &max);
 
        for (level = 1; level <= max_level; level++) {
                struct intel_wm_level wm = {};
 
-               ilk_compute_wm_level(dev_priv, intel_crtc, level, cstate, &wm);
+               ilk_compute_wm_level(dev_priv, intel_crtc, level, cstate,
+                                    pristate, sprstate, curstate, &wm);
 
                /*
                 * Disable any watermark level that exceeds the
@@ -2156,7 +2183,7 @@ static bool intel_compute_pipe_wm(struct intel_crtc_state 
*cstate,
                pipe_wm->wm[level] = wm;
        }
 
-       return true;
+       return 0;
 }
 
 /*
@@ -3479,10 +3506,9 @@ static void ilk_update_wm(struct drm_crtc *crtc)
 {
        struct drm_i915_private *dev_priv = to_i915(crtc->dev);
        struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
-       struct intel_crtc_state *cstate = to_intel_crtc_state(crtc->state);
        struct intel_pipe_wm pipe_wm = {};
 
-       intel_compute_pipe_wm(cstate, &pipe_wm);
+       ilk_compute_pipe_wm(crtc, NULL, &pipe_wm);
 
        if (!memcmp(&intel_crtc->wm.active, &pipe_wm, sizeof(pipe_wm)))
                return;
-- 
1.8.5.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

Reply via email to