1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Copyright (C) 2019 ROHM Semiconductors
4  *
5  * ROHM BD71837 regulator driver
6  */
7 
8 #include <common.h>
9 #include <dm.h>
10 #include <log.h>
11 #include <linux/bitops.h>
12 #include <power/bd71837.h>
13 #include <power/pmic.h>
14 #include <power/regulator.h>
15 
16 #define HW_STATE_CONTROL 0
17 #define DEBUG
18 
19 /**
20  * struct bd71837_vrange - describe linear range of voltages
21  *
22  * @min_volt:	smallest voltage in range
23  * @step:	how much voltage changes at each selector step
24  * @min_sel:	smallest selector in the range
25  * @max_sel:	maximum selector in the range
26  * @rangeval:	register value used to select this range if selectible
27  *		ranges are supported
28  */
29 struct bd71837_vrange {
30 	unsigned int	min_volt;
31 	unsigned int	step;
32 	u8		min_sel;
33 	u8		max_sel;
34 	u8		rangeval;
35 };
36 
37 /**
38  * struct bd71837_plat - describe regulator control registers
39  *
40  * @name:	name of the regulator. Used for matching the dt-entry
41  * @enable_reg:	register address used to enable/disable regulator
42  * @enablemask:	register mask used to enable/disable regulator
43  * @volt_reg:	register address used to configure regulator voltage
44  * @volt_mask:	register mask used to configure regulator voltage
45  * @ranges:	pointer to ranges of regulator voltages and matching register
46  *		values
47  * @numranges:	number of voltage ranges pointed by ranges
48  * @rangemask:	mask for selecting used ranges if multiple ranges are supported
49  * @sel_mask:	bit to toggle in order to transfer the register control to SW
50  * @dvs:	whether the voltage can be changed when regulator is enabled
51  */
52 struct bd71837_plat {
53 	const char		*name;
54 	u8			enable_reg;
55 	u8			enablemask;
56 	u8			volt_reg;
57 	u8			volt_mask;
58 	struct bd71837_vrange	*ranges;
59 	unsigned int		numranges;
60 	u8			rangemask;
61 	u8			sel_mask;
62 	bool			dvs;
63 };
64 
65 #define BD_RANGE(_min, _vstep, _sel_low, _sel_hi, _range_sel) \
66 { \
67 	.min_volt = (_min), .step = (_vstep), .min_sel = (_sel_low), \
68 	.max_sel = (_sel_hi), .rangeval = (_range_sel) \
69 }
70 
71 #define BD_DATA(_name, enreg, enmask, vreg, vmask, _range, rmask, _dvs, sel) \
72 { \
73 	.name = (_name), .enable_reg = (enreg), .enablemask = (enmask), \
74 	.volt_reg = (vreg), .volt_mask = (vmask), .ranges = (_range), \
75 	.numranges = ARRAY_SIZE(_range), .rangemask = (rmask), .dvs = (_dvs), \
76 	.sel_mask = (sel) \
77 }
78 
79 static struct bd71837_vrange dvs_buck_vranges[] = {
80 	BD_RANGE(700000, 10000, 0, 0x3c, 0),
81 	BD_RANGE(1300000, 0, 0x3d, 0x3f, 0),
82 };
83 
84 static struct bd71837_vrange bd71847_buck3_vranges[] = {
85 	BD_RANGE(700000, 100000, 0x00, 0x03, 0),
86 	BD_RANGE(1050000, 50000, 0x04, 0x05, 0),
87 	BD_RANGE(1200000, 150000, 0x06, 0x07, 0),
88 	BD_RANGE(550000, 50000, 0x0, 0x7, 0x40),
89 	BD_RANGE(675000, 100000, 0x0, 0x3, 0x80),
90 	BD_RANGE(1025000, 50000, 0x4, 0x5, 0x80),
91 	BD_RANGE(1175000, 150000, 0x6, 0x7, 0x80),
92 };
93 
94 static struct bd71837_vrange bd71847_buck4_vranges[] = {
95 	BD_RANGE(3000000, 100000, 0x00, 0x03, 0),
96 	BD_RANGE(2600000, 100000, 0x00, 0x03, 40),
97 };
98 
99 static struct bd71837_vrange bd71837_buck5_vranges[] = {
100 	BD_RANGE(700000, 100000, 0, 0x3, 0),
101 	BD_RANGE(1050000, 50000, 0x04, 0x05, 0),
102 	BD_RANGE(1200000, 150000, 0x06, 0x07, 0),
103 	BD_RANGE(675000, 100000, 0x0, 0x3, 0x80),
104 	BD_RANGE(1025000, 50000, 0x04, 0x05, 0x80),
105 	BD_RANGE(1175000, 150000, 0x06, 0x07, 0x80),
106 };
107 
108 static struct bd71837_vrange bd71837_buck6_vranges[] = {
109 	BD_RANGE(3000000, 100000, 0x00, 0x03, 0),
110 };
111 
112 static struct bd71837_vrange nodvs_buck3_vranges[] = {
113 	BD_RANGE(1605000, 90000, 0, 1, 0),
114 	BD_RANGE(1755000, 45000, 2, 4, 0),
115 	BD_RANGE(1905000, 45000, 5, 7, 0),
116 };
117 
118 static struct bd71837_vrange nodvs_buck4_vranges[] = {
119 	BD_RANGE(800000, 10000, 0x00, 0x3C, 0),
120 };
121 
122 static struct bd71837_vrange ldo1_vranges[] = {
123 	BD_RANGE(3000000, 100000, 0x00, 0x03, 0),
124 	BD_RANGE(1600000, 100000, 0x00, 0x03, 0x20),
125 };
126 
127 static struct bd71837_vrange ldo2_vranges[] = {
128 	BD_RANGE(900000, 0, 0, 0, 0),
129 	BD_RANGE(800000, 0, 1, 1, 0),
130 };
131 
132 static struct bd71837_vrange ldo3_vranges[] = {
133 	BD_RANGE(1800000, 100000, 0x00, 0x0f, 0),
134 };
135 
136 static struct bd71837_vrange ldo4_vranges[] = {
137 	BD_RANGE(900000, 100000, 0x00, 0x09, 0),
138 };
139 
140 static struct bd71837_vrange bd71837_ldo5_vranges[] = {
141 	BD_RANGE(1800000, 100000, 0x00, 0x0f, 0),
142 };
143 
144 static struct bd71837_vrange bd71847_ldo5_vranges[] = {
145 	BD_RANGE(1800000, 100000, 0x00, 0x0f, 0),
146 	BD_RANGE(800000, 100000, 0x00, 0x0f, 0x20),
147 };
148 
149 static struct bd71837_vrange ldo6_vranges[] = {
150 	BD_RANGE(900000, 100000, 0x00, 0x09, 0),
151 };
152 
153 static struct bd71837_vrange ldo7_vranges[] = {
154 	BD_RANGE(1800000, 100000, 0x00, 0x0f, 0),
155 };
156 
157 /*
158  * We use enable mask 'HW_STATE_CONTROL' to indicate that this regulator
159  * must not be enabled or disabled by SW. The typical use-case for BD71837
160  * is powering NXP i.MX8. In this use-case we (for now) only allow control
161  * for BUCK3 and BUCK4 which are not boot critical.
162  */
163 static struct bd71837_plat bd71837_reg_data[] = {
164 /* Bucks 1-4 which support dynamic voltage scaling */
165 	BD_DATA("BUCK1", BD718XX_BUCK1_CTRL, HW_STATE_CONTROL,
166 		BD718XX_BUCK1_VOLT_RUN, DVS_BUCK_RUN_MASK, dvs_buck_vranges, 0,
167 		true, BD718XX_BUCK_SEL),
168 	BD_DATA("BUCK2", BD718XX_BUCK2_CTRL, HW_STATE_CONTROL,
169 		BD718XX_BUCK2_VOLT_RUN, DVS_BUCK_RUN_MASK, dvs_buck_vranges, 0,
170 		true, BD718XX_BUCK_SEL),
171 	BD_DATA("BUCK3", BD71837_BUCK3_CTRL, BD718XX_BUCK_EN,
172 		BD71837_BUCK3_VOLT_RUN, DVS_BUCK_RUN_MASK, dvs_buck_vranges, 0,
173 		true, BD718XX_BUCK_SEL),
174 	BD_DATA("BUCK4", BD71837_BUCK4_CTRL, BD718XX_BUCK_EN,
175 		BD71837_BUCK4_VOLT_RUN, DVS_BUCK_RUN_MASK, dvs_buck_vranges, 0,
176 		true, BD718XX_BUCK_SEL),
177 /* Bucks 5-8 which do not support dynamic voltage scaling */
178 	BD_DATA("BUCK5", BD718XX_1ST_NODVS_BUCK_CTRL, HW_STATE_CONTROL,
179 		BD718XX_1ST_NODVS_BUCK_VOLT, BD718XX_1ST_NODVS_BUCK_MASK,
180 		bd71837_buck5_vranges, 0x80, false, BD718XX_BUCK_SEL),
181 	BD_DATA("BUCK6", BD718XX_2ND_NODVS_BUCK_CTRL, HW_STATE_CONTROL,
182 		BD718XX_2ND_NODVS_BUCK_VOLT, BD71837_BUCK6_MASK,
183 		bd71837_buck6_vranges, 0, false, BD718XX_BUCK_SEL),
184 	BD_DATA("BUCK7", BD718XX_3RD_NODVS_BUCK_CTRL, HW_STATE_CONTROL,
185 		BD718XX_3RD_NODVS_BUCK_VOLT, BD718XX_3RD_NODVS_BUCK_MASK,
186 		nodvs_buck3_vranges, 0, false, BD718XX_BUCK_SEL),
187 	BD_DATA("BUCK8", BD718XX_4TH_NODVS_BUCK_CTRL, HW_STATE_CONTROL,
188 		BD718XX_4TH_NODVS_BUCK_VOLT, BD718XX_4TH_NODVS_BUCK_MASK,
189 		nodvs_buck4_vranges, 0, false, BD718XX_BUCK_SEL),
190 /* LDOs */
191 	BD_DATA("LDO1", BD718XX_LDO1_VOLT, HW_STATE_CONTROL, BD718XX_LDO1_VOLT,
192 		BD718XX_LDO1_MASK, ldo1_vranges, 0x20, false, BD718XX_LDO_SEL),
193 	BD_DATA("LDO2", BD718XX_LDO2_VOLT, HW_STATE_CONTROL, BD718XX_LDO2_VOLT,
194 		BD718XX_LDO2_MASK, ldo2_vranges, 0, false, BD718XX_LDO_SEL),
195 	BD_DATA("LDO3", BD718XX_LDO3_VOLT, HW_STATE_CONTROL, BD718XX_LDO3_VOLT,
196 		BD718XX_LDO3_MASK, ldo3_vranges, 0, false, BD718XX_LDO_SEL),
197 	BD_DATA("LDO4", BD718XX_LDO4_VOLT, HW_STATE_CONTROL, BD718XX_LDO4_VOLT,
198 		BD718XX_LDO4_MASK, ldo4_vranges, 0, false, BD718XX_LDO_SEL),
199 	BD_DATA("LDO5", BD718XX_LDO5_VOLT, HW_STATE_CONTROL, BD718XX_LDO5_VOLT,
200 		BD71837_LDO5_MASK, bd71837_ldo5_vranges, 0, false,
201 		BD718XX_LDO_SEL),
202 	BD_DATA("LDO6", BD718XX_LDO6_VOLT, HW_STATE_CONTROL, BD718XX_LDO6_VOLT,
203 		BD718XX_LDO6_MASK, ldo6_vranges, 0, false, BD718XX_LDO_SEL),
204 	BD_DATA("LDO7", BD71837_LDO7_VOLT, HW_STATE_CONTROL, BD71837_LDO7_VOLT,
205 		BD71837_LDO7_MASK, ldo7_vranges, 0, false, BD718XX_LDO_SEL),
206 };
207 
208 static struct bd71837_plat bd71847_reg_data[] = {
209 /* Bucks 1 and 2 which support dynamic voltage scaling */
210 	BD_DATA("BUCK1", BD718XX_BUCK1_CTRL, HW_STATE_CONTROL,
211 		BD718XX_BUCK1_VOLT_RUN, DVS_BUCK_RUN_MASK, dvs_buck_vranges, 0,
212 		true, BD718XX_BUCK_SEL),
213 	BD_DATA("BUCK2", BD718XX_BUCK2_CTRL, HW_STATE_CONTROL,
214 		BD718XX_BUCK2_VOLT_RUN, DVS_BUCK_RUN_MASK, dvs_buck_vranges, 0,
215 		true, BD718XX_BUCK_SEL),
216 /* Bucks 3-6 which do not support dynamic voltage scaling */
217 	BD_DATA("BUCK3", BD718XX_1ST_NODVS_BUCK_CTRL, HW_STATE_CONTROL,
218 		BD718XX_1ST_NODVS_BUCK_VOLT, BD718XX_1ST_NODVS_BUCK_MASK,
219 		bd71847_buck3_vranges, 0xc0, false, BD718XX_BUCK_SEL),
220 	BD_DATA("BUCK4", BD718XX_2ND_NODVS_BUCK_CTRL, HW_STATE_CONTROL,
221 		BD718XX_2ND_NODVS_BUCK_VOLT, BD71837_BUCK6_MASK,
222 		bd71847_buck4_vranges, 0x40, false, BD718XX_BUCK_SEL),
223 	BD_DATA("BUCK5", BD718XX_3RD_NODVS_BUCK_CTRL, HW_STATE_CONTROL,
224 		BD718XX_3RD_NODVS_BUCK_VOLT, BD718XX_3RD_NODVS_BUCK_MASK,
225 		nodvs_buck3_vranges, 0, false, BD718XX_BUCK_SEL),
226 	BD_DATA("BUCK6", BD718XX_4TH_NODVS_BUCK_CTRL, HW_STATE_CONTROL,
227 		BD718XX_4TH_NODVS_BUCK_VOLT, BD718XX_4TH_NODVS_BUCK_MASK,
228 		nodvs_buck4_vranges, 0, false, BD718XX_BUCK_SEL),
229 /* LDOs */
230 	BD_DATA("LDO1", BD718XX_LDO1_VOLT, HW_STATE_CONTROL, BD718XX_LDO1_VOLT,
231 		BD718XX_LDO1_MASK, ldo1_vranges, 0x20, false, BD718XX_LDO_SEL),
232 	BD_DATA("LDO2", BD718XX_LDO2_VOLT, HW_STATE_CONTROL, BD718XX_LDO2_VOLT,
233 		BD718XX_LDO2_MASK, ldo2_vranges, 0, false, BD718XX_LDO_SEL),
234 	BD_DATA("LDO3", BD718XX_LDO3_VOLT, HW_STATE_CONTROL, BD718XX_LDO3_VOLT,
235 		BD718XX_LDO3_MASK, ldo3_vranges, 0, false, BD718XX_LDO_SEL),
236 	BD_DATA("LDO4", BD718XX_LDO4_VOLT, HW_STATE_CONTROL, BD718XX_LDO4_VOLT,
237 		BD718XX_LDO4_MASK, ldo4_vranges, 0, false, BD718XX_LDO_SEL),
238 	BD_DATA("LDO5", BD718XX_LDO5_VOLT, HW_STATE_CONTROL, BD718XX_LDO5_VOLT,
239 		BD71847_LDO5_MASK, bd71847_ldo5_vranges, 0x20, false,
240 		BD718XX_LDO_SEL),
241 	BD_DATA("LDO6", BD718XX_LDO6_VOLT, HW_STATE_CONTROL, BD718XX_LDO6_VOLT,
242 		BD718XX_LDO6_MASK, ldo6_vranges, 0, false, BD718XX_LDO_SEL),
243 };
244 
vrange_find_value(struct bd71837_vrange * r,unsigned int sel,unsigned int * val)245 static int vrange_find_value(struct bd71837_vrange *r, unsigned int sel,
246 			     unsigned int *val)
247 {
248 	if (!val || sel < r->min_sel || sel > r->max_sel)
249 		return -EINVAL;
250 
251 	*val = r->min_volt + r->step * (sel - r->min_sel);
252 	return 0;
253 }
254 
vrange_find_selector(struct bd71837_vrange * r,int val,unsigned int * sel)255 static int vrange_find_selector(struct bd71837_vrange *r, int val,
256 				unsigned int *sel)
257 {
258 	int ret = -EINVAL;
259 	int num_vals = r->max_sel - r->min_sel + 1;
260 
261 	if (val >= r->min_volt &&
262 	    val <= r->min_volt + r->step * (num_vals - 1)) {
263 		if (r->step) {
264 			*sel = r->min_sel + ((val - r->min_volt) / r->step);
265 			ret = 0;
266 		} else {
267 			*sel = r->min_sel;
268 			ret = 0;
269 		}
270 	}
271 	return ret;
272 }
273 
bd71837_get_enable(struct udevice * dev)274 static int bd71837_get_enable(struct udevice *dev)
275 {
276 	int val;
277 	struct bd71837_plat *plat = dev_get_plat(dev);
278 
279 	/*
280 	 * boot critical regulators on bd71837 must not be controlled by sw
281 	 * due to the 'feature' which leaves power rails down if bd71837 is
282 	 * reseted to snvs state. hence we can't get the state here.
283 	 *
284 	 * if we are alive it means we probably are on run state and
285 	 * if the regulator can't be controlled we can assume it is
286 	 * enabled.
287 	 */
288 	if (plat->enablemask == HW_STATE_CONTROL)
289 		return 1;
290 
291 	val = pmic_reg_read(dev->parent, plat->enable_reg);
292 	if (val < 0)
293 		return val;
294 
295 	return (val & plat->enablemask);
296 }
297 
bd71837_set_enable(struct udevice * dev,bool enable)298 static int bd71837_set_enable(struct udevice *dev, bool enable)
299 {
300 	int val = 0;
301 	struct bd71837_plat *plat = dev_get_plat(dev);
302 
303 	/*
304 	 * boot critical regulators on bd71837 must not be controlled by sw
305 	 * due to the 'feature' which leaves power rails down if bd71837 is
306 	 * reseted to snvs state. Hence we can't set the state here.
307 	 */
308 	if (plat->enablemask == HW_STATE_CONTROL)
309 		return -EINVAL;
310 
311 	if (enable)
312 		val = plat->enablemask;
313 
314 	return pmic_clrsetbits(dev->parent, plat->enable_reg, plat->enablemask,
315 			       val);
316 }
317 
bd71837_set_value(struct udevice * dev,int uvolt)318 static int bd71837_set_value(struct udevice *dev, int uvolt)
319 {
320 	unsigned int sel;
321 	unsigned int range;
322 	int i;
323 	int found = 0;
324 	struct bd71837_plat *plat = dev_get_plat(dev);
325 
326 	/*
327 	 * An under/overshooting may occur if voltage is changed for other
328 	 * regulators but buck 1,2,3 or 4 when regulator is enabled. Prevent
329 	 * change to protect the HW
330 	 */
331 	if (!plat->dvs)
332 		if (bd71837_get_enable(dev)) {
333 			pr_err("Only DVS bucks can be changed when enabled\n");
334 			return -EINVAL;
335 		}
336 
337 	for (i = 0; i < plat->numranges; i++) {
338 		struct bd71837_vrange *r = &plat->ranges[i];
339 
340 		found = !vrange_find_selector(r, uvolt, &sel);
341 		if (found) {
342 			unsigned int tmp;
343 
344 			/*
345 			 * We require exactly the requested value to be
346 			 * supported - this can be changed later if needed
347 			 */
348 			range = r->rangeval;
349 			found = !vrange_find_value(r, sel, &tmp);
350 			if (found && tmp == uvolt)
351 				break;
352 			found = 0;
353 		}
354 	}
355 
356 	if (!found)
357 		return -EINVAL;
358 
359 	sel <<= ffs(plat->volt_mask) - 1;
360 
361 	if (plat->rangemask)
362 		sel |= range;
363 
364 	return pmic_clrsetbits(dev->parent, plat->volt_reg, plat->volt_mask |
365 			       plat->rangemask, sel);
366 }
367 
bd71837_get_value(struct udevice * dev)368 static int bd71837_get_value(struct udevice *dev)
369 {
370 	unsigned int reg, range;
371 	unsigned int tmp;
372 	struct bd71837_plat *plat = dev_get_plat(dev);
373 	int i;
374 
375 	reg = pmic_reg_read(dev->parent, plat->volt_reg);
376 	if (((int)reg) < 0)
377 		return reg;
378 
379 	range = reg & plat->rangemask;
380 
381 	reg &= plat->volt_mask;
382 	reg >>= ffs(plat->volt_mask) - 1;
383 
384 	for (i = 0; i < plat->numranges; i++) {
385 		struct bd71837_vrange *r = &plat->ranges[i];
386 
387 		if (plat->rangemask && ((plat->rangemask & range) !=
388 		    r->rangeval))
389 			continue;
390 
391 		if (!vrange_find_value(r, reg, &tmp))
392 			return tmp;
393 	}
394 
395 	pr_err("Unknown voltage value read from pmic\n");
396 
397 	return -EINVAL;
398 }
399 
bd71837_regulator_probe(struct udevice * dev)400 static int bd71837_regulator_probe(struct udevice *dev)
401 {
402 	struct bd71837_plat *plat = dev_get_plat(dev);
403 	int i, ret;
404 	struct dm_regulator_uclass_plat *uc_pdata;
405 	int type;
406 	struct bd71837_plat *init_data;
407 	int data_amnt;
408 
409 	type = dev_get_driver_data(dev_get_parent(dev));
410 
411 	switch (type) {
412 	case ROHM_CHIP_TYPE_BD71837:
413 		init_data = bd71837_reg_data;
414 		data_amnt = ARRAY_SIZE(bd71837_reg_data);
415 		break;
416 	case ROHM_CHIP_TYPE_BD71847:
417 		init_data = bd71847_reg_data;
418 		data_amnt = ARRAY_SIZE(bd71847_reg_data);
419 		break;
420 	default:
421 		debug("Unknown PMIC type\n");
422 		init_data = NULL;
423 		data_amnt = 0;
424 		break;
425 	}
426 
427 	for (i = 0; i < data_amnt; i++) {
428 		if (!strcmp(dev->name, init_data[i].name)) {
429 			*plat = init_data[i];
430 			if (plat->enablemask != HW_STATE_CONTROL) {
431 				/*
432 				 * Take the regulator under SW control. Ensure
433 				 * the initial state matches dt flags and then
434 				 * write the SEL bit
435 				 */
436 				uc_pdata = dev_get_uclass_plat(dev);
437 				ret = bd71837_set_enable(dev,
438 							 !!(uc_pdata->boot_on ||
439 							 uc_pdata->always_on));
440 				if (ret)
441 					return ret;
442 
443 				return pmic_clrsetbits(dev->parent,
444 						      plat->enable_reg,
445 						      plat->sel_mask,
446 						      plat->sel_mask);
447 			}
448 			return 0;
449 		}
450 	}
451 
452 	pr_err("Unknown regulator '%s'\n", dev->name);
453 
454 	return -ENOENT;
455 }
456 
457 static const struct dm_regulator_ops bd71837_regulator_ops = {
458 	.get_value  = bd71837_get_value,
459 	.set_value  = bd71837_set_value,
460 	.get_enable = bd71837_get_enable,
461 	.set_enable = bd71837_set_enable,
462 };
463 
464 U_BOOT_DRIVER(bd71837_regulator) = {
465 	.name = BD718XX_REGULATOR_DRIVER,
466 	.id = UCLASS_REGULATOR,
467 	.ops = &bd71837_regulator_ops,
468 	.probe = bd71837_regulator_probe,
469 	.plat_auto	= sizeof(struct bd71837_plat),
470 };
471