[PATCH 11/16] drm/i915/gen9: Allow watermark calculation on in-flight atomic state

Matt Roper
2016-04-01T01:47:48Z

In an upcoming patch we'll move this calculation to the atomic 'check'
phase so that the display update can be rejected early if no valid
watermark programming is possible.

Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
---
drivers/gpu/drm/i915/intel_drv.h | 21 +++++++++++++++++++++
drivers/gpu/drm/i915/intel_pm.c | 31 +++++++++++++++++++------------
2 files changed, 40 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 483261c..6471f69 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -1667,6 +1667,27 @@ intel_atomic_get_existing_plane_state(struct drm_atomic_state *state,
return to_intel_plane_state(plane_state);
}

+/*
+ * If cstate is in-flight, return in-flight plane state, otherwise
+ * return committed plane state.
+ */
+static inline struct intel_plane_state *
+intel_pstate_for_cstate_plane(struct intel_crtc_state *cstate,
+ struct intel_plane *plane)
+{
+ struct drm_atomic_state *state = cstate->base.state;
+ struct drm_plane_state *pstate;
+
+ if (state == NULL)
+ return to_intel_plane_state(plane->base.state);
+
+ pstate = drm_atomic_get_plane_state(state, &plane->base);
+
+ return to_intel_plane_state(pstate);
+}
+
+
+
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 6aafbb1..0a7f4d7 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -3293,11 +3293,12 @@ static bool skl_compute_plane_wm(const struct drm_i915_private *dev_priv,
return true;
}

-static void skl_compute_wm_level(const struct drm_i915_private *dev_priv,
- struct skl_ddb_allocation *ddb,
- struct intel_crtc_state *cstate,
- int level,
- struct skl_wm_level *result)
+static int
+skl_compute_wm_level(const struct drm_i915_private *dev_priv,
+ struct skl_ddb_allocation *ddb,
+ struct intel_crtc_state *cstate,
+ int level,
+ struct skl_wm_level *result)
{
struct drm_device *dev = dev_priv->dev;
struct intel_crtc *intel_crtc = to_intel_crtc(cstate->base.crtc);
@@ -3309,7 +3310,11 @@ static void skl_compute_wm_level(const struct drm_i915_private *dev_priv,
for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane) {
int i = skl_wm_plane_id(intel_plane);

- intel_pstate = to_intel_plane_state(intel_plane->base.state);
+ intel_pstate = intel_pstate_for_cstate_plane(cstate,
+ intel_plane);
+ if (IS_ERR(intel_pstate))
+ return PTR_ERR(intel_pstate);
+
ddb_blocks = skl_ddb_entry_size(&ddb->plane[pipe][i]);

result->plane_en[i] = skl_compute_plane_wm(dev_priv,
@@ -3320,6 +3325,8 @@ static void skl_compute_wm_level(const struct drm_i915_private *dev_priv,
&result->plane_res_b[i],
&result->plane_res_l[i]);
}
+
+ return 0;
}

static uint32_t
@@ -3614,14 +3621,14 @@ static void skl_flush_wm_values(struct drm_i915_private *dev_priv,
}
}

-static bool skl_update_pipe_wm(struct drm_crtc *crtc,
+static bool skl_update_pipe_wm(struct drm_crtc_state *cstate,
struct skl_ddb_allocation *ddb, /* out */
struct skl_pipe_wm *pipe_wm /* out */)
{
- struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
- struct intel_crtc_state *cstate = to_intel_crtc_state(crtc->state);
+ struct intel_crtc *intel_crtc = to_intel_crtc(cstate->crtc);
+ struct intel_crtc_state *intel_cstate = to_intel_crtc_state(cstate);

- skl_build_pipe_wm(cstate, ddb, pipe_wm);
+ skl_build_pipe_wm(intel_cstate, ddb, pipe_wm);

if (!memcmp(&intel_crtc->wm.active.skl, pipe_wm, sizeof(*pipe_wm)))
return false;
@@ -3661,7 +3668,7 @@ static void skl_update_other_pipe_wm(struct drm_device *dev,
if (!intel_crtc->active)
continue;

- wm_changed = skl_update_pipe_wm(&intel_crtc->base,
+ wm_changed = skl_update_pipe_wm(intel_crtc->base.state,
&r->ddb, &pipe_wm);

/*
@@ -3753,7 +3760,7 @@ static void skl_update_wm(struct drm_crtc *crtc)

skl_clear_wm(results, intel_crtc->pipe);

- if (!skl_update_pipe_wm(crtc, &results->ddb, pipe_wm))
+ if (!skl_update_pipe_wm(crtc->state, &results->ddb, pipe_wm))
return;

skl_compute_wm_results(dev, pipe_wm, results, intel_crtc);