brintos

brintos / linux-shallow public Read only

0
0
Text · 10.2 KiB · 7c1a8c7 Raw
350 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*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/mod_devicetable.h>10#include <linux/platform_device.h>11#include <linux/pm_runtime.h>12#include <linux/soc/mediatek/mtk-cmdq.h>13 14#include "mtk_disp_drv.h"15#include "mtk_drm_drv.h"16#include "mtk_mdp_rdma.h"17 18#define MDP_RDMA_EN			0x00019#define FLD_ROT_ENABLE				BIT(0)20#define MDP_RDMA_RESET			0x00821#define MDP_RDMA_CON			0x02022#define FLD_OUTPUT_10B				BIT(5)23#define FLD_SIMPLE_MODE				BIT(4)24#define MDP_RDMA_GMCIF_CON		0x02825#define FLD_COMMAND_DIV				BIT(0)26#define FLD_EXT_PREULTRA_EN			BIT(3)27#define FLD_RD_REQ_TYPE				GENMASK(7, 4)28#define VAL_RD_REQ_TYPE_BURST_8_ACCESS		729#define FLD_ULTRA_EN				GENMASK(13, 12)30#define VAL_ULTRA_EN_ENABLE			131#define FLD_PRE_ULTRA_EN			GENMASK(17, 16)32#define VAL_PRE_ULTRA_EN_ENABLE			133#define FLD_EXT_ULTRA_EN			BIT(18)34#define MDP_RDMA_SRC_CON		0x03035#define FLD_OUTPUT_ARGB				BIT(25)36#define FLD_BIT_NUMBER				GENMASK(19, 18)37#define FLD_SWAP				BIT(14)38#define FLD_UNIFORM_CONFIG			BIT(17)39#define RDMA_INPUT_10BIT			BIT(18)40#define FLD_SRC_FORMAT				GENMASK(3, 0)41#define MDP_RDMA_COMP_CON		0x03842#define FLD_AFBC_EN				BIT(22)43#define FLD_AFBC_YUV_TRANSFORM			BIT(21)44#define FLD_UFBDC_EN				BIT(12)45#define MDP_RDMA_MF_BKGD_SIZE_IN_BYTE	0x06046#define FLD_MF_BKGD_WB				GENMASK(22, 0)47#define MDP_RDMA_MF_SRC_SIZE		0x07048#define FLD_MF_SRC_H				GENMASK(30, 16)49#define FLD_MF_SRC_W				GENMASK(14, 0)50#define MDP_RDMA_MF_CLIP_SIZE		0x07851#define FLD_MF_CLIP_H				GENMASK(30, 16)52#define FLD_MF_CLIP_W				GENMASK(14, 0)53#define MDP_RDMA_SRC_OFFSET_0		0x11854#define FLD_SRC_OFFSET_0			GENMASK(31, 0)55#define MDP_RDMA_TRANSFORM_0		0x20056#define FLD_INT_MATRIX_SEL			GENMASK(27, 23)57#define FLD_TRANS_EN				BIT(16)58#define MDP_RDMA_SRC_BASE_0		0xf0059#define FLD_SRC_BASE_0				GENMASK(31, 0)60 61#define RDMA_CSC_FULL709_TO_RGB			562#define RDMA_CSC_BT601_TO_RGB			663 64static const u32 formats[] = {65	DRM_FORMAT_XRGB8888,66	DRM_FORMAT_ARGB8888,67	DRM_FORMAT_BGRX8888,68	DRM_FORMAT_BGRA8888,69	DRM_FORMAT_ABGR8888,70	DRM_FORMAT_XBGR8888,71	DRM_FORMAT_RGB888,72	DRM_FORMAT_BGR888,73	DRM_FORMAT_RGB565,74	DRM_FORMAT_UYVY,75	DRM_FORMAT_YUYV,76};77 78enum rdma_format {79	RDMA_INPUT_FORMAT_RGB565 = 0,80	RDMA_INPUT_FORMAT_RGB888 = 1,81	RDMA_INPUT_FORMAT_RGBA8888 = 2,82	RDMA_INPUT_FORMAT_ARGB8888 = 3,83	RDMA_INPUT_FORMAT_UYVY = 4,84	RDMA_INPUT_FORMAT_YUY2 = 5,85	RDMA_INPUT_FORMAT_Y8 = 7,86	RDMA_INPUT_FORMAT_YV12 = 8,87	RDMA_INPUT_FORMAT_UYVY_3PL = 9,88	RDMA_INPUT_FORMAT_NV12 = 12,89	RDMA_INPUT_FORMAT_UYVY_2PL = 13,90	RDMA_INPUT_FORMAT_Y410 = 1491};92 93struct mtk_mdp_rdma {94	void __iomem		*regs;95	struct clk		*clk;96	struct cmdq_client_reg	cmdq_reg;97};98 99static unsigned int rdma_fmt_convert(unsigned int fmt)100{101	switch (fmt) {102	default:103	case DRM_FORMAT_RGB565:104		return RDMA_INPUT_FORMAT_RGB565;105	case DRM_FORMAT_BGR565:106		return RDMA_INPUT_FORMAT_RGB565 | FLD_SWAP;107	case DRM_FORMAT_RGB888:108		return RDMA_INPUT_FORMAT_RGB888;109	case DRM_FORMAT_BGR888:110		return RDMA_INPUT_FORMAT_RGB888 | FLD_SWAP;111	case DRM_FORMAT_RGBX8888:112	case DRM_FORMAT_RGBA8888:113		return RDMA_INPUT_FORMAT_ARGB8888;114	case DRM_FORMAT_BGRX8888:115	case DRM_FORMAT_BGRA8888:116		return RDMA_INPUT_FORMAT_ARGB8888 | FLD_SWAP;117	case DRM_FORMAT_XRGB8888:118	case DRM_FORMAT_ARGB8888:119		return RDMA_INPUT_FORMAT_RGBA8888;120	case DRM_FORMAT_XBGR8888:121	case DRM_FORMAT_ABGR8888:122		return RDMA_INPUT_FORMAT_RGBA8888 | FLD_SWAP;123	case DRM_FORMAT_ABGR2101010:124		return RDMA_INPUT_FORMAT_RGBA8888 | FLD_SWAP | RDMA_INPUT_10BIT;125	case DRM_FORMAT_ARGB2101010:126		return RDMA_INPUT_FORMAT_RGBA8888 | RDMA_INPUT_10BIT;127	case DRM_FORMAT_RGBA1010102:128		return RDMA_INPUT_FORMAT_ARGB8888 | FLD_SWAP | RDMA_INPUT_10BIT;129	case DRM_FORMAT_BGRA1010102:130		return RDMA_INPUT_FORMAT_ARGB8888 | RDMA_INPUT_10BIT;131	case DRM_FORMAT_UYVY:132		return RDMA_INPUT_FORMAT_UYVY;133	case DRM_FORMAT_YUYV:134		return RDMA_INPUT_FORMAT_YUY2;135	}136}137 138static unsigned int rdma_color_convert(unsigned int color_encoding)139{140	switch (color_encoding) {141	default:142	case DRM_COLOR_YCBCR_BT709:143		return RDMA_CSC_FULL709_TO_RGB;144	case DRM_COLOR_YCBCR_BT601:145		return RDMA_CSC_BT601_TO_RGB;146	}147}148 149static void mtk_mdp_rdma_fifo_config(struct device *dev, struct cmdq_pkt *cmdq_pkt)150{151	struct mtk_mdp_rdma *priv = dev_get_drvdata(dev);152 153	mtk_ddp_write_mask(cmdq_pkt, FLD_EXT_ULTRA_EN | VAL_PRE_ULTRA_EN_ENABLE << 16 |154			   VAL_ULTRA_EN_ENABLE << 12 | VAL_RD_REQ_TYPE_BURST_8_ACCESS << 4 |155			   FLD_EXT_PREULTRA_EN | FLD_COMMAND_DIV, &priv->cmdq_reg,156			   priv->regs, MDP_RDMA_GMCIF_CON, FLD_EXT_ULTRA_EN |157			   FLD_PRE_ULTRA_EN | FLD_ULTRA_EN | FLD_RD_REQ_TYPE |158			   FLD_EXT_PREULTRA_EN | FLD_COMMAND_DIV);159}160 161void mtk_mdp_rdma_start(struct device *dev, struct cmdq_pkt *cmdq_pkt)162{163	struct mtk_mdp_rdma *priv = dev_get_drvdata(dev);164 165	mtk_ddp_write_mask(cmdq_pkt, FLD_ROT_ENABLE, &priv->cmdq_reg,166			   priv->regs, MDP_RDMA_EN, FLD_ROT_ENABLE);167}168 169void mtk_mdp_rdma_stop(struct device *dev, struct cmdq_pkt *cmdq_pkt)170{171	struct mtk_mdp_rdma *priv = dev_get_drvdata(dev);172 173	mtk_ddp_write_mask(cmdq_pkt, 0, &priv->cmdq_reg,174			   priv->regs, MDP_RDMA_EN, FLD_ROT_ENABLE);175	mtk_ddp_write(cmdq_pkt, 1, &priv->cmdq_reg, priv->regs, MDP_RDMA_RESET);176	mtk_ddp_write(cmdq_pkt, 0, &priv->cmdq_reg, priv->regs, MDP_RDMA_RESET);177}178 179void mtk_mdp_rdma_config(struct device *dev, struct mtk_mdp_rdma_cfg *cfg,180			 struct cmdq_pkt *cmdq_pkt)181{182	struct mtk_mdp_rdma *priv = dev_get_drvdata(dev);183	const struct drm_format_info *fmt_info = drm_format_info(cfg->fmt);184	bool csc_enable = fmt_info->is_yuv ? true : false;185	unsigned int src_pitch_y = cfg->pitch;186	unsigned int offset_y = 0;187 188	mtk_mdp_rdma_fifo_config(dev, cmdq_pkt);189 190	mtk_ddp_write_mask(cmdq_pkt, FLD_UNIFORM_CONFIG, &priv->cmdq_reg, priv->regs,191			   MDP_RDMA_SRC_CON, FLD_UNIFORM_CONFIG);192	mtk_ddp_write_mask(cmdq_pkt, rdma_fmt_convert(cfg->fmt), &priv->cmdq_reg, priv->regs,193			   MDP_RDMA_SRC_CON, FLD_SWAP | FLD_SRC_FORMAT | FLD_BIT_NUMBER);194 195	if (!csc_enable && fmt_info->has_alpha)196		mtk_ddp_write_mask(cmdq_pkt, FLD_OUTPUT_ARGB, &priv->cmdq_reg,197				   priv->regs, MDP_RDMA_SRC_CON, FLD_OUTPUT_ARGB);198	else199		mtk_ddp_write_mask(cmdq_pkt, 0, &priv->cmdq_reg, priv->regs,200				   MDP_RDMA_SRC_CON, FLD_OUTPUT_ARGB);201 202	mtk_ddp_write_mask(cmdq_pkt, cfg->addr0, &priv->cmdq_reg, priv->regs,203			   MDP_RDMA_SRC_BASE_0, FLD_SRC_BASE_0);204 205	mtk_ddp_write_mask(cmdq_pkt, src_pitch_y, &priv->cmdq_reg, priv->regs,206			   MDP_RDMA_MF_BKGD_SIZE_IN_BYTE, FLD_MF_BKGD_WB);207 208	mtk_ddp_write_mask(cmdq_pkt, 0, &priv->cmdq_reg, priv->regs, MDP_RDMA_COMP_CON,209			   FLD_AFBC_YUV_TRANSFORM | FLD_UFBDC_EN | FLD_AFBC_EN);210	mtk_ddp_write_mask(cmdq_pkt, FLD_OUTPUT_10B, &priv->cmdq_reg, priv->regs,211			   MDP_RDMA_CON, FLD_OUTPUT_10B);212	mtk_ddp_write_mask(cmdq_pkt, FLD_SIMPLE_MODE, &priv->cmdq_reg, priv->regs,213			   MDP_RDMA_CON, FLD_SIMPLE_MODE);214	if (csc_enable)215		mtk_ddp_write_mask(cmdq_pkt, rdma_color_convert(cfg->color_encoding) << 23,216				   &priv->cmdq_reg, priv->regs, MDP_RDMA_TRANSFORM_0,217				   FLD_INT_MATRIX_SEL);218	mtk_ddp_write_mask(cmdq_pkt, csc_enable << 16, &priv->cmdq_reg, priv->regs,219			   MDP_RDMA_TRANSFORM_0, FLD_TRANS_EN);220 221	offset_y  = cfg->x_left * fmt_info->cpp[0] + cfg->y_top * src_pitch_y;222 223	mtk_ddp_write_mask(cmdq_pkt, offset_y, &priv->cmdq_reg, priv->regs,224			   MDP_RDMA_SRC_OFFSET_0, FLD_SRC_OFFSET_0);225	mtk_ddp_write_mask(cmdq_pkt, cfg->width, &priv->cmdq_reg, priv->regs,226			   MDP_RDMA_MF_SRC_SIZE, FLD_MF_SRC_W);227	mtk_ddp_write_mask(cmdq_pkt, cfg->height << 16, &priv->cmdq_reg, priv->regs,228			   MDP_RDMA_MF_SRC_SIZE, FLD_MF_SRC_H);229	mtk_ddp_write_mask(cmdq_pkt, cfg->width, &priv->cmdq_reg, priv->regs,230			   MDP_RDMA_MF_CLIP_SIZE, FLD_MF_CLIP_W);231	mtk_ddp_write_mask(cmdq_pkt, cfg->height << 16, &priv->cmdq_reg, priv->regs,232			   MDP_RDMA_MF_CLIP_SIZE, FLD_MF_CLIP_H);233}234 235const u32 *mtk_mdp_rdma_get_formats(struct device *dev)236{237	return formats;238}239 240size_t mtk_mdp_rdma_get_num_formats(struct device *dev)241{242	return ARRAY_SIZE(formats);243}244 245int mtk_mdp_rdma_power_on(struct device *dev)246{247	int ret = pm_runtime_resume_and_get(dev);248 249	if (ret < 0) {250		dev_err(dev, "Failed to power on: %d\n", ret);251		return ret;252	}253	return 0;254}255 256void mtk_mdp_rdma_power_off(struct device *dev)257{258	pm_runtime_put(dev);259}260 261int mtk_mdp_rdma_clk_enable(struct device *dev)262{263	struct mtk_mdp_rdma *rdma = dev_get_drvdata(dev);264 265	return clk_prepare_enable(rdma->clk);266}267 268void mtk_mdp_rdma_clk_disable(struct device *dev)269{270	struct mtk_mdp_rdma *rdma = dev_get_drvdata(dev);271 272	clk_disable_unprepare(rdma->clk);273}274 275static int mtk_mdp_rdma_bind(struct device *dev, struct device *master,276			     void *data)277{278	return 0;279}280 281static void mtk_mdp_rdma_unbind(struct device *dev, struct device *master,282				void *data)283{284}285 286static const struct component_ops mtk_mdp_rdma_component_ops = {287	.bind	= mtk_mdp_rdma_bind,288	.unbind = mtk_mdp_rdma_unbind,289};290 291static int mtk_mdp_rdma_probe(struct platform_device *pdev)292{293	struct device *dev = &pdev->dev;294	struct resource *res;295	struct mtk_mdp_rdma *priv;296	int ret = 0;297 298	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);299	if (!priv)300		return -ENOMEM;301 302	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);303	priv->regs = devm_ioremap_resource(dev, res);304	if (IS_ERR(priv->regs))305		return dev_err_probe(dev, PTR_ERR(priv->regs),306				     "failed to ioremap rdma\n");307 308	priv->clk = devm_clk_get(dev, NULL);309	if (IS_ERR(priv->clk))310		return dev_err_probe(dev, PTR_ERR(priv->clk),311				     "failed to get rdma clk\n");312 313#if IS_REACHABLE(CONFIG_MTK_CMDQ)314	ret = cmdq_dev_get_client_reg(dev, &priv->cmdq_reg, 0);315	if (ret)316		dev_dbg(dev, "get mediatek,gce-client-reg fail!\n");317#endif318	platform_set_drvdata(pdev, priv);319 320	pm_runtime_enable(dev);321 322	ret = component_add(dev, &mtk_mdp_rdma_component_ops);323	if (ret != 0) {324		pm_runtime_disable(dev);325		return dev_err_probe(dev, ret, "Failed to add component\n");326	}327	return 0;328}329 330static void mtk_mdp_rdma_remove(struct platform_device *pdev)331{332	component_del(&pdev->dev, &mtk_mdp_rdma_component_ops);333	pm_runtime_disable(&pdev->dev);334}335 336static const struct of_device_id mtk_mdp_rdma_driver_dt_match[] = {337	{ .compatible = "mediatek,mt8195-vdo1-rdma", },338	{},339};340MODULE_DEVICE_TABLE(of, mtk_mdp_rdma_driver_dt_match);341 342struct platform_driver mtk_mdp_rdma_driver = {343	.probe = mtk_mdp_rdma_probe,344	.remove_new = mtk_mdp_rdma_remove,345	.driver = {346		.name = "mediatek-mdp-rdma",347		.of_match_table = mtk_mdp_rdma_driver_dt_match,348	},349};350