tve:rk1000: set default cvbd mode to PAL.
[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 #define MAX_ROCKCHIP_GRF_NUM        2
51
52 struct rockchip_iodomain;
53
54 /**
55  * @supplies: voltage settings matching the register bits.
56  */
57
58 enum rockchip_iodomain_grf_type {
59         GRF,
60         PMU_GRF,
61 };
62
63 struct rockchip_iodomain_soc_data {
64         int grf_offset;
65         int pmugrf_offset;
66         const char *grf_supply_names[MAX_SUPPLIES];
67         const char *pmugrf_supply_names[MAX_SUPPLIES];
68         void (*init)(struct rockchip_iodomain *iod);
69 };
70
71 struct rockchip_iodomain_supply {
72         struct rockchip_iodomain *iod;
73         struct regulator *reg;
74         struct notifier_block nb;
75         int idx;
76         enum rockchip_iodomain_grf_type type;
77 };
78
79 struct rockchip_iodomain {
80         struct device *dev;
81         struct regmap *grf;
82         struct regmap *pmu;
83         struct rockchip_iodomain_soc_data *soc_data;
84         struct rockchip_iodomain_supply grf_supplies[MAX_SUPPLIES];
85         struct rockchip_iodomain_supply pmugrf_supplies[MAX_SUPPLIES];
86 };
87
88 static int rockchip_iodomain_write(struct rockchip_iodomain_supply *supply,
89                                    int uV)
90 {
91         struct rockchip_iodomain *iod = supply->iod;
92         struct regmap *reg;
93         int offset;
94         u32 val;
95         int ret;
96
97         /* set value bit */
98         val = (uV > MAX_VOLTAGE_1_8) ? 0 : 1;
99         val <<= supply->idx;
100
101         /* apply hiword-mask */
102         val |= (BIT(supply->idx) << 16);
103
104         if (supply->type == GRF) {
105                 reg = iod->grf;
106                 offset = iod->soc_data->grf_offset;
107         } else if (supply->type == PMU_GRF) {
108                 reg = iod->pmu;
109                 offset = iod->soc_data->pmugrf_offset;
110         }
111
112         ret = regmap_write(reg, offset, val);
113         if (ret)
114                 dev_err(iod->dev, "Couldn't write to GRF\n");
115
116         return ret;
117 }
118
119 static int rockchip_iodomain_notify(struct notifier_block *nb,
120                                     unsigned long event,
121                                     void *data)
122 {
123         struct rockchip_iodomain_supply *supply =
124                         container_of(nb, struct rockchip_iodomain_supply, nb);
125         int uV;
126         int ret;
127
128         /*
129          * According to Rockchip it's important to keep the SoC IO domain
130          * higher than (or equal to) the external voltage.  That means we need
131          * to change it before external voltage changes happen in the case
132          * of an increase.
133          *
134          * Note that in the "pre" change we pick the max possible voltage that
135          * the regulator might end up at (the client requests a range and we
136          * don't know for certain the exact voltage).  Right now we rely on the
137          * slop in MAX_VOLTAGE_1_8 and MAX_VOLTAGE_3_3 to save us if clients
138          * request something like a max of 3.6V when they really want 3.3V.
139          * We could attempt to come up with better rules if this fails.
140          */
141         if (event & REGULATOR_EVENT_PRE_VOLTAGE_CHANGE) {
142                 struct pre_voltage_change_data *pvc_data = data;
143
144                 uV = max_t(unsigned long, pvc_data->old_uV, pvc_data->max_uV);
145         } else if (event & (REGULATOR_EVENT_VOLTAGE_CHANGE |
146                             REGULATOR_EVENT_ABORT_VOLTAGE_CHANGE)) {
147                 uV = (unsigned long)data;
148         } else {
149                 return NOTIFY_OK;
150         }
151
152         dev_dbg(supply->iod->dev, "Setting to %d\n", uV);
153
154         if (uV > MAX_VOLTAGE_3_3) {
155                 dev_err(supply->iod->dev, "Voltage too high: %d\n", uV);
156
157                 if (event == REGULATOR_EVENT_PRE_VOLTAGE_CHANGE)
158                         return NOTIFY_BAD;
159         }
160
161         ret = rockchip_iodomain_write(supply, uV);
162         if (ret && event == REGULATOR_EVENT_PRE_VOLTAGE_CHANGE)
163                 return NOTIFY_BAD;
164
165         dev_info(supply->iod->dev, "Setting to %d done\n", uV);
166         return NOTIFY_OK;
167 }
168
169 static void rk3288_iodomain_init(struct rockchip_iodomain *iod)
170 {
171         int ret;
172         u32 val;
173
174         /* if no flash supply we should leave things alone */
175         if (!iod->grf_supplies[RK3288_SOC_FLASH_SUPPLY_NUM].reg)
176                 return;
177
178         /*
179          * set flash0 iodomain to also use this framework
180          * instead of a special gpio.
181          */
182         val = RK3288_SOC_CON2_FLASH0 | (RK3288_SOC_CON2_FLASH0 << 16);
183         ret = regmap_write(iod->grf, RK3288_SOC_CON2, val);
184         if (ret < 0)
185                 dev_warn(iod->dev, "couldn't update flash0 ctrl\n");
186 }
187
188 static void rk3368_iodomain_init(struct rockchip_iodomain *iod)
189 {
190         int ret;
191         u32 val;
192
193         /* if no flash supply we should leave things alone */
194         if (!iod->grf_supplies[RK3368_SOC_FLASH_SUPPLY_NUM].reg)
195                 return;
196
197         /*
198          * set flash0 iodomain to also use this framework
199          * instead of a special gpio.
200          */
201         val = RK3368_GRF_SOC_CON15_FLASH0 | (RK3368_GRF_SOC_CON15_FLASH0 << 16);
202         ret = regmap_write(iod->grf, RK3368_GRF_SOC_CON15, val);
203         if (ret < 0)
204                 dev_warn(iod->dev, "couldn't update flash0 ctrl\n");
205 }
206
207
208 /*
209  * On the rk3188 the io-domains are handled by a shared register with the
210  * lower 8 bits being still being continuing drive-strength settings.
211  */
212 static const struct rockchip_iodomain_soc_data soc_data_rk3188 = {
213         .grf_offset = 0x104,
214         .grf_supply_names = {
215                 NULL,
216                 NULL,
217                 NULL,
218                 NULL,
219                 NULL,
220                 NULL,
221                 NULL,
222                 NULL,
223                 "ap0",
224                 "ap1",
225                 "cif",
226                 "flash",
227                 "vccio0",
228                 "vccio1",
229                 "lcdc0",
230                 "lcdc1",
231         },
232 };
233
234 static const struct rockchip_iodomain_soc_data soc_data_rk3288 = {
235         .grf_offset = 0x380,
236         .grf_supply_names = {
237                 "lcdc",         /* LCDC_VDD */
238                 "dvp",          /* DVPIO_VDD */
239                 "flash0",       /* FLASH0_VDD (emmc) */
240                 "flash1",       /* FLASH1_VDD (sdio1) */
241                 "wifi",         /* APIO3_VDD  (sdio0) */
242                 "bb",           /* APIO5_VDD */
243                 "audio",        /* APIO4_VDD */
244                 "sdcard",       /* SDMMC0_VDD (sdmmc) */
245                 "gpio30",       /* APIO1_VDD */
246                 "gpio1830",     /* APIO2_VDD */
247         },
248         .init = rk3288_iodomain_init,
249 };
250
251 static const struct rockchip_iodomain_soc_data soc_data_rk3368 = {
252         .grf_offset = 0x900,
253         .pmugrf_offset = 0x100,
254         .grf_supply_names = {
255                 NULL,
256                 "dvp",          /*DVP IO domain*/
257                 "flash0",       /*FLASH0 IO domain*/
258                 "wifi",         /*APIO2 IO domain*/
259                 NULL,
260                 "audio",        /*APIO3 IO domain*/
261                 "sdcard",       /*SDCARD IO domain*/
262                 "gpio30",       /*APIO1 IO domain*/
263                 "gpio1830",     /*ADIO4 IO domain*/
264         },
265         .pmugrf_supply_names = {
266                 NULL,
267                 NULL,
268                 NULL,
269                 NULL,
270                 "pmu",          /*PMU IO domain*/
271                 "vop",          /*LCDC IO domain*/
272         },
273         .init = rk3368_iodomain_init,
274 };
275
276
277 static const struct of_device_id rockchip_iodomain_match[] = {
278         {
279                 .compatible = "rockchip,rk3188-io-voltage-domain",
280                 .data = (void *)&soc_data_rk3188
281         },
282         {
283                 .compatible = "rockchip,rk3288-io-voltage-domain",
284                 .data = (void *)&soc_data_rk3288
285         },
286         {
287                 .compatible = "rockchip,rk3368-io-voltage-domain",
288                 .data = (void *)&soc_data_rk3368
289         },
290         { /* sentinel */ },
291 };
292
293 static int rockchip_iodomain_parse_supply(struct rockchip_iodomain *iod,
294                                           struct device_node *np,
295                                           enum rockchip_iodomain_grf_type type)
296 {
297         struct rockchip_iodomain_supply *group_supply;
298         const char **group_supply_names;
299         int i, ret = 0;
300
301         if (type == GRF) {
302                 group_supply_names =
303                         (const char **)iod->soc_data->grf_supply_names;
304                 group_supply = iod->grf_supplies;
305         } else if (type == PMU_GRF) {
306                 group_supply_names =
307                         (const char **)iod->soc_data->pmugrf_supply_names;
308                 group_supply = iod->pmugrf_supplies;
309         }
310
311         for (i = 0; i < MAX_SUPPLIES; i++) {
312                 const char *supply_name = group_supply_names[i];
313                 struct rockchip_iodomain_supply *supply = &group_supply[i];
314                 struct regulator *reg;
315                 int uV;
316
317                 if (!supply_name)
318                         continue;
319
320                 reg = devm_regulator_get_optional(iod->dev, supply_name);
321                 if (IS_ERR(reg)) {
322                         ret = PTR_ERR(reg);
323
324                         /* If a supply wasn't specified, that's OK */
325                         if (ret == -ENODEV)
326                                 continue;
327                         else if (ret != -EPROBE_DEFER)
328                                 dev_err(iod->dev, "couldn't get regulator %s\n",
329                                         supply_name);
330                         goto unreg_notify;
331                 }
332
333                 /* set initial correct value */
334                 uV = regulator_get_voltage(reg);
335
336                 /* must be a regulator we can get the voltage of */
337                 if (uV < 0) {
338                         dev_err(iod->dev, "Can't determine voltage: %s\n",
339                                 supply_name);
340                         goto unreg_notify;
341                 }
342
343                 if (uV > MAX_VOLTAGE_3_3) {
344                         dev_crit(iod->dev,
345                                  "%d uV is too high. May damage SoC!\n",
346                                  uV);
347                         ret = -EINVAL;
348                         goto unreg_notify;
349                 }
350
351                 /* setup our supply */
352                 supply->idx = i;
353                 supply->iod = iod;
354                 supply->reg = reg;
355                 supply->type = type;
356                 supply->nb.notifier_call = rockchip_iodomain_notify;
357
358                 ret = rockchip_iodomain_write(supply, uV);
359                 if (ret) {
360                         supply->reg = NULL;
361                         goto unreg_notify;
362                 }
363
364                 /* register regulator notifier */
365                 ret = regulator_register_notifier(reg, &supply->nb);
366                 if (ret) {
367                         dev_err(iod->dev,
368                                 "regulator notifier request failed\n");
369                         supply->reg = NULL;
370                         goto unreg_notify;
371                 }
372         }
373
374 unreg_notify:
375         for (i = MAX_SUPPLIES - 1; i >= 0; i--) {
376                 struct rockchip_iodomain_supply *io_supply = &group_supply[i];
377
378                 if (io_supply->reg)
379                         regulator_unregister_notifier(io_supply->reg,
380                                                       &io_supply->nb);
381         }
382
383         return ret;
384 }
385
386 static int rockchip_iodomain_probe(struct platform_device *pdev)
387 {
388         struct device_node *np = pdev->dev.of_node, *node;
389         const struct of_device_id *match;
390         struct rockchip_iodomain *iod;
391         int ret = 0;
392
393         if (!np)
394                 return -ENODEV;
395
396         iod = devm_kzalloc(&pdev->dev, sizeof(*iod), GFP_KERNEL);
397         if (!iod)
398                 return -ENOMEM;
399
400         iod->dev = &pdev->dev;
401         platform_set_drvdata(pdev, iod);
402
403         match = of_match_node(rockchip_iodomain_match, np);
404         iod->soc_data = (struct rockchip_iodomain_soc_data *)match->data;
405
406         iod->grf = syscon_regmap_lookup_by_phandle(np, "rockchip,grf");
407         if (IS_ERR(iod->grf)) {
408                 dev_err(&pdev->dev, "couldn't find grf regmap\n");
409                 return PTR_ERR(iod->grf);
410         }
411         ret = rockchip_iodomain_parse_supply(iod, np, GRF);
412         if (ret) {
413                 dev_err(iod->dev,
414                         "rockchip iodomain parse grf supply failed\n");
415                 return ret;
416         }
417
418         /* try to find the optional reference to the pmu syscon */
419         node = of_parse_phandle(np, "rockchip,pmugrf", 0);
420         if (node) {
421                 iod->pmu = syscon_node_to_regmap(node);
422                 if (IS_ERR(iod->pmu))
423                         return PTR_ERR(iod->pmu);
424                 ret = rockchip_iodomain_parse_supply(iod, np, PMU_GRF);
425                 if (ret) {
426                         dev_err(iod->dev,
427                                 "rockchip iodomain parse pmu_grf supply failed\n");
428                         return ret;
429                 }
430         }
431
432         if (iod->soc_data->init)
433                 iod->soc_data->init(iod);
434
435         return ret;
436 }
437
438 static int rockchip_iodomain_remove(struct platform_device *pdev)
439 {
440         struct rockchip_iodomain *iod = platform_get_drvdata(pdev);
441         int i;
442
443         for (i = MAX_SUPPLIES - 1; i >= 0; i--) {
444                 struct rockchip_iodomain_supply *io_supply
445                         = &iod->grf_supplies[i];
446
447                 if (io_supply->reg)
448                         regulator_unregister_notifier(io_supply->reg,
449                                                       &io_supply->nb);
450         }
451
452         for (i = MAX_SUPPLIES - 1; i >= 0; i--) {
453                 struct rockchip_iodomain_supply *io_supply =
454                         &iod->pmugrf_supplies[i];
455
456                 if (io_supply->reg)
457                         regulator_unregister_notifier(io_supply->reg,
458                                                       &io_supply->nb);
459         }
460
461         return 0;
462 }
463
464 static struct platform_driver rockchip_iodomain_driver = {
465         .probe   = rockchip_iodomain_probe,
466         .remove  = rockchip_iodomain_remove,
467         .driver  = {
468                 .name  = "rockchip-iodomain",
469                 .of_match_table = rockchip_iodomain_match,
470         },
471 };
472
473 module_platform_driver(rockchip_iodomain_driver);
474
475 MODULE_DESCRIPTION("Rockchip IO-domain driver");
476 MODULE_AUTHOR("Heiko Stuebner <heiko@sntech.de>");
477 MODULE_AUTHOR("Doug Anderson <dianders@chromium.org>");
478 MODULE_LICENSE("GPL v2");