As of now, the all of the supported SoCs have small differences in
the register offsets for their version of the DSI IP, at least for
the VM_CMD_CON, SHADOW_DEBUG and CMDQ offsets.

As a preparation for introducing support for newer generation DSI
IPs, having even more differences in the register offsets (but not
in the layout of their fields, nor in the actual programming), as
found on Dimensity 9400 MT6991, Kompanio Ultra MT8196 and Genio
Pro 5100 MT8894, transfer all the register offsets to two const
arrays, splitting the DSI IP version specific registers from the
SoC specific ones (as those depend on interfacing with CMDQ and
other IPs external to DSI, but internal to the SoC, and embedded
in DSI).

This change brings no functional difference, as it only changes
how the register offsets are retrieved and nothing else.

Signed-off-by: AngeloGioacchino Del Regno 
<[email protected]>
---
 drivers/gpu/drm/mediatek/mtk_dsi.c | 378 +++++++++++++++++++----------
 1 file changed, 253 insertions(+), 125 deletions(-)

diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c 
b/drivers/gpu/drm/mediatek/mtk_dsi.c
index 56c69f80a2ef..37c34413130b 100644
--- a/drivers/gpu/drm/mediatek/mtk_dsi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
@@ -1,6 +1,8 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
  * Copyright (c) 2015 MediaTek Inc.
+ * Copyright (c) 2026 Collabora Ltd.
+ *                    AngeloGioacchino Del Regno 
<[email protected]>
  */
 
 #include <linux/bitfield.h>
@@ -34,11 +36,11 @@
 #include "mtk_disp_drv.h"
 #include "mtk_drm_drv.h"
 
-#define DSI_START              0x00
+/* DSI_START */
 
-#define DSI_INTEN              0x08
+/* DSI_INTEN */
 
-#define DSI_INTSTA             0x0c
+/* DSI_INTSTA */
 #define LPRX_RD_RDY_INT_FLAG           BIT(0)
 #define CMD_DONE_INT_FLAG              BIT(1)
 #define TE_RDY_INT_FLAG                        BIT(2)
@@ -46,12 +48,13 @@
 #define EXT_TE_RDY_INT_FLAG            BIT(4)
 #define DSI_BUSY                       BIT(31)
 
-#define DSI_CON_CTRL           0x10
+/* DSI_CON_CTRL */
 #define DSI_RESET                      BIT(0)
 #define DSI_EN                         BIT(1)
 #define DPHY_RESET                     BIT(2)
+#define CMDMODE_WAIT_DATA_EVERY_LINE_EN        BIT(24)
 
-#define DSI_MODE_CTRL          0x14
+/* DSI_MODE_CTRL */
 #define MODE                           (3)
 #define CMD_MODE                       0
 #define SYNC_PULSE_MODE                        1
@@ -60,7 +63,7 @@
 #define FRM_MODE                       BIT(16)
 #define MIX_MODE                       BIT(17)
 
-#define DSI_TXRX_CTRL          0x18
+/* DSI_TXRX_CTRL */
 #define VC_NUM                         BIT(1)
 #define LANE_NUM                       GENMASK(5, 2)
 #define DIS_EOT                                BIT(6)
@@ -71,7 +74,7 @@
 #define MAX_RTN_SIZE                   GENMASK(15, 12)
 #define HSTX_CKLP_EN                   BIT(16)
 
-#define DSI_PSCTRL             0x1c
+/* DSI_PSCTRL */
 #define DSI_PS_WC                      GENMASK(13, 0)
 #define DSI_PS_SEL                     GENMASK(19, 16)
 #define PACKED_PS_16BIT_RGB565         0
@@ -80,64 +83,64 @@
 #define PACKED_PS_24BIT_RGB888         3
 #define COMPRESSED_PS_DSC              5
 
-#define DSI_VSA_NL             0x20
-#define DSI_VBP_NL             0x24
-#define DSI_VFP_NL             0x28
-#define DSI_VACT_NL            0x2C
+/* DSI_VSA_NL */
+/* DSI_VBP_NL */
+/* DSI_VFP_NL */
+/* DSI_VACT_NL */
 #define VACT_NL                                GENMASK(14, 0)
-#define DSI_SIZE_CON           0x38
-#define DSI_HEIGHT                             GENMASK(30, 16)
-#define DSI_WIDTH                              GENMASK(14, 0)
-#define DSI_HSA_WC             0x50
-#define DSI_HBP_WC             0x54
-#define DSI_HFP_WC             0x58
-#define HFP_HS_VB_PS_WC                GENMASK(30, 16)
+/* DSI_SIZE_CON */
+#define DSI_HEIGHT                     GENMASK(30, 16)
+#define DSI_WIDTH                      GENMASK(14, 0)
+/* DSI_HSA_WC */
+/* DSI_HBP_WC */
+/* DSI_HFP_WC */
+#define HFP_HS_VB_PS_WC                        GENMASK(30, 16)
 #define HFP_HS_EN                      BIT(31)
 
-#define DSI_CMDQ_SIZE          0x60
+/* DSI_CMDQ_SIZE */
 #define CMDQ_SIZE                      0x3f
-#define CMDQ_SIZE_SEL          BIT(15)
+#define CMDQ_SIZE_SEL                  BIT(15)
 
