The MDP RDMA is the DMA engine reading the framebuffer on some
MediaTek SoCs, such as the MT8188. Two instances are used, each
reading one half of the frame; the second one starts at the middle of
the line (apply_offset).

Signed-off-by: Julien Stephan <[email protected]>
---
 drivers/video/mediatek/mtk_mdp_rdma_mt8188.c | 97 ++++++++++++++++++++++++++++
 drivers/video/mediatek/mtk_mdp_rdma_mt8188.h | 20 ++++++
 2 files changed, 117 insertions(+)

diff --git a/drivers/video/mediatek/mtk_mdp_rdma_mt8188.c 
b/drivers/video/mediatek/mtk_mdp_rdma_mt8188.c
new file mode 100644
index 00000000000..cf85df94d10
--- /dev/null
+++ b/drivers/video/mediatek/mtk_mdp_rdma_mt8188.c
@@ -0,0 +1,97 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Mediatek Video MDP RDMA Support
+ *
+ * Copyright (c) 2022 BayLibre, SAS.
+ * Author: Julien Masson <[email protected]>
+ */
+
+#include <dm.h>
+#include <video.h>
+
+#include "mtk_disp_comp.h"
+#include "mtk_mdp_rdma_mt8188.h"
+
+/* MDP RDMA registers */
+#define MDP_RDMA_EN                            0x0000
+#define MDP_RDMA_EN_ENABLE                     BIT(0)
+#define MDP_RDMA_EN_DISABLE                    0
+#define MDP_RDMA_EN_INTERNAL_DCM_EN            GENMASK(23, 4)
+
+#define MDP_RDMA_SRC_CON                       0x0030
+#define MDP_RDMA_SRC_FORMAT_BGRA8888           2
+#define MDP_RDMA_SRC_CON_SRC_FORMAT(x)         ((x) & GENMASK(3, 0))
+#define MDP_RDMA_ENABLE_UNIFORM_CONFIG         BIT(17)
+#define MDP_RDMA_ENABLE_ARGB_OUTPUT            BIT(25)
+
+#define MDP_RDMA_SRC_BASE_0                    0x0f00
+#define MDP_RDMA_MF_BKGD_SIZE_IN_BYTE          0x0060
+#define MDP_RDMA_MF_SRC_SIZE                   0x0070
+#define MDP_RDMA_MF_CLIP_SIZE                  0x0078
+#define MDP_RDMA_SRC_OFFSET_0                  0x0118
+
+#define MDP_RDMA_CON                           0x0020
+#define MDP_RDMA_CON_SIMPLE_MODE               BIT(4)
+
+#define MDP_RDMA_TRANSFORM_0                   0x0200
+#define MDP_RDMA_TRANSFORM_BITEXTEND_ZERO      BIT(15)
+
+#define FB_BYTES_PER_PIXEL                     4
+
+void mtk_mdp_rdma_config(struct udevice *dev, struct video_uc_plat *plat,
+                        const struct display_timing *timing,
+                        bool apply_offset)
+{
+       u32 width = timing->hactive.typ;
+       u32 height = timing->vactive.typ;
+       u32 fb = plat->base;
+       int offset = apply_offset ? ((width / 2) * FB_BYTES_PER_PIXEL) : 0;
+
+       mtk_disp_comp_write(dev, MDP_RDMA_EN, MDP_RDMA_EN_INTERNAL_DCM_EN);
+
+       /* set source format and output bit depth */
+       mtk_disp_comp_write(dev, MDP_RDMA_SRC_CON,
+                           
MDP_RDMA_SRC_CON_SRC_FORMAT(MDP_RDMA_SRC_FORMAT_BGRA8888) |
+                           MDP_RDMA_ENABLE_ARGB_OUTPUT |
+                           MDP_RDMA_ENABLE_UNIFORM_CONFIG);
+
+       /* set base address */
+       mtk_disp_comp_write(dev, MDP_RDMA_SRC_BASE_0, fb);
+
+       /* stride: aligned width * bytes-per-pixel */
+       mtk_disp_comp_write(dev, MDP_RDMA_MF_BKGD_SIZE_IN_BYTE,
+                           ALIGN(width, 4) * FB_BYTES_PER_PIXEL);
+
+       /*
+        * each of the two RDMAs reads one half of the frame: size and
+        * clip cover half the width, and the second RDMA (apply_offset)
+        * starts at the middle of the line
+        */
+       mtk_disp_comp_write(dev, MDP_RDMA_MF_SRC_SIZE,
+                           (height << 16) | (width / 2));
+       mtk_disp_comp_write(dev, MDP_RDMA_MF_CLIP_SIZE,
+                           (height << 16) | (width / 2));
+       mtk_disp_comp_write(dev, MDP_RDMA_SRC_OFFSET_0, offset);
+
+       /* simple mode + zero bit extension for 8bit -> 10bit */
+       mtk_disp_comp_write(dev, MDP_RDMA_CON, MDP_RDMA_CON_SIMPLE_MODE);
+       mtk_disp_comp_write(dev, MDP_RDMA_TRANSFORM_0,
+                           MDP_RDMA_TRANSFORM_BITEXTEND_ZERO);
+
+       /* enable engine */
+       mtk_disp_comp_write(dev, MDP_RDMA_EN,
+                           MDP_RDMA_EN_INTERNAL_DCM_EN | MDP_RDMA_EN_ENABLE);
+}
+
+static const struct udevice_id mtk_mdp_rdma_ids[] = {
+       { .compatible = "mediatek,mt8188-vdo1-rdma" },
+       {}
+};
+
+U_BOOT_DRIVER(mtk_mdp_rdma) = {
+       .name      = "mtk_mdp_rdma",
+       .id        = UCLASS_MISC,
+       .of_match  = mtk_mdp_rdma_ids,
+       .probe     = mtk_disp_comp_probe,
+       .priv_auto = sizeof(struct mtk_disp_comp_priv),
+};
diff --git a/drivers/video/mediatek/mtk_mdp_rdma_mt8188.h 
b/drivers/video/mediatek/mtk_mdp_rdma_mt8188.h
new file mode 100644
index 00000000000..6646b353e3f
--- /dev/null
+++ b/drivers/video/mediatek/mtk_mdp_rdma_mt8188.h
@@ -0,0 +1,20 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Mediatek Video MDP RDMA Support
+ *
+ * Copyright (c) 2025 BayLibre, SAS.
+ * Author: Julien Stephan <[email protected]>
+ */
+
+#ifndef _MTK_MDP_RDMA_MT8188_H
+#define _MTK_MDP_RDMA_MT8188_H
+
+struct udevice;
+struct video_uc_plat;
+struct display_timing;
+
+void mtk_mdp_rdma_config(struct udevice *dev, struct video_uc_plat *plat,
+                        const struct display_timing *timing,
+                        bool apply_offset);
+
+#endif

-- 
2.54.0

Reply via email to