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
{
45 int port_in_larb
[MTK_LARB_NR_MAX
+ 1];
46 void (*config_port
)(struct device
*);
51 struct clk
*clk_apb
, *clk_smi
;
52 struct clk
*clk_async
; /*only needed by mt2701*/
53 void __iomem
*smi_ao_base
;
56 struct mtk_smi_larb
{ /* larb: local arbiter */
59 struct device
*smi_common_dev
;
60 const struct mtk_smi_larb_gen
*larb_gen
;
70 static int mtk_smi_enable(const struct mtk_smi
*smi
)
74 ret
= pm_runtime_get_sync(smi
->dev
);
78 ret
= clk_prepare_enable(smi
->clk_apb
);
82 ret
= clk_prepare_enable(smi
->clk_smi
);
89 clk_disable_unprepare(smi
->clk_apb
);
91 pm_runtime_put_sync(smi
->dev
);
95 static void mtk_smi_disable(const struct mtk_smi
*smi
)
97 clk_disable_unprepare(smi
->clk_smi
);
98 clk_disable_unprepare(smi
->clk_apb
);
99 pm_runtime_put_sync(smi
->dev
);
102 int mtk_smi_larb_get(struct device
*larbdev
)
104 struct mtk_smi_larb
*larb
= dev_get_drvdata(larbdev
);
105 const struct mtk_smi_larb_gen
*larb_gen
= larb
->larb_gen
;
106 struct mtk_smi
*common
= dev_get_drvdata(larb
->smi_common_dev
);
109 /* Enable the smi-common's power and clocks */
110 ret
= mtk_smi_enable(common
);
114 /* Enable the larb's power and clocks */
115 ret
= mtk_smi_enable(&larb
->smi
);
117 mtk_smi_disable(common
);
121 /* Configure the iommu info for this larb */
122 larb_gen
->config_port(larbdev
);
126 EXPORT_SYMBOL_GPL(mtk_smi_larb_get
);
128 void mtk_smi_larb_put(struct device
*larbdev
)
130 struct mtk_smi_larb
*larb
= dev_get_drvdata(larbdev
);
131 struct mtk_smi
*common
= dev_get_drvdata(larb
->smi_common_dev
);
134 * Don't de-configure the iommu info for this larb since there may be
135 * several modules in this larb.
136 * The iommu info will be reset after power off.
139 mtk_smi_disable(&larb
->smi
);
140 mtk_smi_disable(common
);
142 EXPORT_SYMBOL_GPL(mtk_smi_larb_put
);
145 mtk_smi_larb_bind(struct device
*dev
, struct device
*master
, void *data
)
147 struct mtk_smi_larb
*larb
= dev_get_drvdata(dev
);
148 struct mtk_smi_iommu
*smi_iommu
= data
;
151 for (i
= 0; i
< smi_iommu
->larb_nr
; i
++) {
152 if (dev
== smi_iommu
->larb_imu
[i
].dev
) {
153 /* The 'mmu' may be updated in iommu-attach/detach. */
154 larb
->mmu
= &smi_iommu
->larb_imu
[i
].mmu
;
161 static void mtk_smi_larb_config_port(struct device
*dev
)
163 struct mtk_smi_larb
*larb
= dev_get_drvdata(dev
);
165 writel(*larb
->mmu
, larb
->base
+ SMI_LARB_MMU_EN
);
169 static void mtk_smi_larb_config_port_gen1(struct device
*dev
)
171 struct mtk_smi_larb
*larb
= dev_get_drvdata(dev
);
172 const struct mtk_smi_larb_gen
*larb_gen
= larb
->larb_gen
;
173 struct mtk_smi
*common
= dev_get_drvdata(larb
->smi_common_dev
);
174 int i
, m4u_port_id
, larb_port_num
;
175 u32 sec_con_val
, reg_val
;
177 m4u_port_id
= larb_gen
->port_in_larb
[larb
->larbid
];
178 larb_port_num
= larb_gen
->port_in_larb
[larb
->larbid
+ 1]
179 - larb_gen
->port_in_larb
[larb
->larbid
];
181 for (i
= 0; i
< larb_port_num
; i
++, m4u_port_id
++) {
182 if (*larb
->mmu
& BIT(i
)) {
183 /* bit[port + 3] controls the virtual or physical */
184 sec_con_val
= SMI_SECUR_CON_VAL_VIRT(m4u_port_id
);
186 /* do not need to enable m4u for this port */
189 reg_val
= readl(common
->smi_ao_base
190 + REG_SMI_SECUR_CON_ADDR(m4u_port_id
));
191 reg_val
&= SMI_SECUR_CON_VAL_MSK(m4u_port_id
);
192 reg_val
|= sec_con_val
;
193 reg_val
|= SMI_SECUR_CON_VAL_DOMAIN(m4u_port_id
);
196 + REG_SMI_SECUR_CON_ADDR(m4u_port_id
));
201 mtk_smi_larb_unbind(struct device
*dev
, struct device
*master
, void *data
)
203 /* Do nothing as the iommu is always enabled. */
206 static const struct component_ops mtk_smi_larb_component_ops
= {
207 .bind
= mtk_smi_larb_bind
,
208 .unbind
= mtk_smi_larb_unbind
,
211 static const struct mtk_smi_larb_gen mtk_smi_larb_mt8173
= {
212 /* mt8173 do not need the port in larb */
213 .config_port
= mtk_smi_larb_config_port
,
216 static const struct mtk_smi_larb_gen mtk_smi_larb_mt2701
= {
218 LARB0_PORT_OFFSET
, LARB1_PORT_OFFSET
,
219 LARB2_PORT_OFFSET
, LARB3_PORT_OFFSET
221 .config_port
= mtk_smi_larb_config_port_gen1
,
224 static const struct of_device_id mtk_smi_larb_of_ids
[] = {
226 .compatible
= "mediatek,mt8173-smi-larb",
227 .data
= &mtk_smi_larb_mt8173
230 .compatible
= "mediatek,mt2701-smi-larb",
231 .data
= &mtk_smi_larb_mt2701
236 static int mtk_smi_larb_probe(struct platform_device
*pdev
)
238 struct mtk_smi_larb
*larb
;
239 struct resource
*res
;
240 struct device
*dev
= &pdev
->dev
;
241 struct device_node
*smi_node
;
242 struct platform_device
*smi_pdev
;
243 const struct of_device_id
*of_id
;
246 return -EPROBE_DEFER
;
248 of_id
= of_match_node(mtk_smi_larb_of_ids
, pdev
->dev
.of_node
);
252 larb
= devm_kzalloc(dev
, sizeof(*larb
), GFP_KERNEL
);
256 larb
->larb_gen
= of_id
->data
;
257 res
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
258 larb
->base
= devm_ioremap_resource(dev
, res
);
259 if (IS_ERR(larb
->base
))
260 return PTR_ERR(larb
->base
);
262 larb
->smi
.clk_apb
= devm_clk_get(dev
, "apb");
263 if (IS_ERR(larb
->smi
.clk_apb
))
264 return PTR_ERR(larb
->smi
.clk_apb
);
266 larb
->smi
.clk_smi
= devm_clk_get(dev
, "smi");
267 if (IS_ERR(larb
->smi
.clk_smi
))
268 return PTR_ERR(larb
->smi
.clk_smi
);
271 smi_node
= of_parse_phandle(dev
->of_node
, "mediatek,smi", 0);
275 smi_pdev
= of_find_device_by_node(smi_node
);
276 of_node_put(smi_node
);
278 larb
->smi_common_dev
= &smi_pdev
->dev
;
280 dev_err(dev
, "Failed to get the smi_common device\n");
284 pm_runtime_enable(dev
);
285 platform_set_drvdata(pdev
, larb
);
286 return component_add(dev
, &mtk_smi_larb_component_ops
);
289 static int mtk_smi_larb_remove(struct platform_device
*pdev
)
291 pm_runtime_disable(&pdev
->dev
);
292 component_del(&pdev
->dev
, &mtk_smi_larb_component_ops
);
296 static struct platform_driver mtk_smi_larb_driver
= {
297 .probe
= mtk_smi_larb_probe
,
298 .remove
= mtk_smi_larb_remove
,
300 .name
= "mtk-smi-larb",
301 .of_match_table
= mtk_smi_larb_of_ids
,
305 static const struct of_device_id mtk_smi_common_of_ids
[] = {
307 .compatible
= "mediatek,mt8173-smi-common",
308 .data
= (void *)MTK_SMI_GEN2
311 .compatible
= "mediatek,mt2701-smi-common",
312 .data
= (void *)MTK_SMI_GEN1
317 static int mtk_smi_common_probe(struct platform_device
*pdev
)
319 struct device
*dev
= &pdev
->dev
;
320 struct mtk_smi
*common
;
321 struct resource
*res
;
322 const struct of_device_id
*of_id
;
323 enum mtk_smi_gen smi_gen
;
326 return -EPROBE_DEFER
;
328 common
= devm_kzalloc(dev
, sizeof(*common
), GFP_KERNEL
);
333 common
->clk_apb
= devm_clk_get(dev
, "apb");
334 if (IS_ERR(common
->clk_apb
))
335 return PTR_ERR(common
->clk_apb
);
337 common
->clk_smi
= devm_clk_get(dev
, "smi");
338 if (IS_ERR(common
->clk_smi
))
339 return PTR_ERR(common
->clk_smi
);
341 of_id
= of_match_node(mtk_smi_common_of_ids
, pdev
->dev
.of_node
);
346 * for mtk smi gen 1, we need to get the ao(always on) base to config
347 * m4u port, and we need to enable the aync clock for transform the smi
348 * clock into emi clock domain, but for mtk smi gen2, there's no smi ao
351 smi_gen
= (enum mtk_smi_gen
)of_id
->data
;
352 if (smi_gen
== MTK_SMI_GEN1
) {
353 res
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
354 common
->smi_ao_base
= devm_ioremap_resource(dev
, res
);
355 if (IS_ERR(common
->smi_ao_base
))
356 return PTR_ERR(common
->smi_ao_base
);
358 common
->clk_async
= devm_clk_get(dev
, "async");
359 if (IS_ERR(common
->clk_async
))
360 return PTR_ERR(common
->clk_async
);
362 clk_prepare_enable(common
->clk_async
);
364 pm_runtime_enable(dev
);
365 platform_set_drvdata(pdev
, common
);
369 static int mtk_smi_common_remove(struct platform_device
*pdev
)
371 pm_runtime_disable(&pdev
->dev
);
375 static struct platform_driver mtk_smi_common_driver
= {
376 .probe
= mtk_smi_common_probe
,
377 .remove
= mtk_smi_common_remove
,
379 .name
= "mtk-smi-common",
380 .of_match_table
= mtk_smi_common_of_ids
,
384 static int __init
mtk_smi_init(void)
388 ret
= platform_driver_register(&mtk_smi_common_driver
);
390 pr_err("Failed to register SMI driver\n");
394 ret
= platform_driver_register(&mtk_smi_larb_driver
);
396 pr_err("Failed to register SMI-LARB driver\n");
402 platform_driver_unregister(&mtk_smi_common_driver
);
406 subsys_initcall(mtk_smi_init
);