rk3368: io-domain: sync with upstream to add REGULATOR_EVENT_PRE_VOLTAGE_CHANGE
[firefly-linux-kernel-4.4.55.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 RK3368_GRF_SOC_CON15                    0x43c
47 #define RK3368_GRF_SOC_CON15_FLASH0             BIT(14)
48 #define RK3368_SOC_FLASH_SUPPLY_NUM     2
49
50
51 struct rockchip_iodomain;
52
53 /**
54  * @supplies: voltage settings matching the register bits.
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         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_info(supply->iod->dev, "Setting to %d done\n", uV);
144         return NOTIFY_OK;
145 }
146
147 static void rk3288_iodomain_init(struct rockchip_iodomain *iod)
148 {
149         int ret;
150         u32 val;
151
152         /* if no flash supply we should leave things alone */
153         if (!iod->supplies[RK3288_SOC_FLASH_SUPPLY_NUM].reg)
154                 return;
155
156         /*
157          * set flash0 iodomain to also use this framework
158          * instead of a special gpio.
159          */
160         val = RK3288_SOC_CON2_FLASH0 | (RK3288_SOC_CON2_FLASH0 << 16);
161         ret = regmap_write(iod->grf, RK3288_SOC_CON2, val);
162         if (ret < 0)
163                 dev_warn(iod->dev, "couldn't update flash0 ctrl\n");
164 }
165
166 static void rk3368_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[RK3368_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 = RK3368_GRF_SOC_CON15_FLASH0 | (RK3368_GRF_SOC_CON15_FLASH0 << 16);
180         ret = regmap_write(iod->grf, RK3368_GRF_SOC_CON15, val);
181         if (ret < 0)
182                 dev_warn(iod->dev, "couldn't update flash0 ctrl\n");
183 }
184
185
186 /*
187  * On the rk3188 the io-domains are handled by a shared register with the
188  * lower 8 bits being still being continuing drive-strength settings.
189  */
190 static const struct rockchip_iodomain_soc_data soc_data_rk3188 = {
191         .grf_offset = 0x104,
192         .supply_names = {
193                 NULL,
194                 NULL,
195                 NULL,
196                 NULL,
197                 NULL,
198                 NULL,
199                 NULL,
200                 NULL,
201                 "ap0",
202                 "ap1",
203                 "cif",
204                 "flash",
205                 "vccio0",
206                 "vccio1",
207                 "lcdc0",
208                 "lcdc1",
209         },
210 };
211
212 static const struct rockchip_iodomain_soc_data soc_data_rk3288 = {
213         .grf_offset = 0x380,
214         .supply_names = {
215                 "lcdc",         /* LCDC_VDD */
216                 "dvp",          /* DVPIO_VDD */
217                 "flash0",       /* FLASH0_VDD (emmc) */
218                 "flash1",       /* FLASH1_VDD (sdio1) */
219                 "wifi",         /* APIO3_VDD  (sdio0) */
220                 "bb",           /* APIO5_VDD */
221                 "audio",        /* APIO4_VDD */
222                 "sdcard",       /* SDMMC0_VDD (sdmmc) */
223                 "gpio30",       /* APIO1_VDD */
224                 "gpio1830",     /* APIO2_VDD */
225         },
226         .init = rk3288_iodomain_init,
227 };
228
229 static const struct rockchip_iodomain_soc_data soc_data_rk3368 = {
230         .grf_offset = 0x900,
231         .supply_names = {
232                 NULL,
233                 "dvp_v18sel",           /*DVP IO domain*/
234                 "flash0_v18sel",                /*FLASH0 IO domain*/
235                 "wifi_v18sel",  /*WIFI IO domain*/
236                 NULL,
237                 "audio_v18sel", /*AUDIO IO domain*/
238                 "sdcard_v18sel",                /*SDCARD IO domain*/
239                 "gpio30_v18sel",                /*GPIO30 IO domain*/
240                 "gpio1830_v18sel",      /*GPIO1830 IO domain*/
241         },
242         .init = rk3368_iodomain_init,
243 };
244
245
246 static const struct of_device_id rockchip_iodomain_match[] = {
247         {
248                 .compatible = "rockchip,rk3188-io-voltage-domain",
249                 .data = (void *)&soc_data_rk3188
250         },
251         {
252                 .compatible = "rockchip,rk3288-io-voltage-domain",
253                 .data = (void *)&soc_data_rk3288
254         },
255         {
256                 .compatible = "rockchip,rk3368-io-voltage-domain",
257                 .data = (void *)&soc_data_rk3368
258         },
259         { /* sentinel */ },
260 };
261
262 static int rockchip_iodomain_probe(struct platform_device *pdev)
263 {
264         struct device_node *np = pdev->dev.of_node;
265         const struct of_device_id *match;
266         struct rockchip_iodomain *iod;
267         int i, ret = 0;
268
269         if (!np)
270                 return -ENODEV;
271
272         iod = devm_kzalloc(&pdev->dev, sizeof(*iod), GFP_KERNEL);
273         if (!iod)
274                 return -ENOMEM;
275
276         iod->dev = &pdev->dev;
277         platform_set_drvdata(pdev, iod);
278
279         match = of_match_node(rockchip_iodomain_match, np);
280         iod->soc_data = (struct rockchip_iodomain_soc_data *)match->data;
281
282         iod->grf = syscon_regmap_lookup_by_phandle(np, "rockchip,grf");
283         if (IS_ERR(iod->grf)) {
284                 dev_err(&pdev->dev, "couldn't find grf regmap\n");
285                 return PTR_ERR(iod->grf);
286         }
287
288         for (i = 0; i < MAX_SUPPLIES; i++) {
289                 const char *supply_name = iod->soc_data->supply_names[i];
290                 struct rockchip_iodomain_supply *supply = &iod->supplies[i];
291                 struct regulator *reg;
292                 int uV;
293                 const char *regulator_name = NULL;
294
295                 if (!supply_name)
296                         continue;
297
298                 of_property_read_string(np, supply_name, &regulator_name);
299                 if (!regulator_name)
300                         continue;
301
302                 reg = regulator_get(NULL, regulator_name);
303                 if (IS_ERR(reg)) {
304                         ret = PTR_ERR(reg);
305
306                         /* If a supply wasn't specified, that's OK */
307                         if (ret == -ENODEV)
308                                 continue;
309                         else if (ret != -EPROBE_DEFER)
310                                 dev_err(iod->dev, "couldn't get regulator %s\n",
311                                         supply_name);
312                         goto unreg_notify;
313                 }
314
315                 /* set initial correct value */
316                 uV = regulator_get_voltage(reg);
317
318                 /* must be a regulator we can get the voltage of */
319                 if (uV < 0) {
320                         dev_err(iod->dev, "Can't determine voltage: %s\n",
321                                 supply_name);
322                         goto unreg_notify;
323                 }
324
325                 if (uV > MAX_VOLTAGE_3_3) {
326                         dev_crit(iod->dev,
327                                  "%d uV is too high. May damage SoC!\n",
328                                  uV);
329                         ret = -EINVAL;
330                         goto unreg_notify;
331                 }
332
333                 /* setup our supply */
334                 supply->idx = i;
335                 supply->iod = iod;
336                 supply->reg = reg;
337                 supply->nb.notifier_call = rockchip_iodomain_notify;
338
339                 ret = rockchip_iodomain_write(supply, uV);
340                 if (ret) {
341                         supply->reg = NULL;
342                         goto unreg_notify;
343                 }
344
345                 /* register regulator notifier */
346                 ret = regulator_register_notifier(reg, &supply->nb);
347                 if (ret) {
348                         dev_err(&pdev->dev,
349                                 "regulator notifier request failed\n");
350                         supply->reg = NULL;
351                         goto unreg_notify;
352                 }
353         }
354
355         if (iod->soc_data->init)
356                 iod->soc_data->init(iod);
357
358         return 0;
359
360 unreg_notify:
361         for (i = MAX_SUPPLIES - 1; i >= 0; i--) {
362                 struct rockchip_iodomain_supply *io_supply = &iod->supplies[i];
363
364                 if (io_supply->reg)
365                         regulator_unregister_notifier(io_supply->reg,
366                                                       &io_supply->nb);
367         }
368
369         return ret;
370 }
371
372 static int rockchip_iodomain_remove(struct platform_device *pdev)
373 {
374         struct rockchip_iodomain *iod = platform_get_drvdata(pdev);
375         int i;
376
377         for (i = MAX_SUPPLIES - 1; i >= 0; i--) {
378                 struct rockchip_iodomain_supply *io_supply = &iod->supplies[i];
379
380                 if (io_supply->reg)
381                         regulator_unregister_notifier(io_supply->reg,
382                                                       &io_supply->nb);
383         }
384
385         return 0;
386 }
387
388 static struct platform_driver rockchip_iodomain_driver = {
389         .probe   = rockchip_iodomain_probe,
390         .remove  = rockchip_iodomain_remove,
391         .driver  = {
392                 .name  = "rockchip-iodomain",
393                 .of_match_table = rockchip_iodomain_match,
394         },
395 };
396
397 module_platform_driver(rockchip_iodomain_driver);
398
399 MODULE_DESCRIPTION("Rockchip IO-domain driver");
400 MODULE_AUTHOR("Heiko Stuebner <heiko@sntech.de>");
401 MODULE_AUTHOR("Doug Anderson <dianders@chromium.org>");
402 MODULE_LICENSE("GPL v2");