Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/mediatek: Add display MDP RDMA support for MT8195

Add MDP_RDMA driver for MT8195. MDP_RDMA is the DMA engine of
the ovl_adaptor component.

Signed-off-by: Nancy.Lin <nancy.lin@mediatek.com>
Reviewed-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Tested-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Tested-by: Bo-Chen Chen <rex-bc.chen@mediatek.com>
Link: https://patchwork.kernel.org/project/linux-mediatek/patch/20220620091930.27797-4-nancy.lin@mediatek.com/
Signed-off-by: Chun-Kuang Hu <chunkuang.hu@kernel.org>

authored by

Nancy.Lin and committed by
Chun-Kuang Hu
f8946e2b e201c963

+346 -1
+2 -1
drivers/gpu/drm/mediatek/Makefile
··· 13 13 mtk_drm_gem.o \ 14 14 mtk_drm_plane.o \ 15 15 mtk_dsi.o \ 16 - mtk_dpi.o 16 + mtk_dpi.o \ 17 + mtk_mdp_rdma.o 17 18 18 19 obj-$(CONFIG_DRM_MEDIATEK) += mediatek-drm.o 19 20
+7
drivers/gpu/drm/mediatek/mtk_disp_drv.h
··· 8 8 9 9 #include <linux/soc/mediatek/mtk-cmdq.h> 10 10 #include "mtk_drm_plane.h" 11 + #include "mtk_mdp_rdma.h" 11 12 12 13 int mtk_aal_clk_enable(struct device *dev); 13 14 void mtk_aal_clk_disable(struct device *dev); ··· 111 110 void mtk_rdma_enable_vblank(struct device *dev); 112 111 void mtk_rdma_disable_vblank(struct device *dev); 113 112 113 + int mtk_mdp_rdma_clk_enable(struct device *dev); 114 + void mtk_mdp_rdma_clk_disable(struct device *dev); 115 + void mtk_mdp_rdma_start(struct device *dev, struct cmdq_pkt *cmdq_pkt); 116 + void mtk_mdp_rdma_stop(struct device *dev, struct cmdq_pkt *cmdq_pkt); 117 + void mtk_mdp_rdma_config(struct device *dev, struct mtk_mdp_rdma_cfg *cfg, 118 + struct cmdq_pkt *cmdq_pkt); 114 119 #endif
+1
drivers/gpu/drm/mediatek/mtk_drm_drv.c
··· 875 875 &mtk_dpi_driver, 876 876 &mtk_drm_platform_driver, 877 877 &mtk_dsi_driver, 878 + &mtk_mdp_rdma_driver, 878 879 }; 879 880 880 881 static int __init mtk_drm_init(void)
+1
drivers/gpu/drm/mediatek/mtk_drm_drv.h
··· 61 61 extern struct platform_driver mtk_disp_rdma_driver; 62 62 extern struct platform_driver mtk_dpi_driver; 63 63 extern struct platform_driver mtk_dsi_driver; 64 + extern struct platform_driver mtk_mdp_rdma_driver; 64 65 65 66 #endif /* MTK_DRM_DRV_H */
+315
drivers/gpu/drm/mediatek/mtk_mdp_rdma.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /* 3 + * Copyright (c) 2021 MediaTek Inc. 4 + */ 5 + 6 + #include <drm/drm_fourcc.h> 7 + #include <linux/clk.h> 8 + #include <linux/component.h> 9 + #include <linux/of_address.h> 10 + #include <linux/of_device.h> 11 + #include <linux/platform_device.h> 12 + #include <linux/pm_runtime.h> 13 + #include <linux/soc/mediatek/mtk-cmdq.h> 14 + 15 + #include "mtk_disp_drv.h" 16 + #include "mtk_drm_drv.h" 17 + #include "mtk_mdp_rdma.h" 18 + 19 + #define MDP_RDMA_EN 0x000 20 + #define FLD_ROT_ENABLE BIT(0) 21 + #define MDP_RDMA_RESET 0x008 22 + #define MDP_RDMA_CON 0x020 23 + #define FLD_OUTPUT_10B BIT(5) 24 + #define FLD_SIMPLE_MODE BIT(4) 25 + #define MDP_RDMA_GMCIF_CON 0x028 26 + #define FLD_COMMAND_DIV BIT(0) 27 + #define FLD_EXT_PREULTRA_EN BIT(3) 28 + #define FLD_RD_REQ_TYPE GENMASK(7, 4) 29 + #define VAL_RD_REQ_TYPE_BURST_8_ACCESS 7 30 + #define FLD_ULTRA_EN GENMASK(13, 12) 31 + #define VAL_ULTRA_EN_ENABLE 1 32 + #define FLD_PRE_ULTRA_EN GENMASK(17, 16) 33 + #define VAL_PRE_ULTRA_EN_ENABLE 1 34 + #define FLD_EXT_ULTRA_EN BIT(18) 35 + #define MDP_RDMA_SRC_CON 0x030 36 + #define FLD_OUTPUT_ARGB BIT(25) 37 + #define FLD_BIT_NUMBER GENMASK(19, 18) 38 + #define FLD_SWAP BIT(14) 39 + #define FLD_UNIFORM_CONFIG BIT(17) 40 + #define RDMA_INPUT_10BIT BIT(18) 41 + #define FLD_SRC_FORMAT GENMASK(3, 0) 42 + #define MDP_RDMA_COMP_CON 0x038 43 + #define FLD_AFBC_EN BIT(22) 44 + #define FLD_AFBC_YUV_TRANSFORM BIT(21) 45 + #define FLD_UFBDC_EN BIT(12) 46 + #define MDP_RDMA_MF_BKGD_SIZE_IN_BYTE 0x060 47 + #define FLD_MF_BKGD_WB GENMASK(22, 0) 48 + #define MDP_RDMA_MF_SRC_SIZE 0x070 49 + #define FLD_MF_SRC_H GENMASK(30, 16) 50 + #define FLD_MF_SRC_W GENMASK(14, 0) 51 + #define MDP_RDMA_MF_CLIP_SIZE 0x078 52 + #define FLD_MF_CLIP_H GENMASK(30, 16) 53 + #define FLD_MF_CLIP_W GENMASK(14, 0) 54 + #define MDP_RDMA_SRC_OFFSET_0 0x118 55 + #define FLD_SRC_OFFSET_0 GENMASK(31, 0) 56 + #define MDP_RDMA_TRANSFORM_0 0x200 57 + #define FLD_INT_MATRIX_SEL GENMASK(27, 23) 58 + #define FLD_TRANS_EN BIT(16) 59 + #define MDP_RDMA_SRC_BASE_0 0xf00 60 + #define FLD_SRC_BASE_0 GENMASK(31, 0) 61 + 62 + #define RDMA_CSC_FULL709_TO_RGB 5 63 + #define RDMA_CSC_BT601_TO_RGB 6 64 + 65 + enum rdma_format { 66 + RDMA_INPUT_FORMAT_RGB565 = 0, 67 + RDMA_INPUT_FORMAT_RGB888 = 1, 68 + RDMA_INPUT_FORMAT_RGBA8888 = 2, 69 + RDMA_INPUT_FORMAT_ARGB8888 = 3, 70 + RDMA_INPUT_FORMAT_UYVY = 4, 71 + RDMA_INPUT_FORMAT_YUY2 = 5, 72 + RDMA_INPUT_FORMAT_Y8 = 7, 73 + RDMA_INPUT_FORMAT_YV12 = 8, 74 + RDMA_INPUT_FORMAT_UYVY_3PL = 9, 75 + RDMA_INPUT_FORMAT_NV12 = 12, 76 + RDMA_INPUT_FORMAT_UYVY_2PL = 13, 77 + RDMA_INPUT_FORMAT_Y410 = 14 78 + }; 79 + 80 + struct mtk_mdp_rdma { 81 + void __iomem *regs; 82 + struct clk *clk; 83 + struct cmdq_client_reg cmdq_reg; 84 + }; 85 + 86 + static unsigned int rdma_fmt_convert(unsigned int fmt) 87 + { 88 + switch (fmt) { 89 + default: 90 + case DRM_FORMAT_RGB565: 91 + return RDMA_INPUT_FORMAT_RGB565; 92 + case DRM_FORMAT_BGR565: 93 + return RDMA_INPUT_FORMAT_RGB565 | FLD_SWAP; 94 + case DRM_FORMAT_RGB888: 95 + return RDMA_INPUT_FORMAT_RGB888; 96 + case DRM_FORMAT_BGR888: 97 + return RDMA_INPUT_FORMAT_RGB888 | FLD_SWAP; 98 + case DRM_FORMAT_RGBX8888: 99 + case DRM_FORMAT_RGBA8888: 100 + return RDMA_INPUT_FORMAT_ARGB8888; 101 + case DRM_FORMAT_BGRX8888: 102 + case DRM_FORMAT_BGRA8888: 103 + return RDMA_INPUT_FORMAT_ARGB8888 | FLD_SWAP; 104 + case DRM_FORMAT_XRGB8888: 105 + case DRM_FORMAT_ARGB8888: 106 + return RDMA_INPUT_FORMAT_RGBA8888; 107 + case DRM_FORMAT_XBGR8888: 108 + case DRM_FORMAT_ABGR8888: 109 + return RDMA_INPUT_FORMAT_RGBA8888 | FLD_SWAP; 110 + case DRM_FORMAT_ABGR2101010: 111 + return RDMA_INPUT_FORMAT_RGBA8888 | FLD_SWAP | RDMA_INPUT_10BIT; 112 + case DRM_FORMAT_ARGB2101010: 113 + return RDMA_INPUT_FORMAT_RGBA8888 | RDMA_INPUT_10BIT; 114 + case DRM_FORMAT_RGBA1010102: 115 + return RDMA_INPUT_FORMAT_ARGB8888 | FLD_SWAP | RDMA_INPUT_10BIT; 116 + case DRM_FORMAT_BGRA1010102: 117 + return RDMA_INPUT_FORMAT_ARGB8888 | RDMA_INPUT_10BIT; 118 + case DRM_FORMAT_UYVY: 119 + return RDMA_INPUT_FORMAT_UYVY; 120 + case DRM_FORMAT_YUYV: 121 + return RDMA_INPUT_FORMAT_YUY2; 122 + } 123 + } 124 + 125 + static unsigned int rdma_color_convert(unsigned int color_encoding) 126 + { 127 + switch (color_encoding) { 128 + default: 129 + case DRM_COLOR_YCBCR_BT709: 130 + return RDMA_CSC_FULL709_TO_RGB; 131 + case DRM_COLOR_YCBCR_BT601: 132 + return RDMA_CSC_BT601_TO_RGB; 133 + } 134 + } 135 + 136 + static void mtk_mdp_rdma_fifo_config(struct device *dev, struct cmdq_pkt *cmdq_pkt) 137 + { 138 + struct mtk_mdp_rdma *priv = dev_get_drvdata(dev); 139 + 140 + mtk_ddp_write_mask(cmdq_pkt, FLD_EXT_ULTRA_EN | VAL_PRE_ULTRA_EN_ENABLE << 16 | 141 + VAL_ULTRA_EN_ENABLE << 12 | VAL_RD_REQ_TYPE_BURST_8_ACCESS << 4 | 142 + FLD_EXT_PREULTRA_EN | FLD_COMMAND_DIV, &priv->cmdq_reg, 143 + priv->regs, MDP_RDMA_GMCIF_CON, FLD_EXT_ULTRA_EN | 144 + FLD_PRE_ULTRA_EN | FLD_ULTRA_EN | FLD_RD_REQ_TYPE | 145 + FLD_EXT_PREULTRA_EN | FLD_COMMAND_DIV); 146 + } 147 + 148 + void mtk_mdp_rdma_start(struct device *dev, struct cmdq_pkt *cmdq_pkt) 149 + { 150 + struct mtk_mdp_rdma *priv = dev_get_drvdata(dev); 151 + 152 + mtk_ddp_write_mask(cmdq_pkt, FLD_ROT_ENABLE, &priv->cmdq_reg, 153 + priv->regs, MDP_RDMA_EN, FLD_ROT_ENABLE); 154 + } 155 + 156 + void mtk_mdp_rdma_stop(struct device *dev, struct cmdq_pkt *cmdq_pkt) 157 + { 158 + struct mtk_mdp_rdma *priv = dev_get_drvdata(dev); 159 + 160 + mtk_ddp_write_mask(cmdq_pkt, 0, &priv->cmdq_reg, 161 + priv->regs, MDP_RDMA_EN, FLD_ROT_ENABLE); 162 + mtk_ddp_write(cmdq_pkt, 1, &priv->cmdq_reg, priv->regs, MDP_RDMA_RESET); 163 + mtk_ddp_write(cmdq_pkt, 0, &priv->cmdq_reg, priv->regs, MDP_RDMA_RESET); 164 + } 165 + 166 + void mtk_mdp_rdma_config(struct device *dev, struct mtk_mdp_rdma_cfg *cfg, 167 + struct cmdq_pkt *cmdq_pkt) 168 + { 169 + struct mtk_mdp_rdma *priv = dev_get_drvdata(dev); 170 + const struct drm_format_info *fmt_info = drm_format_info(cfg->fmt); 171 + bool csc_enable = fmt_info->is_yuv ? true : false; 172 + unsigned int src_pitch_y = cfg->pitch; 173 + unsigned int offset_y = 0; 174 + 175 + mtk_mdp_rdma_fifo_config(dev, cmdq_pkt); 176 + 177 + mtk_ddp_write_mask(cmdq_pkt, FLD_UNIFORM_CONFIG, &priv->cmdq_reg, priv->regs, 178 + MDP_RDMA_SRC_CON, FLD_UNIFORM_CONFIG); 179 + mtk_ddp_write_mask(cmdq_pkt, rdma_fmt_convert(cfg->fmt), &priv->cmdq_reg, priv->regs, 180 + MDP_RDMA_SRC_CON, FLD_SWAP | FLD_SRC_FORMAT | FLD_BIT_NUMBER); 181 + 182 + if (!csc_enable && fmt_info->has_alpha) 183 + mtk_ddp_write_mask(cmdq_pkt, FLD_OUTPUT_ARGB, &priv->cmdq_reg, 184 + priv->regs, MDP_RDMA_SRC_CON, FLD_OUTPUT_ARGB); 185 + else 186 + mtk_ddp_write_mask(cmdq_pkt, 0, &priv->cmdq_reg, priv->regs, 187 + MDP_RDMA_SRC_CON, FLD_OUTPUT_ARGB); 188 + 189 + mtk_ddp_write_mask(cmdq_pkt, cfg->addr0, &priv->cmdq_reg, priv->regs, 190 + MDP_RDMA_SRC_BASE_0, FLD_SRC_BASE_0); 191 + 192 + mtk_ddp_write_mask(cmdq_pkt, src_pitch_y, &priv->cmdq_reg, priv->regs, 193 + MDP_RDMA_MF_BKGD_SIZE_IN_BYTE, FLD_MF_BKGD_WB); 194 + 195 + mtk_ddp_write_mask(cmdq_pkt, 0, &priv->cmdq_reg, priv->regs, MDP_RDMA_COMP_CON, 196 + FLD_AFBC_YUV_TRANSFORM | FLD_UFBDC_EN | FLD_AFBC_EN); 197 + mtk_ddp_write_mask(cmdq_pkt, FLD_OUTPUT_10B, &priv->cmdq_reg, priv->regs, 198 + MDP_RDMA_CON, FLD_OUTPUT_10B); 199 + mtk_ddp_write_mask(cmdq_pkt, FLD_SIMPLE_MODE, &priv->cmdq_reg, priv->regs, 200 + MDP_RDMA_CON, FLD_SIMPLE_MODE); 201 + if (csc_enable) 202 + mtk_ddp_write_mask(cmdq_pkt, rdma_color_convert(cfg->color_encoding) << 23, 203 + &priv->cmdq_reg, priv->regs, MDP_RDMA_TRANSFORM_0, 204 + FLD_INT_MATRIX_SEL); 205 + mtk_ddp_write_mask(cmdq_pkt, csc_enable << 16, &priv->cmdq_reg, priv->regs, 206 + MDP_RDMA_TRANSFORM_0, FLD_TRANS_EN); 207 + 208 + offset_y = cfg->x_left * fmt_info->cpp[0] + cfg->y_top * src_pitch_y; 209 + 210 + mtk_ddp_write_mask(cmdq_pkt, offset_y, &priv->cmdq_reg, priv->regs, 211 + MDP_RDMA_SRC_OFFSET_0, FLD_SRC_OFFSET_0); 212 + mtk_ddp_write_mask(cmdq_pkt, cfg->width, &priv->cmdq_reg, priv->regs, 213 + MDP_RDMA_MF_SRC_SIZE, FLD_MF_SRC_W); 214 + mtk_ddp_write_mask(cmdq_pkt, cfg->height << 16, &priv->cmdq_reg, priv->regs, 215 + MDP_RDMA_MF_SRC_SIZE, FLD_MF_SRC_H); 216 + mtk_ddp_write_mask(cmdq_pkt, cfg->width, &priv->cmdq_reg, priv->regs, 217 + MDP_RDMA_MF_CLIP_SIZE, FLD_MF_CLIP_W); 218 + mtk_ddp_write_mask(cmdq_pkt, cfg->height << 16, &priv->cmdq_reg, priv->regs, 219 + MDP_RDMA_MF_CLIP_SIZE, FLD_MF_CLIP_H); 220 + } 221 + 222 + int mtk_mdp_rdma_clk_enable(struct device *dev) 223 + { 224 + struct mtk_mdp_rdma *rdma = dev_get_drvdata(dev); 225 + 226 + clk_prepare_enable(rdma->clk); 227 + return 0; 228 + } 229 + 230 + void mtk_mdp_rdma_clk_disable(struct device *dev) 231 + { 232 + struct mtk_mdp_rdma *rdma = dev_get_drvdata(dev); 233 + 234 + clk_disable_unprepare(rdma->clk); 235 + } 236 + 237 + static int mtk_mdp_rdma_bind(struct device *dev, struct device *master, 238 + void *data) 239 + { 240 + return 0; 241 + } 242 + 243 + static void mtk_mdp_rdma_unbind(struct device *dev, struct device *master, 244 + void *data) 245 + { 246 + } 247 + 248 + static const struct component_ops mtk_mdp_rdma_component_ops = { 249 + .bind = mtk_mdp_rdma_bind, 250 + .unbind = mtk_mdp_rdma_unbind, 251 + }; 252 + 253 + static int mtk_mdp_rdma_probe(struct platform_device *pdev) 254 + { 255 + struct device *dev = &pdev->dev; 256 + struct resource *res; 257 + struct mtk_mdp_rdma *priv; 258 + int ret = 0; 259 + 260 + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); 261 + if (!priv) 262 + return -ENOMEM; 263 + 264 + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 265 + priv->regs = devm_ioremap_resource(dev, res); 266 + if (IS_ERR(priv->regs)) { 267 + dev_err(dev, "failed to ioremap rdma\n"); 268 + return PTR_ERR(priv->regs); 269 + } 270 + 271 + priv->clk = devm_clk_get(dev, NULL); 272 + if (IS_ERR(priv->clk)) { 273 + dev_err(dev, "failed to get rdma clk\n"); 274 + return PTR_ERR(priv->clk); 275 + } 276 + 277 + #if IS_REACHABLE(CONFIG_MTK_CMDQ) 278 + ret = cmdq_dev_get_client_reg(dev, &priv->cmdq_reg, 0); 279 + if (ret) 280 + dev_dbg(dev, "get mediatek,gce-client-reg fail!\n"); 281 + #endif 282 + platform_set_drvdata(pdev, priv); 283 + 284 + pm_runtime_enable(dev); 285 + 286 + ret = component_add(dev, &mtk_mdp_rdma_component_ops); 287 + if (ret != 0) { 288 + pm_runtime_disable(dev); 289 + dev_err(dev, "Failed to add component: %d\n", ret); 290 + } 291 + return ret; 292 + } 293 + 294 + static int mtk_mdp_rdma_remove(struct platform_device *pdev) 295 + { 296 + component_del(&pdev->dev, &mtk_mdp_rdma_component_ops); 297 + pm_runtime_disable(&pdev->dev); 298 + return 0; 299 + } 300 + 301 + static const struct of_device_id mtk_mdp_rdma_driver_dt_match[] = { 302 + { .compatible = "mediatek,mt8195-vdo1-rdma", }, 303 + {}, 304 + }; 305 + MODULE_DEVICE_TABLE(of, mtk_mdp_rdma_driver_dt_match); 306 + 307 + struct platform_driver mtk_mdp_rdma_driver = { 308 + .probe = mtk_mdp_rdma_probe, 309 + .remove = mtk_mdp_rdma_remove, 310 + .driver = { 311 + .name = "mediatek-mdp-rdma", 312 + .owner = THIS_MODULE, 313 + .of_match_table = mtk_mdp_rdma_driver_dt_match, 314 + }, 315 + };
+20
drivers/gpu/drm/mediatek/mtk_mdp_rdma.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0-only */ 2 + /* 3 + * Copyright (c) 2021 MediaTek Inc. 4 + */ 5 + 6 + #ifndef __MTK_MDP_RDMA_H__ 7 + #define __MTK_MDP_RDMA_H__ 8 + 9 + struct mtk_mdp_rdma_cfg { 10 + unsigned int pitch; 11 + unsigned int addr0; 12 + unsigned int width; 13 + unsigned int height; 14 + unsigned int x_left; 15 + unsigned int y_top; 16 + int fmt; 17 + int color_encoding; 18 + }; 19 + 20 + #endif // __MTK_MDP_RDMA_H__