From 326b9703c572d3224aff305368b861437bbed3d8 Mon Sep 17 00:00:00 2001
From: Dom Cobley <popcornmix@gmail.com>
Date: Tue, 14 Nov 2023 16:43:03 +0000
Subject: [PATCH 0829/1085] vc4/hvs: Add support for D0 register changes

Signed-off-by: Dom Cobley <popcornmix@gmail.com>
---
 drivers/gpu/drm/vc4/vc4_drv.c  |   8 +-
 drivers/gpu/drm/vc4/vc4_drv.h  |   7 ++
 drivers/gpu/drm/vc4/vc4_hvs.c  | 142 ++++++++++++++++++++++--------
 drivers/gpu/drm/vc4/vc4_regs.h | 154 +++++++++++++++++++++++++++++----
 4 files changed, 255 insertions(+), 56 deletions(-)

--- a/drivers/gpu/drm/vc4/vc4_drv.c
+++ b/drivers/gpu/drm/vc4/vc4_drv.c
@@ -322,9 +322,13 @@ static int vc4_drm_bind(struct device *d
 	struct device_node *node;
 	struct drm_crtc *crtc;
 	enum vc4_gen gen;
+	bool step_d0 = false;
 	int ret = 0;
 
-	if (of_device_is_compatible(dev->of_node, "brcm,bcm2712-vc6"))
+	if (of_device_is_compatible(dev->of_node, "brcm,bcm2712d0-vc6")) {
+		gen = VC4_GEN_6;
+		step_d0 = true;
+	} else if (of_device_is_compatible(dev->of_node, "brcm,bcm2712-vc6"))
 		gen = VC4_GEN_6;
 	else if (of_device_is_compatible(dev->of_node, "brcm,bcm2711-vc5"))
 		gen = VC4_GEN_5;
@@ -355,6 +359,7 @@ static int vc4_drm_bind(struct device *d
 	if (IS_ERR(vc4))
 		return PTR_ERR(vc4);
 	vc4->gen = gen;
+	vc4->step_d0 = step_d0;
 	vc4->dev = dev;
 
 	drm = &vc4->base;
@@ -494,6 +499,7 @@ static void vc4_platform_drm_remove(stru
 static const struct of_device_id vc4_of_match[] = {
 	{ .compatible = "brcm,bcm2711-vc5", },
 	{ .compatible = "brcm,bcm2712-vc6", },
+	{ .compatible = "brcm,bcm2712d0-vc6", },
 	{ .compatible = "brcm,bcm2835-vc4", },
 	{ .compatible = "brcm,cygnus-vc4", },
 	{},
--- a/drivers/gpu/drm/vc4/vc4_drv.h
+++ b/drivers/gpu/drm/vc4/vc4_drv.h
@@ -92,6 +92,7 @@ struct vc4_dev {
 	struct device *dev;
 
 	enum vc4_gen gen;
+	bool step_d0;
 
 	unsigned int irq;
 
@@ -714,6 +715,12 @@ struct vc4_crtc_state {
 		writel(val, hvs->regs + (offset));					\
 	} while (0)
 
+#define HVS_READ6(offset) \
+	HVS_READ(hvs->vc4->step_d0 ? SCALER6_ ## offset : SCALER6D0_ ## offset)		\
+
+#define HVS_WRITE6(offset, val) \
+	HVS_WRITE(hvs->vc4->step_d0 ? SCALER6_ ## offset : SCALER6D0_ ## offset, val)	\
+
 #define VC4_REG32(reg) { .name = #reg, .offset = reg }
 
 struct vc4_exec_info {
--- a/drivers/gpu/drm/vc4/vc4_hvs.c
+++ b/drivers/gpu/drm/vc4/vc4_hvs.c
@@ -104,7 +104,6 @@ static const struct debugfs_reg32 vc6_hv
 	VC4_REG32(SCALER6_DISP2_RUN),
 	VC4_REG32(SCALER6_EOLN),
 	VC4_REG32(SCALER6_DL_STATUS),
-	VC4_REG32(SCALER6_BFG_MISC),
 	VC4_REG32(SCALER6_QOS0),
 	VC4_REG32(SCALER6_PROF0),
 	VC4_REG32(SCALER6_QOS1),
@@ -141,6 +140,66 @@ static const struct debugfs_reg32 vc6_hv
 	VC4_REG32(SCALER6_BAD_AXI),
 };
 
+static const struct debugfs_reg32 vc6_hvs_regs_d0[] = {
+	VC4_REG32(SCALER6D0_VERSION),
+	VC4_REG32(SCALER6D0_CXM_SIZE),
+	VC4_REG32(SCALER6D0_LBM_SIZE),
+	VC4_REG32(SCALER6D0_UBM_SIZE),
+	VC4_REG32(SCALER6D0_COBA_SIZE),
+	VC4_REG32(SCALER6D0_COB_SIZE),
+	VC4_REG32(SCALER6D0_CONTROL),
+	VC4_REG32(SCALER6D0_FETCHER_STATUS),
+	VC4_REG32(SCALER6D0_FETCH_STATUS),
+	VC4_REG32(SCALER6D0_HANDLE_ERROR),
+	VC4_REG32(SCALER6D0_DISP0_CTRL0),
+	VC4_REG32(SCALER6D0_DISP0_CTRL1),
+	VC4_REG32(SCALER6D0_DISP0_BGND0),
+	VC4_REG32(SCALER6D0_DISP0_BGND1),
+	VC4_REG32(SCALER6D0_DISP0_LPTRS),
+	VC4_REG32(SCALER6D0_DISP0_COB),
+	VC4_REG32(SCALER6D0_DISP0_STATUS),
+	VC4_REG32(SCALER6D0_DISP0_DL),
+	VC4_REG32(SCALER6D0_DISP0_RUN),
+	VC4_REG32(SCALER6D0_DISP1_CTRL0),
+	VC4_REG32(SCALER6D0_DISP1_CTRL1),
+	VC4_REG32(SCALER6D0_DISP1_BGND0),
+	VC4_REG32(SCALER6D0_DISP1_BGND1),
+	VC4_REG32(SCALER6D0_DISP1_LPTRS),
+	VC4_REG32(SCALER6D0_DISP1_COB),
+	VC4_REG32(SCALER6D0_DISP1_STATUS),
+	VC4_REG32(SCALER6D0_DISP1_DL),
+	VC4_REG32(SCALER6D0_DISP1_RUN),
+	VC4_REG32(SCALER6D0_DISP2_CTRL0),
+	VC4_REG32(SCALER6D0_DISP2_CTRL1),
+	VC4_REG32(SCALER6D0_DISP2_BGND0),
+	VC4_REG32(SCALER6D0_DISP2_BGND1),
+	VC4_REG32(SCALER6D0_DISP2_LPTRS),
+	VC4_REG32(SCALER6D0_DISP2_COB),
+	VC4_REG32(SCALER6D0_DISP2_STATUS),
+	VC4_REG32(SCALER6D0_DISP2_DL),
+	VC4_REG32(SCALER6D0_DISP2_RUN),
+	VC4_REG32(SCALER6D0_EOLN),
+	VC4_REG32(SCALER6D0_DL_STATUS),
+	VC4_REG32(SCALER6D0_QOS0),
+	VC4_REG32(SCALER6D0_PROF0),
+	VC4_REG32(SCALER6D0_QOS1),
+	VC4_REG32(SCALER6D0_PROF1),
+	VC4_REG32(SCALER6D0_QOS2),
+	VC4_REG32(SCALER6D0_PROF2),
+	VC4_REG32(SCALER6D0_PRI_MAP0),
+	VC4_REG32(SCALER6D0_PRI_MAP1),
+	VC4_REG32(SCALER6D0_HISTCTRL),
+	VC4_REG32(SCALER6D0_HISTBIN0),
+	VC4_REG32(SCALER6D0_HISTBIN1),
+	VC4_REG32(SCALER6D0_HISTBIN2),
+	VC4_REG32(SCALER6D0_HISTBIN3),
+	VC4_REG32(SCALER6D0_HISTBIN4),
+	VC4_REG32(SCALER6D0_HISTBIN5),
+	VC4_REG32(SCALER6D0_HISTBIN6),
+	VC4_REG32(SCALER6D0_HISTBIN7),
+	VC4_REG32(SCALER6D0_HVS_ID),
+};
+
 void vc4_hvs_dump_state(struct vc4_hvs *hvs)
 {
 	struct drm_device *drm = &hvs->vc4->base;
@@ -234,18 +293,18 @@ static int vc6_hvs_debugfs_dlist(struct
 		unsigned int active_dlist, dispstat;
 		unsigned int j;
 
-		dispstat = VC4_GET_FIELD(HVS_READ(SCALER6_DISPX_STATUS(i)),
-					 SCALER6_DISPX_STATUS_MODE);
-		if (dispstat == SCALER6_DISPX_STATUS_MODE_DISABLED ||
-		    dispstat == SCALER6_DISPX_STATUS_MODE_EOF) {
+		dispstat = VC4_GET_FIELD6(HVS_READ(SCALER6_DISPX_STATUS(i)),
+					 DISPX_STATUS_MODE);
+		if (dispstat == SCALER6(DISPX_STATUS_MODE_DISABLED) ||
+		    dispstat == SCALER6(DISPX_STATUS_MODE_EOF)) {
 			drm_printf(&p, "HVS chan %u disabled\n", i);
 			continue;
 		}
 
 		drm_printf(&p, "HVS chan %u:\n", i);
 
-		active_dlist = VC4_GET_FIELD(HVS_READ(SCALER6_DISPX_DL(i)),
-					     SCALER6_DISPX_DL_LACT);
+		active_dlist = VC4_GET_FIELD6(HVS_READ(SCALER6_DISPX_DL(i)),
+					     DISPX_DL_LACT);
 		next_entry_start = 0;
 
 		for (j = active_dlist; j < dlist_mem_size; j++) {
@@ -760,7 +819,7 @@ bool vc4_hvs_check_channel_active(struct
 		return 0;
 
 	if (vc4->gen >= VC4_GEN_6)
-		enabled = HVS_READ(SCALER6_DISPX_CTRL0(fifo)) & SCALER6_DISPX_CTRL0_ENB;
+		enabled = HVS_READ(SCALER6_DISPX_CTRL0(fifo)) & SCALER6(DISPX_CTRL0_ENB);
 	else
 		enabled = HVS_READ(SCALER_DISPCTRLX(fifo)) & SCALER_DISPCTRLX_ENABLE;
 
@@ -825,8 +884,8 @@ u8 vc4_hvs_get_fifo_frame_count(struct v
 
 	switch (vc4->gen) {
 	case VC4_GEN_6:
-		field = VC4_GET_FIELD(HVS_READ(SCALER6_DISPX_STATUS(fifo)),
-				      SCALER6_DISPX_STATUS_FRCNT);
+		field = VC4_GET_FIELD6(HVS_READ(SCALER6_DISPX_STATUS(fifo)),
+				      DISPX_STATUS_FRCNT);
 		break;
 	case VC4_GEN_5:
 		switch (fifo) {
@@ -1037,20 +1096,20 @@ static int vc6_hvs_init_channel(struct v
 	if (!drm_dev_enter(drm, &idx))
 		return -ENODEV;
 
-	HVS_WRITE(SCALER6_DISPX_CTRL0(chan), SCALER6_DISPX_CTRL0_RESET);
+	HVS_WRITE(SCALER6_DISPX_CTRL0(chan), SCALER6(DISPX_CTRL0_RESET));
 
 	disp_ctrl1 = HVS_READ(SCALER6_DISPX_CTRL1(chan));
-	disp_ctrl1 &= ~SCALER6_DISPX_CTRL1_INTLACE;
+	disp_ctrl1 &= ~SCALER6(DISPX_CTRL1_INTLACE);
 	HVS_WRITE(SCALER6_DISPX_CTRL1(chan),
-		  disp_ctrl1 | (interlace ? SCALER6_DISPX_CTRL1_INTLACE : 0));
+		  disp_ctrl1 | (interlace ? SCALER6(DISPX_CTRL1_INTLACE) : 0));
 
 	HVS_WRITE(SCALER6_DISPX_CTRL0(chan),
-		  SCALER6_DISPX_CTRL0_ENB |
-		  VC4_SET_FIELD(mode->hdisplay - 1,
-				SCALER6_DISPX_CTRL0_FWIDTH) |
-		  (oneshot ? SCALER6_DISPX_CTRL0_ONESHOT : 0) |
-		  VC4_SET_FIELD(mode->vdisplay - 1,
-				SCALER6_DISPX_CTRL0_LINES));
+		  SCALER6(DISPX_CTRL0_ENB) |
+		  VC4_SET_FIELD6(mode->hdisplay - 1,
+				DISPX_CTRL0_FWIDTH) |
+		  (oneshot ? SCALER6(DISPX_CTRL0_ONESHOT) : 0) |
+		  VC4_SET_FIELD6(mode->vdisplay - 1,
+				DISPX_CTRL0_LINES));
 
 	drm_dev_exit(idx);
 
@@ -1096,18 +1155,18 @@ static void __vc6_hvs_stop_channel(struc
 	if (!drm_dev_enter(drm, &idx))
 		return;
 
-	if (!(HVS_READ(SCALER6_DISPX_CTRL0(chan)) & SCALER6_DISPX_CTRL0_ENB))
+	if (!(HVS_READ(SCALER6_DISPX_CTRL0(chan)) & SCALER6(DISPX_CTRL0_ENB)))
 		goto out;
 
 	HVS_WRITE(SCALER6_DISPX_CTRL0(chan),
-		  HVS_READ(SCALER6_DISPX_CTRL0(chan)) | SCALER6_DISPX_CTRL0_RESET);
+		  HVS_READ(SCALER6_DISPX_CTRL0(chan)) | SCALER6(DISPX_CTRL0_RESET));
 
 	HVS_WRITE(SCALER6_DISPX_CTRL0(chan),
-		  HVS_READ(SCALER6_DISPX_CTRL0(chan)) & ~SCALER6_DISPX_CTRL0_ENB);
+		  HVS_READ(SCALER6_DISPX_CTRL0(chan)) & ~SCALER6(DISPX_CTRL0_ENB));
 
-	WARN_ON_ONCE(VC4_GET_FIELD(HVS_READ(SCALER6_DISPX_STATUS(chan)),
-				   SCALER6_DISPX_STATUS_MODE) !=
-		     SCALER6_DISPX_STATUS_MODE_DISABLED);
+	WARN_ON_ONCE(VC4_GET_FIELD6(HVS_READ(SCALER6_DISPX_STATUS(chan)),
+				   DISPX_STATUS_MODE) !=
+		     SCALER6(DISPX_STATUS_MODE_DISABLED));
 
 out:
 	drm_dev_exit(idx);
@@ -1227,8 +1286,8 @@ static void vc4_hvs_install_dlist(struct
 
 	if (vc4->gen >= VC4_GEN_6)
 		HVS_WRITE(SCALER6_DISPX_LPTRS(vc4_state->assigned_channel),
-			  VC4_SET_FIELD(vc4_state->mm->mm_node.start,
-					SCALER6_DISPX_LPTRS_HEADE));
+			  VC4_SET_FIELD6(vc4_state->mm->mm_node.start,
+					DISPX_LPTRS_HEADE));
 	else
 		HVS_WRITE(SCALER_DISPLISTX(vc4_state->assigned_channel),
 			  vc4_state->mm->mm_node.start);
@@ -1427,11 +1486,11 @@ void vc4_hvs_atomic_flush(struct drm_crt
 		if (enable_bg_fill)
 			HVS_WRITE(SCALER6_DISPX_CTRL1(channel),
 				  HVS_READ(SCALER6_DISPX_CTRL1(channel)) |
-				  SCALER6_DISPX_CTRL1_BGENB);
+				  SCALER6(DISPX_CTRL1_BGENB));
 		else
 			HVS_WRITE(SCALER6_DISPX_CTRL1(channel),
 				  HVS_READ(SCALER6_DISPX_CTRL1(channel)) &
-				  ~SCALER6_DISPX_CTRL1_BGENB);
+				  ~SCALER6(DISPX_CTRL1_BGENB));
 	} else {
 		/* we can actually run with a lower core clock when background
 		 * fill is enabled on VC4_GEN_5 so leave it enabled always.
@@ -1701,7 +1760,7 @@ struct vc4_hvs *__vc4_hvs_alloc(struct v
 		 * access a register. Use a plausible size then.
 		 */
 		if (!kunit_get_current_test())
-			dlist_size = HVS_READ(SCALER6_CXM_SIZE);
+			dlist_size = HVS_READ(SCALER6(CXM_SIZE));
 		else
 			dlist_size = 4096;
 
@@ -1935,14 +1994,17 @@ static int vc6_hvs_hw_init(struct vc4_hv
 	const struct vc6_csc_coeff_entry *coeffs;
 	unsigned int i;
 
-	HVS_WRITE(SCALER6_CONTROL,
+	HVS_WRITE6(CONTROL,
 		  SCALER6_CONTROL_HVS_EN |
-		  VC4_SET_FIELD(8, SCALER6_CONTROL_PF_LINES) |
+		  VC4_SET_FIELD(8, SCALER6_CONTROL_PF_LINES)|
 		  VC4_SET_FIELD(15, SCALER6_CONTROL_MAX_REQS));
 
 	/* Set HVS arbiter priority to max */
-	HVS_WRITE(SCALER6_PRI_MAP0, 0xffffffff);
-	HVS_WRITE(SCALER6_PRI_MAP1, 0xffffffff);
+	HVS_WRITE(SCALER6(PRI_MAP0), 0xffffffff);
+	HVS_WRITE(SCALER6(PRI_MAP1), 0xffffffff);
+
+	if (hvs->vc4->step_d0)
+		return;
 
 	for (i = 0; i < 6; i++) {
 		coeffs = &csc_coeffs[i / 3][i % 3];
@@ -2041,21 +2103,21 @@ static int vc4_hvs_cob_init(struct vc4_h
 		reg = 0;
 		top = 3840;
 
-		HVS_WRITE(SCALER6_DISP2_COB,
+		HVS_WRITE(SCALER6(DISP2_COB),
 			  VC4_SET_FIELD(top, SCALER6_DISPX_COB_TOP) |
 			  VC4_SET_FIELD(base, SCALER6_DISPX_COB_BASE));
 
 		base = top + 16;
 		top += VC6_COB_LINE_WIDTH * VC6_COB_NUM_LINES;
 
-		HVS_WRITE(SCALER6_DISP1_COB,
+		HVS_WRITE(SCALER6(DISP1_COB),
 			  VC4_SET_FIELD(top, SCALER6_DISPX_COB_TOP) |
 			  VC4_SET_FIELD(base, SCALER6_DISPX_COB_BASE));
 
 		base = top + 16;
 		top += VC6_COB_LINE_WIDTH * VC6_COB_NUM_LINES;
 
-		HVS_WRITE(SCALER6_DISP0_COB,
+		HVS_WRITE(SCALER6(DISP0_COB),
 			  VC4_SET_FIELD(top, SCALER6_DISPX_COB_TOP) |
 			  VC4_SET_FIELD(base, SCALER6_DISPX_COB_BASE));
 		break;
@@ -2086,7 +2148,10 @@ static int vc4_hvs_bind(struct device *d
 
 	hvs->regset.base = hvs->regs;
 
-	if (vc4->gen >= VC4_GEN_6) {
+	if (vc4->gen >= VC4_GEN_6 && vc4->step_d0) {
+		hvs->regset.regs = vc6_hvs_regs_d0;
+		hvs->regset.nregs = ARRAY_SIZE(vc6_hvs_regs_d0);
+	} else if (vc4->gen >= VC4_GEN_6) {
 		hvs->regset.regs = vc6_hvs_regs;
 		hvs->regset.nregs = ARRAY_SIZE(vc6_hvs_regs);
 	} else {
@@ -2253,6 +2318,7 @@ static void vc4_hvs_dev_remove(struct pl
 static const struct of_device_id vc4_hvs_dt_match[] = {
 	{ .compatible = "brcm,bcm2711-hvs" },
 	{ .compatible = "brcm,bcm2712-hvs" },
+	{ .compatible = "brcm,bcm2712d0-hvs" },
 	{ .compatible = "brcm,bcm2835-hvs" },
 	{}
 };
--- a/drivers/gpu/drm/vc4/vc4_regs.h
+++ b/drivers/gpu/drm/vc4/vc4_regs.h
@@ -13,11 +13,24 @@
 /* Using the GNU statement expression extension */
 #define VC4_SET_FIELD(value, field)					\
 	({								\
-		WARN_ON(!FIELD_FIT(field##_MASK, value));		\
-		FIELD_PREP(field##_MASK, value);			\
+		WARN_ON(!FIELD_FIT(field ## _MASK, value));		\
+		FIELD_PREP(field ## _MASK, value);			\
 	 })
 
-#define VC4_GET_FIELD(word, field) FIELD_GET(field##_MASK, word)
+#define VC4_GET_FIELD(word, field) FIELD_GET(field ## _MASK, word)
+
+#define VC4_SET_FIELD6(value, field)					\
+	({								\
+		WARN_ON(!FIELD_FIT(hvs->vc4->step_d0 ?			\
+				    SCALER6D0_ ## field ## _MASK :	\
+				    SCALER6_ ## field ## _MASK, value));\
+		FIELD_PREP(hvs->vc4->step_d0 ?				\
+				    SCALER6D0_ ## field ## _MASK :	\
+				    SCALER6_ ## field ## _MASK, value);	\
+	 })
+
+#define VC4_GET_FIELD6(word, field) FIELD_GET(hvs->vc4->step_d0 ? \
+				    SCALER6D0_ ## field ## _MASK : SCALER6_ ## field ## _MASK, word)
 
 #define V3D_IDENT0   0x00000
 # define V3D_EXPECTED_IDENT0 \
@@ -567,8 +580,9 @@
 #define SCALER6_HANDLE_ERROR			0x0000002c
 
 #define SCALER6_DISP0_CTRL0			0x00000030
-#define SCALER6_DISPX_CTRL0(x)						\
-	(SCALER6_DISP0_CTRL0 + ((x) * (SCALER6_DISP1_CTRL0 - SCALER6_DISP0_CTRL0)))
+#define SCALER6_DISPX_CTRL0(x)	((hvs->vc4->step_d0) ? \
+	(SCALER6D0_DISP0_CTRL0 + ((x) * (SCALER6D0_DISP1_CTRL0 - SCALER6D0_DISP0_CTRL0))) : \
+	(SCALER6_DISP0_CTRL0 + ((x) * (SCALER6_DISP1_CTRL0 - SCALER6_DISP0_CTRL0))))
 # define SCALER6_DISPX_CTRL0_ENB		BIT(31)
 # define SCALER6_DISPX_CTRL0_RESET		BIT(30)
 # define SCALER6_DISPX_CTRL0_FWIDTH_MASK	VC4_MASK(28, 16)
@@ -577,30 +591,35 @@
 # define SCALER6_DISPX_CTRL0_LINES_MASK		VC4_MASK(12, 0)
 
 #define SCALER6_DISP0_CTRL1			0x00000034
-#define SCALER6_DISPX_CTRL1(x)						\
-	(SCALER6_DISP0_CTRL1 + ((x) * (SCALER6_DISP1_CTRL1 - SCALER6_DISP0_CTRL1)))
+#define SCALER6_DISPX_CTRL1(x)		((hvs->vc4->step_d0) ? \
+	(SCALER6D0_DISP0_CTRL1 + ((x) * (SCALER6D0_DISP1_CTRL1 - SCALER6D0_DISP0_CTRL1))) : \
+	(SCALER6_DISP0_CTRL1 + ((x) * (SCALER6_DISP1_CTRL1 - SCALER6_DISP0_CTRL1))))
 # define SCALER6_DISPX_CTRL1_BGENB		BIT(8)
 # define SCALER6_DISPX_CTRL1_INTLACE		BIT(0)
 
 #define SCALER6_DISP0_BGND			0x00000038
-#define SCALER6_DISPX_BGND(x)						\
-	(SCALER6_DISP0_BGND + ((x) * (SCALER6_DISP1_BGND - SCALER6_DISP0_BGND)))
+#define SCALER6_DISPX_BGND(x)		((hvs->vc4->step_d0) ? \
+	(SCALER6D0_DISP0_BGND + ((x) * (SCALER6D0_DISP1_BGND - SCALER6D0_DISP0_BGND))) : \
+	(SCALER6_DISP0_BGND + ((x) * (SCALER6_DISP1_BGND - SCALER6_DISP0_BGND))))
 
 #define SCALER6_DISP0_LPTRS			0x0000003c
-#define SCALER6_DISPX_LPTRS(x)						\
-	(SCALER6_DISP0_LPTRS + ((x) * (SCALER6_DISP1_LPTRS - SCALER6_DISP0_LPTRS)))
+#define SCALER6_DISPX_LPTRS(x)		((hvs->vc4->step_d0) ? \
+	(SCALER6D0_DISP0_LPTRS + ((x) * (SCALER6D0_DISP1_LPTRS - SCALER6D0_DISP0_LPTRS))) : \
+	(SCALER6_DISP0_LPTRS + ((x) * (SCALER6_DISP1_LPTRS - SCALER6_DISP0_LPTRS))))
 # define SCALER6_DISPX_LPTRS_HEADE_MASK		VC4_MASK(11, 0)
 
 #define SCALER6_DISP0_COB			0x00000040
-#define SCALER6_DISPX_COB(x)						\
-	(SCALER6_DISP0_COB + ((x) * (SCALER6_DISP1_COB - SCALER6_DISP0_COB)))
+#define SCALER6_DISPX_COB(x)		((hvs->vc4->step_d0) ? \
+	(SCALER6D0_DISP0_COB + ((x) * (SCALER6D0_DISP1_COB - SCALER6D0_DISP0_COB))) : \
+	(SCALER6_DISP0_COB + ((x) * (SCALER6_DISP1_COB - SCALER6_DISP0_COB))))
 # define SCALER6_DISPX_COB_TOP_MASK		VC4_MASK(31, 16)
 # define SCALER6_DISPX_COB_BASE_MASK		VC4_MASK(15, 0)
 
 #define SCALER6_DISP0_STATUS			0x00000044
 
-#define SCALER6_DISPX_STATUS(x)						\
-	(SCALER6_DISP0_STATUS + ((x) * (SCALER6_DISP1_STATUS - SCALER6_DISP0_STATUS)))
+#define SCALER6_DISPX_STATUS(x)	((hvs->vc4->step_d0) ? \
+	(SCALER6D0_DISP0_STATUS + ((x) * (SCALER6D0_DISP1_STATUS - SCALER6D0_DISP0_STATUS))) : \
+	(SCALER6_DISP0_STATUS + ((x) * (SCALER6_DISP1_STATUS - SCALER6_DISP0_STATUS))))
 # define SCALER6_DISPX_STATUS_EMPTY		BIT(22)
 # define SCALER6_DISPX_STATUS_FRCNT_MASK	VC4_MASK(21, 16)
 # define SCALER6_DISPX_STATUS_OFIELD		BIT(15)
@@ -613,8 +632,9 @@
 
 #define SCALER6_DISP0_DL			0x00000048
 
-#define SCALER6_DISPX_DL(x)						\
-	(SCALER6_DISP0_DL + ((x) * (SCALER6_DISP1_DL - SCALER6_DISP0_DL)))
+#define SCALER6_DISPX_DL(x)	((hvs->vc4->step_d0) ? \
+	(SCALER6D0_DISP0_DL + ((x) * (SCALER6D0_DISP1_DL - SCALER6D0_DISP0_DL))) : \
+	(SCALER6_DISP0_DL + ((x) * (SCALER6_DISP1_DL - SCALER6_DISP0_DL))))
 # define SCALER6_DISPX_DL_LACT_MASK		VC4_MASK(11, 0)
 
 #define SCALER6_DISP0_RUN			0x0000004c
@@ -672,6 +692,106 @@
 #define SCALER6_BAD_UPM				0x0000022c
 #define SCALER6_BAD_AXI				0x00000230
 
+
+#define SCALER6D0_VERSION				0x00000000
+#define SCALER6D0_CXM_SIZE			0x00000004
+#define SCALER6D0_LBM_SIZE			0x00000008
+#define SCALER6D0_UBM_SIZE			0x0000000c
+#define SCALER6D0_COBA_SIZE			0x00000010
+#define SCALER6D0_COB_SIZE			0x00000014
+#define SCALER6D0_CONTROL				0x00000020
+#define SCALER6D0_FETCHER_STATUS			0x00000024
+#define SCALER6D0_FETCH_STATUS			0x00000028
+#define SCALER6D0_HANDLE_ERROR			0x0000002c
+
+#define SCALER6D0_EOLN				0x00000030
+#define SCALER6D0_DL_STATUS			0x00000034
+#define SCALER6D0_PRI_MAP0			0x00000038
+#define SCALER6D0_PRI_MAP1			0x0000003c
+#define SCALER6D0_HISTCTRL			0x000000d0
+#define SCALER6D0_HISTBIN0			0x000000d4
+#define SCALER6D0_HISTBIN1			0x000000d8
+#define SCALER6D0_HISTBIN2			0x000000dc
+#define SCALER6D0_HISTBIN3			0x000000e0
+#define SCALER6D0_HISTBIN4			0x000000e4
+#define SCALER6D0_HISTBIN5			0x000000e8
+#define SCALER6D0_HISTBIN6			0x000000ec
+#define SCALER6D0_HISTBIN7			0x000000f0
+#define SCALER6D0_HVS_ID			0x000000fc
+
+#define SCALER6D0_DISP0_CTRL0			0x00000100
+# define SCALER6D0_DISPX_CTRL0_ENB		BIT(31)
+# define SCALER6D0_DISPX_CTRL0_RESET		BIT(30)
+# define SCALER6D0_DISPX_CTRL0_FWIDTH_MASK	VC4_MASK(28, 16)
+# define SCALER6D0_DISPX_CTRL0_ONESHOT		BIT(15)
+# define SCALER6D0_DISPX_CTRL0_ONECTX_MASK	VC4_MASK(14, 13)
+# define SCALER6D0_DISPX_CTRL0_LINES_MASK		VC4_MASK(12, 0)
+
+#define SCALER6D0_DISP0_CTRL1			0x00000104
+# define SCALER6D0_DISPX_CTRL1_BGENB		BIT(8)
+# define SCALER6D0_DISPX_CTRL1_INTLACE		BIT(0)
+
+#define SCALER6D0_DISP0_BGND			0x00000108
+
+#define SCALER6D0_DISP0_LPTRS			0x00000110
+# define SCALER6D0_DISPX_LPTRS_HEADE_MASK		VC4_MASK(11, 0)
+
+#define SCALER6D0_DISP0_COB			0x00000114
+# define SCALER6D0_DISPX_COB_TOP_MASK		VC4_MASK(31, 16)
+# define SCALER6D0_DISPX_COB_BASE_MASK		VC4_MASK(15, 0)
+
+#define SCALER6D0_DISP0_STATUS			0x00000118
+
+# define SCALER6D0_DISPX_STATUS_EMPTY		BIT(22)
+# define SCALER6D0_DISPX_STATUS_FRCNT_MASK	VC4_MASK(21, 16)
+# define SCALER6D0_DISPX_STATUS_OFIELD		BIT(15)
+# define SCALER6D0_DISPX_STATUS_MODE_MASK		VC4_MASK(14, 13)
+# define SCALER6D0_DISPX_STATUS_MODE_DISABLED	0
+# define SCALER6D0_DISPX_STATUS_MODE_INIT		1
+# define SCALER6D0_DISPX_STATUS_MODE_RUN		2
+# define SCALER6D0_DISPX_STATUS_MODE_EOF		3
+# define SCALER6D0_DISPX_STATUS_YLINE_MASK	VC4_MASK(12, 0)
+
+
+#define SCALER6D0_DISP0_CTRL0			0x00000100
+#define SCALER6D0_DISP0_CTRL1			0x00000104
+#define SCALER6D0_DISP0_BGND0			0x00000108
+#define SCALER6D0_DISP0_BGND1			0x0000010c
+#define SCALER6D0_DISP0_LPTRS			0x00000110
+#define SCALER6D0_DISP0_COB			0x00000114
+#define SCALER6D0_DISP0_STATUS			0x00000118
+#define SCALER6D0_DISP0_DL			0x0000011c
+# define SCALER6D0_DISPX_DL_LACT_MASK		VC4_MASK(11, 0)
+#define SCALER6D0_DISP0_RUN			0x00000120
+#define SCALER6D0_QOS0				0x00000124
+#define SCALER6D0_PROF0				0x00000128
+
+#define SCALER6D0_DISP1_CTRL0			0x00000140
+#define SCALER6D0_DISP1_CTRL1			0x00000144
+#define SCALER6D0_DISP1_BGND0			0x00000148
+#define SCALER6D0_DISP1_BGND1			0x0000014c
+#define SCALER6D0_DISP1_LPTRS			0x00000150
+#define SCALER6D0_DISP1_COB			0x00000154
+#define SCALER6D0_DISP1_STATUS			0x00000158
+#define SCALER6D0_DISP1_DL			0x0000015c
+#define SCALER6D0_DISP1_RUN			0x00000160
+#define SCALER6D0_QOS1				0x00000164
+#define SCALER6D0_PROF1				0x00000168
+
+#define SCALER6D0_DISP2_CTRL0			0x00000180
+#define SCALER6D0_DISP2_CTRL1			0x00000184
+#define SCALER6D0_DISP2_BGND0			0x00000188
+#define SCALER6D0_DISP2_BGND1			0x0000018c
+#define SCALER6D0_DISP2_LPTRS			0x00000190
+#define SCALER6D0_DISP2_COB			0x00000194
+#define SCALER6D0_DISP2_STATUS			0x00000198
+#define SCALER6D0_DISP2_DL			0x0000019c
+#define SCALER6D0_DISP2_RUN			0x000001a0
+#define SCALER6D0_QOS2				0x000001a4
+#define SCALER6D0_PROF2				0x000001a8
+
+#define SCALER6(x) ((hvs->vc4->step_d0) ? SCALER6D0_ ## x : SCALER6_ ## x)
+
 # define VC4_HDMI_SW_RESET_FORMAT_DETECT	BIT(1)
 # define VC4_HDMI_SW_RESET_HDMI			BIT(0)
 
