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