diff mbox series

[1/3] drm/i915/dsb: multi dsb instance support in prepare() and cleanup()

Message ID 20201222063400.9509-2-animesh.manna@intel.com (mailing list archive)
State New, archived
Headers show
Series Multi DSB instance support | expand

Commit Message

Manna, Animesh Dec. 22, 2020, 6:33 a.m. UTC
Command buffer allocation is done for all 3 dsb instances for every
pipe and cleanup code is modified accordingly.

v1: Initial version.
v2: Improved commit description.

Signed-off-by: Animesh Manna <animesh.manna@intel.com>
---
 drivers/gpu/drm/i915/display/intel_atomic.c   |  9 +-
 drivers/gpu/drm/i915/display/intel_display.c  |  6 +-
 .../drm/i915/display/intel_display_types.h    |  2 +-
 drivers/gpu/drm/i915/display/intel_dsb.c      | 99 ++++++++++---------
 4 files changed, 65 insertions(+), 51 deletions(-)
diff mbox series

Patch

diff --git a/drivers/gpu/drm/i915/display/intel_atomic.c b/drivers/gpu/drm/i915/display/intel_atomic.c
index e00fdc47c0eb..3833f3b4851b 100644
--- a/drivers/gpu/drm/i915/display/intel_atomic.c
+++ b/drivers/gpu/drm/i915/display/intel_atomic.c
@@ -226,6 +226,7 @@  intel_crtc_duplicate_state(struct drm_crtc *crtc)
 {
 	const struct intel_crtc_state *old_crtc_state = to_intel_crtc_state(crtc->state);
 	struct intel_crtc_state *crtc_state;
+	int i;
 
 	crtc_state = kmemdup(old_crtc_state, sizeof(*crtc_state), GFP_KERNEL);
 	if (!crtc_state)
@@ -252,7 +253,9 @@  intel_crtc_duplicate_state(struct drm_crtc *crtc)
 	crtc_state->wm.need_postvbl_update = false;
 	crtc_state->fb_bits = 0;
 	crtc_state->update_planes = 0;
-	crtc_state->dsb = NULL;
+
+	for (i = 0; i < MAX_DSB_PER_PIPE; i++)
+		crtc_state->dsb[i] = NULL;
 
 	return &crtc_state->uapi;
 }
@@ -293,8 +296,10 @@  intel_crtc_destroy_state(struct drm_crtc *crtc,
 			 struct drm_crtc_state *state)
 {
 	struct intel_crtc_state *crtc_state = to_intel_crtc_state(state);
+	int i;
 
-	drm_WARN_ON(crtc->dev, crtc_state->dsb);
+	for (i = 0; i < MAX_DSB_PER_PIPE; i++)
+		drm_WARN_ON(crtc->dev, crtc_state->dsb[i]);
 
 	__drm_atomic_helper_crtc_destroy_state(&crtc_state->uapi);
 	intel_crtc_free_hw_state(crtc_state);
diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
index 78452de5e12f..3afe8a22c784 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -16256,7 +16256,7 @@  static void intel_atomic_commit_tail(struct intel_atomic_state *state)
 	struct intel_crtc *crtc;
 	u64 put_domains[I915_MAX_PIPES] = {};
 	intel_wakeref_t wakeref = 0;
-	int i;
+	int i, j;
 
 	intel_atomic_commit_fence_wait(state);
 
@@ -16386,7 +16386,9 @@  static void intel_atomic_commit_tail(struct intel_atomic_state *state)
 		 * cleanup. So copy and reset the dsb structure to sync with
 		 * commit_done and later do dsb cleanup in cleanup_work.
 		 */
-		old_crtc_state->dsb = fetch_and_zero(&new_crtc_state->dsb);
+		for (j = 0; j < MAX_DSB_PER_PIPE; j++)
+			old_crtc_state->dsb[j] =
+				fetch_and_zero(&new_crtc_state->dsb[j]);
 	}
 
 	/* Underruns don't always raise interrupts, so check manually */
diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
index 5bc5bfbc4551..06ae7470ab8c 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -1124,7 +1124,7 @@  struct intel_crtc_state {
 	enum transcoder mst_master_transcoder;
 
 	/* For DSB related info */
-	struct intel_dsb *dsb;
+	struct intel_dsb *dsb[MAX_DSB_PER_PIPE];
 
 	u32 psr2_man_track_ctl;
 };
