0903551
From 6a86f1d01bb25a687c59dd6b3e6deea362cf0ee1 Mon Sep 17 00:00:00 2001
0903551
From: Fedora Kernel Team <kernel-team@fedoraproject.org>
0903551
Date: Mon, 20 Jun 2016 12:40:40 +0200
0903551
Subject: [PATCH 10/17] drm/i915/gen9: Drop re-allocation of DDB at atomic
0903551
 commit (v2)
0903551
0903551
Upstream: since drm-intel-next-2016-05-22
0903551
commit a6d3460e62d17098a815a53f23e44d814cb347e0
0903551
0903551
Author:     Matt Roper <matthew.d.roper@intel.com>
0903551
AuthorDate: Thu May 12 07:06:04 2016 -0700
0903551
Commit:     Matt Roper <matthew.d.roper@intel.com>
0903551
CommitDate: Fri May 13 07:34:06 2016 -0700
0903551
0903551
    drm/i915/gen9: Drop re-allocation of DDB at atomic commit (v2)
0903551
0903551
    Now that we're properly pre-allocating the DDB during the atomic check
0903551
    phase and we trust that the allocation is appropriate, let's actually
0903551
    use the allocation computed and not duplicate that work during the
0903551
    commit phase.
0903551
0903551
    v2:
0903551
     - Significant rebasing now that we can use cached data rates and
0903551
       minimum block allocations to avoid grabbing additional plane states.
0903551
0903551
    Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
0903551
    Reviewed-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
0903551
    Link: http://patchwork.freedesktop.org/patch/msgid/1463061971-19638-11-git-send-email-matthew.d.roper@intel.com
0903551
---
0903551
 drivers/gpu/drm/i915/intel_display.c |  14 +--
0903551
 drivers/gpu/drm/i915/intel_pm.c      | 224 +++++++++++------------------------
0903551
 2 files changed, 67 insertions(+), 171 deletions(-)
