soc / drm: mediatek: Move routing control to mmsys device
authorEnric Balletbo i Serra <enric.balletbo@collabora.com>
Wed, 25 Mar 2020 17:31:22 +0000 (18:31 +0100)
committerMatthias Brugger <matthias.bgg@gmail.com>
Mon, 13 Apr 2020 11:01:16 +0000 (13:01 +0200)
Provide a mtk_mmsys_ddp_connect() and mtk_mmsys_disconnect() functions to
replace mtk_ddp_add_comp_to_path() and mtk_ddp_remove_comp_from_path().
Those functions will allow DRM driver and others to control the data
path routing.

Signed-off-by: Enric Balletbo i Serra <enric.balletbo@collabora.com>
Reviewed-by: Matthias Brugger <matthias.bgg@gmail.com>
Reviewed-by: CK Hu <ck.hu@mediatek.com>
Acked-by: CK Hu <ck.hu@mediatek.com>
Tested-by: Anders Roxell <anders.roxell@linaro.org>
Reviewed-by: Chun-Kuang Hu <chunkuang.hu@kernel.org>
Signed-off-by: Matthias Brugger <matthias.bgg@gmail.com>
drivers/gpu/drm/mediatek/Kconfig
drivers/gpu/drm/mediatek/mtk_drm_crtc.c
drivers/gpu/drm/mediatek/mtk_drm_ddp.c
drivers/gpu/drm/mediatek/mtk_drm_ddp.h
drivers/gpu/drm/mediatek/mtk_drm_drv.c
drivers/gpu/drm/mediatek/mtk_drm_drv.h
drivers/soc/mediatek/mtk-mmsys.c
include/linux/soc/mediatek/mtk-mmsys.h [new file with mode: 0644]

index fa5ffc4..c420f5a 100644 (file)
@@ -11,6 +11,7 @@ config DRM_MEDIATEK
        select DRM_MIPI_DSI
        select DRM_PANEL
        select MEMORY
+       select MTK_MMSYS
        select MTK_SMI
        select VIDEOMODE_HELPERS
        help
index fe85e48..fe46c4b 100644 (file)
@@ -6,6 +6,7 @@
 #include <linux/clk.h>
 #include <linux/pm_runtime.h>
 #include <linux/soc/mediatek/mtk-cmdq.h>
+#include <linux/soc/mediatek/mtk-mmsys.h>
 
 #include <asm/barrier.h>
 #include <soc/mediatek/smi.h>
@@ -28,7 +29,7 @@
  * @enabled: records whether crtc_enable succeeded
  * @planes: array of 4 drm_plane structures, one for each overlay plane
  * @pending_planes: whether any plane has pending changes to be applied
- * @config_regs: memory mapped mmsys configuration register space
+ * @mmsys_dev: pointer to the mmsys device for configuration registers
  * @mutex: handle to one of the ten disp_mutex streams
  * @ddp_comp_nr: number of components in ddp_comp
  * @ddp_comp: array of pointers the mtk_ddp_comp structures used by this crtc
@@ -50,7 +51,7 @@ struct mtk_drm_crtc {
        u32                             cmdq_event;
 #endif
 
-       void __iomem                    *config_regs;
+       struct device                   *mmsys_dev;
        struct mtk_disp_mutex           *mutex;
        unsigned int                    ddp_comp_nr;
        struct mtk_ddp_comp             **ddp_comp;
@@ -300,9 +301,9 @@ static int mtk_crtc_ddp_hw_init(struct mtk_drm_crtc *mtk_crtc)
 
        DRM_DEBUG_DRIVER("mediatek_ddp_ddp_path_setup\n");
        for (i = 0; i < mtk_crtc->ddp_comp_nr - 1; i++) {
-               mtk_ddp_add_comp_to_path(mtk_crtc->config_regs,
-                                        mtk_crtc->ddp_comp[i]->id,
-                                        mtk_crtc->ddp_comp[i + 1]->id);
+               mtk_mmsys_ddp_connect(mtk_crtc->mmsys_dev,
+                                     mtk_crtc->ddp_comp[i]->id,
+                                     mtk_crtc->ddp_comp[i + 1]->id);
                mtk_disp_mutex_add_comp(mtk_crtc->mutex,
                                        mtk_crtc->ddp_comp[i]->id);
        }
@@ -360,9 +361,9 @@ static void mtk_crtc_ddp_hw_fini(struct mtk_drm_crtc *mtk_crtc)
                                           mtk_crtc->ddp_comp[i]->id);
        mtk_disp_mutex_disable(mtk_crtc->mutex);
        for (i = 0; i < mtk_crtc->ddp_comp_nr - 1; i++) {
-               mtk_ddp_remove_comp_from_path(mtk_crtc->config_regs,
-                                             mtk_crtc->ddp_comp[i]->id,
-                                             mtk_crtc->ddp_comp[i + 1]->id);
+               mtk_mmsys_ddp_disconnect(mtk_crtc->mmsys_dev,
+                                        mtk_crtc->ddp_comp[i]->id,
+                                        mtk_crtc->ddp_comp[i + 1]->id);
                mtk_disp_mutex_remove_comp(mtk_crtc->mutex,
                                           mtk_crtc->ddp_comp[i]->id);
        }