-#define DSI_HSTX_CKL_WC                0x64
+/* DSI_HSTX_CKL_WC */
 #define HSTX_CKL_WC                    GENMASK(15, 2)
 
-#define DSI_RX_DATA0           0x74
-#define DSI_RX_DATA1           0x78
-#define DSI_RX_DATA2           0x7c
-#define DSI_RX_DATA3           0x80
+/* DSI_RX_DATA0 */
+/* DSI_RX_DATA1 */
+/* DSI_RX_DATA2 */
+/* DSI_RX_DATA3 */
 
-#define DSI_RACK               0x84
+/* DSI_RACK */
 #define RACK                           BIT(0)
 
-#define DSI_PHY_LCCON          0x104
+/* DSI_PHY_LCCON */
 #define LC_HS_TX_EN                    BIT(0)
 #define LC_ULPM_EN                     BIT(1)
 #define LC_WAKEUP_EN                   BIT(2)
 
-#define DSI_PHY_LD0CON         0x108
+/* DSI_PHY_LD0CON */
 #define LD0_HS_TX_EN                   BIT(0)
 #define LD0_ULPM_EN                    BIT(1)
 #define LD0_WAKEUP_EN                  BIT(2)
 
-#define DSI_PHY_TIMECON0       0x110
+/* DSI_PHY_TIMECON0 */
 #define LPX                            GENMASK(7, 0)
 #define HS_PREP                                GENMASK(15, 8)
 #define HS_ZERO                                GENMASK(23, 16)
 #define HS_TRAIL                       GENMASK(31, 24)
 
-#define DSI_PHY_TIMECON1       0x114
+/* DSI_PHY_TIMECON1 */
 #define TA_GO                          GENMASK(7, 0)
 #define TA_SURE                                GENMASK(15, 8)
 #define TA_GET                         GENMASK(23, 16)
 #define DA_HS_EXIT                     GENMASK(31, 24)
 
-#define DSI_PHY_TIMECON2       0x118
+/* DSI_PHY_TIMECON2 */
 #define CONT_DET                       GENMASK(7, 0)
 #define DA_HS_SYNC                     GENMASK(15, 8)
 #define CLK_ZERO                       GENMASK(23, 16)
 #define CLK_TRAIL                      GENMASK(31, 24)
 
-#define DSI_PHY_TIMECON3       0x11c
+/* DSI_PHY_TIMECON3 */
 #define CLK_HS_PREP                    GENMASK(7, 0)
 #define CLK_HS_POST                    GENMASK(15, 8)
 #define CLK_HS_EXIT                    GENMASK(23, 16)
@@ -168,6 +171,45 @@
        (type == MIPI_DSI_GENERIC_READ_REQUEST_2_PARAM) || \
        (type == MIPI_DSI_DCS_READ))
 
