2121#include <linux/platform_device.h>
2222#include <linux/pm_runtime.h>
2323#include <soc/mediatek/smi.h>
24+ #include <dt-bindings/memory/mt2701-larb-port.h>
2425
2526#define SMI_LARB_MMU_EN 0xf00
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+ struct mtk_smi_larb_gen {
45+ int port_in_larb [MTK_LARB_NR_MAX + 1 ];
46+ void (* config_port )(struct device * );
47+ };
2648
2749struct mtk_smi {
28- struct device * dev ;
29- struct clk * clk_apb , * clk_smi ;
50+ struct device * dev ;
51+ struct clk * clk_apb , * clk_smi ;
52+ struct clk * clk_async ; /*only needed by mt2701*/
53+ void __iomem * smi_ao_base ;
3054};
3155
3256struct mtk_smi_larb { /* larb: local arbiter */
33- struct mtk_smi smi ;
34- void __iomem * base ;
35- struct device * smi_common_dev ;
36- u32 * mmu ;
57+ struct mtk_smi smi ;
58+ void __iomem * base ;
59+ struct device * smi_common_dev ;
60+ const struct mtk_smi_larb_gen * larb_gen ;
61+ int larbid ;
62+ u32 * mmu ;
63+ };
64+
65+ enum mtk_smi_gen {
66+ MTK_SMI_GEN1 ,
67+ MTK_SMI_GEN2
3768};
3869
3970static int mtk_smi_enable (const struct mtk_smi * smi )
@@ -71,6 +102,7 @@ static void mtk_smi_disable(const struct mtk_smi *smi)
71102int mtk_smi_larb_get (struct device * larbdev )
72103{
73104 struct mtk_smi_larb * larb = dev_get_drvdata (larbdev );
105+ const struct mtk_smi_larb_gen * larb_gen = larb -> larb_gen ;
74106 struct mtk_smi * common = dev_get_drvdata (larb -> smi_common_dev );
75107 int ret ;
76108
@@ -87,7 +119,7 @@ int mtk_smi_larb_get(struct device *larbdev)
87119 }
88120
89121 /* Configure the iommu info for this larb */
90- writel ( * larb -> mmu , larb -> base + SMI_LARB_MMU_EN );
122+ larb_gen -> config_port ( larbdev );
91123
92124 return 0 ;
93125}
@@ -126,6 +158,45 @@ mtk_smi_larb_bind(struct device *dev, struct device *master, void *data)
126158 return - ENODEV ;
127159}
128160
161+ static void mtk_smi_larb_config_port (struct device * dev )
162+ {
163+ struct mtk_smi_larb * larb = dev_get_drvdata (dev );
164+
165+ writel (* larb -> mmu , larb -> base + SMI_LARB_MMU_EN );
166+ }
167+
168+
169+ static void mtk_smi_larb_config_port_gen1 (struct device * dev )
170+ {
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 ;
176+
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 ];
180+
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 );
185+ } else {
186+ /* do not need to enable m4u for this port */
187+ continue ;
188+ }
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 );
194+ writel (reg_val ,
195+ common -> smi_ao_base
196+ + REG_SMI_SECUR_CON_ADDR (m4u_port_id ));
197+ }
198+ }
199+
129200static void
130201mtk_smi_larb_unbind (struct device * dev , struct device * master , void * data )
131202{
@@ -137,21 +208,52 @@ static const struct component_ops mtk_smi_larb_component_ops = {
137208 .unbind = mtk_smi_larb_unbind ,
138209};
139210
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 ,
214+ };
215+
216+ static const struct mtk_smi_larb_gen mtk_smi_larb_mt2701 = {
217+ .port_in_larb = {
218+ LARB0_PORT_OFFSET , LARB1_PORT_OFFSET ,
219+ LARB2_PORT_OFFSET , LARB3_PORT_OFFSET
220+ },
221+ .config_port = mtk_smi_larb_config_port_gen1 ,
222+ };
223+
224+ static const struct of_device_id mtk_smi_larb_of_ids [] = {
225+ {
226+ .compatible = "mediatek,mt8173-smi-larb" ,
227+ .data = & mtk_smi_larb_mt8173
228+ },
229+ {
230+ .compatible = "mediatek,mt2701-smi-larb" ,
231+ .data = & mtk_smi_larb_mt2701
232+ },
233+ {}
234+ };
235+
140236static int mtk_smi_larb_probe (struct platform_device * pdev )
141237{
142238 struct mtk_smi_larb * larb ;
143239 struct resource * res ;
144240 struct device * dev = & pdev -> dev ;
145241 struct device_node * smi_node ;
146242 struct platform_device * smi_pdev ;
243+ const struct of_device_id * of_id ;
147244
148245 if (!dev -> pm_domain )
149246 return - EPROBE_DEFER ;
150247
248+ of_id = of_match_node (mtk_smi_larb_of_ids , pdev -> dev .of_node );
249+ if (!of_id )
250+ return - EINVAL ;
251+
151252 larb = devm_kzalloc (dev , sizeof (* larb ), GFP_KERNEL );
152253 if (!larb )
153254 return - ENOMEM ;
154255
256+ larb -> larb_gen = of_id -> data ;
155257 res = platform_get_resource (pdev , IORESOURCE_MEM , 0 );
156258 larb -> base = devm_ioremap_resource (dev , res );
157259 if (IS_ERR (larb -> base ))
@@ -191,24 +293,34 @@ static int mtk_smi_larb_remove(struct platform_device *pdev)
191293 return 0 ;
192294}
193295
194- static const struct of_device_id mtk_smi_larb_of_ids [] = {
195- { .compatible = "mediatek,mt8173-smi-larb" ,},
196- {}
197- };
198-
199296static struct platform_driver mtk_smi_larb_driver = {
200297 .probe = mtk_smi_larb_probe ,
201- .remove = mtk_smi_larb_remove ,
298+ .remove = mtk_smi_larb_remove ,
202299 .driver = {
203300 .name = "mtk-smi-larb" ,
204301 .of_match_table = mtk_smi_larb_of_ids ,
205302 }
206303};
207304
305+ static const struct of_device_id mtk_smi_common_of_ids [] = {
306+ {
307+ .compatible = "mediatek,mt8173-smi-common" ,
308+ .data = (void * )MTK_SMI_GEN2
309+ },
310+ {
311+ .compatible = "mediatek,mt2701-smi-common" ,
312+ .data = (void * )MTK_SMI_GEN1
313+ },
314+ {}
315+ };
316+
208317static int mtk_smi_common_probe (struct platform_device * pdev )
209318{
210319 struct device * dev = & pdev -> dev ;
211320 struct mtk_smi * common ;
321+ struct resource * res ;
322+ const struct of_device_id * of_id ;
323+ enum mtk_smi_gen smi_gen ;
212324
213325 if (!dev -> pm_domain )
214326 return - EPROBE_DEFER ;
@@ -226,6 +338,29 @@ static int mtk_smi_common_probe(struct platform_device *pdev)
226338 if (IS_ERR (common -> clk_smi ))
227339 return PTR_ERR (common -> clk_smi );
228340
341+ of_id = of_match_node (mtk_smi_common_of_ids , pdev -> dev .of_node );
342+ if (!of_id )
343+ return - EINVAL ;
344+
345+ /*
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
349+ * base.
350+ */
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 );
357+
358+ common -> clk_async = devm_clk_get (dev , "async" );
359+ if (IS_ERR (common -> clk_async ))
360+ return PTR_ERR (common -> clk_async );
361+
362+ clk_prepare_enable (common -> clk_async );
363+ }
229364 pm_runtime_enable (dev );
230365 platform_set_drvdata (pdev , common );
231366 return 0 ;
@@ -237,11 +372,6 @@ static int mtk_smi_common_remove(struct platform_device *pdev)
237372 return 0 ;
238373}
239374
240- static const struct of_device_id mtk_smi_common_of_ids [] = {
241- { .compatible = "mediatek,mt8173-smi-common" , },
242- {}
243- };
244-
245375static struct platform_driver mtk_smi_common_driver = {
246376 .probe = mtk_smi_common_probe ,
247377 .remove = mtk_smi_common_remove ,
@@ -272,4 +402,5 @@ static int __init mtk_smi_init(void)
272402 platform_driver_unregister (& mtk_smi_common_driver );
273403 return ret ;
274404}
405+
275406subsys_initcall (mtk_smi_init );
0 commit comments