diff mbox series

[v2,09/13] video: mediatek: add ddp component

Message ID 20261002-mt8365-mt8366-add-dsi-support-v2-9-9e435457b90c@baylibre.com
State Under Review
Delegated to: David Lechner
Headers show
Series mediatek: add DSI panel support for MT8365 and MT8366 boards | expand

Commit Message

Julien Stephan Oct. 2, 2026, 2:04 p.m. UTC
The display data path (ddp) is the set of muxes of the mmsys register
space routing the components of the video pipeline into each other.

Add the route needed to bring up a splash screen, the overlay to the
DSI, with one function per SoC: mt8365_ddp_ovl_to_dsi() goes through the
colour pipeline, mt8366_ddp_ovl_to_dsi() straight through the crossbar.

The muxes have no device of their own: they live in the mmsys syscon
window, which the DSI driver maps and hands over, so no compatible is
added here. The MT8365 offsets and values are the ones of the Linux
mt8365_mmsys_routing_table; the MT8366 ones come from its downstream
mmsys, that SoC not being upstream yet.

Signed-off-by: Julien Stephan <jstephan@baylibre.com>
---
 drivers/video/mediatek/mtk_ddp.c | 122 +++++++++++++++++++++++++++++++++++++++
 drivers/video/mediatek/mtk_ddp.h |  30 ++++++++++
 2 files changed, 152 insertions(+)
diff mbox series

Patch

