diff mbox

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

Message ID 1459475198-30094-12-git-send-email-matthew.d.roper@intel.com (mailing list archive)
State New, archived
Headers show

Commit Message

Matt Roper April 1, 2016, 1:46 a.m. UTC
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(-)

Comments

Maarten Lankhorst April 5, 2016, 9:52 a.m. UTC | #1
Op 01-04-16 om 03:46 schreef Matt Roper:
> 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);
> +}
> +
Don't create a helper please, this should only be done when transitioning code situations.

plane->base.state might not be the right state when we support more than 1 pending atomic commit.

~Maarten
diff mbox

Patch

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);