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