GNU Linux-libre 4.19.264-gnu1
[releases.git] / drivers / soc / imx / gpc.c
1 /*
2  * Copyright 2015-2017 Pengutronix, Lucas Stach <kernel@pengutronix.de>
3  * Copyright 2011-2013 Freescale Semiconductor, Inc.
4  *
5  * The code contained herein is licensed under the GNU General Public
6  * License. You may obtain a copy of the GNU General Public License
7  * Version 2 or later at the following locations:
8  *
9  * http://www.opensource.org/licenses/gpl-license.html
10  * http://www.gnu.org/copyleft/gpl.html
11  */
12
13 #include <linux/clk.h>
14 #include <linux/delay.h>
15 #include <linux/io.h>
16 #include <linux/of_device.h>
17 #include <linux/platform_device.h>
18 #include <linux/pm_domain.h>
19 #include <linux/regmap.h>
20 #include <linux/regulator/consumer.h>
21
22 #define GPC_CNTR                0x000
23
24 #define GPC_PGC_CTRL_OFFS       0x0
25 #define GPC_PGC_PUPSCR_OFFS     0x4
26 #define GPC_PGC_PDNSCR_OFFS     0x8
27 #define GPC_PGC_SW2ISO_SHIFT    0x8
28 #define GPC_PGC_SW_SHIFT        0x0
29
30 #define GPC_PGC_PCI_PDN         0x200
31 #define GPC_PGC_PCI_SR          0x20c
32
33 #define GPC_PGC_GPU_PDN         0x260
34 #define GPC_PGC_GPU_PUPSCR      0x264
35 #define GPC_PGC_GPU_PDNSCR      0x268
36 #define GPC_PGC_GPU_SR          0x26c
37
38 #define GPC_PGC_DISP_PDN        0x240
39 #define GPC_PGC_DISP_SR         0x24c
40
41 #define GPU_VPU_PUP_REQ         BIT(1)
42 #define GPU_VPU_PDN_REQ         BIT(0)
43
44 #define GPC_CLK_MAX             6
45
46 #define PGC_DOMAIN_FLAG_NO_PD           BIT(0)
47
48 struct imx_pm_domain {
49         struct generic_pm_domain base;
50         struct regmap *regmap;
51         struct regulator *supply;
52         struct clk *clk[GPC_CLK_MAX];
53         int num_clks;
54         unsigned int reg_offs;
55         signed char cntr_pdn_bit;
56         unsigned int ipg_rate_mhz;
57 };
58
59 static inline struct imx_pm_domain *
60 to_imx_pm_domain(struct generic_pm_domain *genpd)
61 {
62         return container_of(genpd, struct imx_pm_domain, base);
63 }
64
65 static int imx6_pm_domain_power_off(struct generic_pm_domain *genpd)
66 {
67         struct imx_pm_domain *pd = to_imx_pm_domain(genpd);
68         int iso, iso2sw;
69         u32 val;
70
71         /* Read ISO and ISO2SW power down delays */
72         regmap_read(pd->regmap, pd->reg_offs + GPC_PGC_PDNSCR_OFFS, &val);
73         iso = val & 0x3f;
74         iso2sw = (val >> 8) & 0x3f;
75
76         /* Gate off domain when powered down */
77         regmap_update_bits(pd->regmap, pd->reg_offs + GPC_PGC_CTRL_OFFS,
78                            0x1, 0x1);
79
80         /* Request GPC to power down domain */
81         val = BIT(pd->cntr_pdn_bit);
82         regmap_update_bits(pd->regmap, GPC_CNTR, val, val);
83
84         /* Wait ISO + ISO2SW IPG clock cycles */
85         udelay(DIV_ROUND_UP(iso + iso2sw, pd->ipg_rate_mhz));
86
87         if (pd->supply)
88                 regulator_disable(pd->supply);
89
90         return 0;
91 }
92
93 static int imx6_pm_domain_power_on(struct generic_pm_domain *genpd)
94 {
95         struct imx_pm_domain *pd = to_imx_pm_domain(genpd);
96         int i, ret;
97         u32 val, req;
98
99         if (pd->supply) {
100                 ret = regulator_enable(pd->supply);
101                 if (ret) {
102                         pr_err("%s: failed to enable regulator: %d\n",
103                                __func__, ret);
104                         return ret;
105                 }
106         }
107
108         /* Enable reset clocks for all devices in the domain */
109         for (i = 0; i < pd->num_clks; i++)
110                 clk_prepare_enable(pd->clk[i]);
111
112         /* Gate off domain when powered down */
113         regmap_update_bits(pd->regmap, pd->reg_offs + GPC_PGC_CTRL_OFFS,
114                            0x1, 0x1);
115
116         /* Request GPC to power up domain */
117         req = BIT(pd->cntr_pdn_bit + 1);
118         regmap_update_bits(pd->regmap, GPC_CNTR, req, req);
119
120         /* Wait for the PGC to handle the request */
121         ret = regmap_read_poll_timeout(pd->regmap, GPC_CNTR, val, !(val & req),
122                                        1, 50);
123         if (ret)
124                 pr_err("powerup request on domain %s timed out\n", genpd->name);
125
126         /* Wait for reset to propagate through peripherals */
127         usleep_range(5, 10);
128
129         /* Disable reset clocks for all devices in the domain */
130         for (i = 0; i < pd->num_clks; i++)
131                 clk_disable_unprepare(pd->clk[i]);
132
133         return 0;
134 }
135
136 static int imx_pgc_get_clocks(struct device *dev, struct imx_pm_domain *domain)
137 {
138         int i, ret;
139
140         for (i = 0; ; i++) {
141                 struct clk *clk = of_clk_get(dev->of_node, i);
142                 if (IS_ERR(clk))
143                         break;
144                 if (i >= GPC_CLK_MAX) {
145                         dev_err(dev, "more than %d clocks\n", GPC_CLK_MAX);
146                         ret = -EINVAL;
147                         goto clk_err;
148                 }
149                 domain->clk[i] = clk;
150         }
151         domain->num_clks = i;
152
153         return 0;
154
155 clk_err:
156         while (i--)
157                 clk_put(domain->clk[i]);
158
159         return ret;
160 }
161
162 static void imx_pgc_put_clocks(struct imx_pm_domain *domain)
163 {
164         int i;
165
166         for (i = domain->num_clks - 1; i >= 0; i--)
167                 clk_put(domain->clk[i]);
168 }
169
170 static int imx_pgc_parse_dt(struct device *dev, struct imx_pm_domain *domain)
171 {
172         /* try to get the domain supply regulator */
173         domain->supply = devm_regulator_get_optional(dev, "power");
174         if (IS_ERR(domain->supply)) {
175                 if (PTR_ERR(domain->supply) == -ENODEV)
176                         domain->supply = NULL;
177                 else
178                         return PTR_ERR(domain->supply);
179         }
180
181         /* try to get all clocks needed for reset propagation */
182         return imx_pgc_get_clocks(dev, domain);
183 }
184
185 static int imx_pgc_power_domain_probe(struct platform_device *pdev)
186 {
187         struct imx_pm_domain *domain = pdev->dev.platform_data;
188         struct device *dev = &pdev->dev;
189         int ret;
190
191         /* if this PD is associated with a DT node try to parse it */
192         if (dev->of_node) {
193                 ret = imx_pgc_parse_dt(dev, domain);
194                 if (ret)
195                         return ret;
196         }
197
198         /* initially power on the domain */
199         if (domain->base.power_on)
200                 domain->base.power_on(&domain->base);
201
202         if (IS_ENABLED(CONFIG_PM_GENERIC_DOMAINS)) {
203                 pm_genpd_init(&domain->base, NULL, false);
204                 ret = of_genpd_add_provider_simple(dev->of_node, &domain->base);
205                 if (ret)
206                         goto genpd_err;
207         }
208
209         device_link_add(dev, dev->parent, DL_FLAG_AUTOREMOVE_CONSUMER);
210
211         return 0;
212
213 genpd_err:
214         pm_genpd_remove(&domain->base);
215         imx_pgc_put_clocks(domain);
216
217         return ret;
218 }
219
220 static int imx_pgc_power_domain_remove(struct platform_device *pdev)
221 {
222         struct imx_pm_domain *domain = pdev->dev.platform_data;
223
224         if (IS_ENABLED(CONFIG_PM_GENERIC_DOMAINS)) {
225                 of_genpd_del_provider(pdev->dev.of_node);
226                 pm_genpd_remove(&domain->base);
227                 imx_pgc_put_clocks(domain);
228         }
229
230         return 0;
231 }
232
233 static const struct platform_device_id imx_pgc_power_domain_id[] = {
234         { "imx-pgc-power-domain"},
235         { },
236 };
237
238 static struct platform_driver imx_pgc_power_domain_driver = {
239         .driver = {
240                 .name = "imx-pgc-pd",
241         },
242         .probe = imx_pgc_power_domain_probe,
243         .remove = imx_pgc_power_domain_remove,
244         .id_table = imx_pgc_power_domain_id,
245 };
246 builtin_platform_driver(imx_pgc_power_domain_driver)
247
248 #define GPC_PGC_DOMAIN_ARM      0
249 #define GPC_PGC_DOMAIN_PU       1
250 #define GPC_PGC_DOMAIN_DISPLAY  2
251
252 static struct genpd_power_state imx6_pm_domain_pu_state = {
253         .power_off_latency_ns = 25000,
254         .power_on_latency_ns = 2000000,
255 };
256
257 static struct imx_pm_domain imx_gpc_domains[] = {
258         {
259                 .base = {
260                         .name = "ARM",
261                         .flags = GENPD_FLAG_ALWAYS_ON,
262                 },
263         }, {
264                 .base = {
265                         .name = "PU",
266                         .power_off = imx6_pm_domain_power_off,
267                         .power_on = imx6_pm_domain_power_on,
268                         .states = &imx6_pm_domain_pu_state,
269                         .state_count = 1,
270                 },
271                 .reg_offs = 0x260,
272                 .cntr_pdn_bit = 0,
273         }, {
274                 .base = {
275                         .name = "DISPLAY",
276                         .power_off = imx6_pm_domain_power_off,
277                         .power_on = imx6_pm_domain_power_on,
278                 },
279                 .reg_offs = 0x240,
280                 .cntr_pdn_bit = 4,
281         }, {
282                 .base = {
283                         .name = "PCI",
284                         .power_off = imx6_pm_domain_power_off,
285                         .power_on = imx6_pm_domain_power_on,
286                 },
287                 .reg_offs = 0x200,
288                 .cntr_pdn_bit = 6,
289         },
290 };
291
292 struct imx_gpc_dt_data {
293         int num_domains;
294         bool err009619_present;
295         bool err006287_present;
296 };
297
298 static const struct imx_gpc_dt_data imx6q_dt_data = {
299         .num_domains = 2,
300         .err009619_present = false,
301         .err006287_present = false,
302 };
303
304 static const struct imx_gpc_dt_data imx6qp_dt_data = {
305         .num_domains = 2,
306         .err009619_present = true,
307         .err006287_present = false,
308 };
309
310 static const struct imx_gpc_dt_data imx6sl_dt_data = {
311         .num_domains = 3,
312         .err009619_present = false,
313         .err006287_present = true,
314 };
315
316 static const struct imx_gpc_dt_data imx6sx_dt_data = {
317         .num_domains = 4,
318         .err009619_present = false,
319         .err006287_present = false,
320 };
321
322 static const struct of_device_id imx_gpc_dt_ids[] = {
323         { .compatible = "fsl,imx6q-gpc", .data = &imx6q_dt_data },
324         { .compatible = "fsl,imx6qp-gpc", .data = &imx6qp_dt_data },
325         { .compatible = "fsl,imx6sl-gpc", .data = &imx6sl_dt_data },
326         { .compatible = "fsl,imx6sx-gpc", .data = &imx6sx_dt_data },
327         { }
328 };
329
330 static const struct regmap_range yes_ranges[] = {
331         regmap_reg_range(GPC_CNTR, GPC_CNTR),
332         regmap_reg_range(GPC_PGC_PCI_PDN, GPC_PGC_PCI_SR),
333         regmap_reg_range(GPC_PGC_GPU_PDN, GPC_PGC_GPU_SR),
334         regmap_reg_range(GPC_PGC_DISP_PDN, GPC_PGC_DISP_SR),
335 };
336
337 static const struct regmap_access_table access_table = {
338         .yes_ranges     = yes_ranges,
339         .n_yes_ranges   = ARRAY_SIZE(yes_ranges),
340 };
341
342 static const struct regmap_config imx_gpc_regmap_config = {
343         .reg_bits = 32,
344         .val_bits = 32,
345         .reg_stride = 4,
346         .rd_table = &access_table,
347         .wr_table = &access_table,
348         .max_register = 0x2ac,
349         .fast_io = true,
350 };
351
352 static struct generic_pm_domain *imx_gpc_onecell_domains[] = {
353         &imx_gpc_domains[0].base,
354         &imx_gpc_domains[1].base,
355 };
356
357 static struct genpd_onecell_data imx_gpc_onecell_data = {
358         .domains = imx_gpc_onecell_domains,
359         .num_domains = 2,
360 };
361
362 static int imx_gpc_old_dt_init(struct device *dev, struct regmap *regmap,
363                                unsigned int num_domains)
364 {
365         struct imx_pm_domain *domain;
366         int i, ret;
367
368         for (i = 0; i < num_domains; i++) {
369                 domain = &imx_gpc_domains[i];
370                 domain->regmap = regmap;
371                 domain->ipg_rate_mhz = 66;
372
373                 if (i == 1) {
374                         domain->supply = devm_regulator_get(dev, "pu");
375                         if (IS_ERR(domain->supply))
376                                 return PTR_ERR(domain->supply);
377
378                         ret = imx_pgc_get_clocks(dev, domain);
379                         if (ret)
380                                 goto clk_err;
381
382                         domain->base.power_on(&domain->base);
383                 }
384         }
385
386         for (i = 0; i < num_domains; i++)
387                 pm_genpd_init(&imx_gpc_domains[i].base, NULL, false);
388
389         if (IS_ENABLED(CONFIG_PM_GENERIC_DOMAINS)) {
390                 ret = of_genpd_add_provider_onecell(dev->of_node,
391                                                     &imx_gpc_onecell_data);
392                 if (ret)
393                         goto genpd_err;
394         }
395
396         return 0;
397
398 genpd_err:
399         for (i = 0; i < num_domains; i++)
400                 pm_genpd_remove(&imx_gpc_domains[i].base);
401         imx_pgc_put_clocks(&imx_gpc_domains[GPC_PGC_DOMAIN_PU]);
402 clk_err:
403         return ret;
404 }
405
406 static int imx_gpc_probe(struct platform_device *pdev)
407 {
408         const struct of_device_id *of_id =
409                         of_match_device(imx_gpc_dt_ids, &pdev->dev);
410         const struct imx_gpc_dt_data *of_id_data = of_id->data;
411         struct device_node *pgc_node;
412         struct regmap *regmap;
413         struct resource *res;
414         void __iomem *base;
415         int ret;
416
417         pgc_node = of_get_child_by_name(pdev->dev.of_node, "pgc");
418
419         /* bail out if DT too old and doesn't provide the necessary info */
420         if (!of_property_read_bool(pdev->dev.of_node, "#power-domain-cells") &&
421             !pgc_node)
422                 return 0;
423
424         res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
425         base = devm_ioremap_resource(&pdev->dev, res);
426         if (IS_ERR(base))
427                 return PTR_ERR(base);
428
429         regmap = devm_regmap_init_mmio_clk(&pdev->dev, NULL, base,
430                                            &imx_gpc_regmap_config);
431         if (IS_ERR(regmap)) {
432                 ret = PTR_ERR(regmap);
433                 dev_err(&pdev->dev, "failed to init regmap: %d\n",
434                         ret);
435                 return ret;
436         }
437
438         /* Disable PU power down in normal operation if ERR009619 is present */
439         if (of_id_data->err009619_present)
440                 imx_gpc_domains[GPC_PGC_DOMAIN_PU].base.flags |=
441                                 GENPD_FLAG_ALWAYS_ON;
442
443         /* Keep DISP always on if ERR006287 is present */
444         if (of_id_data->err006287_present)
445                 imx_gpc_domains[GPC_PGC_DOMAIN_DISPLAY].base.flags |=
446                                 GENPD_FLAG_ALWAYS_ON;
447
448         if (!pgc_node) {
449                 ret = imx_gpc_old_dt_init(&pdev->dev, regmap,
450                                           of_id_data->num_domains);
451                 if (ret)
452                         return ret;
453         } else {
454                 struct imx_pm_domain *domain;
455                 struct platform_device *pd_pdev;
456                 struct device_node *np;
457                 struct clk *ipg_clk;
458                 unsigned int ipg_rate_mhz;
459                 int domain_index;
460
461                 ipg_clk = devm_clk_get(&pdev->dev, "ipg");
462                 if (IS_ERR(ipg_clk))
463                         return PTR_ERR(ipg_clk);
464                 ipg_rate_mhz = clk_get_rate(ipg_clk) / 1000000;
465
466                 for_each_child_of_node(pgc_node, np) {
467                         ret = of_property_read_u32(np, "reg", &domain_index);
468                         if (ret) {
469                                 of_node_put(np);
470                                 return ret;
471                         }
472                         if (domain_index >= of_id_data->num_domains)
473                                 continue;
474
475                         pd_pdev = platform_device_alloc("imx-pgc-power-domain",
476                                                         domain_index);
477                         if (!pd_pdev) {
478                                 of_node_put(np);
479                                 return -ENOMEM;
480                         }
481
482                         ret = platform_device_add_data(pd_pdev,
483                                                        &imx_gpc_domains[domain_index],
484                                                        sizeof(imx_gpc_domains[domain_index]));
485                         if (ret) {
486                                 platform_device_put(pd_pdev);
487                                 of_node_put(np);
488                                 return ret;
489                         }
490                         domain = pd_pdev->dev.platform_data;
491                         domain->regmap = regmap;
492                         domain->ipg_rate_mhz = ipg_rate_mhz;
493
494                         pd_pdev->dev.parent = &pdev->dev;
495                         pd_pdev->dev.of_node = np;
496
497                         ret = platform_device_add(pd_pdev);
498                         if (ret) {
499                                 platform_device_put(pd_pdev);
500                                 of_node_put(np);
501                                 return ret;
502                         }
503                 }
504         }
505
506         return 0;
507 }
508
509 static int imx_gpc_remove(struct platform_device *pdev)
510 {
511         struct device_node *pgc_node;
512         int ret;
513
514         pgc_node = of_get_child_by_name(pdev->dev.of_node, "pgc");
515
516         /* bail out if DT too old and doesn't provide the necessary info */
517         if (!of_property_read_bool(pdev->dev.of_node, "#power-domain-cells") &&
518             !pgc_node)
519                 return 0;
520
521         /*
522          * If the old DT binding is used the toplevel driver needs to
523          * de-register the power domains
524          */
525         if (!pgc_node) {
526                 of_genpd_del_provider(pdev->dev.of_node);
527
528                 ret = pm_genpd_remove(&imx_gpc_domains[GPC_PGC_DOMAIN_PU].base);
529                 if (ret)
530                         return ret;
531                 imx_pgc_put_clocks(&imx_gpc_domains[GPC_PGC_DOMAIN_PU]);
532
533                 ret = pm_genpd_remove(&imx_gpc_domains[GPC_PGC_DOMAIN_ARM].base);
534                 if (ret)
535                         return ret;
536         }
537
538         return 0;
539 }
540
541 static struct platform_driver imx_gpc_driver = {
542         .driver = {
543                 .name = "imx-gpc",
544                 .of_match_table = imx_gpc_dt_ids,
545         },
546         .probe = imx_gpc_probe,
547         .remove = imx_gpc_remove,
548 };
549 builtin_platform_driver(imx_gpc_driver)