[03/15] drm/i915/dsb: single register write function for DSB.

Submitted by Animesh Manna on Aug. 14, 2019, 2:05 a.m.

Details

Message ID 20190814020529.4969-3-animesh.manna@intel.com
State New
Headers show
Series "Series without cover letter" ( rev: 1 ) in Intel GFX - Try Bot

Not browsing as part of any series.

Commit Message

Animesh Manna Aug. 14, 2019, 2:05 a.m.
DSB support single register write through opcode 0x1. Generic
api created which accumulate all single register write in a batch
buffer and once DSB is triggered, it will program all the registers
at the same time.

Signed-off-by: Animesh Manna <animesh.manna@intel.com>
---
 drivers/gpu/drm/i915/display/intel_dsb.c | 36 ++++++++++++++++++++++++
 drivers/gpu/drm/i915/display/intel_dsb.h |  9 ++++++
 2 files changed, 45 insertions(+)

Patch hide | download patch | download mbox

diff --git a/drivers/gpu/drm/i915/display/intel_dsb.c b/drivers/gpu/drm/i915/display/intel_dsb.c
index 6cde3af30643..8a9d082b1601 100644
--- a/drivers/gpu/drm/i915/display/intel_dsb.c
+++ b/drivers/gpu/drm/i915/display/intel_dsb.c
@@ -9,6 +9,20 @@ 
 
 #define DSB_BUF_SIZE    (2 * PAGE_SIZE)
 
+/* DSB opcodes. */
+#define DSB_OPCODE_SHIFT		24
+#define DSB_OPCODE_NOOP			0x0
+#define DSB_OPCODE_MMIO_WRITE		0x1
+#define DSB_OPCODE_WAIT_FOR_US		0x2
+#define DSB_OPCODE_WAIT_FOR_LINES	0x3
+#define DSB_OPCODE_WAIT_FOR_VBLANK	0x4
+#define DSB_OPCODE_WAIT_FOR_SL_IN	0x5
+#define DSB_OPCODE_WAIT_FOR_SL_OUT	0x6
+#define DSB_OPCODE_GENERATE_INT		0x7
+#define DSB_OPCODE_INDEXED_WRITE	0x9
+#define DSB_OPCODE_POLL			0xA
+#define DSB_BYTE_EN			(0xf << 20)
+
 struct intel_dsb *
 intel_dsb_get(struct intel_crtc *crtc)
 {
@@ -64,3 +78,25 @@  intel_dsb_get(struct intel_crtc *crtc)
 	intel_runtime_pm_put(&i915->runtime_pm, wakeref);
 	return dsb;
 }
+
+void intel_dsb_reg_write(struct intel_dsb *dsb, i915_reg_t reg, u32 val)
+{
+	struct intel_crtc *crtc = dsb->crtc;
+	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
+	u32 *buf = dsb->cmd_buf;
+
+	if (!buf) {
+		I915_WRITE(reg, val);
+		return;
+	}
+
+	if (WARN_ON(dsb->free_pos >= DSB_BUF_SIZE)) {
+		DRM_DEBUG_KMS("DSB buffer overflow.\n");
+		return;
+	}
+
+	buf[dsb->free_pos++] = val;
+	buf[dsb->free_pos++] = (DSB_OPCODE_MMIO_WRITE  <<
+				DSB_OPCODE_SHIFT) | DSB_BYTE_EN |
+				i915_mmio_reg_offset(reg);
+}
diff --git a/drivers/gpu/drm/i915/display/intel_dsb.h b/drivers/gpu/drm/i915/display/intel_dsb.h
index 50a2a6590a71..2015c372b0d5 100644
--- a/drivers/gpu/drm/i915/display/intel_dsb.h
+++ b/drivers/gpu/drm/i915/display/intel_dsb.h
@@ -6,6 +6,8 @@ 
 #ifndef _INTEL_DSB_H
 #define _INTEL_DSB_H
 
+#include "i915_reg.h"
+
 struct intel_crtc;
 struct i915_vma;
 
@@ -23,9 +25,16 @@  struct intel_dsb {
 	u32 *cmd_buf;
 	u32 cmd_buf_head;
 	struct i915_vma *vma;
+
+	/*
+	 * free_pos will point the first free entry position
+	 * and help in calculating cmd_buf_tail.
+	 */
+	int free_pos;
 };
 
 struct intel_dsb *
 intel_dsb_get(struct intel_crtc *crtc);
+void intel_dsb_reg_write(struct intel_dsb *dsb, i915_reg_t reg, u32 val);
 
 #endif