+enum mtk_dsi_main_regidx {
+       DSI_START,
+       DSI_INTEN,
+       DSI_INTSTA,
+       DSI_CON_CTRL,
+       DSI_MODE_CTRL,
+       DSI_TXRX_CTRL,
+       DSI_PSCTRL,
+       DSI_VSA_NL,
+       DSI_VBP_NL,
+       DSI_VFP_NL,
+       DSI_VACT_NL,
+       DSI_SIZE_CON,
+       DSI_HSA_WC,
+       DSI_HBP_WC,
+       DSI_HFP_WC,
+       DSI_CMDQ_SIZE,
+       DSI_HSTX_CKL_WC,
+       DSI_RX_DATA0,
+       DSI_RX_DATA1,
+       DSI_RX_DATA2,
+       DSI_RX_DATA3,
+       DSI_RACK,
+       DSI_PHY_LCCON,
+       DSI_PHY_LD0CON,
+       DSI_PHY_TIMECON0,
+       DSI_PHY_TIMECON1,
+       DSI_PHY_TIMECON2,
+       DSI_PHY_TIMECON3,
+       DSI_MAIN_REG_MAX
+};
+
+enum mtk_dsi_adv_regidx {
+       DSI_VM_CMD_CON,
+       DSI_SHADOW_DEBUG,
+       DSI_CMDQ,
+       DSI_ADV_REG_MAX
+};
+
 struct mtk_phy_timing {
        u32 lpx;
        u32 da_hs_prepare;
@@ -190,10 +232,9 @@ struct mtk_phy_timing {
 struct phy;
 
 struct mtk_dsi_driver_data {
-       const u32 reg_cmdq_off;
-       const u32 reg_vm_cmd_off;
-       const u32 reg_shadow_dbg_off;
-       bool has_shadow_ctl;
+       const u16 *reg_main;
+       const u16 *reg_adv;
+
        bool has_size_ctl;
        bool cmdq_long_packet_ctl;
        bool support_per_frame_lp;
@@ -231,6 +272,61 @@ struct mtk_dsi {
        const struct mtk_dsi_driver_data *driver_data;
 };
 
+static const u16 mtk_dsi_regs_main_v1[DSI_MAIN_REG_MAX] = {
+       [DSI_START] = 0x00,
+       [DSI_INTEN] = 0x08,
+       [DSI_INTSTA] = 0x0c,
+       [DSI_CON_CTRL] = 0x10,
+       [DSI_MODE_CTRL] = 0x14,
+       [DSI_TXRX_CTRL] = 0x18,
+       [DSI_PSCTRL] = 0x1c,
+       [DSI_VSA_NL] = 0x20,
+       [DSI_VBP_NL] = 0x24,
+       [DSI_VFP_NL] = 0x28,
+       [DSI_VACT_NL] = 0x2c,
+       [DSI_SIZE_CON] = 0x38,
+       [DSI_HSA_WC] = 0x50,
+       [DSI_HBP_WC] = 0x54,
+       [DSI_HFP_WC] = 0x58,
+       [DSI_CMDQ_SIZE] = 0x60,
+       [DSI_HSTX_CKL_WC] = 0x64,
+       [DSI_RX_DATA0] = 0x74,
+       [DSI_RX_DATA1] = 0x78,
+       [DSI_RX_DATA2] = 0x7c,
+       [DSI_RX_DATA3] = 0x80,
+       [DSI_RACK] = 0x84,
+       [DSI_PHY_LCCON] = 0x104,
+       [DSI_PHY_LD0CON] = 0x108,
+       [DSI_PHY_TIMECON0] = 0x110,
+       [DSI_PHY_TIMECON1] = 0x114,
+       [DSI_PHY_TIMECON2] = 0x118,
+       [DSI_PHY_TIMECON3] = 0x11c,
+};
+
+static const u16 mtk_dsi_regs_mt2701[DSI_ADV_REG_MAX] = {
+       [DSI_VM_CMD_CON] = 0x130,
+       [DSI_SHADOW_DEBUG] = 0,
+       [DSI_CMDQ] = 0x180,
+};
+
+static const u16 mtk_dsi_regs_mt8173[DSI_ADV_REG_MAX] = {
+       [DSI_VM_CMD_CON] = 0x130,
+       [DSI_SHADOW_DEBUG] = 0,
+       [DSI_CMDQ] = 0x200,
+};
+
+static const u16 mtk_dsi_regs_mt8183[DSI_ADV_REG_MAX] = {
+       [DSI_VM_CMD_CON] = 0x130,
+       [DSI_SHADOW_DEBUG] = 0x190,
+       [DSI_CMDQ] = 0x200,
+};
+
+static const u16 mtk_dsi_regs_mt8186[DSI_ADV_REG_MAX] = {
+       [DSI_VM_CMD_CON] = 0x200,
+       [DSI_SHADOW_DEBUG] = 0xc00,
+       [DSI_CMDQ] = 0xd00,
+};
+
 static inline struct mtk_dsi *bridge_to_dsi(struct drm_bridge *b)
 {
        return container_of(b, struct mtk_dsi, bridge);
@@ -253,6 +349,7 @@ static void mtk_dsi_phy_timconfig(struct mtk_dsi *dsi)
        u32 timcon0, timcon1, timcon2, timcon3;
        u32 data_rate_mhz = DIV_ROUND_UP(dsi->data_rate, HZ_PER_MHZ);
        struct mtk_phy_timing *timing = &dsi->phy_timing;
+       const u16 *reg_main = dsi->driver_data->reg_main;
 
        timing->lpx = (60 * data_rate_mhz / (8 * 1000)) + 1;
        timing->da_hs_prepare = (80 * data_rate_mhz + 4 * 1000) / 8000;
@@ -289,76 +386,97 @@ static void mtk_dsi_phy_timconfig(struct mtk_dsi *dsi)
                  FIELD_PREP(CLK_HS_POST, timing->clk_hs_post) |
                  FIELD_PREP(CLK_HS_EXIT, timing->clk_hs_exit);
 
-       writel(timcon0, dsi->regs + DSI_PHY_TIMECON0);
-       writel(timcon1, dsi->regs + DSI_PHY_TIMECON1);
-       writel(timcon2, dsi->regs + DSI_PHY_TIMECON2);
-       writel(timcon3, dsi->regs + DSI_PHY_TIMECON3);
+       writel(timcon0, dsi->regs + reg_main[DSI_PHY_TIMECON0]);
+       writel(timcon1, dsi->regs + reg_main[DSI_PHY_TIMECON1]);
+       writel(timcon2, dsi->regs + reg_main[DSI_PHY_TIMECON2]);
+       writel(timcon3, dsi->regs + reg_main[DSI_PHY_TIMECON3]);
 }
 
 static void mtk_dsi_enable(struct mtk_dsi *dsi)
 {
-       mtk_dsi_mask(dsi, DSI_CON_CTRL, DSI_EN, DSI_EN);
+       const u16 *reg_main = dsi->driver_data->reg_main;
+
+       mtk_dsi_mask(dsi, reg_main[DSI_CON_CTRL], DSI_EN, DSI_EN);
 }
 
 static void mtk_dsi_disable(struct mtk_dsi *dsi)
 {
-       mtk_dsi_mask(dsi, DSI_CON_CTRL, DSI_EN, 0);
+       const u16 *reg_main = dsi->driver_data->reg_main;
+
+       mtk_dsi_mask(dsi, reg_main[DSI_CON_CTRL], DSI_EN, 0);
 }
 
 static void mtk_dsi_reset_engine(struct mtk_dsi *dsi)
 {
-       mtk_dsi_mask(dsi, DSI_CON_CTRL, DSI_RESET, DSI_RESET);
-       mtk_dsi_mask(dsi, DSI_CON_CTRL, DSI_RESET, 0);
+       const u16 *reg_main = dsi->driver_data->reg_main;
+
+       mtk_dsi_mask(dsi, reg_main[DSI_CON_CTRL], DSI_RESET, DSI_RESET);
+       mtk_dsi_mask(dsi, reg_main[DSI_CON_CTRL], DSI_RESET, 0);
 }
 
 static void mtk_dsi_reset_dphy(struct mtk_dsi *dsi)
 {
-       mtk_dsi_mask(dsi, DSI_CON_CTRL, DPHY_RESET, DPHY_RESET);
-       mtk_dsi_mask(dsi, DSI_CON_CTRL, DPHY_RESET, 0);
+       const u16 *reg_main = dsi->driver_data->reg_main;
+
+       mtk_dsi_mask(dsi, reg_main[DSI_CON_CTRL], DPHY_RESET, DPHY_RESET);
+       mtk_dsi_mask(dsi, reg_main[DSI_CON_CTRL], DPHY_RESET, 0);
 }
 
 static void mtk_dsi_clk_ulp_mode_enter(struct mtk_dsi *dsi)
 {
-       mtk_dsi_mask(dsi, DSI_PHY_LCCON, LC_HS_TX_EN, 0);
-       mtk_dsi_mask(dsi, DSI_PHY_LCCON, LC_ULPM_EN, 0);
+       const u16 *reg_main = dsi->driver_data->reg_main;
+
+       mtk_dsi_mask(dsi, reg_main[DSI_PHY_LCCON], LC_HS_TX_EN, 0);
+       mtk_dsi_mask(dsi, reg_main[DSI_PHY_LCCON], LC_ULPM_EN, 0);
 }
 
 static void mtk_dsi_clk_ulp_mode_leave(struct mtk_dsi *dsi)
 {
-       mtk_dsi_mask(dsi, DSI_PHY_LCCON, LC_ULPM_EN, 0);
-       mtk_dsi_mask(dsi, DSI_PHY_LCCON, LC_WAKEUP_EN, LC_WAKEUP_EN);
-       mtk_dsi_mask(dsi, DSI_PHY_LCCON, LC_WAKEUP_EN, 0);
+       const u16 *reg_main = dsi->driver_data->reg_main;
+
+       mtk_dsi_mask(dsi, reg_main[DSI_PHY_LCCON], LC_ULPM_EN, 0);
+       mtk_dsi_mask(dsi, reg_main[DSI_PHY_LCCON], LC_WAKEUP_EN, LC_WAKEUP_EN);
+       mtk_dsi_mask(dsi, reg_main[DSI_PHY_LCCON], LC_WAKEUP_EN, 0);
 }
 
 static void mtk_dsi_lane0_ulp_mode_enter(struct mtk_dsi *dsi)
 {
-       mtk_dsi_mask(dsi, DSI_PHY_LD0CON, LD0_HS_TX_EN, 0);
-       mtk_dsi_mask(dsi, DSI_PHY_LD0CON, LD0_ULPM_EN, 0);
+       const u16 *reg_main = dsi->driver_data->reg_main;
+
+       mtk_dsi_mask(dsi, reg_main[DSI_PHY_LD0CON], LD0_HS_TX_EN, 0);
+       mtk_dsi_mask(dsi, reg_main[DSI_PHY_LD0CON], LD0_ULPM_EN, 0);
 }
 
 static void mtk_dsi_lane0_ulp_mode_leave(struct mtk_dsi *dsi)
 {
-       mtk_dsi_mask(dsi, DSI_PHY_LD0CON, LD0_ULPM_EN, 0);
-       mtk_dsi_mask(dsi, DSI_PHY_LD0CON, LD0_WAKEUP_EN, LD0_WAKEUP_EN);
-       mtk_dsi_mask(dsi, DSI_PHY_LD0CON, LD0_WAKEUP_EN, 0);
+       const u16 *reg_main = dsi->driver_data->reg_main;
+
+       mtk_dsi_mask(dsi, reg_main[DSI_PHY_LD0CON], LD0_ULPM_EN, 0);
+       mtk_dsi_mask(dsi, reg_main[DSI_PHY_LD0CON], LD0_WAKEUP_EN, 
LD0_WAKEUP_EN);
+       mtk_dsi_mask(dsi, reg_main[DSI_PHY_LD0CON], LD0_WAKEUP_EN, 0);
 }
 
 static bool mtk_dsi_clk_hs_state(struct mtk_dsi *dsi)
 {
-       return readl(dsi->regs + DSI_PHY_LCCON) & LC_HS_TX_EN;
+       const u16 *regoff = dsi->driver_data->reg_main;
+
+       return readl(dsi->regs + regoff[DSI_PHY_LCCON]) & LC_HS_TX_EN;
 }
 
 static void mtk_dsi_clk_hs_mode(struct mtk_dsi *dsi, bool enter)
 {
+       const u16 *reg_main = dsi->driver_data->reg_main;
+
        if (enter && !mtk_dsi_clk_hs_state(dsi))
-               mtk_dsi_mask(dsi, DSI_PHY_LCCON, LC_HS_TX_EN, LC_HS_TX_EN);
+               mtk_dsi_mask(dsi, reg_main[DSI_PHY_LCCON], LC_HS_TX_EN, 
LC_HS_TX_EN);
        else if (!enter && mtk_dsi_clk_hs_state(dsi))
-               mtk_dsi_mask(dsi, DSI_PHY_LCCON, LC_HS_TX_EN, 0);
+               mtk_dsi_mask(dsi, reg_main[DSI_PHY_LCCON], LC_HS_TX_EN, 0);
 }
 
 static void mtk_dsi_set_mode(struct mtk_dsi *dsi)
 {
-       u32 vid_mode = CMD_MODE;
+       const u16 *reg_main = dsi->driver_data->reg_main;
+       u32 vid_mode;
 
        if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO) {
                if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO_BURST)
@@ -367,19 +485,24 @@ static void mtk_dsi_set_mode(struct mtk_dsi *dsi)
                        vid_mode = SYNC_PULSE_MODE;
                else
                        vid_mode = SYNC_EVENT_MODE;
+       } else {
+               vid_mode = CMD_MODE;
        }
 
-       writel(vid_mode, dsi->regs + DSI_MODE_CTRL);
+       writel(vid_mode, dsi->regs + reg_main[DSI_MODE_CTRL]);
 }
 
 static void mtk_dsi_set_vm_cmd(struct mtk_dsi *dsi)
 {
-       mtk_dsi_mask(dsi, dsi->driver_data->reg_vm_cmd_off, VM_CMD_EN, 
VM_CMD_EN);
-       mtk_dsi_mask(dsi, dsi->driver_data->reg_vm_cmd_off, TS_VFP_EN, 
TS_VFP_EN);
+       const u16 *reg_adv = dsi->driver_data->reg_adv;
+
+       mtk_dsi_mask(dsi, reg_adv[DSI_VM_CMD_CON], VM_CMD_EN, VM_CMD_EN);
+       mtk_dsi_mask(dsi, reg_adv[DSI_VM_CMD_CON], TS_VFP_EN, TS_VFP_EN);
 }
 
 static void mtk_dsi_rxtx_control(struct mtk_dsi *dsi)
 {
+       const u16 *reg_main = dsi->driver_data->reg_main;
        u32 regval, tmp_reg = 0;
        u8 i;
 
@@ -395,11 +518,13 @@ static void mtk_dsi_rxtx_control(struct mtk_dsi *dsi)
        if (dsi->mode_flags & MIPI_DSI_MODE_NO_EOT_PACKET)
                regval |= DIS_EOT;
 
-       writel(regval, dsi->regs + DSI_TXRX_CTRL);
+       writel(regval, dsi->regs + reg_main[DSI_TXRX_CTRL]);
 }
 
 static void mtk_dsi_ps_control(struct mtk_dsi *dsi, bool config_vact)
 {
+       const struct mtk_dsi_driver_data *data = dsi->driver_data;
+       const u16 *reg_main = dsi->driver_data->reg_main;
        u32 dsi_buf_bpp, ps_val, ps_wc, size_val, vact_nl;
 
        if (dsi->format == MIPI_DSI_FMT_RGB565)
@@ -437,12 +562,12 @@ static void mtk_dsi_ps_control(struct mtk_dsi *dsi, bool 
config_vact)
 
        if (config_vact) {
                vact_nl = FIELD_PREP(VACT_NL, dsi->vm.vactive);
-               writel(vact_nl, dsi->regs + DSI_VACT_NL);
-               writel(ps_wc, dsi->regs + DSI_HSTX_CKL_WC);
+               writel(vact_nl, dsi->regs + reg_main[DSI_VACT_NL]);
+               writel(ps_wc, dsi->regs + reg_main[DSI_HSTX_CKL_WC]);
        }
-       writel(ps_val, dsi->regs + DSI_PSCTRL);
+       writel(ps_val, dsi->regs + reg_main[DSI_PSCTRL]);
 
-       if (dsi->driver_data->has_size_ctl) {
+       if (data->has_size_ctl) {
                size_val = FIELD_PREP(DSI_HEIGHT, dsi->vm.vactive);
                if (dsi->dsc)
                        size_val |= FIELD_PREP(DSI_WIDTH,
@@ -451,12 +576,13 @@ static void mtk_dsi_ps_control(struct mtk_dsi *dsi, bool 
config_vact)
                else
                        size_val |= FIELD_PREP(DSI_WIDTH, dsi->vm.hactive);
 
-               writel(size_val, dsi->regs + DSI_SIZE_CON);
+               writel(size_val, dsi->regs + reg_main[DSI_SIZE_CON]);
        }
 }
 
 static void mtk_dsi_config_vdo_timing_per_frame_lp(struct mtk_dsi *dsi)
 {
+       const u16 *reg_main = dsi->driver_data->reg_main;
        u32 horizontal_sync_active_byte;
        u32 horizontal_backporch_byte;
        u32 horizontal_frontporch_byte;
@@ -511,20 +637,21 @@ static void mtk_dsi_config_vdo_timing_per_frame_lp(struct 
mtk_dsi *dsi)
                           ps_wc), dsi->lanes) + da_hs_trail + 1) * dsi->lanes 
/ 6 - 1;
 
        hstx_cklp_wc = FIELD_PREP(HSTX_CKL_WC, (hstx_cklp_wc_min + 
hstx_cklp_wc_max) / 2);
-       writel(hstx_cklp_wc, dsi->regs + DSI_HSTX_CKL_WC);
+       writel(hstx_cklp_wc, dsi->regs + reg_main[DSI_HSTX_CKL_WC]);
 
        hs_vb_ps_wc = ps_wc - (dsi->phy_timing.lpx + dsi->phy_timing.da_hs_exit 
+
                      dsi->phy_timing.da_hs_prepare + 
dsi->phy_timing.da_hs_zero + 2) * dsi->lanes;
        horizontal_frontporch_byte |= FIELD_PREP(HFP_HS_EN, 1) |
                                      FIELD_PREP(HFP_HS_VB_PS_WC, hs_vb_ps_wc);
 
-       writel(horizontal_sync_active_byte, dsi->regs + DSI_HSA_WC);
-       writel(horizontal_backporch_byte, dsi->regs + DSI_HBP_WC);
-       writel(horizontal_frontporch_byte, dsi->regs + DSI_HFP_WC);
+       writel(horizontal_sync_active_byte, dsi->regs + reg_main[DSI_HSA_WC]);
+       writel(horizontal_backporch_byte, dsi->regs + reg_main[DSI_HBP_WC]);
+       writel(horizontal_frontporch_byte, dsi->regs + reg_main[DSI_HFP_WC]);
 }
 
 static void mtk_dsi_config_vdo_timing_per_line_lp(struct mtk_dsi *dsi)
 {
+       const u16 *reg_main = dsi->driver_data->reg_main;
        u32 horizontal_sync_active_byte;
        u32 horizontal_backporch_byte;
        u32 horizontal_frontporch_byte;
@@ -582,9 +709,9 @@ static void mtk_dsi_config_vdo_timing_per_line_lp(struct 
mtk_dsi *dsi)
                        (vm->hactive * dsi_tmp_buf_bpp + 2) % dsi->lanes;
        }
 
