Linux Audio

Check our new training course

Yocto / OpenEmbedded training

Mar 24-27, 2025, special US time zones
Register
Loading...
Note: File does not exist in v3.15.
  1// SPDX-License-Identifier: GPL-2.0-only
  2/*
  3 * Copyright (c) 2015-2016 MediaTek Inc.
  4 * Author: Yong Wu <yong.wu@mediatek.com>
  5 */
  6#include <linux/clk.h>
  7#include <linux/component.h>
  8#include <linux/device.h>
  9#include <linux/err.h>
 10#include <linux/io.h>
 11#include <linux/module.h>
 12#include <linux/of.h>
 13#include <linux/of_platform.h>
 14#include <linux/platform_device.h>
 15#include <linux/pm_runtime.h>
 16#include <soc/mediatek/smi.h>
 17#include <dt-bindings/memory/mt2701-larb-port.h>
 18#include <dt-bindings/memory/mtk-memory-port.h>
 19
 20/* mt8173 */
 21#define SMI_LARB_MMU_EN		0xf00
 22
 23/* mt8167 */
 24#define MT8167_SMI_LARB_MMU_EN	0xfc0
 25
 26/* mt2701 */
 27#define REG_SMI_SECUR_CON_BASE		0x5c0
 28
 29/* every register control 8 port, register offset 0x4 */
 30#define REG_SMI_SECUR_CON_OFFSET(id)	(((id) >> 3) << 2)
 31#define REG_SMI_SECUR_CON_ADDR(id)	\
 32	(REG_SMI_SECUR_CON_BASE + REG_SMI_SECUR_CON_OFFSET(id))
 33
 34/*
 35 * every port have 4 bit to control, bit[port + 3] control virtual or physical,
 36 * bit[port + 2 : port + 1] control the domain, bit[port] control the security
 37 * or non-security.
 38 */
 39#define SMI_SECUR_CON_VAL_MSK(id)	(~(0xf << (((id) & 0x7) << 2)))
 40#define SMI_SECUR_CON_VAL_VIRT(id)	BIT((((id) & 0x7) << 2) + 3)
 41/* mt2701 domain should be set to 3 */
 42#define SMI_SECUR_CON_VAL_DOMAIN(id)	(0x3 << ((((id) & 0x7) << 2) + 1))
 43
 44/* mt2712 */
 45#define SMI_LARB_NONSEC_CON(id)	(0x380 + ((id) * 4))
 46#define F_MMU_EN		BIT(0)
 47#define BANK_SEL(id)		({			\
 48	u32 _id = (id) & 0x3;				\
 49	(_id << 8 | _id << 10 | _id << 12 | _id << 14);	\
 50})
 51
 52/* SMI COMMON */
 53#define SMI_BUS_SEL			0x220
 54#define SMI_BUS_LARB_SHIFT(larbid)	((larbid) << 1)
 55/* All are MMU0 defaultly. Only specialize mmu1 here. */
 56#define F_MMU1_LARB(larbid)		(0x1 << SMI_BUS_LARB_SHIFT(larbid))
 57
 58enum mtk_smi_gen {
 59	MTK_SMI_GEN1,
 60	MTK_SMI_GEN2
 61};
 62
 63struct mtk_smi_common_plat {
 64	enum mtk_smi_gen gen;
 65	bool             has_gals;
 66	u32              bus_sel; /* Balance some larbs to enter mmu0 or mmu1 */
 67};
 68
 69struct mtk_smi_larb_gen {
 70	int port_in_larb[MTK_LARB_NR_MAX + 1];
 71	void (*config_port)(struct device *dev);
 72	unsigned int			larb_direct_to_common_mask;
 73	bool				has_gals;
 74};
 75
 76struct mtk_smi {
 77	struct device			*dev;
 78	struct clk			*clk_apb, *clk_smi;
 79	struct clk			*clk_gals0, *clk_gals1;
 80	struct clk			*clk_async; /*only needed by mt2701*/
 81	union {
 82		void __iomem		*smi_ao_base; /* only for gen1 */
 83		void __iomem		*base;	      /* only for gen2 */
 84	};
 85	const struct mtk_smi_common_plat *plat;
 86};
 87
 88struct mtk_smi_larb { /* larb: local arbiter */
 89	struct mtk_smi			smi;
 90	void __iomem			*base;
 91	struct device			*smi_common_dev;
 92	const struct mtk_smi_larb_gen	*larb_gen;
 93	int				larbid;
 94	u32				*mmu;
 95	unsigned char			*bank;
 96};
 97
 98static int mtk_smi_clk_enable(const struct mtk_smi *smi)
 99{
100	int ret;
101
102	ret = clk_prepare_enable(smi->clk_apb);
103	if (ret)
104		return ret;
105
106	ret = clk_prepare_enable(smi->clk_smi);
107	if (ret)
108		goto err_disable_apb;
109
110	ret = clk_prepare_enable(smi->clk_gals0);
111	if (ret)
112		goto err_disable_smi;
113
114	ret = clk_prepare_enable(smi->clk_gals1);
115	if (ret)
116		goto err_disable_gals0;
117
118	return 0;
119
120err_disable_gals0:
121	clk_disable_unprepare(smi->clk_gals0);
122err_disable_smi:
123	clk_disable_unprepare(smi->clk_smi);
124err_disable_apb:
125	clk_disable_unprepare(smi->clk_apb);
126	return ret;
127}
128
129static void mtk_smi_clk_disable(const struct mtk_smi *smi)
130{
131	clk_disable_unprepare(smi->clk_gals1);
132	clk_disable_unprepare(smi->clk_gals0);
133	clk_disable_unprepare(smi->clk_smi);
134	clk_disable_unprepare(smi->clk_apb);
135}
136
137int mtk_smi_larb_get(struct device *larbdev)
138{
139	int ret = pm_runtime_resume_and_get(larbdev);
140
141	return (ret < 0) ? ret : 0;
142}
143EXPORT_SYMBOL_GPL(mtk_smi_larb_get);
144
145void mtk_smi_larb_put(struct device *larbdev)
146{
147	pm_runtime_put_sync(larbdev);
148}
149EXPORT_SYMBOL_GPL(mtk_smi_larb_put);
150
151static int
152mtk_smi_larb_bind(struct device *dev, struct device *master, void *data)
153{
154	struct mtk_smi_larb *larb = dev_get_drvdata(dev);
155	struct mtk_smi_larb_iommu *larb_mmu = data;
156	unsigned int         i;
157
158	for (i = 0; i < MTK_LARB_NR_MAX; i++) {
159		if (dev == larb_mmu[i].dev) {
160			larb->larbid = i;
161			larb->mmu = &larb_mmu[i].mmu;
162			larb->bank = larb_mmu[i].bank;
163			return 0;
164		}
165	}
166	return -ENODEV;
167}
168
169static void mtk_smi_larb_config_port_gen2_general(struct device *dev)
170{
171	struct mtk_smi_larb *larb = dev_get_drvdata(dev);
172	u32 reg;
173	int i;
174
175	if (BIT(larb->larbid) & larb->larb_gen->larb_direct_to_common_mask)
176		return;
177
178	for_each_set_bit(i, (unsigned long *)larb->mmu, 32) {
179		reg = readl_relaxed(larb->base + SMI_LARB_NONSEC_CON(i));
180		reg |= F_MMU_EN;
181		reg |= BANK_SEL(larb->bank[i]);
182		writel(reg, larb->base + SMI_LARB_NONSEC_CON(i));
183	}
184}
185
186static void mtk_smi_larb_config_port_mt8173(struct device *dev)
187{
188	struct mtk_smi_larb *larb = dev_get_drvdata(dev);
189
190	writel(*larb->mmu, larb->base + SMI_LARB_MMU_EN);
191}
192
193static void mtk_smi_larb_config_port_mt8167(struct device *dev)
194{
195	struct mtk_smi_larb *larb = dev_get_drvdata(dev);
196
197	writel(*larb->mmu, larb->base + MT8167_SMI_LARB_MMU_EN);
198}
199
200static void mtk_smi_larb_config_port_gen1(struct device *dev)
201{
202	struct mtk_smi_larb *larb = dev_get_drvdata(dev);
203	const struct mtk_smi_larb_gen *larb_gen = larb->larb_gen;
204	struct mtk_smi *common = dev_get_drvdata(larb->smi_common_dev);
205	int i, m4u_port_id, larb_port_num;
206	u32 sec_con_val, reg_val;
207
208	m4u_port_id = larb_gen->port_in_larb[larb->larbid];
209	larb_port_num = larb_gen->port_in_larb[larb->larbid + 1]
210			- larb_gen->port_in_larb[larb->larbid];
211
212	for (i = 0; i < larb_port_num; i++, m4u_port_id++) {
213		if (*larb->mmu & BIT(i)) {
214			/* bit[port + 3] controls the virtual or physical */
215			sec_con_val = SMI_SECUR_CON_VAL_VIRT(m4u_port_id);
216		} else {
217			/* do not need to enable m4u for this port */
218			continue;
219		}
220		reg_val = readl(common->smi_ao_base
221			+ REG_SMI_SECUR_CON_ADDR(m4u_port_id));
222		reg_val &= SMI_SECUR_CON_VAL_MSK(m4u_port_id);
223		reg_val |= sec_con_val;
224		reg_val |= SMI_SECUR_CON_VAL_DOMAIN(m4u_port_id);
225		writel(reg_val,
226			common->smi_ao_base
227			+ REG_SMI_SECUR_CON_ADDR(m4u_port_id));
228	}
229}
230
231static void
232mtk_smi_larb_unbind(struct device *dev, struct device *master, void *data)
233{
234	/* Do nothing as the iommu is always enabled. */
235}
236
237static const struct component_ops mtk_smi_larb_component_ops = {
238	.bind = mtk_smi_larb_bind,
239	.unbind = mtk_smi_larb_unbind,
240};
241
242static const struct mtk_smi_larb_gen mtk_smi_larb_mt8173 = {
243	/* mt8173 do not need the port in larb */
244	.config_port = mtk_smi_larb_config_port_mt8173,
245};
246
247static const struct mtk_smi_larb_gen mtk_smi_larb_mt8167 = {
248	/* mt8167 do not need the port in larb */
249	.config_port = mtk_smi_larb_config_port_mt8167,
250};
251
252static const struct mtk_smi_larb_gen mtk_smi_larb_mt2701 = {
253	.port_in_larb = {
254		LARB0_PORT_OFFSET, LARB1_PORT_OFFSET,
255		LARB2_PORT_OFFSET, LARB3_PORT_OFFSET
256	},
257	.config_port = mtk_smi_larb_config_port_gen1,
258};
259
260static const struct mtk_smi_larb_gen mtk_smi_larb_mt2712 = {
261	.config_port                = mtk_smi_larb_config_port_gen2_general,
262	.larb_direct_to_common_mask = BIT(8) | BIT(9),      /* bdpsys */
263};
264
265static const struct mtk_smi_larb_gen mtk_smi_larb_mt6779 = {
266	.config_port  = mtk_smi_larb_config_port_gen2_general,
267	.larb_direct_to_common_mask =
268		BIT(4) | BIT(6) | BIT(11) | BIT(12) | BIT(13),
269		/* DUMMY | IPU0 | IPU1 | CCU | MDLA */
270};
271
272static const struct mtk_smi_larb_gen mtk_smi_larb_mt8183 = {
273	.has_gals                   = true,
274	.config_port                = mtk_smi_larb_config_port_gen2_general,
275	.larb_direct_to_common_mask = BIT(2) | BIT(3) | BIT(7),
276				      /* IPU0 | IPU1 | CCU */
277};
278
279static const struct mtk_smi_larb_gen mtk_smi_larb_mt8192 = {
280	.config_port                = mtk_smi_larb_config_port_gen2_general,
281};
282
283static const struct of_device_id mtk_smi_larb_of_ids[] = {
284	{
285		.compatible = "mediatek,mt8167-smi-larb",
286		.data = &mtk_smi_larb_mt8167
287	},
288	{
289		.compatible = "mediatek,mt8173-smi-larb",
290		.data = &mtk_smi_larb_mt8173
291	},
292	{
293		.compatible = "mediatek,mt2701-smi-larb",
294		.data = &mtk_smi_larb_mt2701
295	},
296	{
297		.compatible = "mediatek,mt2712-smi-larb",
298		.data = &mtk_smi_larb_mt2712
299	},
300	{
301		.compatible = "mediatek,mt6779-smi-larb",
302		.data = &mtk_smi_larb_mt6779
303	},
304	{
305		.compatible = "mediatek,mt8183-smi-larb",
306		.data = &mtk_smi_larb_mt8183
307	},
308	{
309		.compatible = "mediatek,mt8192-smi-larb",
310		.data = &mtk_smi_larb_mt8192
311	},
312	{}
313};
314
315static int mtk_smi_larb_probe(struct platform_device *pdev)
316{
317	struct mtk_smi_larb *larb;
318	struct resource *res;
319	struct device *dev = &pdev->dev;
320	struct device_node *smi_node;
321	struct platform_device *smi_pdev;
322	struct device_link *link;
323
324	larb = devm_kzalloc(dev, sizeof(*larb), GFP_KERNEL);
325	if (!larb)
326		return -ENOMEM;
327
328	larb->larb_gen = of_device_get_match_data(dev);
329	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
330	larb->base = devm_ioremap_resource(dev, res);
331	if (IS_ERR(larb->base))
332		return PTR_ERR(larb->base);
333
334	larb->smi.clk_apb = devm_clk_get(dev, "apb");
335	if (IS_ERR(larb->smi.clk_apb))
336		return PTR_ERR(larb->smi.clk_apb);
337
338	larb->smi.clk_smi = devm_clk_get(dev, "smi");
339	if (IS_ERR(larb->smi.clk_smi))
340		return PTR_ERR(larb->smi.clk_smi);
341
342	if (larb->larb_gen->has_gals) {
343		/* The larbs may still haven't gals even if the SoC support.*/
344		larb->smi.clk_gals0 = devm_clk_get(dev, "gals");
345		if (PTR_ERR(larb->smi.clk_gals0) == -ENOENT)
346			larb->smi.clk_gals0 = NULL;
347		else if (IS_ERR(larb->smi.clk_gals0))
348			return PTR_ERR(larb->smi.clk_gals0);
349	}
350	larb->smi.dev = dev;
351
352	smi_node = of_parse_phandle(dev->of_node, "mediatek,smi", 0);
353	if (!smi_node)
354		return -EINVAL;
355
356	smi_pdev = of_find_device_by_node(smi_node);
357	of_node_put(smi_node);
358	if (smi_pdev) {
359		if (!platform_get_drvdata(smi_pdev))
360			return -EPROBE_DEFER;
361		larb->smi_common_dev = &smi_pdev->dev;
362		link = device_link_add(dev, larb->smi_common_dev,
363				       DL_FLAG_PM_RUNTIME | DL_FLAG_STATELESS);
364		if (!link) {
365			dev_err(dev, "Unable to link smi-common dev\n");
366			return -ENODEV;
367		}
368	} else {
369		dev_err(dev, "Failed to get the smi_common device\n");
370		return -EINVAL;
371	}
372
373	pm_runtime_enable(dev);
374	platform_set_drvdata(pdev, larb);
375	return component_add(dev, &mtk_smi_larb_component_ops);
376}
377
378static int mtk_smi_larb_remove(struct platform_device *pdev)
379{
380	struct mtk_smi_larb *larb = platform_get_drvdata(pdev);
381
382	device_link_remove(&pdev->dev, larb->smi_common_dev);
383	pm_runtime_disable(&pdev->dev);
384	component_del(&pdev->dev, &mtk_smi_larb_component_ops);
385	return 0;
386}
387
388static int __maybe_unused mtk_smi_larb_resume(struct device *dev)
389{
390	struct mtk_smi_larb *larb = dev_get_drvdata(dev);
391	const struct mtk_smi_larb_gen *larb_gen = larb->larb_gen;
392	int ret;
393
394	ret = mtk_smi_clk_enable(&larb->smi);
395	if (ret < 0) {
396		dev_err(dev, "Failed to enable clock(%d).\n", ret);
397		return ret;
398	}
399
400	/* Configure the basic setting for this larb */
401	larb_gen->config_port(dev);
402
403	return 0;
404}
405
406static int __maybe_unused mtk_smi_larb_suspend(struct device *dev)
407{
408	struct mtk_smi_larb *larb = dev_get_drvdata(dev);
409
410	mtk_smi_clk_disable(&larb->smi);
411	return 0;
412}
413
414static const struct dev_pm_ops smi_larb_pm_ops = {
415	SET_RUNTIME_PM_OPS(mtk_smi_larb_suspend, mtk_smi_larb_resume, NULL)
416	SET_LATE_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
417				     pm_runtime_force_resume)
418};
419
420static struct platform_driver mtk_smi_larb_driver = {
421	.probe	= mtk_smi_larb_probe,
422	.remove	= mtk_smi_larb_remove,
423	.driver	= {
424		.name = "mtk-smi-larb",
425		.of_match_table = mtk_smi_larb_of_ids,
426		.pm             = &smi_larb_pm_ops,
427	}
428};
429
430static const struct mtk_smi_common_plat mtk_smi_common_gen1 = {
431	.gen = MTK_SMI_GEN1,
432};
433
434static const struct mtk_smi_common_plat mtk_smi_common_gen2 = {
435	.gen = MTK_SMI_GEN2,
436};
437
438static const struct mtk_smi_common_plat mtk_smi_common_mt6779 = {
439	.gen		= MTK_SMI_GEN2,
440	.has_gals	= true,
441	.bus_sel	= F_MMU1_LARB(1) | F_MMU1_LARB(2) | F_MMU1_LARB(4) |
442			  F_MMU1_LARB(5) | F_MMU1_LARB(6) | F_MMU1_LARB(7),
443};
444
445static const struct mtk_smi_common_plat mtk_smi_common_mt8183 = {
446	.gen      = MTK_SMI_GEN2,
447	.has_gals = true,
448	.bus_sel  = F_MMU1_LARB(1) | F_MMU1_LARB(2) | F_MMU1_LARB(5) |
449		    F_MMU1_LARB(7),
450};
451
452static const struct mtk_smi_common_plat mtk_smi_common_mt8192 = {
453	.gen      = MTK_SMI_GEN2,
454	.has_gals = true,
455	.bus_sel  = F_MMU1_LARB(1) | F_MMU1_LARB(2) | F_MMU1_LARB(5) |
456		    F_MMU1_LARB(6),
457};
458
459static const struct of_device_id mtk_smi_common_of_ids[] = {
460	{
461		.compatible = "mediatek,mt8173-smi-common",
462		.data = &mtk_smi_common_gen2,
463	},
464	{
465		.compatible = "mediatek,mt8167-smi-common",
466		.data = &mtk_smi_common_gen2,
467	},
468	{
469		.compatible = "mediatek,mt2701-smi-common",
470		.data = &mtk_smi_common_gen1,
471	},
472	{
473		.compatible = "mediatek,mt2712-smi-common",
474		.data = &mtk_smi_common_gen2,
475	},
476	{
477		.compatible = "mediatek,mt6779-smi-common",
478		.data = &mtk_smi_common_mt6779,
479	},
480	{
481		.compatible = "mediatek,mt8183-smi-common",
482		.data = &mtk_smi_common_mt8183,
483	},
484	{
485		.compatible = "mediatek,mt8192-smi-common",
486		.data = &mtk_smi_common_mt8192,
487	},
488	{}
489};
490
491static int mtk_smi_common_probe(struct platform_device *pdev)
492{
493	struct device *dev = &pdev->dev;
494	struct mtk_smi *common;
495	struct resource *res;
496	int ret;
497
498	common = devm_kzalloc(dev, sizeof(*common), GFP_KERNEL);
499	if (!common)
500		return -ENOMEM;
501	common->dev = dev;
502	common->plat = of_device_get_match_data(dev);
503
504	common->clk_apb = devm_clk_get(dev, "apb");
505	if (IS_ERR(common->clk_apb))
506		return PTR_ERR(common->clk_apb);
507
508	common->clk_smi = devm_clk_get(dev, "smi");
509	if (IS_ERR(common->clk_smi))
510		return PTR_ERR(common->clk_smi);
511
512	if (common->plat->has_gals) {
513		common->clk_gals0 = devm_clk_get(dev, "gals0");
514		if (IS_ERR(common->clk_gals0))
515			return PTR_ERR(common->clk_gals0);
516
517		common->clk_gals1 = devm_clk_get(dev, "gals1");
518		if (IS_ERR(common->clk_gals1))
519			return PTR_ERR(common->clk_gals1);
520	}
521
522	/*
523	 * for mtk smi gen 1, we need to get the ao(always on) base to config
524	 * m4u port, and we need to enable the aync clock for transform the smi
525	 * clock into emi clock domain, but for mtk smi gen2, there's no smi ao
526	 * base.
527	 */
528	if (common->plat->gen == MTK_SMI_GEN1) {
529		res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
530		common->smi_ao_base = devm_ioremap_resource(dev, res);
531		if (IS_ERR(common->smi_ao_base))
532			return PTR_ERR(common->smi_ao_base);
533
534		common->clk_async = devm_clk_get(dev, "async");
535		if (IS_ERR(common->clk_async))
536			return PTR_ERR(common->clk_async);
537
538		ret = clk_prepare_enable(common->clk_async);
539		if (ret)
540			return ret;
541	} else {
542		res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
543		common->base = devm_ioremap_resource(dev, res);
544		if (IS_ERR(common->base))
545			return PTR_ERR(common->base);
546	}
547	pm_runtime_enable(dev);
548	platform_set_drvdata(pdev, common);
549	return 0;
550}
551
552static int mtk_smi_common_remove(struct platform_device *pdev)
553{
554	pm_runtime_disable(&pdev->dev);
555	return 0;
556}
557
558static int __maybe_unused mtk_smi_common_resume(struct device *dev)
559{
560	struct mtk_smi *common = dev_get_drvdata(dev);
561	u32 bus_sel = common->plat->bus_sel;
562	int ret;
563
564	ret = mtk_smi_clk_enable(common);
565	if (ret) {
566		dev_err(common->dev, "Failed to enable clock(%d).\n", ret);
567		return ret;
568	}
569
570	if (common->plat->gen == MTK_SMI_GEN2 && bus_sel)
571		writel(bus_sel, common->base + SMI_BUS_SEL);
572	return 0;
573}
574
575static int __maybe_unused mtk_smi_common_suspend(struct device *dev)
576{
577	struct mtk_smi *common = dev_get_drvdata(dev);
578
579	mtk_smi_clk_disable(common);
580	return 0;
581}
582
583static const struct dev_pm_ops smi_common_pm_ops = {
584	SET_RUNTIME_PM_OPS(mtk_smi_common_suspend, mtk_smi_common_resume, NULL)
585	SET_LATE_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
586				     pm_runtime_force_resume)
587};
588
589static struct platform_driver mtk_smi_common_driver = {
590	.probe	= mtk_smi_common_probe,
591	.remove = mtk_smi_common_remove,
592	.driver	= {
593		.name = "mtk-smi-common",
594		.of_match_table = mtk_smi_common_of_ids,
595		.pm             = &smi_common_pm_ops,
596	}
597};
598
599static struct platform_driver * const smidrivers[] = {
600	&mtk_smi_common_driver,
601	&mtk_smi_larb_driver,
602};
603
604static int __init mtk_smi_init(void)
605{
606	return platform_register_drivers(smidrivers, ARRAY_SIZE(smidrivers));
607}
608module_init(mtk_smi_init);
609
610static void __exit mtk_smi_exit(void)
611{
612	platform_unregister_drivers(smidrivers, ARRAY_SIZE(smidrivers));
613}
614module_exit(mtk_smi_exit);
615
616MODULE_DESCRIPTION("MediaTek SMI driver");
617MODULE_LICENSE("GPL v2");