Merge tag 'soc-5.15' of git://git.kernel.org/pub/scm/linux/kernel/git/soc/soc
[linux-2.6-microblaze.git] / drivers / soc / rockchip / io-domain.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Rockchip IO Voltage Domain driver
4  *
5  * Copyright 2014 MundoReader S.L.
6  * Copyright 2014 Google, Inc.
7  */
8
9 #include <linux/kernel.h>
10 #include <linux/module.h>
11 #include <linux/err.h>
12 #include <linux/mfd/syscon.h>
13 #include <linux/of.h>
14 #include <linux/platform_device.h>
15 #include <linux/regmap.h>
16 #include <linux/regulator/consumer.h>
17
18 #define MAX_SUPPLIES            16
19
20 /*
21  * The max voltage for 1.8V and 3.3V come from the Rockchip datasheet under
22  * "Recommended Operating Conditions" for "Digital GPIO".   When the typical
23  * is 3.3V the max is 3.6V.  When the typical is 1.8V the max is 1.98V.
24  *
25  * They are used like this:
26  * - If the voltage on a rail is above the "1.8" voltage (1.98V) we'll tell the
27  *   SoC we're at 3.3.
28  * - If the voltage on a rail is above the "3.3" voltage (3.6V) we'll consider
29  *   that to be an error.
30  */
31 #define MAX_VOLTAGE_1_8         1980000
32 #define MAX_VOLTAGE_3_3         3600000
33
34 #define PX30_IO_VSEL                    0x180
35 #define PX30_IO_VSEL_VCCIO6_SRC         BIT(0)
36 #define PX30_IO_VSEL_VCCIO6_SUPPLY_NUM  1
37
38 #define RK3288_SOC_CON2                 0x24c
39 #define RK3288_SOC_CON2_FLASH0          BIT(7)
40 #define RK3288_SOC_FLASH_SUPPLY_NUM     2
41
42 #define RK3328_SOC_CON4                 0x410
43 #define RK3328_SOC_CON4_VCCIO2          BIT(7)
44 #define RK3328_SOC_VCCIO2_SUPPLY_NUM    1
45
46 #define RK3368_SOC_CON15                0x43c
47 #define RK3368_SOC_CON15_FLASH0         BIT(14)
48 #define RK3368_SOC_FLASH_SUPPLY_NUM     2
49
50 #define RK3399_PMUGRF_CON0              0x180
51 #define RK3399_PMUGRF_CON0_VSEL         BIT(8)
52 #define RK3399_PMUGRF_VSEL_SUPPLY_NUM   9
53
54 struct rockchip_iodomain;
55
56 struct rockchip_iodomain_soc_data {
57         int grf_offset;
58         const char *supply_names[MAX_SUPPLIES];
59         void (*init)(struct rockchip_iodomain *iod);
60 };
61
62 struct rockchip_iodomain_supply {
63         struct rockchip_iodomain *iod;
64         struct regulator *reg;
65         struct notifier_block nb;
66         int idx;
67 };
68
69 struct rockchip_iodomain {
70         struct device *dev;
71         struct regmap *grf;
72         const struct rockchip_iodomain_soc_data *soc_data;
73         struct rockchip_iodomain_supply supplies[MAX_SUPPLIES];
74 };
75
76 static int rockchip_iodomain_write(struct rockchip_iodomain_supply *supply,
77                                    int uV)
78 {
79         struct rockchip_iodomain *iod = supply->iod;
80         u32 val;
81         int ret;
82
83         /* set value bit */
84         val = (uV > MAX_VOLTAGE_1_8) ? 0 : 1;
85         val <<= supply->idx;
86
87         /* apply hiword-mask */
88         val |= (BIT(supply->idx) << 16);
89
90         ret = regmap_write(iod->grf, iod->soc_data->grf_offset, val);
91         if (ret)
92                 dev_err(iod->dev, "Couldn't write to GRF\n");
93
94         return ret;
95 }
96
97 static int rockchip_iodomain_notify(struct notifier_block *nb,
98                                     unsigned long event,
99                                     void *data)
100 {
101         struct rockchip_iodomain_supply *supply =
102                         container_of(nb, struct rockchip_iodomain_supply, nb);
103         int uV;
104         int ret;
105
106         /*
107          * According to Rockchip it's important to keep the SoC IO domain
108          * higher than (or equal to) the external voltage.  That means we need
109          * to change it before external voltage changes happen in the case
110          * of an increase.
111          *
112          * Note that in the "pre" change we pick the max possible voltage that
113          * the regulator might end up at (the client requests a range and we
114          * don't know for certain the exact voltage).  Right now we rely on the
115          * slop in MAX_VOLTAGE_1_8 and MAX_VOLTAGE_3_3 to save us if clients
116          * request something like a max of 3.6V when they really want 3.3V.
117          * We could attempt to come up with better rules if this fails.
118          */
119         if (event & REGULATOR_EVENT_PRE_VOLTAGE_CHANGE) {
120                 struct pre_voltage_change_data *pvc_data = data;
121
122                 uV = max_t(unsigned long, pvc_data->old_uV, pvc_data->max_uV);
123         } else if (event & (REGULATOR_EVENT_VOLTAGE_CHANGE |
124                             REGULATOR_EVENT_ABORT_VOLTAGE_CHANGE)) {
125                 uV = (unsigned long)data;
126         } else {
127                 return NOTIFY_OK;
128         }
129
130         dev_dbg(supply->iod->dev, "Setting to %d\n", uV);
131
132         if (uV > MAX_VOLTAGE_3_3) {
133                 dev_err(supply->iod->dev, "Voltage too high: %d\n", uV);
134
135                 if (event == REGULATOR_EVENT_PRE_VOLTAGE_CHANGE)
136                         return NOTIFY_BAD;
137         }
138
139         ret = rockchip_iodomain_write(supply, uV);
140         if (ret && event == REGULATOR_EVENT_PRE_VOLTAGE_CHANGE)
141                 return NOTIFY_BAD;
142
143         dev_dbg(supply->iod->dev, "Setting to %d done\n", uV);
144         return NOTIFY_OK;
145 }
146
147 static void px30_iodomain_init(struct rockchip_iodomain *iod)
148 {
149         int ret;
150         u32 val;
151
152         /* if no VCCIO6 supply we should leave things alone */
153         if (!iod->supplies[PX30_IO_VSEL_VCCIO6_SUPPLY_NUM].reg)
154                 return;
155
156         /*
157          * set vccio6 iodomain to also use this framework
158          * instead of a special gpio.
159          */
160         val = PX30_IO_VSEL_VCCIO6_SRC | (PX30_IO_VSEL_VCCIO6_SRC << 16);
161         ret = regmap_write(iod->grf, PX30_IO_VSEL, val);
162         if (ret < 0)
163                 dev_warn(iod->dev, "couldn't update vccio6 ctrl\n");
164 }
165
166 static void rk3288_iodomain_init(struct rockchip_iodomain *iod)
167 {
168         int ret;
169         u32 val;
170
171         /* if no flash supply we should leave things alone */
172         if (!iod->supplies[RK3288_SOC_FLASH_SUPPLY_NUM].reg)
173                 return;
174
175         /*
176          * set flash0 iodomain to also use this framework
177          * instead of a special gpio.
178          */
179         val = RK3288_SOC_CON2_FLASH0 | (RK3288_SOC_CON2_FLASH0 << 16);
180         ret = regmap_write(iod->grf, RK3288_SOC_CON2, val);
181         if (ret < 0)
182                 dev_warn(iod->dev, "couldn't update flash0 ctrl\n");
183 }
184
185 static void rk3328_iodomain_init(struct rockchip_iodomain *iod)
186 {
187         int ret;
188         u32 val;
189
190         /* if no vccio2 supply we should leave things alone */
191         if (!iod->supplies[RK3328_SOC_VCCIO2_SUPPLY_NUM].reg)
192                 return;
193
194         /*
195          * set vccio2 iodomain to also use this framework
196          * instead of a special gpio.
197          */
198         val = RK3328_SOC_CON4_VCCIO2 | (RK3328_SOC_CON4_VCCIO2 << 16);
199         ret = regmap_write(iod->grf, RK3328_SOC_CON4, val);
200         if (ret < 0)
201                 dev_warn(iod->dev, "couldn't update vccio2 vsel ctrl\n");
202 }
203
204 static void rk3368_iodomain_init(struct rockchip_iodomain *iod)
205 {
206         int ret;
207         u32 val;
208
209         /* if no flash supply we should leave things alone */
210         if (!iod->supplies[RK3368_SOC_FLASH_SUPPLY_NUM].reg)
211                 return;
212
213         /*
214          * set flash0 iodomain to also use this framework
215          * instead of a special gpio.
216          */
217         val = RK3368_SOC_CON15_FLASH0 | (RK3368_SOC_CON15_FLASH0 << 16);
218         ret = regmap_write(iod->grf, RK3368_SOC_CON15, val);
219         if (ret < 0)
220                 dev_warn(iod->dev, "couldn't update flash0 ctrl\n");
221 }
222
223 static void rk3399_pmu_iodomain_init(struct rockchip_iodomain *iod)
224 {
225         int ret;
226         u32 val;
227
228         /* if no pmu io supply we should leave things alone */
229         if (!iod->supplies[RK3399_PMUGRF_VSEL_SUPPLY_NUM].reg)
230                 return;
231
232         /*
233          * set pmu io iodomain to also use this framework
234          * instead of a special gpio.
235          */
236         val = RK3399_PMUGRF_CON0_VSEL | (RK3399_PMUGRF_CON0_VSEL << 16);
237         ret = regmap_write(iod->grf, RK3399_PMUGRF_CON0, val);
238         if (ret < 0)
239                 dev_warn(iod->dev, "couldn't update pmu io iodomain ctrl\n");
240 }
241
242 static const struct rockchip_iodomain_soc_data soc_data_px30 = {
243         .grf_offset = 0x180,
244         .supply_names = {
245                 NULL,
246                 "vccio6",
247                 "vccio1",
248                 "vccio2",
249                 "vccio3",
250                 "vccio4",
251                 "vccio5",
252                 "vccio-oscgpi",
253         },
254         .init = px30_iodomain_init,
255 };
256
257 static const struct rockchip_iodomain_soc_data soc_data_px30_pmu = {
258         .grf_offset = 0x100,
259         .supply_names = {
260                 NULL,
261                 NULL,
262                 NULL,
263                 NULL,
264                 NULL,
265                 NULL,
266                 NULL,
267                 NULL,
268                 NULL,
269                 NULL,
270                 NULL,
271                 NULL,
272                 NULL,
273                 NULL,
274                 "pmuio1",
275                 "pmuio2",
276         },
277 };
278
279 /*
280  * On the rk3188 the io-domains are handled by a shared register with the
281  * lower 8 bits being still being continuing drive-strength settings.
282  */
283 static const struct rockchip_iodomain_soc_data soc_data_rk3188 = {
284         .grf_offset = 0x104,
285         .supply_names = {
286                 NULL,
287                 NULL,
288                 NULL,
289                 NULL,
290                 NULL,
291                 NULL,
292                 NULL,
293                 NULL,
294                 "ap0",
295                 "ap1",
296                 "cif",
297                 "flash",
298                 "vccio0",
299                 "vccio1",
300                 "lcdc0",
301                 "lcdc1",
302         },
303 };
304
305 static const struct rockchip_iodomain_soc_data soc_data_rk3228 = {
306         .grf_offset = 0x418,
307         .supply_names = {
308                 "vccio1",
309                 "vccio2",
310                 "vccio3",
311                 "vccio4",
312         },
313 };
314
315 static const struct rockchip_iodomain_soc_data soc_data_rk3288 = {
316         .grf_offset = 0x380,
317         .supply_names = {
318                 "lcdc",         /* LCDC_VDD */
319                 "dvp",          /* DVPIO_VDD */
320                 "flash0",       /* FLASH0_VDD (emmc) */
321                 "flash1",       /* FLASH1_VDD (sdio1) */
322                 "wifi",         /* APIO3_VDD  (sdio0) */
323                 "bb",           /* APIO5_VDD */
324                 "audio",        /* APIO4_VDD */
325                 "sdcard",       /* SDMMC0_VDD (sdmmc) */
326                 "gpio30",       /* APIO1_VDD */
327                 "gpio1830",     /* APIO2_VDD */
328         },
329         .init = rk3288_iodomain_init,
330 };
331
332 static const struct rockchip_iodomain_soc_data soc_data_rk3328 = {
333         .grf_offset = 0x410,
334         .supply_names = {
335                 "vccio1",
336                 "vccio2",
337                 "vccio3",
338                 "vccio4",
339                 "vccio5",
340                 "vccio6",
341                 "pmuio",
342         },
343         .init = rk3328_iodomain_init,
344 };
345
346 static const struct rockchip_iodomain_soc_data soc_data_rk3368 = {
347         .grf_offset = 0x900,
348         .supply_names = {
349                 NULL,           /* reserved */
350                 "dvp",          /* DVPIO_VDD */
351                 "flash0",       /* FLASH0_VDD (emmc) */
352                 "wifi",         /* APIO2_VDD (sdio0) */
353                 NULL,
354                 "audio",        /* APIO3_VDD */
355                 "sdcard",       /* SDMMC0_VDD (sdmmc) */
356                 "gpio30",       /* APIO1_VDD */
357                 "gpio1830",     /* APIO4_VDD (gpujtag) */
358         },
359         .init = rk3368_iodomain_init,
360 };
361
362 static const struct rockchip_iodomain_soc_data soc_data_rk3368_pmu = {
363         .grf_offset = 0x100,
364         .supply_names = {
365                 NULL,
366                 NULL,
367                 NULL,
368                 NULL,
369                 "pmu",          /*PMU IO domain*/
370                 "vop",          /*LCDC IO domain*/
371         },
372 };
373
374 static const struct rockchip_iodomain_soc_data soc_data_rk3399 = {
375         .grf_offset = 0xe640,
376         .supply_names = {
377                 "bt656",                /* APIO2_VDD */
378                 "audio",                /* APIO5_VDD */
379                 "sdmmc",                /* SDMMC0_VDD */
380                 "gpio1830",             /* APIO4_VDD */
381         },
382 };
383
384 static const struct rockchip_iodomain_soc_data soc_data_rk3399_pmu = {
385         .grf_offset = 0x180,
386         .supply_names = {
387                 NULL,
388                 NULL,
389                 NULL,
390                 NULL,
391                 NULL,
392                 NULL,
393                 NULL,
394                 NULL,
395                 NULL,
396                 "pmu1830",              /* PMUIO2_VDD */
397         },
398         .init = rk3399_pmu_iodomain_init,
399 };
400
401 static const struct rockchip_iodomain_soc_data soc_data_rv1108 = {
402         .grf_offset = 0x404,
403         .supply_names = {
404                 NULL,
405                 NULL,
406                 NULL,
407                 NULL,
408                 NULL,
409                 NULL,
410                 NULL,
411                 NULL,
412                 NULL,
413                 NULL,
414                 NULL,
415                 "vccio1",
416                 "vccio2",
417                 "vccio3",
418                 "vccio5",
419                 "vccio6",
420         },
421
422 };
423
424 static const struct rockchip_iodomain_soc_data soc_data_rv1108_pmu = {
425         .grf_offset = 0x104,
426         .supply_names = {
427                 "pmu",
428         },
429 };
430
431 static const struct of_device_id rockchip_iodomain_match[] = {
432         {
433                 .compatible = "rockchip,px30-io-voltage-domain",
434                 .data = (void *)&soc_data_px30
435         },
436         {
437                 .compatible = "rockchip,px30-pmu-io-voltage-domain",
438                 .data = (void *)&soc_data_px30_pmu
439         },
440         {
441                 .compatible = "rockchip,rk3188-io-voltage-domain",
442                 .data = &soc_data_rk3188
443         },
444         {
445                 .compatible = "rockchip,rk3228-io-voltage-domain",
446                 .data = &soc_data_rk3228
447         },
448         {
449                 .compatible = "rockchip,rk3288-io-voltage-domain",
450                 .data = &soc_data_rk3288
451         },
452         {
453                 .compatible = "rockchip,rk3328-io-voltage-domain",
454                 .data = &soc_data_rk3328
455         },
456         {
457                 .compatible = "rockchip,rk3368-io-voltage-domain",
458                 .data = &soc_data_rk3368
459         },
460         {
461                 .compatible = "rockchip,rk3368-pmu-io-voltage-domain",
462                 .data = &soc_data_rk3368_pmu
463         },
464         {
465                 .compatible = "rockchip,rk3399-io-voltage-domain",
466                 .data = &soc_data_rk3399
467         },
468         {
469                 .compatible = "rockchip,rk3399-pmu-io-voltage-domain",
470                 .data = &soc_data_rk3399_pmu
471         },
472         {
473                 .compatible = "rockchip,rv1108-io-voltage-domain",
474                 .data = &soc_data_rv1108
475         },
476         {
477                 .compatible = "rockchip,rv1108-pmu-io-voltage-domain",
478                 .data = &soc_data_rv1108_pmu
479         },
480         { /* sentinel */ },
481 };
482 MODULE_DEVICE_TABLE(of, rockchip_iodomain_match);
483
484 static int rockchip_iodomain_probe(struct platform_device *pdev)
485 {
486         struct device_node *np = pdev->dev.of_node;
487         const struct of_device_id *match;
488         struct rockchip_iodomain *iod;
489         struct device *parent;
490         int i, ret = 0;
491
492         if (!np)
493                 return -ENODEV;
494
495         iod = devm_kzalloc(&pdev->dev, sizeof(*iod), GFP_KERNEL);
496         if (!iod)
497                 return -ENOMEM;
498
499         iod->dev = &pdev->dev;
500         platform_set_drvdata(pdev, iod);
501
502         match = of_match_node(rockchip_iodomain_match, np);
503         iod->soc_data = match->data;
504
505         parent = pdev->dev.parent;
506         if (parent && parent->of_node) {
507                 iod->grf = syscon_node_to_regmap(parent->of_node);
508         } else {
509                 dev_dbg(&pdev->dev, "falling back to old binding\n");
510                 iod->grf = syscon_regmap_lookup_by_phandle(np, "rockchip,grf");
511         }
512
513         if (IS_ERR(iod->grf)) {
514                 dev_err(&pdev->dev, "couldn't find grf regmap\n");
515                 return PTR_ERR(iod->grf);
516         }
517
518         for (i = 0; i < MAX_SUPPLIES; i++) {
519                 const char *supply_name = iod->soc_data->supply_names[i];
520                 struct rockchip_iodomain_supply *supply = &iod->supplies[i];
521                 struct regulator *reg;
522                 int uV;
523
524                 if (!supply_name)
525                         continue;
526
527                 reg = devm_regulator_get_optional(iod->dev, supply_name);
528                 if (IS_ERR(reg)) {
529                         ret = PTR_ERR(reg);
530
531                         /* If a supply wasn't specified, that's OK */
532                         if (ret == -ENODEV)
533                                 continue;
534                         else if (ret != -EPROBE_DEFER)
535                                 dev_err(iod->dev, "couldn't get regulator %s\n",
536                                         supply_name);
537                         goto unreg_notify;
538                 }
539
540                 /* set initial correct value */
541                 uV = regulator_get_voltage(reg);
542
543                 /* must be a regulator we can get the voltage of */
544                 if (uV < 0) {
545                         dev_err(iod->dev, "Can't determine voltage: %s\n",
546                                 supply_name);
547                         ret = uV;
548                         goto unreg_notify;
549                 }
550
551                 if (uV > MAX_VOLTAGE_3_3) {
552                         dev_crit(iod->dev,
553                                  "%d uV is too high. May damage SoC!\n",
554                                  uV);
555                         ret = -EINVAL;
556                         goto unreg_notify;
557                 }
558
559                 /* setup our supply */
560                 supply->idx = i;
561                 supply->iod = iod;
562                 supply->reg = reg;
563                 supply->nb.notifier_call = rockchip_iodomain_notify;
564
565                 ret = rockchip_iodomain_write(supply, uV);
566                 if (ret) {
567                         supply->reg = NULL;
568                         goto unreg_notify;
569                 }
570
571                 /* register regulator notifier */
572                 ret = regulator_register_notifier(reg, &supply->nb);
573                 if (ret) {
574                         dev_err(&pdev->dev,
575                                 "regulator notifier request failed\n");
576                         supply->reg = NULL;
577                         goto unreg_notify;
578                 }
579         }
580
581         if (iod->soc_data->init)
582                 iod->soc_data->init(iod);
583
584         return 0;
585
586 unreg_notify:
587         for (i = MAX_SUPPLIES - 1; i >= 0; i--) {
588                 struct rockchip_iodomain_supply *io_supply = &iod->supplies[i];
589
590                 if (io_supply->reg)
591                         regulator_unregister_notifier(io_supply->reg,
592                                                       &io_supply->nb);
593         }
594
595         return ret;
596 }
597
598 static int rockchip_iodomain_remove(struct platform_device *pdev)
599 {
600         struct rockchip_iodomain *iod = platform_get_drvdata(pdev);
601         int i;
602
603         for (i = MAX_SUPPLIES - 1; i >= 0; i--) {
604                 struct rockchip_iodomain_supply *io_supply = &iod->supplies[i];
605
606                 if (io_supply->reg)
607                         regulator_unregister_notifier(io_supply->reg,
608                                                       &io_supply->nb);
609         }
610
611         return 0;
612 }
613
614 static struct platform_driver rockchip_iodomain_driver = {
615         .probe   = rockchip_iodomain_probe,
616         .remove  = rockchip_iodomain_remove,
617         .driver  = {
618                 .name  = "rockchip-iodomain",
619                 .of_match_table = rockchip_iodomain_match,
620         },
621 };
622
623 module_platform_driver(rockchip_iodomain_driver);
624
625 MODULE_DESCRIPTION("Rockchip IO-domain driver");
626 MODULE_AUTHOR("Heiko Stuebner <heiko@sntech.de>");
627 MODULE_AUTHOR("Doug Anderson <dianders@chromium.org>");
628 MODULE_LICENSE("GPL v2");