-       writel(horizontal_sync_active_byte, dsi->regs + DSI_HSA_WC);
-       writel(horizontal_backporch_byte, dsi->regs + DSI_HBP_WC);
-       writel(horizontal_frontporch_byte, dsi->regs + DSI_HFP_WC);
+       writel(horizontal_sync_active_byte, dsi->regs + reg_main[DSI_HSA_WC]);
+       writel(horizontal_backporch_byte, dsi->regs + reg_main[DSI_HBP_WC]);
+       writel(horizontal_frontporch_byte, dsi->regs + reg_main[DSI_HFP_WC]);
 }
 
 static int mtk_dsi_set_dsc_params(struct mtk_dsi *dsi)
@@ -625,14 +752,16 @@ static int mtk_dsi_set_dsc_params(struct mtk_dsi *dsi)
 
 static int mtk_dsi_config_vdo_timing(struct mtk_dsi *dsi)
 {
+       const struct mtk_dsi_driver_data *data = dsi->driver_data;
+       const u16 *reg_main = data->reg_main;
        struct videomode *vm = &dsi->vm;
 
-       writel(vm->vsync_len, dsi->regs + DSI_VSA_NL);
-       writel(vm->vback_porch, dsi->regs + DSI_VBP_NL);
-       writel(vm->vfront_porch, dsi->regs + DSI_VFP_NL);
-       writel(vm->vactive, dsi->regs + DSI_VACT_NL);
+       writel(vm->vsync_len, dsi->regs + reg_main[DSI_VSA_NL]);
+       writel(vm->vback_porch, dsi->regs + reg_main[DSI_VBP_NL]);
+       writel(vm->vfront_porch, dsi->regs + reg_main[DSI_VFP_NL]);
+       writel(vm->vactive, dsi->regs + reg_main[DSI_VACT_NL]);
 
-       if (dsi->driver_data->support_per_frame_lp)
+       if (data->support_per_frame_lp)
                mtk_dsi_config_vdo_timing_per_frame_lp(dsi);
        else
                mtk_dsi_config_vdo_timing_per_line_lp(dsi);
@@ -647,25 +776,25 @@ static int mtk_dsi_config_vdo_timing(struct mtk_dsi *dsi)
 
 static void mtk_dsi_start(struct mtk_dsi *dsi)
 {
-       writel(0, dsi->regs + DSI_START);
-       writel(1, dsi->regs + DSI_START);
+       writel(0, dsi->regs + dsi->driver_data->reg_main[DSI_START]);
+       writel(1, dsi->regs + dsi->driver_data->reg_main[DSI_START]);
 }
 
 static void mtk_dsi_stop(struct mtk_dsi *dsi)
 {
-       writel(0, dsi->regs + DSI_START);
+       writel(0, dsi->regs + dsi->driver_data->reg_main[DSI_START]);
 }
 
 static void mtk_dsi_set_cmd_mode(struct mtk_dsi *dsi)
 {
-       writel(CMD_MODE, dsi->regs + DSI_MODE_CTRL);
+       writel(CMD_MODE, dsi->regs + dsi->driver_data->reg_main[DSI_MODE_CTRL]);
 }
 
 static void mtk_dsi_set_interrupt_enable(struct mtk_dsi *dsi)
 {
        u32 inten = LPRX_RD_RDY_INT_FLAG | CMD_DONE_INT_FLAG | VM_DONE_INT_FLAG;
 
-       writel(inten, dsi->regs + DSI_INTEN);
+       writel(inten, dsi->regs + dsi->driver_data->reg_main[DSI_INTEN]);
 }
 
 static void mtk_dsi_irq_data_set(struct mtk_dsi *dsi, u32 irq_bit)
@@ -699,19 +828,20 @@ static s32 mtk_dsi_wait_for_irq_done(struct mtk_dsi *dsi, 
u32 irq_flag,
 
 static irqreturn_t mtk_dsi_irq(int irq, void *dev_id)
 {
-       struct mtk_dsi *dsi = dev_id;
        u32 status, tmp;
-       u32 flag = LPRX_RD_RDY_INT_FLAG | CMD_DONE_INT_FLAG | VM_DONE_INT_FLAG;
+       struct mtk_dsi *dsi = dev_id;
+       const u16 *reg_main = dsi->driver_data->reg_main;
+       const u32 flag = LPRX_RD_RDY_INT_FLAG | CMD_DONE_INT_FLAG | 
VM_DONE_INT_FLAG;
 
-       status = readl(dsi->regs + DSI_INTSTA) & flag;
+       status = readl(dsi->regs + dsi->driver_data->reg_main[DSI_INTSTA]) & 
flag;
 
        if (status) {
                do {
-                       mtk_dsi_mask(dsi, DSI_RACK, RACK, RACK);
-                       tmp = readl(dsi->regs + DSI_INTSTA);
+                       mtk_dsi_mask(dsi, reg_main[DSI_RACK], RACK, RACK);
+                       tmp = readl(dsi->regs + reg_main[DSI_INTSTA]);
                } while (tmp & DSI_BUSY);
 
-               mtk_dsi_mask(dsi, DSI_INTSTA, status, 0);
+               mtk_dsi_mask(dsi, reg_main[DSI_INTSTA], status, 0);
                mtk_dsi_irq_data_set(dsi, status);
                wake_up_interruptible(&dsi->irq_wait_queue);
        }
@@ -749,9 +879,10 @@ static void mtk_dsi_lane_ready(struct mtk_dsi *dsi)
 
 static int mtk_dsi_poweron(struct mtk_dsi *dsi)
 {
+       const struct mtk_dsi_driver_data *data = dsi->driver_data;
        struct device *dev = dsi->host.dev;
-       int ret;
        u32 bit_per_pixel;
+       int ret;
 
        if (++dsi->refcount != 1)
                return 0;
@@ -788,9 +919,10 @@ static int mtk_dsi_poweron(struct mtk_dsi *dsi)
 
        mtk_dsi_enable(dsi);
 
-       if (dsi->driver_data->has_shadow_ctl)
+       /* Bypass shadow and force commit only if the register is present */
+       if (data->reg_adv[DSI_SHADOW_DEBUG])
                writel(FORCE_COMMIT | BYPASS_SHADOW,
-                      dsi->regs + dsi->driver_data->reg_shadow_dbg_off);
+                      dsi->regs + data->reg_adv[DSI_SHADOW_DEBUG]);
 
        mtk_dsi_reset_engine(dsi);
        mtk_dsi_phy_timconfig(dsi);
@@ -839,7 +971,7 @@ static void mtk_dsi_poweroff(struct mtk_dsi *dsi)
        mtk_dsi_lane0_ulp_mode_enter(dsi);
        mtk_dsi_clk_ulp_mode_enter(dsi);
        /* set the lane number as 0 to pull down mipi */
-       writel(0, dsi->regs + DSI_TXRX_CTRL);
+       writel(0, dsi->regs + dsi->driver_data->reg_main[DSI_TXRX_CTRL]);
 
        mtk_dsi_disable(dsi);
 
@@ -1122,11 +1254,12 @@ static int mtk_dsi_host_detach(struct mipi_dsi_host 
*host,
 
 static void mtk_dsi_wait_for_idle(struct mtk_dsi *dsi)
 {
+       const struct mtk_dsi_driver_data *data = dsi->driver_data;
        int ret;
        u32 val;
 
-       ret = readl_poll_timeout(dsi->regs + DSI_INTSTA, val, !(val & DSI_BUSY),
-                                4, 2000000);
+       ret = readl_poll_timeout(dsi->regs + data->reg_main[DSI_INTSTA],
+                                val, !(val & DSI_BUSY), 4, 2000000);
        if (ret) {
                DRM_WARN("polling dsi wait not busy timeout!\n");
 
@@ -1160,10 +1293,12 @@ static u32 mtk_dsi_recv_cnt(u8 type, u8 *read_data)
 
 static void mtk_dsi_cmdq(struct mtk_dsi *dsi, const struct mipi_dsi_msg *msg)
 {
+       const struct mtk_dsi_driver_data *data = dsi->driver_data;
        const char *tx_buf = msg->tx_buf;
-       u8 config, cmdq_size, cmdq_off, type = msg->type;
+       const u8 type = msg->type;
        u32 reg_val, cmdq_mask, i;
-       u32 reg_cmdq_off = dsi->driver_data->reg_cmdq_off;
+       u8 cmdq_size, cmdq_off;
+       u8 config;
 
        if (MTK_DSI_HOST_IS_READ(type))
                config = BTA;
@@ -1186,15 +1321,15 @@ static void mtk_dsi_cmdq(struct mtk_dsi *dsi, const 
struct mipi_dsi_msg *msg)
        }
 
        for (i = 0; i < msg->tx_len; i++)
-               mtk_dsi_mask(dsi, (reg_cmdq_off + cmdq_off + i) & (~0x3U),
+               mtk_dsi_mask(dsi, (data->reg_adv[DSI_CMDQ] + cmdq_off + i) & 
(~0x3U),
                             (0xffUL << (((i + cmdq_off) & 3U) * 8U)),
                             tx_buf[i] << (((i + cmdq_off) & 3U) * 8U));
 
-       mtk_dsi_mask(dsi, reg_cmdq_off, cmdq_mask, reg_val);
-       mtk_dsi_mask(dsi, DSI_CMDQ_SIZE, CMDQ_SIZE, cmdq_size);
-       if (dsi->driver_data->cmdq_long_packet_ctl) {
+       mtk_dsi_mask(dsi, data->reg_adv[DSI_CMDQ], cmdq_mask, reg_val);
+       mtk_dsi_mask(dsi, data->reg_main[DSI_CMDQ_SIZE], CMDQ_SIZE, cmdq_size);
+       if (data->cmdq_long_packet_ctl) {
                /* Disable setting cmdq_size automatically for long packets */
-               mtk_dsi_mask(dsi, DSI_CMDQ_SIZE, CMDQ_SIZE_SEL, CMDQ_SIZE_SEL);
+               mtk_dsi_mask(dsi, data->reg_main[DSI_CMDQ_SIZE], CMDQ_SIZE_SEL, 
CMDQ_SIZE_SEL);
        }
 }
 
@@ -1223,7 +1358,7 @@ static ssize_t mtk_dsi_host_transfer(struct mipi_dsi_host 
*host,
        u32 dsi_mode;
        int ret, i;
 
-       dsi_mode = readl(dsi->regs + DSI_MODE_CTRL);
+       dsi_mode = readl(dsi->regs + dsi->driver_data->reg_main[DSI_MODE_CTRL]);
        if (dsi_mode & MODE) {
                mtk_dsi_stop(dsi);
                ret = mtk_dsi_switch_to_cmd_mode(dsi, VM_DONE_INT_FLAG, 500);
@@ -1252,7 +1387,8 @@ static ssize_t mtk_dsi_host_transfer(struct mipi_dsi_host 
*host,
        }
 
        for (i = 0; i < 16; i++)
-               *(read_data + i) = readb(dsi->regs + DSI_RX_DATA0 + i);
+               *(read_data + i) = readb(dsi->regs +
+                                        
dsi->driver_data->reg_main[DSI_RX_DATA0 + i]);
 
        recv_cnt = mtk_dsi_recv_cnt(read_data[0], read_data);
 
@@ -1361,38 +1497,30 @@ static void mtk_dsi_remove(struct platform_device *pdev)
 }
 
 static const struct mtk_dsi_driver_data mt8173_dsi_driver_data = {
-       .reg_cmdq_off = 0x200,
-       .reg_vm_cmd_off = 0x130,
-       .reg_shadow_dbg_off = 0x190
+       .reg_main = mtk_dsi_regs_main_v1,
+       .reg_adv = mtk_dsi_regs_mt8173,
 };
 
 static const struct mtk_dsi_driver_data mt2701_dsi_driver_data = {
-       .reg_cmdq_off = 0x180,
-       .reg_vm_cmd_off = 0x130,
-       .reg_shadow_dbg_off = 0x190
+       .reg_main = mtk_dsi_regs_main_v1,
+       .reg_adv = mtk_dsi_regs_mt2701,
 };
 
 static const struct mtk_dsi_driver_data mt8183_dsi_driver_data = {
-       .reg_cmdq_off = 0x200,
-       .reg_vm_cmd_off = 0x130,
-       .reg_shadow_dbg_off = 0x190,
-       .has_shadow_ctl = true,
+       .reg_main = mtk_dsi_regs_main_v1,
+       .reg_adv = mtk_dsi_regs_mt8183,
        .has_size_ctl = true,
 };
 
 static const struct mtk_dsi_driver_data mt8186_dsi_driver_data = {
-       .reg_cmdq_off = 0xd00,
-       .reg_vm_cmd_off = 0x200,
-       .reg_shadow_dbg_off = 0xc00,
-       .has_shadow_ctl = true,
+       .reg_main = mtk_dsi_regs_main_v1,
+       .reg_adv = mtk_dsi_regs_mt8186,
        .has_size_ctl = true,
 };
 
 static const struct mtk_dsi_driver_data mt8188_dsi_driver_data = {
-       .reg_cmdq_off = 0xd00,
-       .reg_vm_cmd_off = 0x200,
-       .reg_shadow_dbg_off = 0xc00,
-       .has_shadow_ctl = true,
+       .reg_main = mtk_dsi_regs_main_v1,
+       .reg_adv = mtk_dsi_regs_mt8186,
        .has_size_ctl = true,
        .cmdq_long_packet_ctl = true,
        .support_per_frame_lp = true,
-- 
2.54.0

Reply via email to