xref: /openbmc/linux/drivers/memory/mtk-smi.c (revision d3964221)
1 /*
2  * Copyright (c) 2015-2016 MediaTek Inc.
3  * Author: Yong Wu <yong.wu@mediatek.com>
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  */
14 #include <linux/clk.h>
15 #include <linux/component.h>
16 #include <linux/device.h>
17 #include <linux/err.h>
18 #include <linux/io.h>
19 #include <linux/module.h>
20 #include <linux/of.h>
21 #include <linux/of_platform.h>
22 #include <linux/platform_device.h>
23 #include <linux/pm_runtime.h>
24 #include <soc/mediatek/smi.h>
25 #include <dt-bindings/memory/mt2701-larb-port.h>
26 
27 /* mt8173 */
28 #define SMI_LARB_MMU_EN		0xf00
29 
30 /* mt2701 */
31 #define REG_SMI_SECUR_CON_BASE		0x5c0
32 
33 /* every register control 8 port, register offset 0x4 */
34 #define REG_SMI_SECUR_CON_OFFSET(id)	(((id) >> 3) << 2)
35 #define REG_SMI_SECUR_CON_ADDR(id)	\
36 	(REG_SMI_SECUR_CON_BASE + REG_SMI_SECUR_CON_OFFSET(id))
37 
38 /*
39  * every port have 4 bit to control, bit[port + 3] control virtual or physical,
40  * bit[port + 2 : port + 1] control the domain, bit[port] control the security
41  * or non-security.
42  */
43 #define SMI_SECUR_CON_VAL_MSK(id)	(~(0xf << (((id) & 0x7) << 2)))
44 #define SMI_SECUR_CON_VAL_VIRT(id)	BIT((((id) & 0x7) << 2) + 3)
45 /* mt2701 domain should be set to 3 */
46 #define SMI_SECUR_CON_VAL_DOMAIN(id)	(0x3 << ((((id) & 0x7) << 2) + 1))
47 
48 /* mt2712 */
49 #define SMI_LARB_NONSEC_CON(id)	(0x380 + ((id) * 4))
50 #define F_MMU_EN		BIT(0)
51 
52 struct mtk_smi_larb_gen {
53 	bool need_larbid;
54 	int port_in_larb[MTK_LARB_NR_MAX + 1];
55 	void (*config_port)(struct device *);
56 };
57 
58 struct mtk_smi {
59 	struct device			*dev;
60 	struct clk			*clk_apb, *clk_smi;
61 	struct clk			*clk_async; /*only needed by mt2701*/
62 	void __iomem			*smi_ao_base;
63 };
64 
65 struct mtk_smi_larb { /* larb: local arbiter */
66 	struct mtk_smi			smi;
67 	void __iomem			*base;
68 	struct device			*smi_common_dev;
69 	const struct mtk_smi_larb_gen	*larb_gen;
70 	int				larbid;
71 	u32				*mmu;
72 };
73 
74 enum mtk_smi_gen {
75 	MTK_SMI_GEN1,
76 	MTK_SMI_GEN2
77 };
78 
79 static int mtk_smi_enable(const struct mtk_smi *smi)
80 {
81 	int ret;
82 
83 	ret = pm_runtime_get_sync(smi->dev);
84 	if (ret < 0)
85 		return ret;
86 
87 	ret = clk_prepare_enable(smi->clk_apb);
88 	if (ret)
89 		goto err_put_pm;
90 
91 	ret = clk_prepare_enable(smi->clk_smi);
92 	if (ret)
93 		goto err_disable_apb;
94 
95 	return 0;
96 
97 err_disable_apb:
98 	clk_disable_unprepare(smi->clk_apb);
99 err_put_pm:
100 	pm_runtime_put_sync(smi->dev);
101 	return ret;
102 }
103 
104 static void mtk_smi_disable(const struct mtk_smi *smi)
105 {
106 	clk_disable_unprepare(smi->clk_smi);
107 	clk_disable_unprepare(smi->clk_apb);
108 	pm_runtime_put_sync(smi->dev);
109 }
110 
111 int mtk_smi_larb_get(struct device *larbdev)
112 {
113 	struct mtk_smi_larb *larb = dev_get_drvdata(larbdev);
114 	const struct mtk_smi_larb_gen *larb_gen = larb->larb_gen;
115 	struct mtk_smi *common = dev_get_drvdata(larb->smi_common_dev);
116 	int ret;
117 
118 	/* Enable the smi-common's power and clocks */
119 	ret = mtk_smi_enable(common);
120 	if (ret)
121 		return ret;
122 
123 	/* Enable the larb's power and clocks */
124 	ret = mtk_smi_enable(&larb->smi);
125 	if (ret) {
126 		mtk_smi_disable(common);
127 		return ret;
128 	}
129 
130 	/* Configure the iommu info for this larb */
131 	larb_gen->config_port(larbdev);
132 
133 	return 0;
134 }
135 EXPORT_SYMBOL_GPL(mtk_smi_larb_get);
136 
137 void mtk_smi_larb_put(struct device *larbdev)
138 {
139 	struct mtk_smi_larb *larb = dev_get_drvdata(larbdev);
140 	struct mtk_smi *common = dev_get_drvdata(larb->smi_common_dev);
141 
142 	/*
143 	 * Don't de-configure the iommu info for this larb since there may be
144 	 * several modules in this larb.
145 	 * The iommu info will be reset after power off.
146 	 */
147 
148 	mtk_smi_disable(&larb->smi);
149 	mtk_smi_disable(common);
150 }
151 EXPORT_SYMBOL_GPL(mtk_smi_larb_put);
152 
153 static int
154 mtk_smi_larb_bind(struct device *dev, struct device *master, void *data)
155 {
156 	struct mtk_smi_larb *larb = dev_get_drvdata(dev);
157 	struct mtk_smi_iommu *smi_iommu = data;
158 	unsigned int         i;
159 
160 	if (larb->larb_gen->need_larbid) {
161 		larb->mmu = &smi_iommu->larb_imu[larb->larbid].mmu;
162 		return 0;
163 	}
164 
165 	/*
166 	 * If there is no larbid property, Loop to find the corresponding
167 	 * iommu information.
168 	 */
169 	for (i = 0; i < smi_iommu->larb_nr; i++) {
170 		if (dev == smi_iommu->larb_imu[i].dev) {
171 			/* The 'mmu' may be updated in iommu-attach/detach. */
172 			larb->mmu = &smi_iommu->larb_imu[i].mmu;
173 			return 0;
174 		}
175 	}
176 	return -ENODEV;
177 }
178 
179 static void mtk_smi_larb_config_port_mt2712(struct device *dev)
180 {
181 	struct mtk_smi_larb *larb = dev_get_drvdata(dev);
182 	u32 reg;
183 	int i;
184 
185 	/*
186 	 * larb 8/9 is the bdpsys larb, the iommu_en is enabled defaultly.
187 	 * Don't need to set it again.
188 	 */
189 	if (larb->larbid == 8 || larb->larbid == 9)
190 		return;
191 
192 	for_each_set_bit(i, (unsigned long *)larb->mmu, 32) {
193 		reg = readl_relaxed(larb->base + SMI_LARB_NONSEC_CON(i));
194 		reg |= F_MMU_EN;
195 		writel(reg, larb->base + SMI_LARB_NONSEC_CON(i));
196 	}
197 }
198 
199 static void mtk_smi_larb_config_port_mt8173(struct device *dev)
200 {
201 	struct mtk_smi_larb *larb = dev_get_drvdata(dev);
202 
203 	writel(*larb->mmu, larb->base + SMI_LARB_MMU_EN);
204 }
205 
206 static void mtk_smi_larb_config_port_gen1(struct device *dev)
207 {
208 	struct mtk_smi_larb *larb = dev_get_drvdata(dev);
209 	const struct mtk_smi_larb_gen *larb_gen = larb->larb_gen;
210 	struct mtk_smi *common = dev_get_drvdata(larb->smi_common_dev);
211 	int i, m4u_port_id, larb_port_num;
212 	u32 sec_con_val, reg_val;
213 
214 	m4u_port_id = larb_gen->port_in_larb[larb->larbid];
215 	larb_port_num = larb_gen->port_in_larb[larb->larbid + 1]
216 			- larb_gen->port_in_larb[larb->larbid];
217 
218 	for (i = 0; i < larb_port_num; i++, m4u_port_id++) {
219 		if (*larb->mmu & BIT(i)) {
220 			/* bit[port + 3] controls the virtual or physical */
221 			sec_con_val = SMI_SECUR_CON_VAL_VIRT(m4u_port_id);
222 		} else {
223 			/* do not need to enable m4u for this port */
224 			continue;
225 		}
226 		reg_val = readl(common->smi_ao_base
227 			+ REG_SMI_SECUR_CON_ADDR(m4u_port_id));
228 		reg_val &= SMI_SECUR_CON_VAL_MSK(m4u_port_id);
229 		reg_val |= sec_con_val;
230 		reg_val |= SMI_SECUR_CON_VAL_DOMAIN(m4u_port_id);
231 		writel(reg_val,
232 			common->smi_ao_base
233 			+ REG_SMI_SECUR_CON_ADDR(m4u_port_id));
234 	}
235 }
236 
237 static void
238 mtk_smi_larb_unbind(struct device *dev, struct device *master, void *data)
239 {
240 	/* Do nothing as the iommu is always enabled. */
241 }
242 
243 static const struct component_ops mtk_smi_larb_component_ops = {
244 	.bind = mtk_smi_larb_bind,
245 	.unbind = mtk_smi_larb_unbind,
246 };
247 
248 static const struct mtk_smi_larb_gen mtk_smi_larb_mt8173 = {
249 	/* mt8173 do not need the port in larb */
250 	.config_port = mtk_smi_larb_config_port_mt8173,
251 };
252 
253 static const struct mtk_smi_larb_gen mtk_smi_larb_mt2701 = {
254 	.need_larbid = true,
255 	.port_in_larb = {
256 		LARB0_PORT_OFFSET, LARB1_PORT_OFFSET,
257 		LARB2_PORT_OFFSET, LARB3_PORT_OFFSET
258 	},
259 	.config_port = mtk_smi_larb_config_port_gen1,
260 };
261 
262 static const struct mtk_smi_larb_gen mtk_smi_larb_mt2712 = {
263 	.need_larbid = true,
264 	.config_port = mtk_smi_larb_config_port_mt2712,
265 };
266 
267 static const struct of_device_id mtk_smi_larb_of_ids[] = {
268 	{
269 		.compatible = "mediatek,mt8173-smi-larb",
270 		.data = &mtk_smi_larb_mt8173
271 	},
272 	{
273 		.compatible = "mediatek,mt2701-smi-larb",
274 		.data = &mtk_smi_larb_mt2701
275 	},
276 	{
277 		.compatible = "mediatek,mt2712-smi-larb",
278 		.data = &mtk_smi_larb_mt2712
279 	},
280 	{}
281 };
282 
283 static int mtk_smi_larb_probe(struct platform_device *pdev)
284 {
285 	struct mtk_smi_larb *larb;
286 	struct resource *res;
287 	struct device *dev = &pdev->dev;
288 	struct device_node *smi_node;
289 	struct platform_device *smi_pdev;
290 	int err;
291 
292 	larb = devm_kzalloc(dev, sizeof(*larb), GFP_KERNEL);
293 	if (!larb)
294 		return -ENOMEM;
295 
296 	larb->larb_gen = of_device_get_match_data(dev);
297 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
298 	larb->base = devm_ioremap_resource(dev, res);
299 	if (IS_ERR(larb->base))
300 		return PTR_ERR(larb->base);
301 
302 	larb->smi.clk_apb = devm_clk_get(dev, "apb");
303 	if (IS_ERR(larb->smi.clk_apb))
304 		return PTR_ERR(larb->smi.clk_apb);
305 
306 	larb->smi.clk_smi = devm_clk_get(dev, "smi");
307 	if (IS_ERR(larb->smi.clk_smi))
308 		return PTR_ERR(larb->smi.clk_smi);
309 	larb->smi.dev = dev;
310 
311 	if (larb->larb_gen->need_larbid) {
312 		err = of_property_read_u32(dev->of_node, "mediatek,larb-id",
313 					   &larb->larbid);
314 		if (err) {
315 			dev_err(dev, "missing larbid property\n");
316 			return err;
317 		}
318 	}
319 
320 	smi_node = of_parse_phandle(dev->of_node, "mediatek,smi", 0);
321 	if (!smi_node)
322 		return -EINVAL;
323 
324 	smi_pdev = of_find_device_by_node(smi_node);
325 	of_node_put(smi_node);
326 	if (smi_pdev) {
327 		if (!platform_get_drvdata(smi_pdev))
328 			return -EPROBE_DEFER;
329 		larb->smi_common_dev = &smi_pdev->dev;
330 	} else {
331 		dev_err(dev, "Failed to get the smi_common device\n");
332 		return -EINVAL;
333 	}
334 
335 	pm_runtime_enable(dev);
336 	platform_set_drvdata(pdev, larb);
337 	return component_add(dev, &mtk_smi_larb_component_ops);
338 }
339 
340 static int mtk_smi_larb_remove(struct platform_device *pdev)
341 {
342 	pm_runtime_disable(&pdev->dev);
343 	component_del(&pdev->dev, &mtk_smi_larb_component_ops);
344 	return 0;
345 }
346 
347 static struct platform_driver mtk_smi_larb_driver = {
348 	.probe	= mtk_smi_larb_probe,
349 	.remove	= mtk_smi_larb_remove,
350 	.driver	= {
351 		.name = "mtk-smi-larb",
352 		.of_match_table = mtk_smi_larb_of_ids,
353 	}
354 };
355 
356 static const struct of_device_id mtk_smi_common_of_ids[] = {
357 	{
358 		.compatible = "mediatek,mt8173-smi-common",
359 		.data = (void *)MTK_SMI_GEN2
360 	},
361 	{
362 		.compatible = "mediatek,mt2701-smi-common",
363 		.data = (void *)MTK_SMI_GEN1
364 	},
365 	{
366 		.compatible = "mediatek,mt2712-smi-common",
367 		.data = (void *)MTK_SMI_GEN2
368 	},
369 	{}
370 };
371 
372 static int mtk_smi_common_probe(struct platform_device *pdev)
373 {
374 	struct device *dev = &pdev->dev;
375 	struct mtk_smi *common;
376 	struct resource *res;
377 	enum mtk_smi_gen smi_gen;
378 	int ret;
379 
380 	common = devm_kzalloc(dev, sizeof(*common), GFP_KERNEL);
381 	if (!common)
382 		return -ENOMEM;
383 	common->dev = dev;
384 
385 	common->clk_apb = devm_clk_get(dev, "apb");
386 	if (IS_ERR(common->clk_apb))
387 		return PTR_ERR(common->clk_apb);
388 
389 	common->clk_smi = devm_clk_get(dev, "smi");
390 	if (IS_ERR(common->clk_smi))
391 		return PTR_ERR(common->clk_smi);
392 
393 	/*
394 	 * for mtk smi gen 1, we need to get the ao(always on) base to config
395 	 * m4u port, and we need to enable the aync clock for transform the smi
396 	 * clock into emi clock domain, but for mtk smi gen2, there's no smi ao
397 	 * base.
398 	 */
399 	smi_gen = (enum mtk_smi_gen)of_device_get_match_data(dev);
400 	if (smi_gen == MTK_SMI_GEN1) {
401 		res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
402 		common->smi_ao_base = devm_ioremap_resource(dev, res);
403 		if (IS_ERR(common->smi_ao_base))
404 			return PTR_ERR(common->smi_ao_base);
405 
406 		common->clk_async = devm_clk_get(dev, "async");
407 		if (IS_ERR(common->clk_async))
408 			return PTR_ERR(common->clk_async);
409 
410 		ret = clk_prepare_enable(common->clk_async);
411 		if (ret)
412 			return ret;
413 	}
414 	pm_runtime_enable(dev);
415 	platform_set_drvdata(pdev, common);
416 	return 0;
417 }
418 
419 static int mtk_smi_common_remove(struct platform_device *pdev)
420 {
421 	pm_runtime_disable(&pdev->dev);
422 	return 0;
423 }
424 
425 static struct platform_driver mtk_smi_common_driver = {
426 	.probe	= mtk_smi_common_probe,
427 	.remove = mtk_smi_common_remove,
428 	.driver	= {
429 		.name = "mtk-smi-common",
430 		.of_match_table = mtk_smi_common_of_ids,
431 	}
432 };
433 
434 static int __init mtk_smi_init(void)
435 {
436 	int ret;
437 
438 	ret = platform_driver_register(&mtk_smi_common_driver);
439 	if (ret != 0) {
440 		pr_err("Failed to register SMI driver\n");
441 		return ret;
442 	}
443 
444 	ret = platform_driver_register(&mtk_smi_larb_driver);
445 	if (ret != 0) {
446 		pr_err("Failed to register SMI-LARB driver\n");
447 		goto err_unreg_smi;
448 	}
449 	return ret;
450 
451 err_unreg_smi:
452 	platform_driver_unregister(&mtk_smi_common_driver);
453 	return ret;
454 }
455 
456 module_init(mtk_smi_init);
457