1 | // SPDX-License-Identifier: GPL-2.0-only |
2 | /* |
3 | * Texas Instruments SoC Adaptive Body Bias(ABB) Regulator |
4 | * |
5 | * Copyright (C) 2011 Texas Instruments, Inc. |
6 | * Mike Turquette <mturquette@ti.com> |
7 | * |
8 | * Copyright (C) 2012-2013 Texas Instruments, Inc. |
9 | * Andrii Tseglytskyi <andrii.tseglytskyi@ti.com> |
10 | * Nishanth Menon <nm@ti.com> |
11 | */ |
12 | #include <linux/clk.h> |
13 | #include <linux/delay.h> |
14 | #include <linux/err.h> |
15 | #include <linux/io.h> |
16 | #include <linux/module.h> |
17 | #include <linux/of.h> |
18 | #include <linux/platform_device.h> |
19 | #include <linux/regulator/driver.h> |
20 | #include <linux/regulator/machine.h> |
21 | #include <linux/regulator/of_regulator.h> |
22 | |
23 | /* |
24 | * ABB LDO operating states: |
25 | * NOMINAL_OPP: bypasses the ABB LDO |
26 | * FAST_OPP: sets ABB LDO to Forward Body-Bias |
27 | * SLOW_OPP: sets ABB LDO to Reverse Body-Bias |
28 | */ |
29 | #define TI_ABB_NOMINAL_OPP 0 |
30 | #define TI_ABB_FAST_OPP 1 |
31 | #define TI_ABB_SLOW_OPP 3 |
32 | |
33 | /** |
34 | * struct ti_abb_info - ABB information per voltage setting |
35 | * @opp_sel: one of TI_ABB macro |
36 | * @vset: (optional) vset value that LDOVBB needs to be overridden with. |
37 | * |
38 | * Array of per voltage entries organized in the same order as regulator_desc's |
39 | * volt_table list. (selector is used to index from this array) |
40 | */ |
41 | struct ti_abb_info { |
42 | u32 opp_sel; |
43 | u32 vset; |
44 | }; |
45 | |
46 | /** |
47 | * struct ti_abb_reg - Register description for ABB block |
48 | * @setup_off: setup register offset from base |
49 | * @control_off: control register offset from base |
50 | * @sr2_wtcnt_value_mask: setup register- sr2_wtcnt_value mask |
51 | * @fbb_sel_mask: setup register- FBB sel mask |
52 | * @rbb_sel_mask: setup register- RBB sel mask |
53 | * @sr2_en_mask: setup register- enable mask |
54 | * @opp_change_mask: control register - mask to trigger LDOVBB change |
55 | * @opp_sel_mask: control register - mask for mode to operate |
56 | */ |
57 | struct ti_abb_reg { |
58 | u32 setup_off; |
59 | u32 control_off; |
60 | |
61 | /* Setup register fields */ |
62 | u32 sr2_wtcnt_value_mask; |
63 | u32 fbb_sel_mask; |
64 | u32 rbb_sel_mask; |
65 | u32 sr2_en_mask; |
66 | |
67 | /* Control register fields */ |
68 | u32 opp_change_mask; |
69 | u32 opp_sel_mask; |
70 | }; |
71 | |
72 | /** |
73 | * struct ti_abb - ABB instance data |
74 | * @rdesc: regulator descriptor |
75 | * @clk: clock(usually sysclk) supplying ABB block |
76 | * @base: base address of ABB block |
77 | * @setup_reg: setup register of ABB block |
78 | * @control_reg: control register of ABB block |
79 | * @int_base: interrupt register base address |
80 | * @efuse_base: (optional) efuse base address for ABB modes |
81 | * @ldo_base: (optional) LDOVBB vset override base address |
82 | * @regs: pointer to struct ti_abb_reg for ABB block |
83 | * @txdone_mask: mask on int_base for tranxdone interrupt |
84 | * @ldovbb_override_mask: mask to ldo_base for overriding default LDO VBB |
85 | * vset with value from efuse |
86 | * @ldovbb_vset_mask: mask to ldo_base for providing the VSET override |
87 | * @info: array to per voltage ABB configuration |
88 | * @current_info_idx: current index to info |
89 | * @settling_time: SoC specific settling time for LDO VBB |
90 | */ |
91 | struct ti_abb { |
92 | struct regulator_desc rdesc; |
93 | struct clk *clk; |
94 | void __iomem *base; |
95 | void __iomem *setup_reg; |
96 | void __iomem *control_reg; |
97 | void __iomem *int_base; |
98 | void __iomem *efuse_base; |
99 | void __iomem *ldo_base; |
100 | |
101 | const struct ti_abb_reg *regs; |
102 | u32 txdone_mask; |
103 | u32 ldovbb_override_mask; |
104 | u32 ldovbb_vset_mask; |
105 | |
106 | struct ti_abb_info *info; |
107 | int current_info_idx; |
108 | |
109 | u32 settling_time; |
110 | }; |
111 | |
112 | /** |
113 | * ti_abb_rmw() - handy wrapper to set specific register bits |
114 | * @mask: mask for register field |
115 | * @value: value shifted to mask location and written |
116 | * @reg: register address |
117 | * |
118 | * Return: final register value (may be unused) |
119 | */ |
120 | static inline u32 ti_abb_rmw(u32 mask, u32 value, void __iomem *reg) |
121 | { |
122 | u32 val; |
123 | |
124 | val = readl(addr: reg); |
125 | val &= ~mask; |
126 | val |= (value << __ffs(mask)) & mask; |
127 | writel(val, addr: reg); |
128 | |
129 | return val; |
130 | } |
131 | |
132 | /** |
133 | * ti_abb_check_txdone() - handy wrapper to check ABB tranxdone status |
134 | * @abb: pointer to the abb instance |
135 | * |
136 | * Return: true or false |
137 | */ |
138 | static inline bool ti_abb_check_txdone(const struct ti_abb *abb) |
139 | { |
140 | return !!(readl(addr: abb->int_base) & abb->txdone_mask); |
141 | } |
142 | |
143 | /** |
144 | * ti_abb_clear_txdone() - handy wrapper to clear ABB tranxdone status |
145 | * @abb: pointer to the abb instance |
146 | */ |
147 | static inline void ti_abb_clear_txdone(const struct ti_abb *abb) |
148 | { |
149 | writel(val: abb->txdone_mask, addr: abb->int_base); |
150 | }; |
151 | |
152 | /** |
153 | * ti_abb_wait_txdone() - waits for ABB tranxdone event |
154 | * @dev: device |
155 | * @abb: pointer to the abb instance |
156 | * |
157 | * Return: 0 on success or -ETIMEDOUT if the event is not cleared on time. |
158 | */ |
159 | static int ti_abb_wait_txdone(struct device *dev, struct ti_abb *abb) |
160 | { |
161 | int timeout = 0; |
162 | bool status; |
163 | |
164 | while (timeout++ <= abb->settling_time) { |
165 | status = ti_abb_check_txdone(abb); |
166 | if (status) |
167 | return 0; |
168 | |
169 | udelay(1); |
170 | } |
171 | |
172 | dev_warn_ratelimited(dev, "%s:TRANXDONE timeout(%duS) int=0x%08x\n" , |
173 | __func__, timeout, readl(abb->int_base)); |
174 | return -ETIMEDOUT; |
175 | } |
176 | |
177 | /** |
178 | * ti_abb_clear_all_txdone() - clears ABB tranxdone event |
179 | * @dev: device |
180 | * @abb: pointer to the abb instance |
181 | * |
182 | * Return: 0 on success or -ETIMEDOUT if the event is not cleared on time. |
183 | */ |
184 | static int ti_abb_clear_all_txdone(struct device *dev, const struct ti_abb *abb) |
185 | { |
186 | int timeout = 0; |
187 | bool status; |
188 | |
189 | while (timeout++ <= abb->settling_time) { |
190 | ti_abb_clear_txdone(abb); |
191 | |
192 | status = ti_abb_check_txdone(abb); |
193 | if (!status) |
194 | return 0; |
195 | |
196 | udelay(1); |
197 | } |
198 | |
199 | dev_warn_ratelimited(dev, "%s:TRANXDONE timeout(%duS) int=0x%08x\n" , |
200 | __func__, timeout, readl(abb->int_base)); |
201 | return -ETIMEDOUT; |
202 | } |
203 | |
204 | /** |
205 | * ti_abb_program_ldovbb() - program LDOVBB register for override value |
206 | * @dev: device |
207 | * @abb: pointer to the abb instance |
208 | * @info: ABB info to program |
209 | */ |
210 | static void ti_abb_program_ldovbb(struct device *dev, const struct ti_abb *abb, |
211 | struct ti_abb_info *info) |
212 | { |
213 | u32 val; |
214 | |
215 | val = readl(addr: abb->ldo_base); |
216 | /* clear up previous values */ |
217 | val &= ~(abb->ldovbb_override_mask | abb->ldovbb_vset_mask); |
218 | |
219 | switch (info->opp_sel) { |
220 | case TI_ABB_SLOW_OPP: |
221 | case TI_ABB_FAST_OPP: |
222 | val |= abb->ldovbb_override_mask; |
223 | val |= info->vset << __ffs(abb->ldovbb_vset_mask); |
224 | break; |
225 | } |
226 | |
227 | writel(val, addr: abb->ldo_base); |
228 | } |
229 | |
230 | /** |
231 | * ti_abb_set_opp() - Setup ABB and LDO VBB for required bias |
232 | * @rdev: regulator device |
233 | * @abb: pointer to the abb instance |
234 | * @info: ABB info to program |
235 | * |
236 | * Return: 0 on success or appropriate error value when fails |
237 | */ |
238 | static int ti_abb_set_opp(struct regulator_dev *rdev, struct ti_abb *abb, |
239 | struct ti_abb_info *info) |
240 | { |
241 | const struct ti_abb_reg *regs = abb->regs; |
242 | struct device *dev = &rdev->dev; |
243 | int ret; |
244 | |
245 | ret = ti_abb_clear_all_txdone(dev, abb); |
246 | if (ret) |
247 | goto out; |
248 | |
249 | ti_abb_rmw(mask: regs->fbb_sel_mask | regs->rbb_sel_mask, value: 0, reg: abb->setup_reg); |
250 | |
251 | switch (info->opp_sel) { |
252 | case TI_ABB_SLOW_OPP: |
253 | ti_abb_rmw(mask: regs->rbb_sel_mask, value: 1, reg: abb->setup_reg); |
254 | break; |
255 | case TI_ABB_FAST_OPP: |
256 | ti_abb_rmw(mask: regs->fbb_sel_mask, value: 1, reg: abb->setup_reg); |
257 | break; |
258 | } |
259 | |
260 | /* program next state of ABB ldo */ |
261 | ti_abb_rmw(mask: regs->opp_sel_mask, value: info->opp_sel, reg: abb->control_reg); |
262 | |
263 | /* |
264 | * program LDO VBB vset override if needed for !bypass mode |
265 | * XXX: Do not switch sequence - for !bypass, LDO override reset *must* |
266 | * be performed *before* switch to bias mode else VBB glitches. |
267 | */ |
268 | if (abb->ldo_base && info->opp_sel != TI_ABB_NOMINAL_OPP) |
269 | ti_abb_program_ldovbb(dev, abb, info); |
270 | |
271 | /* Initiate ABB ldo change */ |
272 | ti_abb_rmw(mask: regs->opp_change_mask, value: 1, reg: abb->control_reg); |
273 | |
274 | /* Wait for ABB LDO to complete transition to new Bias setting */ |
275 | ret = ti_abb_wait_txdone(dev, abb); |
276 | if (ret) |
277 | goto out; |
278 | |
279 | ret = ti_abb_clear_all_txdone(dev, abb); |
280 | if (ret) |
281 | goto out; |
282 | |
283 | /* |
284 | * Reset LDO VBB vset override bypass mode |
285 | * XXX: Do not switch sequence - for bypass, LDO override reset *must* |
286 | * be performed *after* switch to bypass else VBB glitches. |
287 | */ |
288 | if (abb->ldo_base && info->opp_sel == TI_ABB_NOMINAL_OPP) |
289 | ti_abb_program_ldovbb(dev, abb, info); |
290 | |
291 | out: |
292 | return ret; |
293 | } |
294 | |
295 | /** |
296 | * ti_abb_set_voltage_sel() - regulator accessor function to set ABB LDO |
297 | * @rdev: regulator device |
298 | * @sel: selector to index into required ABB LDO settings (maps to |
299 | * regulator descriptor's volt_table) |
300 | * |
301 | * Return: 0 on success or appropriate error value when fails |
302 | */ |
303 | static int ti_abb_set_voltage_sel(struct regulator_dev *rdev, unsigned int sel) |
304 | { |
305 | const struct regulator_desc *desc = rdev->desc; |
306 | struct ti_abb *abb = rdev_get_drvdata(rdev); |
307 | struct device *dev = &rdev->dev; |
308 | struct ti_abb_info *info, *oinfo; |
309 | int ret = 0; |
310 | |
311 | if (!abb) { |
312 | dev_err_ratelimited(dev, "%s: No regulator drvdata\n" , |
313 | __func__); |
314 | return -ENODEV; |
315 | } |
316 | |
317 | if (!desc->n_voltages || !abb->info) { |
318 | dev_err_ratelimited(dev, |
319 | "%s: No valid voltage table entries?\n" , |
320 | __func__); |
321 | return -EINVAL; |
322 | } |
323 | |
324 | if (sel >= desc->n_voltages) { |
325 | dev_err(dev, "%s: sel idx(%d) >= n_voltages(%d)\n" , __func__, |
326 | sel, desc->n_voltages); |
327 | return -EINVAL; |
328 | } |
329 | |
330 | /* If we are in the same index as we were, nothing to do here! */ |
331 | if (sel == abb->current_info_idx) { |
332 | dev_dbg(dev, "%s: Already at sel=%d\n" , __func__, sel); |
333 | return ret; |
334 | } |
335 | |
336 | info = &abb->info[sel]; |
337 | /* |
338 | * When Linux kernel is starting up, we aren't sure of the |
339 | * Bias configuration that bootloader has configured. |
340 | * So, we get to know the actual setting the first time |
341 | * we are asked to transition. |
342 | */ |
343 | if (abb->current_info_idx == -EINVAL) |
344 | goto just_set_abb; |
345 | |
346 | /* If data is exactly the same, then just update index, no change */ |
347 | oinfo = &abb->info[abb->current_info_idx]; |
348 | if (!memcmp(p: info, q: oinfo, size: sizeof(*info))) { |
349 | dev_dbg(dev, "%s: Same data new idx=%d, old idx=%d\n" , __func__, |
350 | sel, abb->current_info_idx); |
351 | goto out; |
352 | } |
353 | |
354 | just_set_abb: |
355 | ret = ti_abb_set_opp(rdev, abb, info); |
356 | |
357 | out: |
358 | if (!ret) |
359 | abb->current_info_idx = sel; |
360 | else |
361 | dev_err_ratelimited(dev, |
362 | "%s: Volt[%d] idx[%d] mode[%d] Fail(%d)\n" , |
363 | __func__, desc->volt_table[sel], sel, |
364 | info->opp_sel, ret); |
365 | return ret; |
366 | } |
367 | |
368 | /** |
369 | * ti_abb_get_voltage_sel() - Regulator accessor to get current ABB LDO setting |
370 | * @rdev: regulator device |
371 | * |
372 | * Return: 0 on success or appropriate error value when fails |
373 | */ |
374 | static int ti_abb_get_voltage_sel(struct regulator_dev *rdev) |
375 | { |
376 | const struct regulator_desc *desc = rdev->desc; |
377 | struct ti_abb *abb = rdev_get_drvdata(rdev); |
378 | struct device *dev = &rdev->dev; |
379 | |
380 | if (!abb) { |
381 | dev_err_ratelimited(dev, "%s: No regulator drvdata\n" , |
382 | __func__); |
383 | return -ENODEV; |
384 | } |
385 | |
386 | if (!desc->n_voltages || !abb->info) { |
387 | dev_err_ratelimited(dev, |
388 | "%s: No valid voltage table entries?\n" , |
389 | __func__); |
390 | return -EINVAL; |
391 | } |
392 | |
393 | if (abb->current_info_idx >= (int)desc->n_voltages) { |
394 | dev_err(dev, "%s: Corrupted data? idx(%d) >= n_voltages(%d)\n" , |
395 | __func__, abb->current_info_idx, desc->n_voltages); |
396 | return -EINVAL; |
397 | } |
398 | |
399 | return abb->current_info_idx; |
400 | } |
401 | |
402 | /** |
403 | * ti_abb_init_timings() - setup ABB clock timing for the current platform |
404 | * @dev: device |
405 | * @abb: pointer to the abb instance |
406 | * |
407 | * Return: 0 if timing is updated, else returns error result. |
408 | */ |
409 | static int ti_abb_init_timings(struct device *dev, struct ti_abb *abb) |
410 | { |
411 | u32 clock_cycles; |
412 | u32 clk_rate, sr2_wt_cnt_val, cycle_rate; |
413 | const struct ti_abb_reg *regs = abb->regs; |
414 | int ret; |
415 | char *pname = "ti,settling-time" ; |
416 | |
417 | /* read device tree properties */ |
418 | ret = of_property_read_u32(np: dev->of_node, propname: pname, out_value: &abb->settling_time); |
419 | if (ret) { |
420 | dev_err(dev, "Unable to get property '%s'(%d)\n" , pname, ret); |
421 | return ret; |
422 | } |
423 | |
424 | /* ABB LDO cannot be settle in 0 time */ |
425 | if (!abb->settling_time) { |
426 | dev_err(dev, "Invalid property:'%s' set as 0!\n" , pname); |
427 | return -EINVAL; |
428 | } |
429 | |
430 | pname = "ti,clock-cycles" ; |
431 | ret = of_property_read_u32(np: dev->of_node, propname: pname, out_value: &clock_cycles); |
432 | if (ret) { |
433 | dev_err(dev, "Unable to get property '%s'(%d)\n" , pname, ret); |
434 | return ret; |
435 | } |
436 | /* ABB LDO cannot be settle in 0 clock cycles */ |
437 | if (!clock_cycles) { |
438 | dev_err(dev, "Invalid property:'%s' set as 0!\n" , pname); |
439 | return -EINVAL; |
440 | } |
441 | |
442 | abb->clk = devm_clk_get(dev, NULL); |
443 | if (IS_ERR(ptr: abb->clk)) { |
444 | ret = PTR_ERR(ptr: abb->clk); |
445 | dev_err(dev, "%s: Unable to get clk(%d)\n" , __func__, ret); |
446 | return ret; |
447 | } |
448 | |
449 | /* |
450 | * SR2_WTCNT_VALUE is the settling time for the ABB ldo after a |
451 | * transition and must be programmed with the correct time at boot. |
452 | * The value programmed into the register is the number of SYS_CLK |
453 | * clock cycles that match a given wall time profiled for the ldo. |
454 | * This value depends on: |
455 | * settling time of ldo in micro-seconds (varies per OMAP family) |
456 | * # of clock cycles per SYS_CLK period (varies per OMAP family) |
457 | * the SYS_CLK frequency in MHz (varies per board) |
458 | * The formula is: |
459 | * |
460 | * ldo settling time (in micro-seconds) |
461 | * SR2_WTCNT_VALUE = ------------------------------------------ |
462 | * (# system clock cycles) * (sys_clk period) |
463 | * |
464 | * Put another way: |
465 | * |
466 | * SR2_WTCNT_VALUE = settling time / (# SYS_CLK cycles / SYS_CLK rate)) |
467 | * |
468 | * To avoid dividing by zero multiply both "# clock cycles" and |
469 | * "settling time" by 10 such that the final result is the one we want. |
470 | */ |
471 | |
472 | /* Convert SYS_CLK rate to MHz & prevent divide by zero */ |
473 | clk_rate = DIV_ROUND_CLOSEST(clk_get_rate(abb->clk), 1000000); |
474 | |
475 | /* Calculate cycle rate */ |
476 | cycle_rate = DIV_ROUND_CLOSEST(clock_cycles * 10, clk_rate); |
477 | |
478 | /* Calculate SR2_WTCNT_VALUE */ |
479 | sr2_wt_cnt_val = DIV_ROUND_CLOSEST(abb->settling_time * 10, cycle_rate); |
480 | |
481 | dev_dbg(dev, "%s: Clk_rate=%ld, sr2_cnt=0x%08x\n" , __func__, |
482 | clk_get_rate(abb->clk), sr2_wt_cnt_val); |
483 | |
484 | ti_abb_rmw(mask: regs->sr2_wtcnt_value_mask, value: sr2_wt_cnt_val, reg: abb->setup_reg); |
485 | |
486 | return 0; |
487 | } |
488 | |
489 | /** |
490 | * ti_abb_init_table() - Initialize ABB table from device tree |
491 | * @dev: device |
492 | * @abb: pointer to the abb instance |
493 | * @rinit_data: regulator initdata |
494 | * |
495 | * Return: 0 on success or appropriate error value when fails |
496 | */ |
497 | static int ti_abb_init_table(struct device *dev, struct ti_abb *abb, |
498 | struct regulator_init_data *rinit_data) |
499 | { |
500 | struct ti_abb_info *info; |
501 | const u32 num_values = 6; |
502 | char *pname = "ti,abb_info" ; |
503 | u32 i; |
504 | unsigned int *volt_table; |
505 | int num_entries, min_uV = INT_MAX, max_uV = 0; |
506 | struct regulation_constraints *c = &rinit_data->constraints; |
507 | |
508 | /* |
509 | * Each abb_info is a set of n-tuple, where n is num_values, consisting |
510 | * of voltage and a set of detection logic for ABB information for that |
511 | * voltage to apply. |
512 | */ |
513 | num_entries = of_property_count_u32_elems(np: dev->of_node, propname: pname); |
514 | if (num_entries < 0) { |
515 | dev_err(dev, "No '%s' property?\n" , pname); |
516 | return num_entries; |
517 | } |
518 | |
519 | if (!num_entries || (num_entries % num_values)) { |
520 | dev_err(dev, "All '%s' list entries need %d vals\n" , pname, |
521 | num_values); |
522 | return -EINVAL; |
523 | } |
524 | num_entries /= num_values; |
525 | |
526 | info = devm_kcalloc(dev, n: num_entries, size: sizeof(*info), GFP_KERNEL); |
527 | if (!info) |
528 | return -ENOMEM; |
529 | |
530 | abb->info = info; |
531 | |
532 | volt_table = devm_kcalloc(dev, n: num_entries, size: sizeof(unsigned int), |
533 | GFP_KERNEL); |
534 | if (!volt_table) |
535 | return -ENOMEM; |
536 | |
537 | abb->rdesc.n_voltages = num_entries; |
538 | abb->rdesc.volt_table = volt_table; |
539 | /* We do not know where the OPP voltage is at the moment */ |
540 | abb->current_info_idx = -EINVAL; |
541 | |
542 | for (i = 0; i < num_entries; i++, info++, volt_table++) { |
543 | u32 efuse_offset, rbb_mask, fbb_mask, vset_mask; |
544 | u32 efuse_val; |
545 | |
546 | /* NOTE: num_values should equal to entries picked up here */ |
547 | of_property_read_u32_index(np: dev->of_node, propname: pname, index: i * num_values, |
548 | out_value: volt_table); |
549 | of_property_read_u32_index(np: dev->of_node, propname: pname, |
550 | index: i * num_values + 1, out_value: &info->opp_sel); |
551 | of_property_read_u32_index(np: dev->of_node, propname: pname, |
552 | index: i * num_values + 2, out_value: &efuse_offset); |
553 | of_property_read_u32_index(np: dev->of_node, propname: pname, |
554 | index: i * num_values + 3, out_value: &rbb_mask); |
555 | of_property_read_u32_index(np: dev->of_node, propname: pname, |
556 | index: i * num_values + 4, out_value: &fbb_mask); |
557 | of_property_read_u32_index(np: dev->of_node, propname: pname, |
558 | index: i * num_values + 5, out_value: &vset_mask); |
559 | |
560 | dev_dbg(dev, |
561 | "[%d]v=%d ABB=%d ef=0x%x rbb=0x%x fbb=0x%x vset=0x%x\n" , |
562 | i, *volt_table, info->opp_sel, efuse_offset, rbb_mask, |
563 | fbb_mask, vset_mask); |
564 | |
565 | /* Find min/max for voltage set */ |
566 | if (min_uV > *volt_table) |
567 | min_uV = *volt_table; |
568 | if (max_uV < *volt_table) |
569 | max_uV = *volt_table; |
570 | |
571 | if (!abb->efuse_base) { |
572 | /* Ignore invalid data, but warn to help cleanup */ |
573 | if (efuse_offset || rbb_mask || fbb_mask || vset_mask) |
574 | dev_err(dev, "prop '%s': v=%d,bad efuse/mask\n" , |
575 | pname, *volt_table); |
576 | goto check_abb; |
577 | } |
578 | |
579 | efuse_val = readl(addr: abb->efuse_base + efuse_offset); |
580 | |
581 | /* Use ABB recommendation from Efuse */ |
582 | if (efuse_val & rbb_mask) |
583 | info->opp_sel = TI_ABB_SLOW_OPP; |
584 | else if (efuse_val & fbb_mask) |
585 | info->opp_sel = TI_ABB_FAST_OPP; |
586 | else if (rbb_mask || fbb_mask) |
587 | info->opp_sel = TI_ABB_NOMINAL_OPP; |
588 | |
589 | dev_dbg(dev, |
590 | "[%d]v=%d efusev=0x%x final ABB=%d\n" , |
591 | i, *volt_table, efuse_val, info->opp_sel); |
592 | |
593 | /* Use recommended Vset bits from Efuse */ |
594 | if (!abb->ldo_base) { |
595 | if (vset_mask) |
596 | dev_err(dev, "prop'%s':v=%d vst=%x LDO base?\n" , |
597 | pname, *volt_table, vset_mask); |
598 | continue; |
599 | } |
600 | info->vset = (efuse_val & vset_mask) >> __ffs(vset_mask); |
601 | dev_dbg(dev, "[%d]v=%d vset=%x\n" , i, *volt_table, info->vset); |
602 | check_abb: |
603 | switch (info->opp_sel) { |
604 | case TI_ABB_NOMINAL_OPP: |
605 | case TI_ABB_FAST_OPP: |
606 | case TI_ABB_SLOW_OPP: |
607 | /* Valid values */ |
608 | break; |
609 | default: |
610 | dev_err(dev, "%s:[%d]v=%d, ABB=%d is invalid! Abort!\n" , |
611 | __func__, i, *volt_table, info->opp_sel); |
612 | return -EINVAL; |
613 | } |
614 | } |
615 | |
616 | /* Setup the min/max voltage constraints from the supported list */ |
617 | c->min_uV = min_uV; |
618 | c->max_uV = max_uV; |
619 | |
620 | return 0; |
621 | } |
622 | |
623 | static const struct regulator_ops ti_abb_reg_ops = { |
624 | .list_voltage = regulator_list_voltage_table, |
625 | |
626 | .set_voltage_sel = ti_abb_set_voltage_sel, |
627 | .get_voltage_sel = ti_abb_get_voltage_sel, |
628 | }; |
629 | |
630 | /* Default ABB block offsets, IF this changes in future, create new one */ |
631 | static const struct ti_abb_reg abb_regs_v1 = { |
632 | /* WARNING: registers are wrongly documented in TRM */ |
633 | .setup_off = 0x04, |
634 | .control_off = 0x00, |
635 | |
636 | .sr2_wtcnt_value_mask = (0xff << 8), |
637 | .fbb_sel_mask = (0x01 << 2), |
638 | .rbb_sel_mask = (0x01 << 1), |
639 | .sr2_en_mask = (0x01 << 0), |
640 | |
641 | .opp_change_mask = (0x01 << 2), |
642 | .opp_sel_mask = (0x03 << 0), |
643 | }; |
644 | |
645 | static const struct ti_abb_reg abb_regs_v2 = { |
646 | .setup_off = 0x00, |
647 | .control_off = 0x04, |
648 | |
649 | .sr2_wtcnt_value_mask = (0xff << 8), |
650 | .fbb_sel_mask = (0x01 << 2), |
651 | .rbb_sel_mask = (0x01 << 1), |
652 | .sr2_en_mask = (0x01 << 0), |
653 | |
654 | .opp_change_mask = (0x01 << 2), |
655 | .opp_sel_mask = (0x03 << 0), |
656 | }; |
657 | |
658 | static const struct ti_abb_reg abb_regs_generic = { |
659 | .sr2_wtcnt_value_mask = (0xff << 8), |
660 | .fbb_sel_mask = (0x01 << 2), |
661 | .rbb_sel_mask = (0x01 << 1), |
662 | .sr2_en_mask = (0x01 << 0), |
663 | |
664 | .opp_change_mask = (0x01 << 2), |
665 | .opp_sel_mask = (0x03 << 0), |
666 | }; |
667 | |
668 | static const struct of_device_id ti_abb_of_match[] = { |
669 | {.compatible = "ti,abb-v1" , .data = &abb_regs_v1}, |
670 | {.compatible = "ti,abb-v2" , .data = &abb_regs_v2}, |
671 | {.compatible = "ti,abb-v3" , .data = &abb_regs_generic}, |
672 | { }, |
673 | }; |
674 | |
675 | MODULE_DEVICE_TABLE(of, ti_abb_of_match); |
676 | |
677 | /** |
678 | * ti_abb_probe() - Initialize an ABB ldo instance |
679 | * @pdev: ABB platform device |
680 | * |
681 | * Initializes an individual ABB LDO for required Body-Bias. ABB is used to |
682 | * additional bias supply to SoC modules for power savings or mandatory stability |
683 | * configuration at certain Operating Performance Points(OPPs). |
684 | * |
685 | * Return: 0 on success or appropriate error value when fails |
686 | */ |
687 | static int ti_abb_probe(struct platform_device *pdev) |
688 | { |
689 | struct device *dev = &pdev->dev; |
690 | struct resource *res; |
691 | struct ti_abb *abb; |
692 | struct regulator_init_data *initdata = NULL; |
693 | struct regulator_dev *rdev = NULL; |
694 | struct regulator_desc *desc; |
695 | struct regulation_constraints *c; |
696 | struct regulator_config config = { }; |
697 | char *pname; |
698 | int ret = 0; |
699 | |
700 | abb = devm_kzalloc(dev, size: sizeof(struct ti_abb), GFP_KERNEL); |
701 | if (!abb) |
702 | return -ENOMEM; |
703 | |
704 | abb->regs = device_get_match_data(dev); |
705 | if (!abb->regs) { |
706 | dev_err(dev, "%s: Bad data in match\n" , __func__); |
707 | return -EINVAL; |
708 | } |
709 | |
710 | /* Map ABB resources */ |
711 | if (abb->regs->setup_off || abb->regs->control_off) { |
712 | abb->base = devm_platform_ioremap_resource_byname(pdev, name: "base-address" ); |
713 | if (IS_ERR(ptr: abb->base)) |
714 | return PTR_ERR(ptr: abb->base); |
715 | |
716 | abb->setup_reg = abb->base + abb->regs->setup_off; |
717 | abb->control_reg = abb->base + abb->regs->control_off; |
718 | |
719 | } else { |
720 | abb->control_reg = devm_platform_ioremap_resource_byname(pdev, name: "control-address" ); |
721 | if (IS_ERR(ptr: abb->control_reg)) |
722 | return PTR_ERR(ptr: abb->control_reg); |
723 | |
724 | abb->setup_reg = devm_platform_ioremap_resource_byname(pdev, name: "setup-address" ); |
725 | if (IS_ERR(ptr: abb->setup_reg)) |
726 | return PTR_ERR(ptr: abb->setup_reg); |
727 | } |
728 | |
729 | abb->int_base = devm_platform_ioremap_resource_byname(pdev, name: "int-address" ); |
730 | if (IS_ERR(ptr: abb->int_base)) |
731 | return PTR_ERR(ptr: abb->int_base); |
732 | |
733 | /* Map Optional resources */ |
734 | pname = "efuse-address" ; |
735 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, pname); |
736 | if (!res) { |
737 | dev_dbg(dev, "Missing '%s' IO resource\n" , pname); |
738 | ret = -ENODEV; |
739 | goto skip_opt; |
740 | } |
741 | |
742 | /* |
743 | * We may have shared efuse register offsets which are read-only |
744 | * between domains |
745 | */ |
746 | abb->efuse_base = devm_ioremap(dev, offset: res->start, |
747 | size: resource_size(res)); |
748 | if (!abb->efuse_base) { |
749 | dev_err(dev, "Unable to map '%s'\n" , pname); |
750 | return -ENOMEM; |
751 | } |
752 | |
753 | pname = "ldo-address" ; |
754 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, pname); |
755 | if (!res) { |
756 | dev_dbg(dev, "Missing '%s' IO resource\n" , pname); |
757 | ret = -ENODEV; |
758 | goto skip_opt; |
759 | } |
760 | abb->ldo_base = devm_ioremap_resource(dev, res); |
761 | if (IS_ERR(ptr: abb->ldo_base)) |
762 | return PTR_ERR(ptr: abb->ldo_base); |
763 | |
764 | /* IF ldo_base is set, the following are mandatory */ |
765 | pname = "ti,ldovbb-override-mask" ; |
766 | ret = |
767 | of_property_read_u32(np: pdev->dev.of_node, propname: pname, |
768 | out_value: &abb->ldovbb_override_mask); |
769 | if (ret) { |
770 | dev_err(dev, "Missing '%s' (%d)\n" , pname, ret); |
771 | return ret; |
772 | } |
773 | if (!abb->ldovbb_override_mask) { |
774 | dev_err(dev, "Invalid property:'%s' set as 0!\n" , pname); |
775 | return -EINVAL; |
776 | } |
777 | |
778 | pname = "ti,ldovbb-vset-mask" ; |
779 | ret = |
780 | of_property_read_u32(np: pdev->dev.of_node, propname: pname, |
781 | out_value: &abb->ldovbb_vset_mask); |
782 | if (ret) { |
783 | dev_err(dev, "Missing '%s' (%d)\n" , pname, ret); |
784 | return ret; |
785 | } |
786 | if (!abb->ldovbb_vset_mask) { |
787 | dev_err(dev, "Invalid property:'%s' set as 0!\n" , pname); |
788 | return -EINVAL; |
789 | } |
790 | |
791 | skip_opt: |
792 | pname = "ti,tranxdone-status-mask" ; |
793 | ret = |
794 | of_property_read_u32(np: pdev->dev.of_node, propname: pname, |
795 | out_value: &abb->txdone_mask); |
796 | if (ret) { |
797 | dev_err(dev, "Missing '%s' (%d)\n" , pname, ret); |
798 | return ret; |
799 | } |
800 | if (!abb->txdone_mask) { |
801 | dev_err(dev, "Invalid property:'%s' set as 0!\n" , pname); |
802 | return -EINVAL; |
803 | } |
804 | |
805 | initdata = of_get_regulator_init_data(dev, node: pdev->dev.of_node, |
806 | desc: &abb->rdesc); |
807 | if (!initdata) { |
808 | dev_err(dev, "%s: Unable to alloc regulator init data\n" , |
809 | __func__); |
810 | return -ENOMEM; |
811 | } |
812 | |
813 | /* init ABB opp_sel table */ |
814 | ret = ti_abb_init_table(dev, abb, rinit_data: initdata); |
815 | if (ret) |
816 | return ret; |
817 | |
818 | /* init ABB timing */ |
819 | ret = ti_abb_init_timings(dev, abb); |
820 | if (ret) |
821 | return ret; |
822 | |
823 | desc = &abb->rdesc; |
824 | desc->name = dev_name(dev); |
825 | desc->owner = THIS_MODULE; |
826 | desc->type = REGULATOR_VOLTAGE; |
827 | desc->ops = &ti_abb_reg_ops; |
828 | |
829 | c = &initdata->constraints; |
830 | if (desc->n_voltages > 1) |
831 | c->valid_ops_mask |= REGULATOR_CHANGE_VOLTAGE; |
832 | c->always_on = true; |
833 | |
834 | config.dev = dev; |
835 | config.init_data = initdata; |
836 | config.driver_data = abb; |
837 | config.of_node = pdev->dev.of_node; |
838 | |
839 | rdev = devm_regulator_register(dev, regulator_desc: desc, config: &config); |
840 | if (IS_ERR(ptr: rdev)) { |
841 | ret = PTR_ERR(ptr: rdev); |
842 | dev_err(dev, "%s: failed to register regulator(%d)\n" , |
843 | __func__, ret); |
844 | return ret; |
845 | } |
846 | platform_set_drvdata(pdev, data: rdev); |
847 | |
848 | /* Enable the ldo if not already done by bootloader */ |
849 | ti_abb_rmw(mask: abb->regs->sr2_en_mask, value: 1, reg: abb->setup_reg); |
850 | |
851 | return 0; |
852 | } |
853 | |
854 | MODULE_ALIAS("platform:ti_abb" ); |
855 | |
856 | static struct platform_driver ti_abb_driver = { |
857 | .probe = ti_abb_probe, |
858 | .driver = { |
859 | .name = "ti_abb" , |
860 | .probe_type = PROBE_PREFER_ASYNCHRONOUS, |
861 | .of_match_table = ti_abb_of_match, |
862 | }, |
863 | }; |
864 | module_platform_driver(ti_abb_driver); |
865 | |
866 | MODULE_DESCRIPTION("Texas Instruments ABB LDO regulator driver" ); |
867 | MODULE_AUTHOR("Texas Instruments Inc." ); |
868 | MODULE_LICENSE("GPL v2" ); |
869 | |