132 lines
4.8 KiB
Diff
132 lines
4.8 KiB
Diff
|
From 2bf927b92091d11f778a2a972b996f24a63281be Mon Sep 17 00:00:00 2001
|
||
|
From: Matt Roper <matthew.d.roper@intel.com>
|
||
|
Date: Thu, 12 May 2016 07:05:58 -0700
|
||
|
Subject: [PATCH 04/17] drm/i915/gen9: Allow calculation of data rate for
|
||
|
in-flight state (v2)
|
||
|
|
||
|
Our skl_get_total_relative_data_rate() function gets passed a crtc state
|
||
|
object to calculate the data rate for, but it currently always looks
|
||
|
up the committed plane states that correspond to that CRTC. Let's
|
||
|
check whether the CRTC state is an in-flight state (meaning
|
||
|
cstate->state is non-NULL) and if so, use the corresponding in-flight
|
||
|
plane states.
|
||
|
|
||
|
We'll soon be using this function exclusively for in-flight states; at
|
||
|
that time we'll be able to simplify the function a bit, but for now we
|
||
|
allow it to be used in either mode.
|
||
|
|
||
|
v2:
|
||
|
- Rebase on top of changes to cache plane data rates.
|
||
|
|
||
|
Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
|
||
|
Reviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
|
||
|
Link: http://patchwork.freedesktop.org/patch/msgid/1463061971-19638-5-git-send-email-matthew.d.roper@intel.com
|
||
|
---
|
||
|
drivers/gpu/drm/i915/intel_pm.c | 74 +++++++++++++++++++++++++++++++++--------
|
||
|
1 file changed, 60 insertions(+), 14 deletions(-)
|
||
|
|
||
|
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
|
||
|
index 6835614..5104ba7 100644
|
||
|
--- a/drivers/gpu/drm/i915/intel_pm.c
|
||
|
+++ b/drivers/gpu/drm/i915/intel_pm.c
|
||
|
@@ -2975,25 +2975,69 @@ skl_plane_relative_data_rate(const struct intel_crtc_state *cstate,
|
||
|
* 3 * 4096 * 8192 * 4 < 2^32
|
||
|
*/
|
||
|
static unsigned int
|
||
|
-skl_get_total_relative_data_rate(struct intel_crtc_state *cstate)
|
||
|
+skl_get_total_relative_data_rate(struct intel_crtc_state *intel_cstate)
|
||
|
{
|
||
|
- struct intel_crtc *intel_crtc = to_intel_crtc(cstate->base.crtc);
|
||
|
- struct drm_device *dev = intel_crtc->base.dev;
|
||
|
+ struct drm_crtc_state *cstate = &intel_cstate->base;
|
||
|
+ struct drm_atomic_state *state = cstate->state;
|
||
|
+ struct drm_crtc *crtc = cstate->crtc;
|
||
|
+ struct drm_device *dev = crtc->dev;
|
||
|
+ struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
|
||
|
const struct intel_plane *intel_plane;
|
||
|
unsigned int rate, total_data_rate = 0;
|
||
|
+ int id;
|
||
|
|
||
|
/* Calculate and cache data rate for each plane */
|
||
|
- for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane) {
|
||
|
- const struct drm_plane_state *pstate = intel_plane->base.state;
|
||
|
- int id = skl_wm_plane_id(intel_plane);
|
||
|
+ /*
|
||
|
+ * FIXME: At the moment this function can be called on either an
|
||
|
+ * in-flight or a committed state object. If it's in-flight then we
|
||
|
+ * only want to re-calculate the plane data rate for planes that are
|
||
|
+ * part of the transaction (i.e., we don't want to grab any additional
|
||
|
+ * plane states if we don't have to). If we're operating on committed
|
||
|
+ * state, we'll just go ahead and recalculate the plane data rate for
|
||
|
+ * all planes.
|
||
|
+ *
|
||
|
+ * Once we finish moving our DDB allocation to the atomic check phase,
|
||
|
+ * we'll only be calling this function on in-flight state objects, so
|
||
|
+ * the 'else' branch here will go away.
|
||
|
+ */
|
||
|
+ if (state) {
|
||
|
+ struct drm_plane *plane;
|
||
|
+ struct drm_plane_state *pstate;
|
||
|
+ int i;
|
||
|
+
|
||
|
+ for_each_plane_in_state(state, plane, pstate, i) {
|
||
|
+ intel_plane = to_intel_plane(plane);
|
||
|
+ id = skl_wm_plane_id(intel_plane);
|
||
|
+
|
||
|
+ if (intel_plane->pipe != intel_crtc->pipe)
|
||
|
+ continue;
|
||
|
+
|
||
|
+ /* packed/uv */
|
||
|
+ rate = skl_plane_relative_data_rate(intel_cstate,
|
||
|
+ pstate, 0);
|
||
|
+ intel_cstate->wm.skl.plane_data_rate[id] = rate;
|
||
|
+
|
||
|
+ /* y-plane */
|
||
|
+ rate = skl_plane_relative_data_rate(intel_cstate,
|
||
|
+ pstate, 1);
|
||
|
+ intel_cstate->wm.skl.plane_y_data_rate[id] = rate;
|
||
|
+ }
|
||
|
+ } else {
|
||
|
+ for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane) {
|
||
|
+ const struct drm_plane_state *pstate =
|
||
|
+ intel_plane->base.state;
|
||
|
+ int id = skl_wm_plane_id(intel_plane);
|
||
|
|
||
|
- /* packed/uv */
|
||
|
- rate = skl_plane_relative_data_rate(cstate, pstate, 0);
|
||
|
- cstate->wm.skl.plane_data_rate[id] = rate;
|
||
|
+ /* packed/uv */
|
||
|
+ rate = skl_plane_relative_data_rate(intel_cstate,
|
||
|
+ pstate, 0);
|
||
|
+ intel_cstate->wm.skl.plane_data_rate[id] = rate;
|
||
|
|
||
|
- /* y-plane */
|
||
|
- rate = skl_plane_relative_data_rate(cstate, pstate, 1);
|
||
|
- cstate->wm.skl.plane_y_data_rate[id] = rate;
|
||
|
+ /* y-plane */
|
||
|
+ rate = skl_plane_relative_data_rate(intel_cstate,
|
||
|
+ pstate, 1);
|
||
|
+ intel_cstate->wm.skl.plane_y_data_rate[id] = rate;
|
||
|
+ }
|
||
|
}
|
||
|
|
||
|
/* Calculate CRTC's total data rate from cached values */
|
||
|
@@ -3001,10 +3045,12 @@ skl_get_total_relative_data_rate(struct intel_crtc_state *cstate)
|
||
|
int id = skl_wm_plane_id(intel_plane);
|
||
|
|
||
|
/* packed/uv */
|
||
|
- total_data_rate += cstate->wm.skl.plane_data_rate[id];
|
||
|
- total_data_rate += cstate->wm.skl.plane_y_data_rate[id];
|
||
|
+ total_data_rate += intel_cstate->wm.skl.plane_data_rate[id];
|
||
|
+ total_data_rate += intel_cstate->wm.skl.plane_y_data_rate[id];
|
||
|
}
|
||
|
|
||
|
+ WARN_ON(cstate->plane_mask && total_data_rate == 0);
|
||
|
+
|
||
|
return total_data_rate;
|
||
|
}
|
||
|
|
||
|
--
|
||
|
2.7.4
|
||
|
|