diff --git a/drivers/gpu/drm/i915/display/intel_dsb.c b/drivers/gpu/drm/i915/display/intel_dsb.c
index 566fa72427b3..cef1015cc04f 100644
--- a/drivers/gpu/drm/i915/display/intel_dsb.c
+++ b/drivers/gpu/drm/i915/display/intel_dsb.c
@@ -92,7 +92,7 @@  static bool intel_dsb_disable_engine(struct drm_i915_private *i915,
 void intel_dsb_indexed_reg_write(const struct intel_crtc_state *crtc_state,
 				 i915_reg_t reg, u32 val)
 {
-	struct intel_dsb *dsb = crtc_state->dsb;
+	struct intel_dsb *dsb = crtc_state->dsb[0];
 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
 	u32 *buf;
@@ -174,7 +174,7 @@  void intel_dsb_reg_write(const struct intel_crtc_state *crtc_state,
 	struct intel_dsb *dsb;
 	u32 *buf;
 
-	dsb = crtc_state->dsb;
+	dsb = crtc_state->dsb[0];
 	if (!dsb) {
 		intel_de_write(dev_priv, reg, val);
 		return;
@@ -202,7 +202,7 @@  void intel_dsb_reg_write(const struct intel_crtc_state *crtc_state,
  */
 void intel_dsb_commit(const struct intel_crtc_state *crtc_state)
 {
-	struct intel_dsb *dsb = crtc_state->dsb;
+	struct intel_dsb *dsb = crtc_state->dsb[0];
 	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 	struct drm_device *dev = crtc->base.dev;
 	struct drm_i915_private *dev_priv = to_i915(dev);
@@ -266,49 +266,52 @@  void intel_dsb_prepare(struct intel_crtc_state *crtc_state)
 	struct i915_vma *vma;
 	u32 *buf;
 	intel_wakeref_t wakeref;
+	int i;
 
 	if (!HAS_DSB(i915))
 		return;
 
-	dsb = kmalloc(sizeof(*dsb), GFP_KERNEL);
-	if (!dsb) {
-		drm_err(&i915->drm, "DSB object creation failed\n");
-		return;
-	}
-
-	wakeref = intel_runtime_pm_get(&i915->runtime_pm);
-
-	obj = i915_gem_object_create_internal(i915, DSB_BUF_SIZE);
-	if (IS_ERR(obj)) {
-		drm_err(&i915->drm, "Gem object creation failed\n");
-		kfree(dsb);
-		goto out;
-	}
-
-	vma = i915_gem_object_ggtt_pin(obj, NULL, 0, 0, 0);
-	if (IS_ERR(vma)) {
-		drm_err(&i915->drm, "Vma creation failed\n");
-		i915_gem_object_put(obj);
-		kfree(dsb);
-		goto out;
-	}
-
-	buf = i915_gem_object_pin_map(vma->obj, I915_MAP_WC);
-	if (IS_ERR(buf)) {
-		drm_err(&i915->drm, "Command buffer creation failed\n");
-		i915_vma_unpin_and_release(&vma, I915_VMA_RELEASE_MAP);
-		kfree(dsb);
-		goto out;
-	}
-
-	dsb->id = DSB1;
-	dsb->vma = vma;
-	dsb->cmd_buf = buf;
-	dsb->free_pos = 0;
-	dsb->ins_start_offset = 0;
-	crtc_state->dsb = dsb;
+	for (i = 0 ; i < MAX_DSB_PER_PIPE; i++)	{
+		dsb = kmalloc(sizeof(*dsb), GFP_KERNEL);
+		if (!dsb) {
+			drm_err(&i915->drm, "DSB%d obj creation failed\n", i);
+			continue;
+		}
+
+		wakeref = intel_runtime_pm_get(&i915->runtime_pm);
+
+		obj = i915_gem_object_create_internal(i915, DSB_BUF_SIZE);
+		if (IS_ERR(obj)) {
+			drm_err(&i915->drm, "Gem object creation failed\n");
+			kfree(dsb);
+			goto out;
+		}
+
+		vma = i915_gem_object_ggtt_pin(obj, NULL, 0, 0, 0);
+		if (IS_ERR(vma)) {
+			drm_err(&i915->drm, "Vma creation failed\n");
+			i915_gem_object_put(obj);
+			kfree(dsb);
+			goto out;
+		}
+
+		buf = i915_gem_object_pin_map(vma->obj, I915_MAP_WC);
+		if (IS_ERR(buf)) {
+			drm_err(&i915->drm, "Command buffer creation failed\n");
+			i915_vma_unpin_and_release(&vma, I915_VMA_RELEASE_MAP);
+			kfree(dsb);
+			goto out;
+		}
+
+		dsb->id = i;
+		dsb->vma = vma;
+		dsb->cmd_buf = buf;
+		dsb->free_pos = 0;
+		dsb->ins_start_offset = 0;
+		crtc_state->dsb[i] = dsb;
 out:
-	intel_runtime_pm_put(&i915->runtime_pm, wakeref);
+		intel_runtime_pm_put(&i915->runtime_pm, wakeref);
+	}
 }
 
 /**
@@ -320,10 +323,14 @@  void intel_dsb_prepare(struct intel_crtc_state *crtc_state)
  */
 void intel_dsb_cleanup(struct intel_crtc_state *crtc_state)
 {
-	if (!crtc_state->dsb)
-		return;
+	int i;
 
-	i915_vma_unpin_and_release(&crtc_state->dsb->vma, I915_VMA_RELEASE_MAP);
-	kfree(crtc_state->dsb);
-	crtc_state->dsb = NULL;
+	for (i = 0; i < MAX_DSB_PER_PIPE; i++) {
+		if (!crtc_state->dsb[i])
+			continue;
+
+		i915_vma_unpin_and_release(&crtc_state->dsb[i]->vma, I915_VMA_RELEASE_MAP);
+		kfree(crtc_state->dsb[i]);
+		crtc_state->dsb[i] = NULL;
+	}
 }