xref: /openbmc/linux/drivers/soc/mediatek/mtk-mmsys.c (revision d01e0aec)
113032709SMatthias Brugger // SPDX-License-Identifier: GPL-2.0-only
213032709SMatthias Brugger /*
313032709SMatthias Brugger  * Copyright (c) 2014 MediaTek Inc.
413032709SMatthias Brugger  * Author: James Liao <jamesjj.liao@mediatek.com>
513032709SMatthias Brugger  */
613032709SMatthias Brugger 
7f27ef285SEnric Balletbo i Serra #include <linux/delay.h>
82c758e30SEnric Balletbo i Serra #include <linux/device.h>
951c0e618SYongqiang Niu #include <linux/io.h>
10a7596e62SYongqiang Niu #include <linux/module.h>
11*d01e0aecSRob Herring #include <linux/of.h>
1213032709SMatthias Brugger #include <linux/platform_device.h>
13f27ef285SEnric Balletbo i Serra #include <linux/reset-controller.h>
142c758e30SEnric Balletbo i Serra #include <linux/soc/mediatek/mtk-mmsys.h>
152c758e30SEnric Balletbo i Serra 
1644014763SCK Hu #include "mtk-mmsys.h"
17060f7875SFabien Parent #include "mt8167-mmsys.h"
182a0a8d87SAngeloGioacchino Del Regno #include "mt8173-mmsys.h"
191ff1270fSHsin-Yi Wang #include "mt8183-mmsys.h"
205f9b5b75SYongqiang Niu #include "mt8186-mmsys.h"
213b1a57c4SNathan Lu #include "mt8188-mmsys.h"
22d687e056SYongqiang Niu #include "mt8192-mmsys.h"
23b2b99a7aSJason-JH.Lin #include "mt8195-mmsys.h"
24bc3fc5c0SFabien Parent #include "mt8365-mmsys.h"
2513032709SMatthias Brugger 
262004f8beSNancy.Lin #define MMSYS_SW_RESET_PER_REG 32
272004f8beSNancy.Lin 
28c292b133SEnric Balletbo i Serra static const struct mtk_mmsys_driver_data mt2701_mmsys_driver_data = {
29c292b133SEnric Balletbo i Serra 	.clk_driver = "clk-mt2701-mm",
3044014763SCK Hu 	.routes = mmsys_default_routing_table,
3144014763SCK Hu 	.num_routes = ARRAY_SIZE(mmsys_default_routing_table),
32c292b133SEnric Balletbo i Serra };
33c292b133SEnric Balletbo i Serra 
349c5a0a3aSEnric Balletbo i Serra static const struct mtk_mmsys_driver_data mt2712_mmsys_driver_data = {
359c5a0a3aSEnric Balletbo i Serra 	.clk_driver = "clk-mt2712-mm",
3644014763SCK Hu 	.routes = mmsys_default_routing_table,
3744014763SCK Hu 	.num_routes = ARRAY_SIZE(mmsys_default_routing_table),
389c5a0a3aSEnric Balletbo i Serra };
399c5a0a3aSEnric Balletbo i Serra 
4032956ddaSMatthias Brugger static const struct mtk_mmsys_driver_data mt6779_mmsys_driver_data = {
4132956ddaSMatthias Brugger 	.clk_driver = "clk-mt6779-mm",
4232956ddaSMatthias Brugger };
4332956ddaSMatthias Brugger 
44e9a6f5bcSAngeloGioacchino Del Regno static const struct mtk_mmsys_driver_data mt6795_mmsys_driver_data = {
45e9a6f5bcSAngeloGioacchino Del Regno 	.clk_driver = "clk-mt6795-mm",
46e9a6f5bcSAngeloGioacchino Del Regno 	.routes = mt8173_mmsys_routing_table,
47e9a6f5bcSAngeloGioacchino Del Regno 	.num_routes = ARRAY_SIZE(mt8173_mmsys_routing_table),
48e9a6f5bcSAngeloGioacchino Del Regno 	.sw0_rst_offset = MT8183_MMSYS_SW0_RST_B,
49e9a6f5bcSAngeloGioacchino Del Regno 	.num_resets = 64,
50e9a6f5bcSAngeloGioacchino Del Regno };
51e9a6f5bcSAngeloGioacchino Del Regno 
52cad4e379SMatthias Brugger static const struct mtk_mmsys_driver_data mt6797_mmsys_driver_data = {
53cad4e379SMatthias Brugger 	.clk_driver = "clk-mt6797-mm",
54cad4e379SMatthias Brugger };
55cad4e379SMatthias Brugger 
56060f7875SFabien Parent static const struct mtk_mmsys_driver_data mt8167_mmsys_driver_data = {
57060f7875SFabien Parent 	.clk_driver = "clk-mt8167-mm",
58060f7875SFabien Parent 	.routes = mt8167_mmsys_routing_table,
59060f7875SFabien Parent 	.num_routes = ARRAY_SIZE(mt8167_mmsys_routing_table),
60060f7875SFabien Parent };
61060f7875SFabien Parent 
6213032709SMatthias Brugger static const struct mtk_mmsys_driver_data mt8173_mmsys_driver_data = {
6313032709SMatthias Brugger 	.clk_driver = "clk-mt8173-mm",
642a0a8d87SAngeloGioacchino Del Regno 	.routes = mt8173_mmsys_routing_table,
652a0a8d87SAngeloGioacchino Del Regno 	.num_routes = ARRAY_SIZE(mt8173_mmsys_routing_table),
6662dc3015SRex-BC Chen 	.sw0_rst_offset = MT8183_MMSYS_SW0_RST_B,
67b427d857SAngeloGioacchino Del Regno 	.num_resets = 64,
6813032709SMatthias Brugger };
6913032709SMatthias Brugger 
701f9adbc7SMatthias Brugger static const struct mtk_mmsys_driver_data mt8183_mmsys_driver_data = {
711f9adbc7SMatthias Brugger 	.clk_driver = "clk-mt8183-mm",
721ff1270fSHsin-Yi Wang 	.routes = mmsys_mt8183_routing_table,
731ff1270fSHsin-Yi Wang 	.num_routes = ARRAY_SIZE(mmsys_mt8183_routing_table),
7462dc3015SRex-BC Chen 	.sw0_rst_offset = MT8183_MMSYS_SW0_RST_B,
752004f8beSNancy.Lin 	.num_resets = 32,
761f9adbc7SMatthias Brugger };
771f9adbc7SMatthias Brugger 
785f9b5b75SYongqiang Niu static const struct mtk_mmsys_driver_data mt8186_mmsys_driver_data = {
795f9b5b75SYongqiang Niu 	.clk_driver = "clk-mt8186-mm",
805f9b5b75SYongqiang Niu 	.routes = mmsys_mt8186_routing_table,
815f9b5b75SYongqiang Niu 	.num_routes = ARRAY_SIZE(mmsys_mt8186_routing_table),
82831785f0SRex-BC Chen 	.sw0_rst_offset = MT8186_MMSYS_SW0_RST_B,
832004f8beSNancy.Lin 	.num_resets = 32,
845f9b5b75SYongqiang Niu };
855f9b5b75SYongqiang Niu 
863b1a57c4SNathan Lu static const struct mtk_mmsys_driver_data mt8188_vdosys0_driver_data = {
873b1a57c4SNathan Lu 	.clk_driver = "clk-mt8188-vdo0",
883b1a57c4SNathan Lu 	.routes = mmsys_mt8188_routing_table,
893b1a57c4SNathan Lu 	.num_routes = ARRAY_SIZE(mmsys_mt8188_routing_table),
903b1a57c4SNathan Lu };
913b1a57c4SNathan Lu 
92d687e056SYongqiang Niu static const struct mtk_mmsys_driver_data mt8192_mmsys_driver_data = {
93d687e056SYongqiang Niu 	.clk_driver = "clk-mt8192-mm",
94d687e056SYongqiang Niu 	.routes = mmsys_mt8192_routing_table,
95d687e056SYongqiang Niu 	.num_routes = ARRAY_SIZE(mmsys_mt8192_routing_table),
969d7370a5SAngeloGioacchino Del Regno 	.sw0_rst_offset = MT8186_MMSYS_SW0_RST_B,
972004f8beSNancy.Lin 	.num_resets = 32,
98d687e056SYongqiang Niu };
99d687e056SYongqiang Niu 
100b2b99a7aSJason-JH.Lin static const struct mtk_mmsys_driver_data mt8195_vdosys0_driver_data = {
101b2b99a7aSJason-JH.Lin 	.clk_driver = "clk-mt8195-vdo0",
102b2b99a7aSJason-JH.Lin 	.routes = mmsys_mt8195_routing_table,
103b2b99a7aSJason-JH.Lin 	.num_routes = ARRAY_SIZE(mmsys_mt8195_routing_table),
104b2b99a7aSJason-JH.Lin };
105b2b99a7aSJason-JH.Lin 
10639170127SNancy.Lin static const struct mtk_mmsys_driver_data mt8195_vdosys1_driver_data = {
10739170127SNancy.Lin 	.clk_driver = "clk-mt8195-vdo1",
10839170127SNancy.Lin 	.routes = mmsys_mt8195_vdo1_routing_table,
10939170127SNancy.Lin 	.num_routes = ARRAY_SIZE(mmsys_mt8195_vdo1_routing_table),
1107f0a38f4SNancy.Lin 	.sw0_rst_offset = MT8195_VDO1_SW0_RST_B,
1117f0a38f4SNancy.Lin 	.num_resets = 64,
11239170127SNancy.Lin };
11339170127SNancy.Lin 
11478ce3093SRoy-CW.Yeh static const struct mtk_mmsys_driver_data mt8195_vppsys0_driver_data = {
11578ce3093SRoy-CW.Yeh 	.clk_driver = "clk-mt8195-vpp0",
11678ce3093SRoy-CW.Yeh 	.is_vppsys = true,
11778ce3093SRoy-CW.Yeh };
11878ce3093SRoy-CW.Yeh 
11978ce3093SRoy-CW.Yeh static const struct mtk_mmsys_driver_data mt8195_vppsys1_driver_data = {
12078ce3093SRoy-CW.Yeh 	.clk_driver = "clk-mt8195-vpp1",
12178ce3093SRoy-CW.Yeh 	.is_vppsys = true,
12278ce3093SRoy-CW.Yeh };
12378ce3093SRoy-CW.Yeh 
124bc3fc5c0SFabien Parent static const struct mtk_mmsys_driver_data mt8365_mmsys_driver_data = {
125bc3fc5c0SFabien Parent 	.clk_driver = "clk-mt8365-mm",
126bc3fc5c0SFabien Parent 	.routes = mt8365_mmsys_routing_table,
127bc3fc5c0SFabien Parent 	.num_routes = ARRAY_SIZE(mt8365_mmsys_routing_table),
128bc3fc5c0SFabien Parent };
129bc3fc5c0SFabien Parent 
130ce15e7faSCK Hu struct mtk_mmsys {
131ce15e7faSCK Hu 	void __iomem *regs;
132ce15e7faSCK Hu 	const struct mtk_mmsys_driver_data *data;
1331ef3e78aSAngeloGioacchino Del Regno 	struct platform_device *clks_pdev;
1341ef3e78aSAngeloGioacchino Del Regno 	struct platform_device *drm_pdev;
135f27ef285SEnric Balletbo i Serra 	spinlock_t lock; /* protects mmsys_sw_rst_b reg */
136f27ef285SEnric Balletbo i Serra 	struct reset_controller_dev rcdev;
1378af1f6b5SNancy.Lin 	struct cmdq_client_reg cmdq_base;
138ce15e7faSCK Hu };
139ce15e7faSCK Hu 
mtk_mmsys_update_bits(struct mtk_mmsys * mmsys,u32 offset,u32 mask,u32 val,struct cmdq_pkt * cmdq_pkt)1408af1f6b5SNancy.Lin static void mtk_mmsys_update_bits(struct mtk_mmsys *mmsys, u32 offset, u32 mask, u32 val,
1418af1f6b5SNancy.Lin 				  struct cmdq_pkt *cmdq_pkt)
1420a815034SNancy.Lin {
143b34884b4SAngeloGioacchino Del Regno 	int ret;
1440a815034SNancy.Lin 	u32 tmp;
1450a815034SNancy.Lin 
146b34884b4SAngeloGioacchino Del Regno 	if (mmsys->cmdq_base.size && cmdq_pkt) {
147b34884b4SAngeloGioacchino Del Regno 		ret = cmdq_pkt_write_mask(cmdq_pkt, mmsys->cmdq_base.subsys,
1488af1f6b5SNancy.Lin 					  mmsys->cmdq_base.offset + offset, val,
1498af1f6b5SNancy.Lin 					  mask);
150b34884b4SAngeloGioacchino Del Regno 		if (ret)
151b34884b4SAngeloGioacchino Del Regno 			pr_debug("CMDQ unavailable: using CPU write\n");
152b34884b4SAngeloGioacchino Del Regno 		else
1538af1f6b5SNancy.Lin 			return;
1548af1f6b5SNancy.Lin 	}
1550a815034SNancy.Lin 	tmp = readl_relaxed(mmsys->regs + offset);
1560a815034SNancy.Lin 	tmp = (tmp & ~mask) | (val & mask);
1570a815034SNancy.Lin 	writel_relaxed(tmp, mmsys->regs + offset);
1580a815034SNancy.Lin }
1590a815034SNancy.Lin 
mtk_mmsys_ddp_connect(struct device * dev,enum mtk_ddp_comp_id cur,enum mtk_ddp_comp_id next)1602c758e30SEnric Balletbo i Serra void mtk_mmsys_ddp_connect(struct device *dev,
1612c758e30SEnric Balletbo i Serra 			   enum mtk_ddp_comp_id cur,
1622c758e30SEnric Balletbo i Serra 			   enum mtk_ddp_comp_id next)
1632c758e30SEnric Balletbo i Serra {
164ce15e7faSCK Hu 	struct mtk_mmsys *mmsys = dev_get_drvdata(dev);
16544014763SCK Hu 	const struct mtk_mmsys_routes *routes = mmsys->data->routes;
16644014763SCK Hu 	int i;
1672c758e30SEnric Balletbo i Serra 
16844014763SCK Hu 	for (i = 0; i < mmsys->data->num_routes; i++)
1690a815034SNancy.Lin 		if (cur == routes[i].from_comp && next == routes[i].to_comp)
1700a815034SNancy.Lin 			mtk_mmsys_update_bits(mmsys, routes[i].addr, routes[i].mask,
1718af1f6b5SNancy.Lin 					      routes[i].val, NULL);
1722c758e30SEnric Balletbo i Serra }
1732c758e30SEnric Balletbo i Serra EXPORT_SYMBOL_GPL(mtk_mmsys_ddp_connect);
1742c758e30SEnric Balletbo i Serra 
mtk_mmsys_ddp_disconnect(struct device * dev,enum mtk_ddp_comp_id cur,enum mtk_ddp_comp_id next)1752c758e30SEnric Balletbo i Serra void mtk_mmsys_ddp_disconnect(struct device *dev,
1762c758e30SEnric Balletbo i Serra 			      enum mtk_ddp_comp_id cur,
1772c758e30SEnric Balletbo i Serra 			      enum mtk_ddp_comp_id next)
1782c758e30SEnric Balletbo i Serra {
179ce15e7faSCK Hu 	struct mtk_mmsys *mmsys = dev_get_drvdata(dev);
18044014763SCK Hu 	const struct mtk_mmsys_routes *routes = mmsys->data->routes;
18144014763SCK Hu 	int i;
1822c758e30SEnric Balletbo i Serra 
18344014763SCK Hu 	for (i = 0; i < mmsys->data->num_routes; i++)
1840a815034SNancy.Lin 		if (cur == routes[i].from_comp && next == routes[i].to_comp)
1858af1f6b5SNancy.Lin 			mtk_mmsys_update_bits(mmsys, routes[i].addr, routes[i].mask, 0, NULL);
1862c758e30SEnric Balletbo i Serra }
1872c758e30SEnric Balletbo i Serra EXPORT_SYMBOL_GPL(mtk_mmsys_ddp_disconnect);
1882c758e30SEnric Balletbo i Serra 
mtk_mmsys_merge_async_config(struct device * dev,int idx,int width,int height,struct cmdq_pkt * cmdq_pkt)1898af1f6b5SNancy.Lin void mtk_mmsys_merge_async_config(struct device *dev, int idx, int width, int height,
1908af1f6b5SNancy.Lin 				  struct cmdq_pkt *cmdq_pkt)
1913dd20b71SNancy.Lin {
1923dd20b71SNancy.Lin 	mtk_mmsys_update_bits(dev_get_drvdata(dev), MT8195_VDO1_MERGE0_ASYNC_CFG_WD + 0x10 * idx,
1938af1f6b5SNancy.Lin 			      ~0, height << 16 | width, cmdq_pkt);
1943dd20b71SNancy.Lin }
1953dd20b71SNancy.Lin EXPORT_SYMBOL_GPL(mtk_mmsys_merge_async_config);
1963dd20b71SNancy.Lin 
mtk_mmsys_hdr_config(struct device * dev,int be_width,int be_height,struct cmdq_pkt * cmdq_pkt)1978af1f6b5SNancy.Lin void mtk_mmsys_hdr_config(struct device *dev, int be_width, int be_height,
1988af1f6b5SNancy.Lin 			  struct cmdq_pkt *cmdq_pkt)
1993dd20b71SNancy.Lin {
2003dd20b71SNancy.Lin 	mtk_mmsys_update_bits(dev_get_drvdata(dev), MT8195_VDO1_HDRBE_ASYNC_CFG_WD, ~0,
2018af1f6b5SNancy.Lin 			      be_height << 16 | be_width, cmdq_pkt);
2023dd20b71SNancy.Lin }
2033dd20b71SNancy.Lin EXPORT_SYMBOL_GPL(mtk_mmsys_hdr_config);
2043dd20b71SNancy.Lin 
mtk_mmsys_mixer_in_config(struct device * dev,int idx,bool alpha_sel,u16 alpha,u8 mode,u32 biwidth,struct cmdq_pkt * cmdq_pkt)2053dd20b71SNancy.Lin void mtk_mmsys_mixer_in_config(struct device *dev, int idx, bool alpha_sel, u16 alpha,
2068af1f6b5SNancy.Lin 			       u8 mode, u32 biwidth, struct cmdq_pkt *cmdq_pkt)
2073dd20b71SNancy.Lin {
2083dd20b71SNancy.Lin 	struct mtk_mmsys *mmsys = dev_get_drvdata(dev);
2093dd20b71SNancy.Lin 
2103dd20b71SNancy.Lin 	mtk_mmsys_update_bits(mmsys, MT8195_VDO1_MIXER_IN1_ALPHA + (idx - 1) * 4, ~0,
2118af1f6b5SNancy.Lin 			      alpha << 16 | alpha, cmdq_pkt);
2123dd20b71SNancy.Lin 	mtk_mmsys_update_bits(mmsys, MT8195_VDO1_HDR_TOP_CFG, BIT(19 + idx),
2138af1f6b5SNancy.Lin 			      alpha_sel << (19 + idx), cmdq_pkt);
2143dd20b71SNancy.Lin 	mtk_mmsys_update_bits(mmsys, MT8195_VDO1_MIXER_IN1_PAD + (idx - 1) * 4,
2158af1f6b5SNancy.Lin 			      GENMASK(31, 16) | GENMASK(1, 0), biwidth << 16 | mode, cmdq_pkt);
2163dd20b71SNancy.Lin }
2173dd20b71SNancy.Lin EXPORT_SYMBOL_GPL(mtk_mmsys_mixer_in_config);
2183dd20b71SNancy.Lin 
mtk_mmsys_mixer_in_channel_swap(struct device * dev,int idx,bool channel_swap,struct cmdq_pkt * cmdq_pkt)2198af1f6b5SNancy.Lin void mtk_mmsys_mixer_in_channel_swap(struct device *dev, int idx, bool channel_swap,
2208af1f6b5SNancy.Lin 				     struct cmdq_pkt *cmdq_pkt)
2213dd20b71SNancy.Lin {
2223dd20b71SNancy.Lin 	mtk_mmsys_update_bits(dev_get_drvdata(dev), MT8195_VDO1_MIXER_IN1_PAD + (idx - 1) * 4,
2238af1f6b5SNancy.Lin 			      BIT(4), channel_swap << 4, cmdq_pkt);
2243dd20b71SNancy.Lin }
2253dd20b71SNancy.Lin EXPORT_SYMBOL_GPL(mtk_mmsys_mixer_in_channel_swap);
2263dd20b71SNancy.Lin 
mtk_mmsys_ddp_dpi_fmt_config(struct device * dev,u32 val)227b404cb45SXinlei Lee void mtk_mmsys_ddp_dpi_fmt_config(struct device *dev, u32 val)
228b404cb45SXinlei Lee {
229e6c7e621SXinlei Lee 	struct mtk_mmsys *mmsys = dev_get_drvdata(dev);
230e6c7e621SXinlei Lee 
231e6c7e621SXinlei Lee 	switch (val) {
232e6c7e621SXinlei Lee 	case MTK_DPI_RGB888_SDR_CON:
233e6c7e621SXinlei Lee 		mtk_mmsys_update_bits(mmsys, MT8186_MMSYS_DPI_OUTPUT_FORMAT,
2348af1f6b5SNancy.Lin 				      MT8186_DPI_FORMAT_MASK, MT8186_DPI_RGB888_SDR_CON, NULL);
235e6c7e621SXinlei Lee 		break;
236e6c7e621SXinlei Lee 	case MTK_DPI_RGB565_SDR_CON:
237e6c7e621SXinlei Lee 		mtk_mmsys_update_bits(mmsys, MT8186_MMSYS_DPI_OUTPUT_FORMAT,
2388af1f6b5SNancy.Lin 				      MT8186_DPI_FORMAT_MASK, MT8186_DPI_RGB565_SDR_CON, NULL);
239e6c7e621SXinlei Lee 		break;
240e6c7e621SXinlei Lee 	case MTK_DPI_RGB565_DDR_CON:
241e6c7e621SXinlei Lee 		mtk_mmsys_update_bits(mmsys, MT8186_MMSYS_DPI_OUTPUT_FORMAT,
2428af1f6b5SNancy.Lin 				      MT8186_DPI_FORMAT_MASK, MT8186_DPI_RGB565_DDR_CON, NULL);
243e6c7e621SXinlei Lee 		break;
244e6c7e621SXinlei Lee 	case MTK_DPI_RGB888_DDR_CON:
245e6c7e621SXinlei Lee 	default:
246e6c7e621SXinlei Lee 		mtk_mmsys_update_bits(mmsys, MT8186_MMSYS_DPI_OUTPUT_FORMAT,
2478af1f6b5SNancy.Lin 				      MT8186_DPI_FORMAT_MASK, MT8186_DPI_RGB888_DDR_CON, NULL);
248e6c7e621SXinlei Lee 		break;
249e6c7e621SXinlei Lee 	}
250b404cb45SXinlei Lee }
251b404cb45SXinlei Lee EXPORT_SYMBOL_GPL(mtk_mmsys_ddp_dpi_fmt_config);
252b404cb45SXinlei Lee 
mtk_mmsys_vpp_rsz_merge_config(struct device * dev,u32 id,bool enable,struct cmdq_pkt * cmdq_pkt)253dd4f373eSRoy-CW.Yeh void mtk_mmsys_vpp_rsz_merge_config(struct device *dev, u32 id, bool enable,
254dd4f373eSRoy-CW.Yeh 				    struct cmdq_pkt *cmdq_pkt)
255dd4f373eSRoy-CW.Yeh {
256dd4f373eSRoy-CW.Yeh 	u32 reg;
257dd4f373eSRoy-CW.Yeh 
258dd4f373eSRoy-CW.Yeh 	switch (id) {
259dd4f373eSRoy-CW.Yeh 	case 2:
260dd4f373eSRoy-CW.Yeh 		reg = MT8195_SVPP2_BUF_BF_RSZ_SWITCH;
261dd4f373eSRoy-CW.Yeh 		break;
262dd4f373eSRoy-CW.Yeh 	case 3:
263dd4f373eSRoy-CW.Yeh 		reg = MT8195_SVPP3_BUF_BF_RSZ_SWITCH;
264dd4f373eSRoy-CW.Yeh 		break;
265dd4f373eSRoy-CW.Yeh 	default:
266dd4f373eSRoy-CW.Yeh 		dev_err(dev, "Invalid id %d\n", id);
267dd4f373eSRoy-CW.Yeh 		return;
268dd4f373eSRoy-CW.Yeh 	}
269dd4f373eSRoy-CW.Yeh 
270dd4f373eSRoy-CW.Yeh 	mtk_mmsys_update_bits(dev_get_drvdata(dev), reg, ~0, enable, cmdq_pkt);
271dd4f373eSRoy-CW.Yeh }
272dd4f373eSRoy-CW.Yeh EXPORT_SYMBOL_GPL(mtk_mmsys_vpp_rsz_merge_config);
273dd4f373eSRoy-CW.Yeh 
mtk_mmsys_vpp_rsz_dcm_config(struct device * dev,bool enable,struct cmdq_pkt * cmdq_pkt)274dd4f373eSRoy-CW.Yeh void mtk_mmsys_vpp_rsz_dcm_config(struct device *dev, bool enable,
275dd4f373eSRoy-CW.Yeh 				  struct cmdq_pkt *cmdq_pkt)
276dd4f373eSRoy-CW.Yeh {
277dd4f373eSRoy-CW.Yeh 	u32 client;
278dd4f373eSRoy-CW.Yeh 
279dd4f373eSRoy-CW.Yeh 	client = MT8195_SVPP1_MDP_RSZ;
280dd4f373eSRoy-CW.Yeh 	mtk_mmsys_update_bits(dev_get_drvdata(dev),
281dd4f373eSRoy-CW.Yeh 			      MT8195_VPP1_HW_DCM_1ST_DIS0, client,
282dd4f373eSRoy-CW.Yeh 			      ((enable) ? client : 0), cmdq_pkt);
283dd4f373eSRoy-CW.Yeh 	mtk_mmsys_update_bits(dev_get_drvdata(dev),
284dd4f373eSRoy-CW.Yeh 			      MT8195_VPP1_HW_DCM_2ND_DIS0, client,
285dd4f373eSRoy-CW.Yeh 			      ((enable) ? client : 0), cmdq_pkt);
286dd4f373eSRoy-CW.Yeh 
287dd4f373eSRoy-CW.Yeh 	client = MT8195_SVPP2_MDP_RSZ | MT8195_SVPP3_MDP_RSZ;
288dd4f373eSRoy-CW.Yeh 	mtk_mmsys_update_bits(dev_get_drvdata(dev),
289dd4f373eSRoy-CW.Yeh 			      MT8195_VPP1_HW_DCM_1ST_DIS1, client,
290dd4f373eSRoy-CW.Yeh 			      ((enable) ? client : 0), cmdq_pkt);
291dd4f373eSRoy-CW.Yeh 	mtk_mmsys_update_bits(dev_get_drvdata(dev),
292dd4f373eSRoy-CW.Yeh 			      MT8195_VPP1_HW_DCM_2ND_DIS1, client,
293dd4f373eSRoy-CW.Yeh 			      ((enable) ? client : 0), cmdq_pkt);
294dd4f373eSRoy-CW.Yeh }
295dd4f373eSRoy-CW.Yeh EXPORT_SYMBOL_GPL(mtk_mmsys_vpp_rsz_dcm_config);
296dd4f373eSRoy-CW.Yeh 
mtk_mmsys_reset_update(struct reset_controller_dev * rcdev,unsigned long id,bool assert)297f27ef285SEnric Balletbo i Serra static int mtk_mmsys_reset_update(struct reset_controller_dev *rcdev, unsigned long id,
298f27ef285SEnric Balletbo i Serra 				  bool assert)
299f27ef285SEnric Balletbo i Serra {
300f27ef285SEnric Balletbo i Serra 	struct mtk_mmsys *mmsys = container_of(rcdev, struct mtk_mmsys, rcdev);
301f27ef285SEnric Balletbo i Serra 	unsigned long flags;
3022004f8beSNancy.Lin 	u32 offset;
3032004f8beSNancy.Lin 	u32 reg;
3042004f8beSNancy.Lin 
3052004f8beSNancy.Lin 	offset = (id / MMSYS_SW_RESET_PER_REG) * sizeof(u32);
3062004f8beSNancy.Lin 	id = id % MMSYS_SW_RESET_PER_REG;
3072004f8beSNancy.Lin 	reg = mmsys->data->sw0_rst_offset + offset;
308f27ef285SEnric Balletbo i Serra 
309f27ef285SEnric Balletbo i Serra 	spin_lock_irqsave(&mmsys->lock, flags);
310f27ef285SEnric Balletbo i Serra 
311f27ef285SEnric Balletbo i Serra 	if (assert)
3122004f8beSNancy.Lin 		mtk_mmsys_update_bits(mmsys, reg, BIT(id), 0, NULL);
313f27ef285SEnric Balletbo i Serra 	else
3142004f8beSNancy.Lin 		mtk_mmsys_update_bits(mmsys, reg, BIT(id), BIT(id), NULL);
315f27ef285SEnric Balletbo i Serra 
316f27ef285SEnric Balletbo i Serra 	spin_unlock_irqrestore(&mmsys->lock, flags);
317f27ef285SEnric Balletbo i Serra 
318f27ef285SEnric Balletbo i Serra 	return 0;
319f27ef285SEnric Balletbo i Serra }
320f27ef285SEnric Balletbo i Serra 
mtk_mmsys_reset_assert(struct reset_controller_dev * rcdev,unsigned long id)321f27ef285SEnric Balletbo i Serra static int mtk_mmsys_reset_assert(struct reset_controller_dev *rcdev, unsigned long id)
322f27ef285SEnric Balletbo i Serra {
323f27ef285SEnric Balletbo i Serra 	return mtk_mmsys_reset_update(rcdev, id, true);
324f27ef285SEnric Balletbo i Serra }
325f27ef285SEnric Balletbo i Serra 
mtk_mmsys_reset_deassert(struct reset_controller_dev * rcdev,unsigned long id)326f27ef285SEnric Balletbo i Serra static int mtk_mmsys_reset_deassert(struct reset_controller_dev *rcdev, unsigned long id)
327f27ef285SEnric Balletbo i Serra {
328f27ef285SEnric Balletbo i Serra 	return mtk_mmsys_reset_update(rcdev, id, false);
329f27ef285SEnric Balletbo i Serra }
330f27ef285SEnric Balletbo i Serra 
mtk_mmsys_reset(struct reset_controller_dev * rcdev,unsigned long id)331f27ef285SEnric Balletbo i Serra static int mtk_mmsys_reset(struct reset_controller_dev *rcdev, unsigned long id)
332f27ef285SEnric Balletbo i Serra {
333f27ef285SEnric Balletbo i Serra 	int ret;
334f27ef285SEnric Balletbo i Serra 
335f27ef285SEnric Balletbo i Serra 	ret = mtk_mmsys_reset_assert(rcdev, id);
336f27ef285SEnric Balletbo i Serra 	if (ret)
337f27ef285SEnric Balletbo i Serra 		return ret;
338f27ef285SEnric Balletbo i Serra 
339f27ef285SEnric Balletbo i Serra 	usleep_range(1000, 1100);
340f27ef285SEnric Balletbo i Serra 
341f27ef285SEnric Balletbo i Serra 	return mtk_mmsys_reset_deassert(rcdev, id);
342f27ef285SEnric Balletbo i Serra }
343f27ef285SEnric Balletbo i Serra 
344f27ef285SEnric Balletbo i Serra static const struct reset_control_ops mtk_mmsys_reset_ops = {
345f27ef285SEnric Balletbo i Serra 	.assert = mtk_mmsys_reset_assert,
346f27ef285SEnric Balletbo i Serra 	.deassert = mtk_mmsys_reset_deassert,
347f27ef285SEnric Balletbo i Serra 	.reset = mtk_mmsys_reset,
348f27ef285SEnric Balletbo i Serra };
349f27ef285SEnric Balletbo i Serra 
mtk_mmsys_probe(struct platform_device * pdev)35013032709SMatthias Brugger static int mtk_mmsys_probe(struct platform_device *pdev)
35113032709SMatthias Brugger {
3522c758e30SEnric Balletbo i Serra 	struct device *dev = &pdev->dev;
35313032709SMatthias Brugger 	struct platform_device *clks;
354667c7692SEnric Balletbo i Serra 	struct platform_device *drm;
355ce15e7faSCK Hu 	struct mtk_mmsys *mmsys;
3562c758e30SEnric Balletbo i Serra 	int ret;
3572c758e30SEnric Balletbo i Serra 
358ce15e7faSCK Hu 	mmsys = devm_kzalloc(dev, sizeof(*mmsys), GFP_KERNEL);
359ce15e7faSCK Hu 	if (!mmsys)
360ce15e7faSCK Hu 		return -ENOMEM;
361ce15e7faSCK Hu 
362ce15e7faSCK Hu 	mmsys->regs = devm_platform_ioremap_resource(pdev, 0);
363ce15e7faSCK Hu 	if (IS_ERR(mmsys->regs)) {
364ce15e7faSCK Hu 		ret = PTR_ERR(mmsys->regs);
365cc657602SEnric Balletbo i Serra 		dev_err(dev, "Failed to ioremap mmsys registers: %d\n", ret);
3662c758e30SEnric Balletbo i Serra 		return ret;
3672c758e30SEnric Balletbo i Serra 	}
3682c758e30SEnric Balletbo i Serra 
3692004f8beSNancy.Lin 	mmsys->data = of_device_get_match_data(&pdev->dev);
3702004f8beSNancy.Lin 
3712004f8beSNancy.Lin 	if (mmsys->data->num_resets > 0) {
372f27ef285SEnric Balletbo i Serra 		spin_lock_init(&mmsys->lock);
373f27ef285SEnric Balletbo i Serra 
374f27ef285SEnric Balletbo i Serra 		mmsys->rcdev.owner = THIS_MODULE;
3752004f8beSNancy.Lin 		mmsys->rcdev.nr_resets = mmsys->data->num_resets;
376f27ef285SEnric Balletbo i Serra 		mmsys->rcdev.ops = &mtk_mmsys_reset_ops;
377f27ef285SEnric Balletbo i Serra 		mmsys->rcdev.of_node = pdev->dev.of_node;
378f27ef285SEnric Balletbo i Serra 		ret = devm_reset_controller_register(&pdev->dev, &mmsys->rcdev);
379f27ef285SEnric Balletbo i Serra 		if (ret) {
380f27ef285SEnric Balletbo i Serra 			dev_err(&pdev->dev, "Couldn't register mmsys reset controller: %d\n", ret);
381f27ef285SEnric Balletbo i Serra 			return ret;
382f27ef285SEnric Balletbo i Serra 		}
3832004f8beSNancy.Lin 	}
3848af1f6b5SNancy.Lin 
385b34884b4SAngeloGioacchino Del Regno 	/* CMDQ is optional */
3868af1f6b5SNancy.Lin 	ret = cmdq_dev_get_client_reg(dev, &mmsys->cmdq_base, 0);
3878af1f6b5SNancy.Lin 	if (ret)
3888af1f6b5SNancy.Lin 		dev_dbg(dev, "No mediatek,gce-client-reg!\n");
3898af1f6b5SNancy.Lin 
390ce15e7faSCK Hu 	platform_set_drvdata(pdev, mmsys);
39113032709SMatthias Brugger 
392ce15e7faSCK Hu 	clks = platform_device_register_data(&pdev->dev, mmsys->data->clk_driver,
39313032709SMatthias Brugger 					     PLATFORM_DEVID_AUTO, NULL, 0);
39413032709SMatthias Brugger 	if (IS_ERR(clks))
39513032709SMatthias Brugger 		return PTR_ERR(clks);
3961ef3e78aSAngeloGioacchino Del Regno 	mmsys->clks_pdev = clks;
39713032709SMatthias Brugger 
39878ce3093SRoy-CW.Yeh 	if (mmsys->data->is_vppsys)
39978ce3093SRoy-CW.Yeh 		goto out_probe_done;
40078ce3093SRoy-CW.Yeh 
401667c7692SEnric Balletbo i Serra 	drm = platform_device_register_data(&pdev->dev, "mediatek-drm",
402667c7692SEnric Balletbo i Serra 					    PLATFORM_DEVID_AUTO, NULL, 0);
403ff34e17cSWei Yongjun 	if (IS_ERR(drm)) {
404ff34e17cSWei Yongjun 		platform_device_unregister(clks);
405667c7692SEnric Balletbo i Serra 		return PTR_ERR(drm);
406ff34e17cSWei Yongjun 	}
4071ef3e78aSAngeloGioacchino Del Regno 	mmsys->drm_pdev = drm;
408667c7692SEnric Balletbo i Serra 
40978ce3093SRoy-CW.Yeh out_probe_done:
41013032709SMatthias Brugger 	return 0;
41113032709SMatthias Brugger }
41213032709SMatthias Brugger 
mtk_mmsys_remove(struct platform_device * pdev)4131ef3e78aSAngeloGioacchino Del Regno static int mtk_mmsys_remove(struct platform_device *pdev)
4141ef3e78aSAngeloGioacchino Del Regno {
4151ef3e78aSAngeloGioacchino Del Regno 	struct mtk_mmsys *mmsys = platform_get_drvdata(pdev);
4161ef3e78aSAngeloGioacchino Del Regno 
4171ef3e78aSAngeloGioacchino Del Regno 	platform_device_unregister(mmsys->drm_pdev);
4181ef3e78aSAngeloGioacchino Del Regno 	platform_device_unregister(mmsys->clks_pdev);
4191ef3e78aSAngeloGioacchino Del Regno 
4201ef3e78aSAngeloGioacchino Del Regno 	return 0;
4211ef3e78aSAngeloGioacchino Del Regno }
4221ef3e78aSAngeloGioacchino Del Regno 
42313032709SMatthias Brugger static const struct of_device_id of_match_mtk_mmsys[] = {
4240fe09bf3SAngeloGioacchino Del Regno 	{ .compatible = "mediatek,mt2701-mmsys", .data = &mt2701_mmsys_driver_data },
4250fe09bf3SAngeloGioacchino Del Regno 	{ .compatible = "mediatek,mt2712-mmsys", .data = &mt2712_mmsys_driver_data },
4260fe09bf3SAngeloGioacchino Del Regno 	{ .compatible = "mediatek,mt6779-mmsys", .data = &mt6779_mmsys_driver_data },
427e9a6f5bcSAngeloGioacchino Del Regno 	{ .compatible = "mediatek,mt6795-mmsys", .data = &mt6795_mmsys_driver_data },
4280fe09bf3SAngeloGioacchino Del Regno 	{ .compatible = "mediatek,mt6797-mmsys", .data = &mt6797_mmsys_driver_data },
4290fe09bf3SAngeloGioacchino Del Regno 	{ .compatible = "mediatek,mt8167-mmsys", .data = &mt8167_mmsys_driver_data },
4300fe09bf3SAngeloGioacchino Del Regno 	{ .compatible = "mediatek,mt8173-mmsys", .data = &mt8173_mmsys_driver_data },
4310fe09bf3SAngeloGioacchino Del Regno 	{ .compatible = "mediatek,mt8183-mmsys", .data = &mt8183_mmsys_driver_data },
4320fe09bf3SAngeloGioacchino Del Regno 	{ .compatible = "mediatek,mt8186-mmsys", .data = &mt8186_mmsys_driver_data },
4330fe09bf3SAngeloGioacchino Del Regno 	{ .compatible = "mediatek,mt8188-vdosys0", .data = &mt8188_vdosys0_driver_data },
4340fe09bf3SAngeloGioacchino Del Regno 	{ .compatible = "mediatek,mt8192-mmsys", .data = &mt8192_mmsys_driver_data },
4350fe09bf3SAngeloGioacchino Del Regno 	/* "mediatek,mt8195-mmsys" compatible is deprecated */
4360fe09bf3SAngeloGioacchino Del Regno 	{ .compatible = "mediatek,mt8195-mmsys", .data = &mt8195_vdosys0_driver_data },
4370fe09bf3SAngeloGioacchino Del Regno 	{ .compatible = "mediatek,mt8195-vdosys0", .data = &mt8195_vdosys0_driver_data },
4380fe09bf3SAngeloGioacchino Del Regno 	{ .compatible = "mediatek,mt8195-vdosys1", .data = &mt8195_vdosys1_driver_data },
4390fe09bf3SAngeloGioacchino Del Regno 	{ .compatible = "mediatek,mt8195-vppsys0", .data = &mt8195_vppsys0_driver_data },
4400fe09bf3SAngeloGioacchino Del Regno 	{ .compatible = "mediatek,mt8195-vppsys1", .data = &mt8195_vppsys1_driver_data },
4410fe09bf3SAngeloGioacchino Del Regno 	{ .compatible = "mediatek,mt8365-mmsys", .data = &mt8365_mmsys_driver_data },
4420fe09bf3SAngeloGioacchino Del Regno 	{ /* sentinel */ }
44313032709SMatthias Brugger };
44410687632SAngeloGioacchino Del Regno MODULE_DEVICE_TABLE(of, of_match_mtk_mmsys);
44513032709SMatthias Brugger 
44613032709SMatthias Brugger static struct platform_driver mtk_mmsys_drv = {
44713032709SMatthias Brugger 	.driver = {
44813032709SMatthias Brugger 		.name = "mtk-mmsys",
44913032709SMatthias Brugger 		.of_match_table = of_match_mtk_mmsys,
45013032709SMatthias Brugger 	},
45113032709SMatthias Brugger 	.probe = mtk_mmsys_probe,
4521ef3e78aSAngeloGioacchino Del Regno 	.remove = mtk_mmsys_remove,
45313032709SMatthias Brugger };
454683c7d38SAngeloGioacchino Del Regno module_platform_driver(mtk_mmsys_drv);
455a7596e62SYongqiang Niu 
456a7596e62SYongqiang Niu MODULE_AUTHOR("Yongqiang Niu <yongqiang.niu@mediatek.com>");
457a7596e62SYongqiang Niu MODULE_DESCRIPTION("MediaTek SoC MMSYS driver");
458a7596e62SYongqiang Niu MODULE_LICENSE("GPL");
459