@@ -766,7 +767,7 @@ int mtk_drm_crtc_create(struct drm_device *drm_dev,
        if (!mtk_crtc)
                return -ENOMEM;
 
-       mtk_crtc->config_regs = priv->config_regs;
+       mtk_crtc->mmsys_dev = priv->mmsys_dev;
        mtk_crtc->ddp_comp_nr = path_len;
        mtk_crtc->ddp_comp = devm_kmalloc_array(dev, mtk_crtc->ddp_comp_nr,
                                                sizeof(*mtk_crtc->ddp_comp),
index b885f60..014c1bb 100644 (file)
 #include "mtk_drm_ddp.h"
 #include "mtk_drm_ddp_comp.h"
 
-#define DISP_REG_CONFIG_DISP_OVL0_MOUT_EN      0x040
-#define DISP_REG_CONFIG_DISP_OVL1_MOUT_EN      0x044
-#define DISP_REG_CONFIG_DISP_OD_MOUT_EN                0x048
-#define DISP_REG_CONFIG_DISP_GAMMA_MOUT_EN     0x04c
-#define DISP_REG_CONFIG_DISP_UFOE_MOUT_EN      0x050
-#define DISP_REG_CONFIG_DISP_COLOR0_SEL_IN     0x084
-#define DISP_REG_CONFIG_DISP_COLOR1_SEL_IN     0x088
-#define DISP_REG_CONFIG_DSIE_SEL_IN            0x0a4
-#define DISP_REG_CONFIG_DSIO_SEL_IN            0x0a8
-#define DISP_REG_CONFIG_DPI_SEL_IN             0x0ac
-#define DISP_REG_CONFIG_DISP_RDMA2_SOUT                0x0b8
-#define DISP_REG_CONFIG_DISP_RDMA0_SOUT_EN     0x0c4
-#define DISP_REG_CONFIG_DISP_RDMA1_SOUT_EN     0x0c8
-#define DISP_REG_CONFIG_MMSYS_CG_CON0          0x100
-
-#define DISP_REG_CONFIG_DISP_OVL_MOUT_EN       0x030
-#define DISP_REG_CONFIG_OUT_SEL                        0x04c
-#define DISP_REG_CONFIG_DSI_SEL                        0x050
-#define DISP_REG_CONFIG_DPI_SEL                        0x064
-
 #define MT2701_DISP_MUTEX0_MOD0                        0x2c
 #define MT2701_DISP_MUTEX0_SOF0                        0x30
 
 #define MUTEX_SOF_DSI2                 5
 #define MUTEX_SOF_DSI3                 6
 
-#define OVL0_MOUT_EN_COLOR0            0x1
-#define OD_MOUT_EN_RDMA0               0x1
-#define OD1_MOUT_EN_RDMA1              BIT(16)
-#define UFOE_MOUT_EN_DSI0              0x1
-#define COLOR0_SEL_IN_OVL0             0x1
-#define OVL1_MOUT_EN_COLOR1            0x1
-#define GAMMA_MOUT_EN_RDMA1            0x1
-#define RDMA0_SOUT_DPI0                        0x2
-#define RDMA0_SOUT_DPI1                        0x3
-#define RDMA0_SOUT_DSI1                        0x1
-#define RDMA0_SOUT_DSI2                        0x4
-#define RDMA0_SOUT_DSI3                        0x5
-#define RDMA1_SOUT_DPI0                        0x2
-#define RDMA1_SOUT_DPI1                        0x3
-#define RDMA1_SOUT_DSI1                        0x1
-#define RDMA1_SOUT_DSI2                        0x4
-#define RDMA1_SOUT_DSI3                        0x5
-#define RDMA2_SOUT_DPI0                        0x2
-#define RDMA2_SOUT_DPI1                        0x3
-#define RDMA2_SOUT_DSI1                        0x1
-#define RDMA2_SOUT_DSI2                        0x4
-#define RDMA2_SOUT_DSI3                        0x5
-#define DPI0_SEL_IN_RDMA1              0x1
-#define DPI0_SEL_IN_RDMA2              0x3
-#define DPI1_SEL_IN_RDMA1              (0x1 << 8)
-#define DPI1_SEL_IN_RDMA2              (0x3 << 8)
-#define DSI0_SEL_IN_RDMA1              0x1
-#define DSI0_SEL_IN_RDMA2              0x4
-#define DSI1_SEL_IN_RDMA1              0x1
-#define DSI1_SEL_IN_RDMA2              0x4
-#define DSI2_SEL_IN_RDMA1              (0x1 << 16)
-#define DSI2_SEL_IN_RDMA2              (0x4 << 16)
-#define DSI3_SEL_IN_RDMA1              (0x1 << 16)
-#define DSI3_SEL_IN_RDMA2              (0x4 << 16)
-#define COLOR1_SEL_IN_OVL1             0x1
-
-#define OVL_MOUT_EN_RDMA               0x1
-#define BLS_TO_DSI_RDMA1_TO_DPI1       0x8
-#define BLS_TO_DPI_RDMA1_TO_DSI                0x2
-#define DSI_SEL_IN_BLS                 0x0
-#define DPI_SEL_IN_BLS                 0x0
-#define DSI_SEL_IN_RDMA                        0x1
 
 struct mtk_disp_mutex {
        int id;
@@ -246,200 +184,6 @@ static const struct mtk_ddp_data mt8173_ddp_driver_data = {
        .mutex_sof_reg = MT2701_DISP_MUTEX0_SOF0,
 };
 
-static unsigned int mtk_ddp_mout_en(enum mtk_ddp_comp_id cur,
-                                   enum mtk_ddp_comp_id next,
-                                   unsigned int *addr)
-{
-       unsigned int value;
-
-       if (cur == DDP_COMPONENT_OVL0 && next == DDP_COMPONENT_COLOR0) {
-               *addr = DISP_REG_CONFIG_DISP_OVL0_MOUT_EN;
-               value = OVL0_MOUT_EN_COLOR0;
-       } else if (cur == DDP_COMPONENT_OVL0 && next == DDP_COMPONENT_RDMA0) {
-               *addr = DISP_REG_CONFIG_DISP_OVL_MOUT_EN;
-               value = OVL_MOUT_EN_RDMA;
-       } else if (cur == DDP_COMPONENT_OD0 && next == DDP_COMPONENT_RDMA0) {
-               *addr = DISP_REG_CONFIG_DISP_OD_MOUT_EN;
-               value = OD_MOUT_EN_RDMA0;
-       } else if (cur == DDP_COMPONENT_UFOE && next == DDP_COMPONENT_DSI0) {
-               *addr = DISP_REG_CONFIG_DISP_UFOE_MOUT_EN;
-               value = UFOE_MOUT_EN_DSI0;
-       } else if (cur == DDP_COMPONENT_OVL1 && next == DDP_COMPONENT_COLOR1) {
-               *addr = DISP_REG_CONFIG_DISP_OVL1_MOUT_EN;
-               value = OVL1_MOUT_EN_COLOR1;
-       } else if (cur == DDP_COMPONENT_GAMMA && next == DDP_COMPONENT_RDMA1) {
-               *addr = DISP_REG_CONFIG_DISP_GAMMA_MOUT_EN;
-               value = GAMMA_MOUT_EN_RDMA1;
-       } else if (cur == DDP_COMPONENT_OD1 && next == DDP_COMPONENT_RDMA1) {
-               *addr = DISP_REG_CONFIG_DISP_OD_MOUT_EN;
-               value = OD1_MOUT_EN_RDMA1;
-       } else if (cur == DDP_COMPONENT_RDMA0 && next == DDP_COMPONENT_DPI0) {
-               *addr = DISP_REG_CONFIG_DISP_RDMA0_SOUT_EN;
-               value = RDMA0_SOUT_DPI0;
-       } else if (cur == DDP_COMPONENT_RDMA0 && next == DDP_COMPONENT_DPI1) {
-               *addr = DISP_REG_CONFIG_DISP_RDMA0_SOUT_EN;
-               value = RDMA0_SOUT_DPI1;
-       } else if (cur == DDP_COMPONENT_RDMA0 && next == DDP_COMPONENT_DSI1) {
-               *addr = DISP_REG_CONFIG_DISP_RDMA0_SOUT_EN;
-               value = RDMA0_SOUT_DSI1;
-       } else if (cur == DDP_COMPONENT_RDMA0 && next == DDP_COMPONENT_DSI2) {
-               *addr = DISP_REG_CONFIG_DISP_RDMA0_SOUT_EN;
-               value = RDMA0_SOUT_DSI2;
-       } else if (cur == DDP_COMPONENT_RDMA0 && next == DDP_COMPONENT_DSI3) {
-               *addr = DISP_REG_CONFIG_DISP_RDMA0_SOUT_EN;
-               value = RDMA0_SOUT_DSI3;
-       } else if (cur == DDP_COMPONENT_RDMA1 && next == DDP_COMPONENT_DSI1) {
-               *addr = DISP_REG_CONFIG_DISP_RDMA1_SOUT_EN;
-               value = RDMA1_SOUT_DSI1;
-       } else if (cur == DDP_COMPONENT_RDMA1 && next == DDP_COMPONENT_DSI2) {
-               *addr = DISP_REG_CONFIG_DISP_RDMA1_SOUT_EN;
-               value = RDMA1_SOUT_DSI2;
-       } else if (cur == DDP_COMPONENT_RDMA1 && next == DDP_COMPONENT_DSI3) {
-               *addr = DISP_REG_CONFIG_DISP_RDMA1_SOUT_EN;
-               value = RDMA1_SOUT_DSI3;
-       } else if (cur == DDP_COMPONENT_RDMA1 && next == DDP_COMPONENT_DPI0) {
-               *addr = DISP_REG_CONFIG_DISP_RDMA1_SOUT_EN;
-               value = RDMA1_SOUT_DPI0;
-       } else if (cur == DDP_COMPONENT_RDMA1 && next == DDP_COMPONENT_DPI1) {
-               *addr = DISP_REG_CONFIG_DISP_RDMA1_SOUT_EN;
-               value = RDMA1_SOUT_DPI1;
-       } else if (cur == DDP_COMPONENT_RDMA2 && next == DDP_COMPONENT_DPI0) {
-               *addr = DISP_REG_CONFIG_DISP_RDMA2_SOUT;
-               value = RDMA2_SOUT_DPI0;
-       } else if (cur == DDP_COMPONENT_RDMA2 && next == DDP_COMPONENT_DPI1) {
-               *addr = DISP_REG_CONFIG_DISP_RDMA2_SOUT;
-               value = RDMA2_SOUT_DPI1;
-       } else if (cur == DDP_COMPONENT_RDMA2 && next == DDP_COMPONENT_DSI1) {
-               *addr = DISP_REG_CONFIG_DISP_RDMA2_SOUT;
-               value = RDMA2_SOUT_DSI1;
-       } else if (cur == DDP_COMPONENT_RDMA2 && next == DDP_COMPONENT_DSI2) {
-               *addr = DISP_REG_CONFIG_DISP_RDMA2_SOUT;
-               value = RDMA2_SOUT_DSI2;
-       } else if (cur == DDP_COMPONENT_RDMA2 && next == DDP_COMPONENT_DSI3) {
-               *addr = DISP_REG_CONFIG_DISP_RDMA2_SOUT;
-               value = RDMA2_SOUT_DSI3;
-       } else {
-               value = 0;
-       }
-
-       return value;
-}
-
-static unsigned int mtk_ddp_sel_in(enum mtk_ddp_comp_id cur,
-                                  enum mtk_ddp_comp_id next,
-                                  unsigned int *addr)
-{
-       unsigned int value;
-
-       if (cur == DDP_COMPONENT_OVL0 && next == DDP_COMPONENT_COLOR0) {
-               *addr = DISP_REG_CONFIG_DISP_COLOR0_SEL_IN;
-               value = COLOR0_SEL_IN_OVL0;
-       } else if (cur == DDP_COMPONENT_RDMA1 && next == DDP_COMPONENT_DPI0) {
-               *addr = DISP_REG_CONFIG_DPI_SEL_IN;
-               value = DPI0_SEL_IN_RDMA1;
-       } else if (cur == DDP_COMPONENT_RDMA1 && next == DDP_COMPONENT_DPI1) {
-               *addr = DISP_REG_CONFIG_DPI_SEL_IN;
-               value = DPI1_SEL_IN_RDMA1;
-       } else if (cur == DDP_COMPONENT_RDMA1 && next == DDP_COMPONENT_DSI0) {
-               *addr = DISP_REG_CONFIG_DSIE_SEL_IN;
-               value = DSI0_SEL_IN_RDMA1;
-       } else if (cur == DDP_COMPONENT_RDMA1 && next == DDP_COMPONENT_DSI1) {
-               *addr = DISP_REG_CONFIG_DSIO_SEL_IN;
-               value = DSI1_SEL_IN_RDMA1;
-       } else if (cur == DDP_COMPONENT_RDMA1 && next == DDP_COMPONENT_DSI2) {
-               *addr = DISP_REG_CONFIG_DSIE_SEL_IN;
-               value = DSI2_SEL_IN_RDMA1;
-       } else if (cur == DDP_COMPONENT_RDMA1 && next == DDP_COMPONENT_DSI3) {
-               *addr = DISP_REG_CONFIG_DSIO_SEL_IN;
-               value = DSI3_SEL_IN_RDMA1;
-       } else if (cur == DDP_COMPONENT_RDMA2 && next == DDP_COMPONENT_DPI0) {
-               *addr = DISP_REG_CONFIG_DPI_SEL_IN;
-               value = DPI0_SEL_IN_RDMA2;
-       } else if (cur == DDP_COMPONENT_RDMA2 && next == DDP_COMPONENT_DPI1) {
-               *addr = DISP_REG_CONFIG_DPI_SEL_IN;
-               value = DPI1_SEL_IN_RDMA2;
-       } else if (cur == DDP_COMPONENT_RDMA2 && next == DDP_COMPONENT_DSI0) {
-               *addr = DISP_REG_CONFIG_DSIE_SEL_IN;
-               value = DSI0_SEL_IN_RDMA2;
-       } else if (cur == DDP_COMPONENT_RDMA2 && next == DDP_COMPONENT_DSI1) {
-               *addr = DISP_REG_CONFIG_DSIO_SEL_IN;
-               value = DSI1_SEL_IN_RDMA2;
-       } else if (cur == DDP_COMPONENT_RDMA2 && next == DDP_COMPONENT_DSI2) {
-               *addr = DISP_REG_CONFIG_DSIE_SEL_IN;
-               value = DSI2_SEL_IN_RDMA2;
-       } else if (cur == DDP_COMPONENT_RDMA2 && next == DDP_COMPONENT_DSI3) {
-               *addr = DISP_REG_CONFIG_DSIE_SEL_IN;
-               value = DSI3_SEL_IN_RDMA2;
-       } else if (cur == DDP_COMPONENT_OVL1 && next == DDP_COMPONENT_COLOR1) {
-               *addr = DISP_REG_CONFIG_DISP_COLOR1_SEL_IN;
-               value = COLOR1_SEL_IN_OVL1;
-       } else if (cur == DDP_COMPONENT_BLS && next == DDP_COMPONENT_DSI0) {
-               *addr = DISP_REG_CONFIG_DSI_SEL;
-               value = DSI_SEL_IN_BLS;
-       } else {
-               value = 0;
-       }
-
-       return value;
-}
-
-static void mtk_ddp_sout_sel(void __iomem *config_regs,
-                            enum mtk_ddp_comp_id cur,
-                            enum mtk_ddp_comp_id next)
-{
-       if (cur == DDP_COMPONENT_BLS && next == DDP_COMPONENT_DSI0) {
-               writel_relaxed(BLS_TO_DSI_RDMA1_TO_DPI1,
-                              config_regs + DISP_REG_CONFIG_OUT_SEL);
-       } else if (cur == DDP_COMPONENT_BLS && next == DDP_COMPONENT_DPI0) {
-               writel_relaxed(BLS_TO_DPI_RDMA1_TO_DSI,
-                              config_regs + DISP_REG_CONFIG_OUT_SEL);
-               writel_relaxed(DSI_SEL_IN_RDMA,
-                              config_regs + DISP_REG_CONFIG_DSI_SEL);
-               writel_relaxed(DPI_SEL_IN_BLS,
-                              config_regs + DISP_REG_CONFIG_DPI_SEL);
-       }
-}
-
-void mtk_ddp_add_comp_to_path(void __iomem *config_regs,
-                             enum mtk_ddp_comp_id cur,
-                             enum mtk_ddp_comp_id next)
-{
-       unsigned int addr, value, reg;
-
-       value = mtk_ddp_mout_en(cur, next, &addr);
-       if (value) {
-               reg = readl_relaxed(config_regs + addr) | value;
-               writel_relaxed(reg, config_regs + addr);
-       }
-
-       mtk_ddp_sout_sel(config_regs, cur, next);
-
-       value = mtk_ddp_sel_in(cur, next, &addr);
-       if (value) {
-               reg = readl_relaxed(config_regs + addr) | value;
-               writel_relaxed(reg, config_regs + addr);
-       }
-}
-
-void mtk_ddp_remove_comp_from_path(void __iomem *config_regs,
-                                  enum mtk_ddp_comp_id cur,
-                                  enum mtk_ddp_comp_id next)
-{
-       unsigned int addr, value, reg;
-
-       value = mtk_ddp_mout_en(cur, next, &addr);
-       if (value) {
-               reg = readl_relaxed(config_regs + addr) & ~value;
-               writel_relaxed(reg, config_regs + addr);
-       }
-
-       value = mtk_ddp_sel_in(cur, next, &addr);
-       if (value) {
-               reg = readl_relaxed(config_regs + addr) & ~value;
-               writel_relaxed(reg, config_regs + addr);
-       }
-}
-
 struct mtk_disp_mutex *mtk_disp_mutex_get(struct device *dev, unsigned int id)
 {
        struct mtk_ddp *ddp = dev_get_drvdata(dev);
index 827be42..6b691a5 100644 (file)
@@ -12,13 +12,6 @@ struct regmap;
 struct device;
 struct mtk_disp_mutex;
 
-void mtk_ddp_add_comp_to_path(void __iomem *config_regs,
-                             enum mtk_ddp_comp_id cur,
-                             enum mtk_ddp_comp_id next);
-void mtk_ddp_remove_comp_from_path(void __iomem *config_regs,
-                                  enum mtk_ddp_comp_id cur,
-                                  enum mtk_ddp_comp_id next);
-
 struct mtk_disp_mutex *mtk_disp_mutex_get(struct device *dev, unsigned int id);
 int mtk_disp_mutex_prepare(struct mtk_disp_mutex *mutex);
 void mtk_disp_mutex_add_comp(struct mtk_disp_mutex *mutex,
index 0563c68..f2f0709 100644 (file)
@@ -10,6 +10,7 @@
 #include <linux/of_address.h>
 #include <linux/of_platform.h>
 #include <linux/pm_runtime.h>
+#include <linux/soc/mediatek/mtk-mmsys.h>
 #include <linux/dma-mapping.h>
 
 #include <drm/drm_atomic.h>
@@ -425,7 +426,6 @@ static int mtk_drm_probe(struct platform_device *pdev)
 {
        struct device *dev = &pdev->dev;
        struct mtk_drm_private *private;
-       struct resource *mem;
        struct device_node *node;
        struct component_match *match = NULL;
        int ret;
@@ -436,14 +436,10 @@ static int mtk_drm_probe(struct platform_device *pdev)
                return -ENOMEM;
 
        private->data = of_device_get_match_data(dev);
-
-       mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       private->config_regs = devm_ioremap_resource(dev, mem);
-       if (IS_ERR(private->config_regs)) {
-               ret = PTR_ERR(private->config_regs);
-               dev_err(dev, "Failed to ioremap mmsys-config resource: %d\n",
-                       ret);
-               return ret;
+       private->mmsys_dev = dev->parent;
+       if (!private->mmsys_dev) {
+               dev_err(dev, "Failed to get MMSYS device\n");
+               return -ENODEV;
        }
 
        /* Iterate over sibling DISP function blocks */
index 17bc99b..b5be63e 100644 (file)
@@ -39,7 +39,7 @@ struct mtk_drm_private {
 
        struct device_node *mutex_node;
        struct device *mutex_dev;
-       void __iomem *config_regs;
+       struct device *mmsys_dev;
        struct device_node *comp_node[DDP_COMPONENT_ID_MAX];
        struct mtk_ddp_comp *ddp_comp[DDP_COMPONENT_ID_MAX];
        const struct mtk_mmsys_driver_data *data;
index dbdfedd..703064f 100644 (file)
@@ -5,8 +5,76 @@
  */
 
 #include <linux/clk-provider.h>
+#include <linux/device.h>
 #include <linux/of_device.h>
 #include <linux/platform_device.h>
+#include <linux/soc/mediatek/mtk-mmsys.h>
+
+#include "../../gpu/drm/mediatek/mtk_drm_ddp.h"
+#include "../../gpu/drm/mediatek/mtk_drm_ddp_comp.h"
+
+#define DISP_REG_CONFIG_DISP_OVL0_MOUT_EN      0x040
+#define DISP_REG_CONFIG_DISP_OVL1_MOUT_EN      0x044
+#define DISP_REG_CONFIG_DISP_OD_MOUT_EN                0x048
+#define DISP_REG_CONFIG_DISP_GAMMA_MOUT_EN     0x04c
+#define DISP_REG_CONFIG_DISP_UFOE_MOUT_EN      0x050
+#define DISP_REG_CONFIG_DISP_COLOR0_SEL_IN     0x084
+#define DISP_REG_CONFIG_DISP_COLOR1_SEL_IN     0x088
+#define DISP_REG_CONFIG_DSIE_SEL_IN            0x0a4
+#define DISP_REG_CONFIG_DSIO_SEL_IN            0x0a8
+#define DISP_REG_CONFIG_DPI_SEL_IN             0x0ac
+#define DISP_REG_CONFIG_DISP_RDMA2_SOUT                0x0b8
+#define DISP_REG_CONFIG_DISP_RDMA0_SOUT_EN     0x0c4
+#define DISP_REG_CONFIG_DISP_RDMA1_SOUT_EN     0x0c8
+#define DISP_REG_CONFIG_MMSYS_CG_CON0          0x100
+
+#define DISP_REG_CONFIG_DISP_OVL_MOUT_EN       0x030
+#define DISP_REG_CONFIG_OUT_SEL                        0x04c
+#define DISP_REG_CONFIG_DSI_SEL                        0x050
+#define DISP_REG_CONFIG_DPI_SEL                        0x064
+
+#define OVL0_MOUT_EN_COLOR0                    0x1
+#define OD_MOUT_EN_RDMA0                       0x1
+#define OD1_MOUT_EN_RDMA1                      BIT(16)
+#define UFOE_MOUT_EN_DSI0                      0x1
+#define COLOR0_SEL_IN_OVL0                     0x1
+#define OVL1_MOUT_EN_COLOR1                    0x1
+#define GAMMA_MOUT_EN_RDMA1                    0x1
+#define RDMA0_SOUT_DPI0                                0x2
+#define RDMA0_SOUT_DPI1                                0x3
+#define RDMA0_SOUT_DSI1                                0x1
+#define RDMA0_SOUT_DSI2                                0x4
+#define RDMA0_SOUT_DSI3                                0x5
+#define RDMA1_SOUT_DPI0                                0x2
+#define RDMA1_SOUT_DPI1                                0x3
+#define RDMA1_SOUT_DSI1                                0x1
+#define RDMA1_SOUT_DSI2                                0x4
+#define RDMA1_SOUT_DSI3                                0x5
+#define RDMA2_SOUT_DPI0                                0x2
+#define RDMA2_SOUT_DPI1                                0x3
+#define RDMA2_SOUT_DSI1                                0x1
+#define RDMA2_SOUT_DSI2                                0x4
+#define RDMA2_SOUT_DSI3                                0x5
+#define DPI0_SEL_IN_RDMA1                      0x1
+#define DPI0_SEL_IN_RDMA2                      0x3
+#define DPI1_SEL_IN_RDMA1                      (0x1 << 8)
+#define DPI1_SEL_IN_RDMA2                      (0x3 << 8)
+#define DSI0_SEL_IN_RDMA1                      0x1
+#define DSI0_SEL_IN_RDMA2                      0x4
+#define DSI1_SEL_IN_RDMA1                      0x1
+#define DSI1_SEL_IN_RDMA2                      0x4
+#define DSI2_SEL_IN_RDMA1                      (0x1 << 16)
+#define DSI2_SEL_IN_RDMA2                      (0x4 << 16)
+#define DSI3_SEL_IN_RDMA1                      (0x1 << 16)
+#define DSI3_SEL_IN_RDMA2                      (0x4 << 16)
+#define COLOR1_SEL_IN_OVL1                     0x1
+
+#define OVL_MOUT_EN_RDMA                       0x1
+#define BLS_TO_DSI_RDMA1_TO_DPI1               0x8
+#define BLS_TO_DPI_RDMA1_TO_DSI                        0x2
+#define DSI_SEL_IN_BLS                         0x0
+#define DPI_SEL_IN_BLS                         0x0
+#define DSI_SEL_IN_RDMA                                0x1
 
 struct mtk_mmsys_driver_data {
        const char *clk_driver;
@@ -16,10 +84,223 @@ static const struct mtk_mmsys_driver_data mt8173_mmsys_driver_data = {
        .clk_driver = "clk-mt8173-mm",
 };
 
+static unsigned int mtk_mmsys_ddp_mout_en(enum mtk_ddp_comp_id cur,
+                                         enum mtk_ddp_comp_id next,
+                                         unsigned int *addr)
+{
+       unsigned int value;
+
+       if (cur == DDP_COMPONENT_OVL0 && next == DDP_COMPONENT_COLOR0) {
+               *addr = DISP_REG_CONFIG_DISP_OVL0_MOUT_EN;
+               value = OVL0_MOUT_EN_COLOR0;
+       } else if (cur == DDP_COMPONENT_OVL0 && next == DDP_COMPONENT_RDMA0) {
+               *addr = DISP_REG_CONFIG_DISP_OVL_MOUT_EN;
+               value = OVL_MOUT_EN_RDMA;
+       } else if (cur == DDP_COMPONENT_OD0 && next == DDP_COMPONENT_RDMA0) {
+               *addr = DISP_REG_CONFIG_DISP_OD_MOUT_EN;
+               value = OD_MOUT_EN_RDMA0;
+       } else if (cur == DDP_COMPONENT_UFOE && next == DDP_COMPONENT_DSI0) {
+               *addr = DISP_REG_CONFIG_DISP_UFOE_MOUT_EN;
+               value = UFOE_MOUT_EN_DSI0;
+       } else if (cur == DDP_COMPONENT_OVL1 && next == DDP_COMPONENT_COLOR1) {
+               *addr = DISP_REG_CONFIG_DISP_OVL1_MOUT_EN;
+               value = OVL1_MOUT_EN_COLOR1;
+       } else if (cur == DDP_COMPONENT_GAMMA && next == DDP_COMPONENT_RDMA1) {
+               *addr = DISP_REG_CONFIG_DISP_GAMMA_MOUT_EN;
+               value = GAMMA_MOUT_EN_RDMA1;
+       } else if (cur == DDP_COMPONENT_OD1 && next == DDP_COMPONENT_RDMA1) {
+               *addr = DISP_REG_CONFIG_DISP_OD_MOUT_EN;
+               value = OD1_MOUT_EN_RDMA1;
+       } else if (cur == DDP_COMPONENT_RDMA0 && next == DDP_COMPONENT_DPI0) {
+               *addr = DISP_REG_CONFIG_DISP_RDMA0_SOUT_EN;
+               value = RDMA0_SOUT_DPI0;
+       } else if (cur == DDP_COMPONENT_RDMA0 && next == DDP_COMPONENT_DPI1) {
+               *addr = DISP_REG_CONFIG_DISP_RDMA0_SOUT_EN;
+               value = RDMA0_SOUT_DPI1;
+       } else if (cur == DDP_COMPONENT_RDMA0 && next == DDP_COMPONENT_DSI1) {
+               *addr = DISP_REG_CONFIG_DISP_RDMA0_SOUT_EN;
+               value = RDMA0_SOUT_DSI1;
+       } else if (cur == DDP_COMPONENT_RDMA0 && next == DDP_COMPONENT_DSI2) {
+               *addr = DISP_REG_CONFIG_DISP_RDMA0_SOUT_EN;
+               value = RDMA0_SOUT_DSI2;
+       } else if (cur == DDP_COMPONENT_RDMA0 && next == DDP_COMPONENT_DSI3) {
+               *addr = DISP_REG_CONFIG_DISP_RDMA0_SOUT_EN;
+               value = RDMA0_SOUT_DSI3;
+       } else if (cur == DDP_COMPONENT_RDMA1 && next == DDP_COMPONENT_DSI1) {
+               *addr = DISP_REG_CONFIG_DISP_RDMA1_SOUT_EN;
+               value = RDMA1_SOUT_DSI1;
+       } else if (cur == DDP_COMPONENT_RDMA1 && next == DDP_COMPONENT_DSI2) {
+               *addr = DISP_REG_CONFIG_DISP_RDMA1_SOUT_EN;
+               value = RDMA1_SOUT_DSI2;
+       } else if (cur == DDP_COMPONENT_RDMA1 && next == DDP_COMPONENT_DSI3) {
+               *addr = DISP_REG_CONFIG_DISP_RDMA1_SOUT_EN;
+               value = RDMA1_SOUT_DSI3;
+       } else if (cur == DDP_COMPONENT_RDMA1 && next == DDP_COMPONENT_DPI0) {
+               *addr = DISP_REG_CONFIG_DISP_RDMA1_SOUT_EN;
+               value = RDMA1_SOUT_DPI0;
+       } else if (cur == DDP_COMPONENT_RDMA1 && next == DDP_COMPONENT_DPI1) {
+               *addr = DISP_REG_CONFIG_DISP_RDMA1_SOUT_EN;
+               value = RDMA1_SOUT_DPI1;
+       } else if (cur == DDP_COMPONENT_RDMA2 && next == DDP_COMPONENT_DPI0) {
+               *addr = DISP_REG_CONFIG_DISP_RDMA2_SOUT;
+               value = RDMA2_SOUT_DPI0;
+       } else if (cur == DDP_COMPONENT_RDMA2 && next == DDP_COMPONENT_DPI1) {
+               *addr = DISP_REG_CONFIG_DISP_RDMA2_SOUT;
+               value = RDMA2_SOUT_DPI1;
+       } else if (cur == DDP_COMPONENT_RDMA2 && next == DDP_COMPONENT_DSI1) {
+               *addr = DISP_REG_CONFIG_DISP_RDMA2_SOUT;
+               value = RDMA2_SOUT_DSI1;
+       } else if (cur == DDP_COMPONENT_RDMA2 && next == DDP_COMPONENT_DSI2) {
+               *addr = DISP_REG_CONFIG_DISP_RDMA2_SOUT;
+               value = RDMA2_SOUT_DSI2;
+       } else if (cur == DDP_COMPONENT_RDMA2 && next == DDP_COMPONENT_DSI3) {
+               *addr = DISP_REG_CONFIG_DISP_RDMA2_SOUT;
+               value = RDMA2_SOUT_DSI3;
+       } else {
+               value = 0;
+       }
+
+       return value;
+}
+
+static unsigned int mtk_mmsys_ddp_sel_in(enum mtk_ddp_comp_id cur,
+                                        enum mtk_ddp_comp_id next,
+                                        unsigned int *addr)
+{
+       unsigned int value;
+
+       if (cur == DDP_COMPONENT_OVL0 && next == DDP_COMPONENT_COLOR0) {
+               *addr = DISP_REG_CONFIG_DISP_COLOR0_SEL_IN;
+               value = COLOR0_SEL_IN_OVL0;
+       } else if (cur == DDP_COMPONENT_RDMA1 && next == DDP_COMPONENT_DPI0) {
+               *addr = DISP_REG_CONFIG_DPI_SEL_IN;
+               value = DPI0_SEL_IN_RDMA1;
+       } else if (cur == DDP_COMPONENT_RDMA1 && next == DDP_COMPONENT_DPI1) {
+               *addr = DISP_REG_CONFIG_DPI_SEL_IN;
+               value = DPI1_SEL_IN_RDMA1;
+       } else if (cur == DDP_COMPONENT_RDMA1 && next == DDP_COMPONENT_DSI0) {
+               *addr = DISP_REG_CONFIG_DSIE_SEL_IN;
+               value = DSI0_SEL_IN_RDMA1;
+       } else if (cur == DDP_COMPONENT_RDMA1 && next == DDP_COMPONENT_DSI1) {
+               *addr = DISP_REG_CONFIG_DSIO_SEL_IN;
+               value = DSI1_SEL_IN_RDMA1;
+       } else if (cur == DDP_COMPONENT_RDMA1 && next == DDP_COMPONENT_DSI2) {
+               *addr = DISP_REG_CONFIG_DSIE_SEL_IN;
+               value = DSI2_SEL_IN_RDMA1;
+       } else if (cur == DDP_COMPONENT_RDMA1 && next == DDP_COMPONENT_DSI3) {
+               *addr = DISP_REG_CONFIG_DSIO_SEL_IN;
+               value = DSI3_SEL_IN_RDMA1;
+       } else if (cur == DDP_COMPONENT_RDMA2 && next == DDP_COMPONENT_DPI0) {
+               *addr = DISP_REG_CONFIG_DPI_SEL_IN;
+               value = DPI0_SEL_IN_RDMA2;
+       } else if (cur == DDP_COMPONENT_RDMA2 && next == DDP_COMPONENT_DPI1) {
+               *addr = DISP_REG_CONFIG_DPI_SEL_IN;
+               value = DPI1_SEL_IN_RDMA2;
+       } else if (cur == DDP_COMPONENT_RDMA2 && next == DDP_COMPONENT_DSI0) {
+               *addr = DISP_REG_CONFIG_DSIE_SEL_IN;
+               value = DSI0_SEL_IN_RDMA2;
+       } else if (cur == DDP_COMPONENT_RDMA2 && next == DDP_COMPONENT_DSI1) {
+               *addr = DISP_REG_CONFIG_DSIO_SEL_IN;
+               value = DSI1_SEL_IN_RDMA2;
+       } else if (cur == DDP_COMPONENT_RDMA2 && next == DDP_COMPONENT_DSI2) {
+               *addr = DISP_REG_CONFIG_DSIE_SEL_IN;
+               value = DSI2_SEL_IN_RDMA2;
+       } else if (cur == DDP_COMPONENT_RDMA2 && next == DDP_COMPONENT_DSI3) {
+               *addr = DISP_REG_CONFIG_DSIE_SEL_IN;
+               value = DSI3_SEL_IN_RDMA2;
+       } else if (cur == DDP_COMPONENT_OVL1 && next == DDP_COMPONENT_COLOR1) {
+               *addr = DISP_REG_CONFIG_DISP_COLOR1_SEL_IN;
+               value = COLOR1_SEL_IN_OVL1;
+       } else if (cur == DDP_COMPONENT_BLS && next == DDP_COMPONENT_DSI0) {
+               *addr = DISP_REG_CONFIG_DSI_SEL;
+               value = DSI_SEL_IN_BLS;
+       } else {
+               value = 0;
+       }
+
+       return value;
+}
+
+static void mtk_mmsys_ddp_sout_sel(void __iomem *config_regs,
+                                  enum mtk_ddp_comp_id cur,
+                                  enum mtk_ddp_comp_id next)
+{
+       if (cur == DDP_COMPONENT_BLS && next == DDP_COMPONENT_DSI0) {
+               writel_relaxed(BLS_TO_DSI_RDMA1_TO_DPI1,
+                              config_regs + DISP_REG_CONFIG_OUT_SEL);
+       } else if (cur == DDP_COMPONENT_BLS && next == DDP_COMPONENT_DPI0) {
+               writel_relaxed(BLS_TO_DPI_RDMA1_TO_DSI,
+                              config_regs + DISP_REG_CONFIG_OUT_SEL);
+               writel_relaxed(DSI_SEL_IN_RDMA,
+                              config_regs + DISP_REG_CONFIG_DSI_SEL);
+               writel_relaxed(DPI_SEL_IN_BLS,
+                              config_regs + DISP_REG_CONFIG_DPI_SEL);
+       }
+}
+
+void mtk_mmsys_ddp_connect(struct device *dev,
+                          enum mtk_ddp_comp_id cur,
+                          enum mtk_ddp_comp_id next)
+{
+       void __iomem *config_regs = dev_get_drvdata(dev);
+       unsigned int addr, value, reg;
+
+       value = mtk_mmsys_ddp_mout_en(cur, next, &addr);
+       if (value) {
+               reg = readl_relaxed(config_regs + addr) | value;
+               writel_relaxed(reg, config_regs + addr);
+       }
+
+       mtk_mmsys_ddp_sout_sel(config_regs, cur, next);
+
+       value = mtk_mmsys_ddp_sel_in(cur, next, &addr);
+       if (value) {
+               reg = readl_relaxed(config_regs + addr) | value;
+               writel_relaxed(reg, config_regs + addr);
+       }
+}
+EXPORT_SYMBOL_GPL(mtk_mmsys_ddp_connect);
+
+void mtk_mmsys_ddp_disconnect(struct device *dev,
+                             enum mtk_ddp_comp_id cur,
+                             enum mtk_ddp_comp_id next)
+{
+       void __iomem *config_regs = dev_get_drvdata(dev);
+       unsigned int addr, value, reg;
+
+       value = mtk_mmsys_ddp_mout_en(cur, next, &addr);
+       if (value) {
+               reg = readl_relaxed(config_regs + addr) & ~value;
+               writel_relaxed(reg, config_regs + addr);
+       }
+
+       value = mtk_mmsys_ddp_sel_in(cur, next, &addr);
+       if (value) {
+               reg = readl_relaxed(config_regs + addr) & ~value;
+               writel_relaxed(reg, config_regs + addr);
+       }
+}
+EXPORT_SYMBOL_GPL(mtk_mmsys_ddp_disconnect);
+
 static int mtk_mmsys_probe(struct platform_device *pdev)
 {
        const struct mtk_mmsys_driver_data *data;
+       struct device *dev = &pdev->dev;
        struct platform_device *clks;
+       void __iomem *config_regs;
+       struct resource *mem;
+       int ret;
+
+       mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       config_regs = devm_ioremap_resource(dev, mem);
+       if (IS_ERR(config_regs)) {
+               ret = PTR_ERR(config_regs);
+               dev_err(dev, "Failed to ioremap mmsys-config resource: %d\n",
+                       ret);
+               return ret;
+       }
+
+       platform_set_drvdata(pdev, config_regs);
 
        data = of_device_get_match_data(&pdev->dev);
 
diff --git a/include/linux/soc/mediatek/mtk-mmsys.h b/include/linux/soc/mediatek/mtk-mmsys.h
new file mode 100644 (file)
index 0000000..7bab5d9
--- /dev/null
@@ -0,0 +1,20 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2015 MediaTek Inc.
+ */
+
+#ifndef __MTK_MMSYS_H
+#define __MTK_MMSYS_H
+
+enum mtk_ddp_comp_id;
+struct device;
+
+void mtk_mmsys_ddp_connect(struct device *dev,
+                          enum mtk_ddp_comp_id cur,
+                          enum mtk_ddp_comp_id next);
+
+void mtk_mmsys_ddp_disconnect(struct device *dev,
+                             enum mtk_ddp_comp_id cur,
+                             enum mtk_ddp_comp_id next);
+
+#endif /* __MTK_MMSYS_H */