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