2 * Copyright (c) 2015-2016 MediaTek Inc.
3 * Author: Yong Wu <yong.wu@mediatek.com>
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.
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.
14 #include <linux/clk.h>
15 #include <linux/component.h>
16 #include <linux/device.h>
17 #include <linux/err.h>
20 #include <linux/of_platform.h>
21 #include <linux/platform_device.h>
22 #include <linux/pm_runtime.h>
23 #include <soc/mediatek/smi.h>
24 #include <dt-bindings/memory/mt2701-larb-port.h>
26 #define SMI_LARB_MMU_EN 0xf00
27 #define REG_SMI_SECUR_CON_BASE 0x5c0
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))
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
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))
44 struct mtk_smi_larb_gen {
46 int port_in_larb[MTK_LARB_NR_MAX + 1];
47 void (*config_port)(struct device *);
52 struct clk *clk_apb, *clk_smi;
53 struct clk *clk_async; /*only needed by mt2701*/
54 void __iomem *smi_ao_base;
57 struct mtk_smi_larb { /* larb: local arbiter */
60 struct device *smi_common_dev;
61 const struct mtk_smi_larb_gen *larb_gen;
71 static int mtk_smi_enable(const struct mtk_smi *smi)
75 ret = pm_runtime_get_sync(smi->dev);
79 ret = clk_prepare_enable(smi->clk_apb);
83 ret = clk_prepare_enable(smi->clk_smi);
90 clk_disable_unprepare(smi->clk_apb);
92 pm_runtime_put_sync(smi->dev);
96 static void mtk_smi_disable(const struct mtk_smi *smi)
98 clk_disable_unprepare(smi->clk_smi);
99 clk_disable_unprepare(smi->clk_apb);
100 pm_runtime_put_sync(smi->dev);
103 int mtk_smi_larb_get(struct device *larbdev)
105 struct mtk_smi_larb *larb = dev_get_drvdata(larbdev);
106 const struct mtk_smi_larb_gen *larb_gen = larb->larb_gen;
107 struct mtk_smi *common = dev_get_drvdata(larb->smi_common_dev);
110 /* Enable the smi-common's power and clocks */
111 ret = mtk_smi_enable(common);
115 /* Enable the larb's power and clocks */
116 ret = mtk_smi_enable(&larb->smi);
118 mtk_smi_disable(common);
122 /* Configure the iommu info for this larb */
123 larb_gen->config_port(larbdev);
127 EXPORT_SYMBOL_GPL(mtk_smi_larb_get);
129 void mtk_smi_larb_put(struct device *larbdev)
131 struct mtk_smi_larb *larb = dev_get_drvdata(larbdev);
132 struct mtk_smi *common = dev_get_drvdata(larb->smi_common_dev);
135 * Don't de-configure the iommu info for this larb since there may be
136 * several modules in this larb.
137 * The iommu info will be reset after power off.
140 mtk_smi_disable(&larb->smi);
141 mtk_smi_disable(common);
143 EXPORT_SYMBOL_GPL(mtk_smi_larb_put);
146 mtk_smi_larb_bind(struct device *dev, struct device *master, void *data)
148 struct mtk_smi_larb *larb = dev_get_drvdata(dev);
149 struct mtk_smi_iommu *smi_iommu = data;
152 for (i = 0; i < smi_iommu->larb_nr; i++) {
153 if (dev == smi_iommu->larb_imu[i].dev) {
154 /* The 'mmu' may be updated in iommu-attach/detach. */
155 larb->mmu = &smi_iommu->larb_imu[i].mmu;
162 static void mtk_smi_larb_config_port(struct device *dev)
164 struct mtk_smi_larb *larb = dev_get_drvdata(dev);
166 writel(*larb->mmu, larb->base + SMI_LARB_MMU_EN);
170 static void mtk_smi_larb_config_port_gen1(struct device *dev)
172 struct mtk_smi_larb *larb = dev_get_drvdata(dev);
173 const struct mtk_smi_larb_gen *larb_gen = larb->larb_gen;
174 struct mtk_smi *common = dev_get_drvdata(larb->smi_common_dev);
175 int i, m4u_port_id, larb_port_num;
176 u32 sec_con_val, reg_val;
178 m4u_port_id = larb_gen->port_in_larb[larb->larbid];
179 larb_port_num = larb_gen->port_in_larb[larb->larbid + 1]
180 - larb_gen->port_in_larb[larb->larbid];
182 for (i = 0; i < larb_port_num; i++, m4u_port_id++) {
183 if (*larb->mmu & BIT(i)) {
184 /* bit[port + 3] controls the virtual or physical */
185 sec_con_val = SMI_SECUR_CON_VAL_VIRT(m4u_port_id);
187 /* do not need to enable m4u for this port */
190 reg_val = readl(common->smi_ao_base
191 + REG_SMI_SECUR_CON_ADDR(m4u_port_id));
192 reg_val &= SMI_SECUR_CON_VAL_MSK(m4u_port_id);
193 reg_val |= sec_con_val;
194 reg_val |= SMI_SECUR_CON_VAL_DOMAIN(m4u_port_id);
197 + REG_SMI_SECUR_CON_ADDR(m4u_port_id));
202 mtk_smi_larb_unbind(struct device *dev, struct device *master, void *data)
204 /* Do nothing as the iommu is always enabled. */
207 static const struct component_ops mtk_smi_larb_component_ops = {
208 .bind = mtk_smi_larb_bind,
209 .unbind = mtk_smi_larb_unbind,
212 static const struct mtk_smi_larb_gen mtk_smi_larb_mt8173 = {
213 /* mt8173 do not need the port in larb */
214 .config_port = mtk_smi_larb_config_port,
217 static const struct mtk_smi_larb_gen mtk_smi_larb_mt2701 = {
220 LARB0_PORT_OFFSET, LARB1_PORT_OFFSET,
221 LARB2_PORT_OFFSET, LARB3_PORT_OFFSET
223 .config_port = mtk_smi_larb_config_port_gen1,
226 static const struct of_device_id mtk_smi_larb_of_ids[] = {
228 .compatible = "mediatek,mt8173-smi-larb",
229 .data = &mtk_smi_larb_mt8173
232 .compatible = "mediatek,mt2701-smi-larb",
233 .data = &mtk_smi_larb_mt2701
238 static int mtk_smi_larb_probe(struct platform_device *pdev)
240 struct mtk_smi_larb *larb;
241 struct resource *res;
242 struct device *dev = &pdev->dev;
243 struct device_node *smi_node;
244 struct platform_device *smi_pdev;
248 return -EPROBE_DEFER;
250 larb = devm_kzalloc(dev, sizeof(*larb), GFP_KERNEL);
254 larb->larb_gen = of_device_get_match_data(dev);
255 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
256 larb->base = devm_ioremap_resource(dev, res);
257 if (IS_ERR(larb->base))
258 return PTR_ERR(larb->base);
260 larb->smi.clk_apb = devm_clk_get(dev, "apb");
261 if (IS_ERR(larb->smi.clk_apb))
262 return PTR_ERR(larb->smi.clk_apb);
264 larb->smi.clk_smi = devm_clk_get(dev, "smi");
265 if (IS_ERR(larb->smi.clk_smi))
266 return PTR_ERR(larb->smi.clk_smi);
269 if (larb->larb_gen->need_larbid) {
270 err = of_property_read_u32(dev->of_node, "mediatek,larb-id",
273 dev_err(dev, "missing larbid property\n");
278 smi_node = of_parse_phandle(dev->of_node, "mediatek,smi", 0);
282 smi_pdev = of_find_device_by_node(smi_node);
283 of_node_put(smi_node);
285 larb->smi_common_dev = &smi_pdev->dev;
287 dev_err(dev, "Failed to get the smi_common device\n");
291 pm_runtime_enable(dev);
292 platform_set_drvdata(pdev, larb);
293 return component_add(dev, &mtk_smi_larb_component_ops);
296 static int mtk_smi_larb_remove(struct platform_device *pdev)
298 pm_runtime_disable(&pdev->dev);
299 component_del(&pdev->dev, &mtk_smi_larb_component_ops);
303 static struct platform_driver mtk_smi_larb_driver = {
304 .probe = mtk_smi_larb_probe,
305 .remove = mtk_smi_larb_remove,
307 .name = "mtk-smi-larb",
308 .of_match_table = mtk_smi_larb_of_ids,
312 static const struct of_device_id mtk_smi_common_of_ids[] = {
314 .compatible = "mediatek,mt8173-smi-common",
315 .data = (void *)MTK_SMI_GEN2
318 .compatible = "mediatek,mt2701-smi-common",
319 .data = (void *)MTK_SMI_GEN1
324 static int mtk_smi_common_probe(struct platform_device *pdev)
326 struct device *dev = &pdev->dev;
327 struct mtk_smi *common;
328 struct resource *res;
329 enum mtk_smi_gen smi_gen;
333 return -EPROBE_DEFER;
335 common = devm_kzalloc(dev, sizeof(*common), GFP_KERNEL);
340 common->clk_apb = devm_clk_get(dev, "apb");
341 if (IS_ERR(common->clk_apb))
342 return PTR_ERR(common->clk_apb);
344 common->clk_smi = devm_clk_get(dev, "smi");
345 if (IS_ERR(common->clk_smi))
346 return PTR_ERR(common->clk_smi);
349 * for mtk smi gen 1, we need to get the ao(always on) base to config
350 * m4u port, and we need to enable the aync clock for transform the smi
351 * clock into emi clock domain, but for mtk smi gen2, there's no smi ao
354 smi_gen = (enum mtk_smi_gen)of_device_get_match_data(dev);
355 if (smi_gen == MTK_SMI_GEN1) {
356 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
357 common->smi_ao_base = devm_ioremap_resource(dev, res);
358 if (IS_ERR(common->smi_ao_base))
359 return PTR_ERR(common->smi_ao_base);
361 common->clk_async = devm_clk_get(dev, "async");
362 if (IS_ERR(common->clk_async))
363 return PTR_ERR(common->clk_async);
365 ret = clk_prepare_enable(common->clk_async);
369 pm_runtime_enable(dev);
370 platform_set_drvdata(pdev, common);
374 static int mtk_smi_common_remove(struct platform_device *pdev)
376 pm_runtime_disable(&pdev->dev);
380 static struct platform_driver mtk_smi_common_driver = {
381 .probe = mtk_smi_common_probe,
382 .remove = mtk_smi_common_remove,
384 .name = "mtk-smi-common",
385 .of_match_table = mtk_smi_common_of_ids,
389 static int __init mtk_smi_init(void)
393 ret = platform_driver_register(&mtk_smi_common_driver);
395 pr_err("Failed to register SMI driver\n");
399 ret = platform_driver_register(&mtk_smi_larb_driver);
401 pr_err("Failed to register SMI-LARB driver\n");
407 platform_driver_unregister(&mtk_smi_common_driver);
411 subsys_initcall(mtk_smi_init);