vc4/hvs: Add support for D0 register changes
authorDom Cobley <popcornmix@gmail.com>
Tue, 14 Nov 2023 16:43:03 +0000 (16:43 +0000)
committerDom Cobley <popcornmix@gmail.com>
Mon, 19 Feb 2024 11:35:28 +0000 (11:35 +0000)
Signed-off-by: Dom Cobley <popcornmix@gmail.com>
drivers/gpu/drm/vc4/vc4_drv.c
drivers/gpu/drm/vc4/vc4_drv.h
drivers/gpu/drm/vc4/vc4_hvs.c
drivers/gpu/drm/vc4/vc4_regs.h

index 43e09a3..220e862 100644 (file)
@@ -322,9 +322,13 @@ static int vc4_drm_bind(struct device *dev)
        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 *dev)
        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(struct platform_device *pdev)
 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", },
        {},
index af8bed2..70703d2 100644 (file)
@@ -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 {
index ce6bce9..479768f 100644 (file)
@@ -104,7 +104,6 @@ static const struct debugfs_reg32 vc6_hvs_regs[] = {
        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_hvs_regs[] = {
        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 seq_file *m, void *data)
                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 vc4_hvs *hvs, unsigned int fifo)
                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 vc4_hvs *hvs, unsigned int fifo)
 
        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 vc4_hvs *hvs, struct drm_crtc *crtc,
        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(struct vc4_hvs *hvs, unsigned int chan)
        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 drm_crtc *crtc)
 
        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_crtc *crtc,
                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 vc4_dev *vc4,
                 * 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_hvs *hvs)
        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_hvs *hvs)
                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 *dev, struct device *master, void *data)
 
        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 platform_device *pdev)
 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" },
        {}
 };
index 0759ced..5c4f643 100644 (file)
 /* 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 \
 #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)
 # 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)
 
 #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
 #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)