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