0903551
0903551
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
0903551
index 03e2635..b484fda 100644
0903551
--- a/drivers/gpu/drm/i915/intel_display.c
0903551
+++ b/drivers/gpu/drm/i915/intel_display.c
0903551
@@ -13522,6 +13522,7 @@ static int intel_atomic_commit(struct drm_device *dev,
0903551
 	drm_atomic_helper_swap_state(dev, state);
0903551
 	dev_priv->wm.config = to_intel_atomic_state(state)->wm_config;
0903551
 	dev_priv->wm.distrust_bios_wm = false;
0903551
+	dev_priv->wm.skl_results.ddb = intel_state->ddb;
0903551
 
0903551
 	if (intel_state->modeset) {
0903551
 		memcpy(dev_priv->min_pixclk, intel_state->min_pixclk,
0903551
@@ -13621,19 +13622,6 @@ static int intel_atomic_commit(struct drm_device *dev,
0903551
 			modeset_put_power_domains(dev_priv, put_domains[i]);
0903551
 	}
0903551
 
0903551
-	/*
0903551
-	 * Temporary sanity check: make sure our pre-computed DDB matches the
0903551
-	 * one we actually wind up programming.
0903551
-	 *
0903551
-	 * Not a great place to put this, but the easiest place we have access
0903551
-	 * to both the pre-computed and final DDB's; we'll be removing this
0903551
-	 * check in the next patch anyway.
0903551
-	 */
0903551
-	WARN(IS_GEN9(dev) &&
0903551
-	     memcmp(&intel_state->ddb, &dev_priv->wm.skl_results.ddb,
0903551
-		    sizeof(intel_state->ddb)),
0903551
-	     "Pre-computed DDB does not match final DDB!\n");
0903551
-
0903551
 	if (intel_state->modeset)
0903551
 		intel_display_power_put(dev_priv, POWER_DOMAIN_MODESET);
0903551
 
0903551
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
0903551
index f60519d..80f9f18 100644
0903551
--- a/drivers/gpu/drm/i915/intel_pm.c
0903551
+++ b/drivers/gpu/drm/i915/intel_pm.c
0903551
@@ -2788,7 +2788,6 @@ skl_wm_plane_id(const struct intel_plane *plane)
0903551
 static void
0903551
 skl_ddb_get_pipe_allocation_limits(struct drm_device *dev,
0903551
 				   const struct intel_crtc_state *cstate,
0903551
-				   struct intel_wm_config *config,
0903551
 				   struct skl_ddb_entry *alloc, /* out */
0903551
 				   int *num_active /* out */)
0903551
 {
0903551
@@ -2796,24 +2795,22 @@ skl_ddb_get_pipe_allocation_limits(struct drm_device *dev,
0903551
 	struct intel_atomic_state *intel_state = to_intel_atomic_state(state);
0903551
 	struct drm_i915_private *dev_priv = to_i915(dev);
0903551
 	struct drm_crtc *for_crtc = cstate->base.crtc;
0903551
-	struct drm_crtc *crtc;
0903551
 	unsigned int pipe_size, ddb_size;
0903551
 	int nth_active_pipe;
0903551
 	int pipe = to_intel_crtc(for_crtc)->pipe;
0903551
 
0903551
-	if (intel_state && intel_state->active_pipe_changes)
0903551
-		*num_active = hweight32(intel_state->active_crtcs);
0903551
-	else if (intel_state)
0903551
-		*num_active = hweight32(dev_priv->active_crtcs);
0903551
-	else
0903551
-		*num_active = config->num_pipes_active;
0903551
-
0903551
-	if (!cstate->base.active) {
0903551
+	if (WARN_ON(!state) || !cstate->base.active) {
0903551
 		alloc->start = 0;
0903551
 		alloc->end = 0;
0903551
+		*num_active = hweight32(dev_priv->active_crtcs);
0903551
 		return;
0903551
 	}
0903551
 
0903551
+	if (intel_state->active_pipe_changes)
0903551
+		*num_active = hweight32(intel_state->active_crtcs);
0903551
+	else
0903551
+		*num_active = hweight32(dev_priv->active_crtcs);
0903551
+
0903551
 	if (IS_BROXTON(dev))
0903551
 		ddb_size = BXT_DDB_SIZE;
0903551
 	else
0903551
@@ -2822,50 +2819,23 @@ skl_ddb_get_pipe_allocation_limits(struct drm_device *dev,
0903551
 	ddb_size -= 4; /* 4 blocks for bypass path allocation */
0903551
 
0903551
 	/*
0903551
-	 * FIXME: At the moment we may be called on either in-flight or fully
0903551
-	 * committed cstate's.  Once we fully move DDB allocation in the check
0903551
-	 * phase, we'll only be called on in-flight states and the 'else'
0903551
-	 * branch here will go away.
0903551
-	 *
0903551
-	 * The 'else' branch is slightly racy here, but it was racy to begin
0903551
-	 * with; since it's going away soon, no effort is made to address that.
0903551
+	 * If the state doesn't change the active CRTC's, then there's
0903551
+	 * no need to recalculate; the existing pipe allocation limits
0903551
+	 * should remain unchanged.  Note that we're safe from racing
0903551
+	 * commits since any racing commit that changes the active CRTC
0903551
+	 * list would need to grab _all_ crtc locks, including the one
0903551
+	 * we currently hold.
0903551
 	 */
0903551
-	if (state) {
0903551
-		/*
0903551
-		 * If the state doesn't change the active CRTC's, then there's
0903551
-		 * no need to recalculate; the existing pipe allocation limits
0903551
-		 * should remain unchanged.  Note that we're safe from racing
0903551
-		 * commits since any racing commit that changes the active CRTC
0903551
-		 * list would need to grab _all_ crtc locks, including the one
0903551
-		 * we currently hold.
0903551
-		 */
0903551
-		if (!intel_state->active_pipe_changes) {
0903551
-			*alloc = dev_priv->wm.skl_hw.ddb.pipe[pipe];
0903551
-			return;
0903551
-		}
0903551
-
0903551
-		nth_active_pipe = hweight32(intel_state->active_crtcs &
0903551
-					    (drm_crtc_mask(for_crtc) - 1));
0903551
-		pipe_size = ddb_size / hweight32(intel_state->active_crtcs);
0903551
-		alloc->start = nth_active_pipe * ddb_size / *num_active;
0903551
-		alloc->end = alloc->start + pipe_size;
0903551
-	} else {
0903551
-		nth_active_pipe = 0;
0903551
-		for_each_crtc(dev, crtc) {
0903551
-			if (!to_intel_crtc(crtc)->active)
0903551
-				continue;
0903551
-
0903551
-			if (crtc == for_crtc)
0903551
-				break;
0903551
-
0903551
-			nth_active_pipe++;
0903551
-		}
0903551
-
0903551
-		pipe_size = ddb_size / config->num_pipes_active;
0903551
-		alloc->start = nth_active_pipe * ddb_size /
0903551
-			config->num_pipes_active;
0903551
-		alloc->end = alloc->start + pipe_size;
0903551
+	if (!intel_state->active_pipe_changes) {
0903551
+		*alloc = dev_priv->wm.skl_hw.ddb.pipe[pipe];
0903551
+		return;
0903551
 	}
0903551
+
0903551
+	nth_active_pipe = hweight32(intel_state->active_crtcs &
0903551
+				    (drm_crtc_mask(for_crtc) - 1));
0903551
+	pipe_size = ddb_size / hweight32(intel_state->active_crtcs);
0903551
+	alloc->start = nth_active_pipe * ddb_size / *num_active;
0903551
+	alloc->end = alloc->start + pipe_size;
0903551
 }
0903551
 
0903551
 static unsigned int skl_cursor_allocation(int num_active)
0903551
@@ -2964,62 +2934,33 @@ skl_get_total_relative_data_rate(struct intel_crtc_state *intel_cstate)
0903551
 	struct drm_crtc *crtc = cstate->crtc;
0903551
 	struct drm_device *dev = crtc->dev;
0903551
 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
0903551
+	const struct drm_plane *plane;
0903551
 	const struct intel_plane *intel_plane;
0903551
+	struct drm_plane_state *pstate;
0903551
 	unsigned int rate, total_data_rate = 0;
0903551
 	int id;
0903551
+	int i;
0903551
+
0903551
+	if (WARN_ON(!state))
0903551
+		return 0;
0903551
 
0903551
 	/* Calculate and cache data rate for each plane */
0903551
-	/*
0903551
-	 * FIXME: At the moment this function can be called on either an
0903551
-	 * in-flight or a committed state object.  If it's in-flight then we
0903551
-	 * only want to re-calculate the plane data rate for planes that are
0903551
-	 * part of the transaction (i.e., we don't want to grab any additional
0903551
-	 * plane states if we don't have to).  If we're operating on committed
0903551
-	 * state, we'll just go ahead and recalculate the plane data rate for
0903551
-	 * all planes.
0903551
-	 *
0903551
-	 * Once we finish moving our DDB allocation to the atomic check phase,
0903551
-	 * we'll only be calling this function on in-flight state objects, so
0903551
-	 * the 'else' branch here will go away.
0903551
-	 */
0903551
-	if (state) {
0903551
-		struct drm_plane *plane;
0903551
-		struct drm_plane_state *pstate;
0903551
-		int i;
0903551
-
0903551
-		for_each_plane_in_state(state, plane, pstate, i) {
0903551
-			intel_plane = to_intel_plane(plane);
0903551
-			id = skl_wm_plane_id(intel_plane);
0903551
-
0903551
-			if (intel_plane->pipe != intel_crtc->pipe)
0903551
-				continue;
0903551
-
0903551
-			/* packed/uv */
0903551
-			rate = skl_plane_relative_data_rate(intel_cstate,
0903551
-							    pstate, 0);
0903551
-			intel_cstate->wm.skl.plane_data_rate[id] = rate;
0903551
-
0903551
-			/* y-plane */
0903551
-			rate = skl_plane_relative_data_rate(intel_cstate,
0903551
-							    pstate, 1);
0903551
-			intel_cstate->wm.skl.plane_y_data_rate[id] = rate;
0903551
-		}
0903551
-	} else {
0903551
-		for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane) {
0903551
-			const struct drm_plane_state *pstate =
0903551
-				intel_plane->base.state;
0903551
-			int id = skl_wm_plane_id(intel_plane);
0903551
+	for_each_plane_in_state(state, plane, pstate, i) {
0903551
+		id = skl_wm_plane_id(to_intel_plane(plane));
0903551
+		intel_plane = to_intel_plane(plane);
0903551
 
0903551
-			/* packed/uv */
0903551
-			rate = skl_plane_relative_data_rate(intel_cstate,
0903551
-							    pstate, 0);
0903551
-			intel_cstate->wm.skl.plane_data_rate[id] = rate;
0903551
+		if (intel_plane->pipe != intel_crtc->pipe)
0903551
+			continue;
0903551
 
0903551
-			/* y-plane */
0903551
-			rate = skl_plane_relative_data_rate(intel_cstate,
0903551
-							    pstate, 1);
0903551
-			intel_cstate->wm.skl.plane_y_data_rate[id] = rate;
0903551
-		}
0903551
+		/* packed/uv */
0903551
+		rate = skl_plane_relative_data_rate(intel_cstate,
0903551
+						    pstate, 0);
0903551
+		intel_cstate->wm.skl.plane_data_rate[id] = rate;
0903551
+
0903551
+		/* y-plane */
0903551
+		rate = skl_plane_relative_data_rate(intel_cstate,
0903551
+						    pstate, 1);
0903551
+		intel_cstate->wm.skl.plane_y_data_rate[id] = rate;
0903551
 	}
0903551
 
0903551
 	/* Calculate CRTC's total data rate from cached values */
0903551
@@ -3043,8 +2984,6 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
0903551
 	struct drm_atomic_state *state = cstate->base.state;
0903551
 	struct drm_crtc *crtc = cstate->base.crtc;
0903551
 	struct drm_device *dev = crtc->dev;
0903551
-	struct drm_i915_private *dev_priv = to_i915(dev);
0903551
-	struct intel_wm_config *config = &dev_priv->wm.config;
0903551
 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
0903551
 	struct intel_plane *intel_plane;
0903551
 	struct drm_plane *plane;
0903551
@@ -3058,6 +2997,9 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
0903551
 	int num_active;
0903551
 	int id, i;
0903551
 
0903551
+	if (WARN_ON(!state))
0903551
+		return 0;
0903551
+
0903551
 	if (!cstate->base.active) {
0903551
 		ddb->pipe[pipe].start = ddb->pipe[pipe].end = 0;
0903551
 		memset(ddb->plane[pipe], 0, sizeof(ddb->plane[pipe]));
0903551
@@ -3065,8 +3007,7 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
0903551
 		return 0;
0903551
 	}
0903551
 
0903551
-	skl_ddb_get_pipe_allocation_limits(dev, cstate, config, alloc,
0903551
-					   &num_active);
0903551
+	skl_ddb_get_pipe_allocation_limits(dev, cstate, alloc, &num_active);
0903551
 	alloc_size = skl_ddb_entry_size(alloc);
0903551
 	if (alloc_size == 0) {
0903551
 		memset(ddb->plane[pipe], 0, sizeof(ddb->plane[pipe]));
0903551
@@ -3078,53 +3019,31 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
0903551
 	ddb->plane[pipe][PLANE_CURSOR].end = alloc->end;
0903551
 
0903551
 	alloc_size -= cursor_blocks;
0903551
-	alloc->end -= cursor_blocks;
0903551
 
0903551
 	/* 1. Allocate the mininum required blocks for each active plane */
0903551
-	/*
0903551
-	 * TODO: Remove support for already-committed state once we
0903551
-	 * only allocate DDB on in-flight states.
0903551
-	 */
0903551
-	if (state) {
0903551
-		for_each_plane_in_state(state, plane, pstate, i) {
0903551
-			intel_plane = to_intel_plane(plane);
0903551
-			id = skl_wm_plane_id(intel_plane);
0903551
-
0903551
-			if (intel_plane->pipe != pipe)
0903551
-				continue;
0903551
-
0903551
-			if (!to_intel_plane_state(pstate)->visible) {
0903551
-				minimum[id] = 0;
0903551
-				y_minimum[id] = 0;
0903551
-				continue;
0903551
-			}
0903551
-			if (plane->type == DRM_PLANE_TYPE_CURSOR) {
0903551
-				minimum[id] = 0;
0903551
-				y_minimum[id] = 0;
0903551
-				continue;
0903551
-			}
0903551
-
0903551
-			minimum[id] = 8;
0903551
-			if (pstate->fb->pixel_format == DRM_FORMAT_NV12)
0903551
-				y_minimum[id] = 8;
0903551
-			else
0903551
-				y_minimum[id] = 0;
0903551
-		}
0903551
-	} else {
0903551
-		for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane) {
0903551
-			struct drm_plane *plane = &intel_plane->base;
0903551
-			struct drm_framebuffer *fb = plane->state->fb;
0903551
-			int id = skl_wm_plane_id(intel_plane);
0903551
-
0903551
-			if (!to_intel_plane_state(plane->state)->visible)
0903551
-				continue;
0903551
+	for_each_plane_in_state(state, plane, pstate, i) {
0903551
+		intel_plane = to_intel_plane(plane);
0903551
+		id = skl_wm_plane_id(intel_plane);
0903551
 
0903551
-			if (plane->type == DRM_PLANE_TYPE_CURSOR)
0903551
-				continue;
0903551
+		if (intel_plane->pipe != pipe)
0903551
+			continue;
0903551
 
0903551
-			minimum[id] = 8;
0903551
-			y_minimum[id] = (fb->pixel_format == DRM_FORMAT_NV12) ? 8 : 0;
0903551
+		if (!to_intel_plane_state(pstate)->visible) {
0903551
+			minimum[id] = 0;
0903551
+			y_minimum[id] = 0;
0903551
+			continue;
0903551
+		}
0903551
+		if (plane->type == DRM_PLANE_TYPE_CURSOR) {
0903551
+			minimum[id] = 0;
0903551
+			y_minimum[id] = 0;
0903551
+			continue;
0903551
 		}
0903551
+
0903551
+		minimum[id] = 8;
0903551
+		if (pstate->fb->pixel_format == DRM_FORMAT_NV12)
0903551
+			y_minimum[id] = 8;
0903551
+		else
0903551
+			y_minimum[id] = 0;
0903551
 	}
0903551
 
0903551
 	for (i = 0; i < PLANE_CURSOR; i++) {
0903551
@@ -3675,7 +3594,6 @@ static bool skl_update_pipe_wm(struct drm_crtc *crtc,
0903551
 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
0903551
 	struct intel_crtc_state *cstate = to_intel_crtc_state(crtc->state);
0903551
 
0903551
-	WARN_ON(skl_allocate_pipe_ddb(cstate, ddb) != 0);
0903551
 	skl_build_pipe_wm(cstate, ddb, pipe_wm);
0903551
 
0903551
 	if (!memcmp(&intel_crtc->wm.active.skl, pipe_wm, sizeof(*pipe_wm)))
0903551
@@ -3739,16 +3657,6 @@ static void skl_clear_wm(struct skl_wm_values *watermarks, enum pipe pipe)
0903551
 	memset(watermarks->plane_trans[pipe],
0903551
 	       0, sizeof(uint32_t) * I915_MAX_PLANES);
0903551
 	watermarks->plane_trans[pipe][PLANE_CURSOR] = 0;
0903551
-
0903551
-	/* Clear ddb entries for pipe */
0903551
-	memset(&watermarks->ddb.pipe[pipe], 0, sizeof(struct skl_ddb_entry));
0903551
-	memset(&watermarks->ddb.plane[pipe], 0,
0903551
-	       sizeof(struct skl_ddb_entry) * I915_MAX_PLANES);
0903551
-	memset(&watermarks->ddb.y_plane[pipe], 0,
0903551
-	       sizeof(struct skl_ddb_entry) * I915_MAX_PLANES);
0903551
-	memset(&watermarks->ddb.plane[pipe][PLANE_CURSOR], 0,
0903551
-	       sizeof(struct skl_ddb_entry));
0903551
-
0903551
 }
0903551
 
0903551
 static int
0903551
-- 
0903551
2.7.4
0903551