diff --git a/drivers/video/mediatek/mtk_ddp.c b/drivers/video/mediatek/mtk_ddp.c
new file mode 100644
index 00000000000..246e6615fa0
--- /dev/null
+++ b/drivers/video/mediatek/mtk_ddp.c
@@ -0,0 +1,122 @@ 
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * MediaTek Display Data Path
+ *
+ * Copyright (c) 2026 BayLibre, SAS.
+ * Author: Julien Masson <jmasson@baylibre.com>
+ *         Julien Stephan <jstephan@baylibre.com>
+ */
+
+#include <asm/io.h>
+#include <linux/bitops.h>
+
+#include "mtk_ddp.h"
+
+/*
+ * mt8365-generation mmsys: the path is built out of direct muxes, one
+ * register per input or output. The offsets and the values are the ones of
+ * the Linux mt8365_mmsys_routing_table.
+ */
+#define MT8365_DISP_MS_IN_OUT_MASK			GENMASK(3, 0)
+
+#define MT8365_DISP_REG_CONFIG_DISP_OVL0_MOUT_EN	0xf3c
+#define MT8365_OVL0_MOUT_PATH0_SEL				BIT(0)
+
+#define MT8365_DISP_REG_CONFIG_DISP_RDMA0_SOUT_SEL	0xf4c
+#define MT8365_RDMA0_SOUT_COLOR0				0x1
+
+#define MT8365_DISP_REG_CONFIG_DISP_DITHER0_MOUT_EN	0xf50
+#define MT8365_DITHER_MOUT_EN_DSI0				BIT(0)
+
+#define MT8365_DISP_REG_CONFIG_DISP_RDMA0_SEL_IN	0xf54
+#define MT8365_RDMA0_SEL_IN_OVL0				0x0
+
+#define MT8365_DISP_REG_CONFIG_DISP_RDMA0_RSZ0_SEL_IN	0xf60
+#define MT8365_RDMA0_RSZ0_SEL_IN_RDMA0				0x0
+
+#define MT8365_DISP_REG_CONFIG_DISP_COLOR0_SEL_IN	0xf64
+#define MT8365_DISP_COLOR_SEL_IN_COLOR0				0x0
+
+#define MT8365_DISP_REG_CONFIG_DISP_DSI0_SEL_IN		0xf68
+#define MT8365_DSI0_SEL_IN_DITHER				0x1
+
+/*
+ * mt8366-generation mmsys uses a multi-stage crossbar instead of the simple
+ * direct muxes above.
+ */
+#define MT8366_DISP_OVL0_BGCLR_MOUT_EN			0xe24
+#define MT8366_DISP_OVL_BGCLR_MOUT_MASK				GENMASK(1, 0)
+#define MT8366_MOUT_OVL_TO_BLENDOUT				BIT(0)
+
+#define MT8366_DISP_OVL0_OUT0_MOUT_EN			0xc10
+#define MT8366_DISP_OVL_OUT0_MOUT_MASK				GENMASK(2, 0)
+#define MT8366_MOUT_DISP_OVL0_TO_DISP_RDMA0			BIT(1)
+
+#define MT8366_DISP_RDMA0_SEL_IN			0xe04
+#define MT8366_DISP_RDMA_SEL_IN_MASK				BIT(0)
+#define MT8366_SEL_IN_DISP_RDMA0_FROM_DISP_OVL0_OUT0_MOUT	0x1
+
+#define MT8366_DISP_RDMA0_RSZ0_SOUT_SEL			0xe00
+#define MT8366_SOUT_DISP_RDMA0_RSZ0_TO_OVL_PQ_OUT_CROSSBAR1	0x0
+
+#define MT8366_OVL_PQ_OUT_CROSSBAR1_MOUT_EN		0xc78
+#define MT8366_OVL_PQ_OUT_CROSSBAR_MOUT_MASK			GENMASK(5, 0)
+#define MT8366_MOUT_OVL_PQ_OUT_CROSSBAR1_TO_COMP_OUT_CROSSBAR4	BIT(4)
+
+#define MT8366_COMP_OUT_CROSSBAR4_MOUT_EN		0xd80
+#define MT8366_COMP_OUT_CROSSBAR_MOUT_MASK			GENMASK(5, 0)
+#define MT8366_MOUT_COMP_OUT_CROSSBAR4_TO_DISP_DSI0		BIT(0)
+
+static void mtk_ddp_mask(void __iomem *base, u32 offset, u32 val, u32 mask)
+{
+	u32 tmp = readl(base + offset) & ~mask;
+
+	writel(tmp | (val & mask), base + offset);
+}
+
+void mt8365_ddp_ovl_to_dsi(void __iomem *mmsys_base)
+{
+	/* OVL0 -> RDMA0 */
+	mtk_ddp_mask(mmsys_base, MT8365_DISP_REG_CONFIG_DISP_OVL0_MOUT_EN,
+		     MT8365_OVL0_MOUT_PATH0_SEL, MT8365_DISP_MS_IN_OUT_MASK);
+	mtk_ddp_mask(mmsys_base, MT8365_DISP_REG_CONFIG_DISP_RDMA0_SEL_IN,
+		     MT8365_RDMA0_SEL_IN_OVL0, MT8365_DISP_MS_IN_OUT_MASK);
+
+	/* RDMA0 -> COLOR0 */
+	mtk_ddp_mask(mmsys_base, MT8365_DISP_REG_CONFIG_DISP_RDMA0_RSZ0_SEL_IN,
+		     MT8365_RDMA0_RSZ0_SEL_IN_RDMA0, MT8365_DISP_MS_IN_OUT_MASK);
+	mtk_ddp_mask(mmsys_base, MT8365_DISP_REG_CONFIG_DISP_RDMA0_SOUT_SEL,
+		     MT8365_RDMA0_SOUT_COLOR0, MT8365_DISP_MS_IN_OUT_MASK);
+
+	/* COLOR0 -> CCORR0 -> AAL0 -> GAMMA0 -> DITHER0 -> DSI0 */
+	mtk_ddp_mask(mmsys_base, MT8365_DISP_REG_CONFIG_DISP_COLOR0_SEL_IN,
+		     MT8365_DISP_COLOR_SEL_IN_COLOR0, MT8365_DISP_MS_IN_OUT_MASK);
+	mtk_ddp_mask(mmsys_base, MT8365_DISP_REG_CONFIG_DISP_DITHER0_MOUT_EN,
+		     MT8365_DITHER_MOUT_EN_DSI0, MT8365_DISP_MS_IN_OUT_MASK);
+	mtk_ddp_mask(mmsys_base, MT8365_DISP_REG_CONFIG_DISP_DSI0_SEL_IN,
+		     MT8365_DSI0_SEL_IN_DITHER, MT8365_DISP_MS_IN_OUT_MASK);
+}
+
+void mt8366_ddp_ovl_to_dsi(void __iomem *mmsys_base)
+{
+	/* OVL0 -> RDMA0 */
+	mtk_ddp_mask(mmsys_base, MT8366_DISP_OVL0_BGCLR_MOUT_EN,
+		     MT8366_MOUT_OVL_TO_BLENDOUT, MT8366_DISP_OVL_BGCLR_MOUT_MASK);
+	mtk_ddp_mask(mmsys_base, MT8366_DISP_OVL0_OUT0_MOUT_EN,
+		     MT8366_MOUT_DISP_OVL0_TO_DISP_RDMA0,
+		     MT8366_DISP_OVL_OUT0_MOUT_MASK);
+	mtk_ddp_mask(mmsys_base, MT8366_DISP_RDMA0_SEL_IN,
+		     MT8366_SEL_IN_DISP_RDMA0_FROM_DISP_OVL0_OUT0_MOUT,
+		     MT8366_DISP_RDMA_SEL_IN_MASK);
+
+	/* RDMA0 -> COMP_OUT_CROSSBAR4 -> DSI0 */
+	mtk_ddp_mask(mmsys_base, MT8366_DISP_RDMA0_RSZ0_SOUT_SEL,
+		     MT8366_SOUT_DISP_RDMA0_RSZ0_TO_OVL_PQ_OUT_CROSSBAR1,
+		     MT8366_OVL_PQ_OUT_CROSSBAR_MOUT_MASK);
+	mtk_ddp_mask(mmsys_base, MT8366_OVL_PQ_OUT_CROSSBAR1_MOUT_EN,
+		     MT8366_MOUT_OVL_PQ_OUT_CROSSBAR1_TO_COMP_OUT_CROSSBAR4,
+		     MT8366_OVL_PQ_OUT_CROSSBAR_MOUT_MASK);
+	mtk_ddp_mask(mmsys_base, MT8366_COMP_OUT_CROSSBAR4_MOUT_EN,
+		     MT8366_MOUT_COMP_OUT_CROSSBAR4_TO_DISP_DSI0,
+		     MT8366_COMP_OUT_CROSSBAR_MOUT_MASK);
+}
diff --git a/drivers/video/mediatek/mtk_ddp.h b/drivers/video/mediatek/mtk_ddp.h
new file mode 100644
index 00000000000..f7efbd64cae
--- /dev/null
+++ b/drivers/video/mediatek/mtk_ddp.h
@@ -0,0 +1,30 @@ 
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2026 BayLibre, SAS.
+ * Author: Julien Masson <jmasson@baylibre.com>
+ *         Julien Stephan <jstephan@baylibre.com>
+ */
+
+#ifndef _MTK_DDP_H
+#define _MTK_DDP_H
+
+#include <linux/compiler.h>
+#include <linux/types.h>
+
+/**
+ * mt8365_ddp_ovl_to_dsi() - route the MT8365 mmsys muxes from the OVL to the DSI
+ * @mmsys_base: mmsys config register window
+ *
+ * Go through the color, ccorr, aal, gamma and dither blocks.
+ */
+void mt8365_ddp_ovl_to_dsi(void __iomem *mmsys_base);
+
+/**
+ * mt8366_ddp_ovl_to_dsi() - route the MT8366 mmsys muxes from the OVL to the DSI
+ * @mmsys_base: mmsys config register window
+ *
+ * Go straight from the rdma to the DSI, through the crossbars.
+ */
+void mt8366_ddp_ovl_to_dsi(void __iomem *mmsys_base);
+
+#endif /* _MTK_DDP_H */