]> asedeno.scripts.mit.edu Git - linux.git/blob - drivers/memory/mtk-smi.c
memory: mtk-smi: Handle return value of clk_prepare_enable
[linux.git] / drivers / memory / mtk-smi.c
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/of.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>
25
26 #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         bool need_larbid;
46         int port_in_larb[MTK_LARB_NR_MAX + 1];
47         void (*config_port)(struct device *);
48 };
49
50 struct mtk_smi {
51         struct device                   *dev;
52         struct clk                      *clk_apb, *clk_smi;
53         struct clk                      *clk_async; /*only needed by mt2701*/
54         void __iomem                    *smi_ao_base;
55 };
56
57 struct mtk_smi_larb { /* larb: local arbiter */
58         struct mtk_smi                  smi;
59         void __iomem                    *base;
60         struct device                   *smi_common_dev;
61         const struct mtk_smi_larb_gen   *larb_gen;
62         int                             larbid;
63         u32                             *mmu;
64 };
65
66 enum mtk_smi_gen {
67         MTK_SMI_GEN1,
68         MTK_SMI_GEN2
69 };
70
71 static int mtk_smi_enable(const struct mtk_smi *smi)
72 {
73         int ret;
74
75         ret = pm_runtime_get_sync(smi->dev);
76         if (ret < 0)
77                 return ret;
78
79         ret = clk_prepare_enable(smi->clk_apb);
80         if (ret)
81                 goto err_put_pm;
82
83         ret = clk_prepare_enable(smi->clk_smi);
84         if (ret)
85                 goto err_disable_apb;
86
87         return 0;
88
89 err_disable_apb:
90         clk_disable_unprepare(smi->clk_apb);
91 err_put_pm:
92         pm_runtime_put_sync(smi->dev);
93         return ret;
94 }
95
96 static void mtk_smi_disable(const struct mtk_smi *smi)
97 {
98         clk_disable_unprepare(smi->clk_smi);
99         clk_disable_unprepare(smi->clk_apb);
100         pm_runtime_put_sync(smi->dev);
101 }
102
103 int mtk_smi_larb_get(struct device *larbdev)
104 {
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);
108         int ret;
109
110         /* Enable the smi-common's power and clocks */
111         ret = mtk_smi_enable(common);
112         if (ret)
113                 return ret;
114
115         /* Enable the larb's power and clocks */
116         ret = mtk_smi_enable(&larb->smi);
117         if (ret) {
118                 mtk_smi_disable(common);
119                 return ret;
120         }
121
122         /* Configure the iommu info for this larb */
123         larb_gen->config_port(larbdev);
124
125         return 0;
126 }
127 EXPORT_SYMBOL_GPL(mtk_smi_larb_get);
128
129 void mtk_smi_larb_put(struct device *larbdev)
130 {
131         struct mtk_smi_larb *larb = dev_get_drvdata(larbdev);
132         struct mtk_smi *common = dev_get_drvdata(larb->smi_common_dev);
133
134         /*
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.
138          */
139
140         mtk_smi_disable(&larb->smi);
141         mtk_smi_disable(common);
142 }
143 EXPORT_SYMBOL_GPL(mtk_smi_larb_put);
144
145 static int
146 mtk_smi_larb_bind(struct device *dev, struct device *master, void *data)
147 {
148         struct mtk_smi_larb *larb = dev_get_drvdata(dev);
149         struct mtk_smi_iommu *smi_iommu = data;
150         unsigned int         i;
151
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;
156                         return 0;
157                 }
158         }
159         return -ENODEV;
160 }
161
162 static void mtk_smi_larb_config_port(struct device *dev)
163 {
164         struct mtk_smi_larb *larb = dev_get_drvdata(dev);
165
166         writel(*larb->mmu, larb->base + SMI_LARB_MMU_EN);
167 }
168
169
170 static void mtk_smi_larb_config_port_gen1(struct device *dev)
171 {
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;
177
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];
181
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);
186                 } else {
187                         /* do not need to enable m4u for this port */
188                         continue;
189                 }
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);
195                 writel(reg_val,
196                         common->smi_ao_base
197                         + REG_SMI_SECUR_CON_ADDR(m4u_port_id));
198         }
199 }
200
201 static void
202 mtk_smi_larb_unbind(struct device *dev, struct device *master, void *data)
203 {
204         /* Do nothing as the iommu is always enabled. */
205 }
206
207 static const struct component_ops mtk_smi_larb_component_ops = {
208         .bind = mtk_smi_larb_bind,
209         .unbind = mtk_smi_larb_unbind,
210 };
211
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,
215 };
216
217 static const struct mtk_smi_larb_gen mtk_smi_larb_mt2701 = {
218         .need_larbid = true,
219         .port_in_larb = {
220                 LARB0_PORT_OFFSET, LARB1_PORT_OFFSET,
221                 LARB2_PORT_OFFSET, LARB3_PORT_OFFSET
222         },
223         .config_port = mtk_smi_larb_config_port_gen1,
224 };
225
226 static const struct of_device_id mtk_smi_larb_of_ids[] = {
227         {
228                 .compatible = "mediatek,mt8173-smi-larb",
229                 .data = &mtk_smi_larb_mt8173
230         },
231         {
232                 .compatible = "mediatek,mt2701-smi-larb",
233                 .data = &mtk_smi_larb_mt2701
234         },
235         {}
236 };
237
238 static int mtk_smi_larb_probe(struct platform_device *pdev)
239 {
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;
245         int err;
246
247         if (!dev->pm_domain)
248                 return -EPROBE_DEFER;
249
250         larb = devm_kzalloc(dev, sizeof(*larb), GFP_KERNEL);
251         if (!larb)
252                 return -ENOMEM;
253
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);
259
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);
263
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);
267         larb->smi.dev = dev;
268
269         if (larb->larb_gen->need_larbid) {
270                 err = of_property_read_u32(dev->of_node, "mediatek,larb-id",
271                                            &larb->larbid);
272                 if (err) {
273                         dev_err(dev, "missing larbid property\n");
274                         return err;
275                 }
276         }
277
278         smi_node = of_parse_phandle(dev->of_node, "mediatek,smi", 0);
279         if (!smi_node)
280                 return -EINVAL;
281
282         smi_pdev = of_find_device_by_node(smi_node);
283         of_node_put(smi_node);
284         if (smi_pdev) {
285                 larb->smi_common_dev = &smi_pdev->dev;
286         } else {
287                 dev_err(dev, "Failed to get the smi_common device\n");
288                 return -EINVAL;
289         }
290
291         pm_runtime_enable(dev);
292         platform_set_drvdata(pdev, larb);
293         return component_add(dev, &mtk_smi_larb_component_ops);
294 }
295
296 static int mtk_smi_larb_remove(struct platform_device *pdev)
297 {
298         pm_runtime_disable(&pdev->dev);
299         component_del(&pdev->dev, &mtk_smi_larb_component_ops);
300         return 0;
301 }
302
303 static struct platform_driver mtk_smi_larb_driver = {
304         .probe  = mtk_smi_larb_probe,
305         .remove = mtk_smi_larb_remove,
306         .driver = {
307                 .name = "mtk-smi-larb",
308                 .of_match_table = mtk_smi_larb_of_ids,
309         }
310 };
311
312 static const struct of_device_id mtk_smi_common_of_ids[] = {
313         {
314                 .compatible = "mediatek,mt8173-smi-common",
315                 .data = (void *)MTK_SMI_GEN2
316         },
317         {
318                 .compatible = "mediatek,mt2701-smi-common",
319                 .data = (void *)MTK_SMI_GEN1
320         },
321         {}
322 };
323
324 static int mtk_smi_common_probe(struct platform_device *pdev)
325 {
326         struct device *dev = &pdev->dev;
327         struct mtk_smi *common;
328         struct resource *res;
329         enum mtk_smi_gen smi_gen;
330         int ret;
331
332         if (!dev->pm_domain)
333                 return -EPROBE_DEFER;
334
335         common = devm_kzalloc(dev, sizeof(*common), GFP_KERNEL);
336         if (!common)
337                 return -ENOMEM;
338         common->dev = dev;
339
340         common->clk_apb = devm_clk_get(dev, "apb");
341         if (IS_ERR(common->clk_apb))
342                 return PTR_ERR(common->clk_apb);
343
344         common->clk_smi = devm_clk_get(dev, "smi");
345         if (IS_ERR(common->clk_smi))
346                 return PTR_ERR(common->clk_smi);
347
348         /*
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
352          * base.
353          */
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);
360
361                 common->clk_async = devm_clk_get(dev, "async");
362                 if (IS_ERR(common->clk_async))
363                         return PTR_ERR(common->clk_async);
364
365                 ret = clk_prepare_enable(common->clk_async);
366                 if (ret)
367                         return ret;
368         }
369         pm_runtime_enable(dev);
370         platform_set_drvdata(pdev, common);
371         return 0;
372 }
373
374 static int mtk_smi_common_remove(struct platform_device *pdev)
375 {
376         pm_runtime_disable(&pdev->dev);
377         return 0;
378 }
379
380 static struct platform_driver mtk_smi_common_driver = {
381         .probe  = mtk_smi_common_probe,
382         .remove = mtk_smi_common_remove,
383         .driver = {
384                 .name = "mtk-smi-common",
385                 .of_match_table = mtk_smi_common_of_ids,
386         }
387 };
388
389 static int __init mtk_smi_init(void)
390 {
391         int ret;
392
393         ret = platform_driver_register(&mtk_smi_common_driver);
394         if (ret != 0) {
395                 pr_err("Failed to register SMI driver\n");
396                 return ret;
397         }
398
399         ret = platform_driver_register(&mtk_smi_larb_driver);
400         if (ret != 0) {
401                 pr_err("Failed to register SMI-LARB driver\n");
402                 goto err_unreg_smi;
403         }
404         return ret;
405
406 err_unreg_smi:
407         platform_driver_unregister(&mtk_smi_common_driver);
408         return ret;
409 }
410
411 subsys_initcall(mtk_smi_init);