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