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
