aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/regulator/ti-abb-regulator.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/regulator/ti-abb-regulator.c')
-rw-r--r--drivers/regulator/ti-abb-regulator.c140
1 files changed, 80 insertions, 60 deletions
diff --git a/drivers/regulator/ti-abb-regulator.c b/drivers/regulator/ti-abb-regulator.c
index b187b6bba7ad..a2dabb575b97 100644
--- a/drivers/regulator/ti-abb-regulator.c
+++ b/drivers/regulator/ti-abb-regulator.c
@@ -54,8 +54,8 @@ struct ti_abb_info {
54 54
55/** 55/**
56 * struct ti_abb_reg - Register description for ABB block 56 * struct ti_abb_reg - Register description for ABB block
57 * @setup_reg: setup register offset from base 57 * @setup_off: setup register offset from base
58 * @control_reg: control register offset from base 58 * @control_off: control register offset from base
59 * @sr2_wtcnt_value_mask: setup register- sr2_wtcnt_value mask 59 * @sr2_wtcnt_value_mask: setup register- sr2_wtcnt_value mask
60 * @fbb_sel_mask: setup register- FBB sel mask 60 * @fbb_sel_mask: setup register- FBB sel mask
61 * @rbb_sel_mask: setup register- RBB sel mask 61 * @rbb_sel_mask: setup register- RBB sel mask
@@ -64,8 +64,8 @@ struct ti_abb_info {
64 * @opp_sel_mask: control register - mask for mode to operate 64 * @opp_sel_mask: control register - mask for mode to operate
65 */ 65 */
66struct ti_abb_reg { 66struct ti_abb_reg {
67 u32 setup_reg; 67 u32 setup_off;
68 u32 control_reg; 68 u32 control_off;
69 69
70 /* Setup register fields */ 70 /* Setup register fields */
71 u32 sr2_wtcnt_value_mask; 71 u32 sr2_wtcnt_value_mask;
@@ -83,6 +83,8 @@ struct ti_abb_reg {
83 * @rdesc: regulator descriptor 83 * @rdesc: regulator descriptor
84 * @clk: clock(usually sysclk) supplying ABB block 84 * @clk: clock(usually sysclk) supplying ABB block
85 * @base: base address of ABB block 85 * @base: base address of ABB block
86 * @setup_reg: setup register of ABB block
87 * @control_reg: control register of ABB block
86 * @int_base: interrupt register base address 88 * @int_base: interrupt register base address
87 * @efuse_base: (optional) efuse base address for ABB modes 89 * @efuse_base: (optional) efuse base address for ABB modes
88 * @ldo_base: (optional) LDOVBB vset override base address 90 * @ldo_base: (optional) LDOVBB vset override base address
@@ -99,6 +101,8 @@ struct ti_abb {
99 struct regulator_desc rdesc; 101 struct regulator_desc rdesc;
100 struct clk *clk; 102 struct clk *clk;
101 void __iomem *base; 103 void __iomem *base;
104 void __iomem *setup_reg;
105 void __iomem *control_reg;
102 void __iomem *int_base; 106 void __iomem *int_base;
103 void __iomem *efuse_base; 107 void __iomem *efuse_base;
104 void __iomem *ldo_base; 108 void __iomem *ldo_base;
@@ -118,20 +122,18 @@ struct ti_abb {
118 * ti_abb_rmw() - handy wrapper to set specific register bits 122 * ti_abb_rmw() - handy wrapper to set specific register bits
119 * @mask: mask for register field 123 * @mask: mask for register field
120 * @value: value shifted to mask location and written 124 * @value: value shifted to mask location and written
121 * @offset: offset of register 125 * @reg: register address
122 * @base: base address
123 * 126 *
124 * Return: final register value (may be unused) 127 * Return: final register value (may be unused)
125 */ 128 */
126static inline u32 ti_abb_rmw(u32 mask, u32 value, u32 offset, 129static inline u32 ti_abb_rmw(u32 mask, u32 value, void __iomem *reg)
127 void __iomem *base)
128{ 130{
129 u32 val; 131 u32 val;
130 132
131 val = readl(base + offset); 133 val = readl(reg);
132 val &= ~mask; 134 val &= ~mask;
133 val |= (value << __ffs(mask)) & mask; 135 val |= (value << __ffs(mask)) & mask;
134 writel(val, base + offset); 136 writel(val, reg);
135 137
136 return val; 138 return val;
137} 139}
@@ -263,21 +265,19 @@ static int ti_abb_set_opp(struct regulator_dev *rdev, struct ti_abb *abb,
263 if (ret) 265 if (ret)
264 goto out; 266 goto out;
265 267
266 ti_abb_rmw(regs->fbb_sel_mask | regs->rbb_sel_mask, 0, regs->setup_reg, 268 ti_abb_rmw(regs->fbb_sel_mask | regs->rbb_sel_mask, 0, abb->setup_reg);
267 abb->base);
268 269
269 switch (info->opp_sel) { 270 switch (info->opp_sel) {
270 case TI_ABB_SLOW_OPP: 271 case TI_ABB_SLOW_OPP:
271 ti_abb_rmw(regs->rbb_sel_mask, 1, regs->setup_reg, abb->base); 272 ti_abb_rmw(regs->rbb_sel_mask, 1, abb->setup_reg);
272 break; 273 break;
273 case TI_ABB_FAST_OPP: 274 case TI_ABB_FAST_OPP:
274 ti_abb_rmw(regs->fbb_sel_mask, 1, regs->setup_reg, abb->base); 275 ti_abb_rmw(regs->fbb_sel_mask, 1, abb->setup_reg);
275 break; 276 break;
276 } 277 }
277 278
278 /* program next state of ABB ldo */ 279 /* program next state of ABB ldo */
279 ti_abb_rmw(regs->opp_sel_mask, info->opp_sel, regs->control_reg, 280 ti_abb_rmw(regs->opp_sel_mask, info->opp_sel, abb->control_reg);
280 abb->base);
281 281
282 /* 282 /*
283 * program LDO VBB vset override if needed for !bypass mode 283 * program LDO VBB vset override if needed for !bypass mode
@@ -288,7 +288,7 @@ static int ti_abb_set_opp(struct regulator_dev *rdev, struct ti_abb *abb,
288 ti_abb_program_ldovbb(dev, abb, info); 288 ti_abb_program_ldovbb(dev, abb, info);
289 289
290 /* Initiate ABB ldo change */ 290 /* Initiate ABB ldo change */
291 ti_abb_rmw(regs->opp_change_mask, 1, regs->control_reg, abb->base); 291 ti_abb_rmw(regs->opp_change_mask, 1, abb->control_reg);
292 292
293 /* Wait for ABB LDO to complete transition to new Bias setting */ 293 /* Wait for ABB LDO to complete transition to new Bias setting */
294 ret = ti_abb_wait_txdone(dev, abb); 294 ret = ti_abb_wait_txdone(dev, abb);
@@ -490,8 +490,7 @@ static int ti_abb_init_timings(struct device *dev, struct ti_abb *abb)
490 dev_dbg(dev, "%s: Clk_rate=%ld, sr2_cnt=0x%08x\n", __func__, 490 dev_dbg(dev, "%s: Clk_rate=%ld, sr2_cnt=0x%08x\n", __func__,
491 clk_get_rate(abb->clk), sr2_wt_cnt_val); 491 clk_get_rate(abb->clk), sr2_wt_cnt_val);
492 492
493 ti_abb_rmw(regs->sr2_wtcnt_value_mask, sr2_wt_cnt_val, regs->setup_reg, 493 ti_abb_rmw(regs->sr2_wtcnt_value_mask, sr2_wt_cnt_val, abb->setup_reg);
494 abb->base);
495 494
496 return 0; 495 return 0;
497} 496}
@@ -508,32 +507,24 @@ static int ti_abb_init_table(struct device *dev, struct ti_abb *abb,
508 struct regulator_init_data *rinit_data) 507 struct regulator_init_data *rinit_data)
509{ 508{
510 struct ti_abb_info *info; 509 struct ti_abb_info *info;
511 const struct property *prop;
512 const __be32 *abb_info;
513 const u32 num_values = 6; 510 const u32 num_values = 6;
514 char *pname = "ti,abb_info"; 511 char *pname = "ti,abb_info";
515 u32 num_entries, i; 512 u32 i;
516 unsigned int *volt_table; 513 unsigned int *volt_table;
517 int min_uV = INT_MAX, max_uV = 0; 514 int num_entries, min_uV = INT_MAX, max_uV = 0;
518 struct regulation_constraints *c = &rinit_data->constraints; 515 struct regulation_constraints *c = &rinit_data->constraints;
519 516
520 prop = of_find_property(dev->of_node, pname, NULL);
521 if (!prop) {
522 dev_err(dev, "No '%s' property?\n", pname);
523 return -ENODEV;
524 }
525
526 if (!prop->value) {
527 dev_err(dev, "Empty '%s' property?\n", pname);
528 return -ENODATA;
529 }
530
531 /* 517 /*
532 * Each abb_info is a set of n-tuple, where n is num_values, consisting 518 * Each abb_info is a set of n-tuple, where n is num_values, consisting
533 * of voltage and a set of detection logic for ABB information for that 519 * of voltage and a set of detection logic for ABB information for that
534 * voltage to apply. 520 * voltage to apply.
535 */ 521 */
536 num_entries = prop->length / sizeof(u32); 522 num_entries = of_property_count_u32_elems(dev->of_node, pname);
523 if (num_entries < 0) {
524 dev_err(dev, "No '%s' property?\n", pname);
525 return num_entries;
526 }
527
537 if (!num_entries || (num_entries % num_values)) { 528 if (!num_entries || (num_entries % num_values)) {
538 dev_err(dev, "All '%s' list entries need %d vals\n", pname, 529 dev_err(dev, "All '%s' list entries need %d vals\n", pname,
539 num_values); 530 num_values);
@@ -542,38 +533,38 @@ static int ti_abb_init_table(struct device *dev, struct ti_abb *abb,
542 num_entries /= num_values; 533 num_entries /= num_values;
543 534
544 info = devm_kzalloc(dev, sizeof(*info) * num_entries, GFP_KERNEL); 535 info = devm_kzalloc(dev, sizeof(*info) * num_entries, GFP_KERNEL);
545 if (!info) { 536 if (!info)
546 dev_err(dev, "Can't allocate info table for '%s' property\n",
547 pname);
548 return -ENOMEM; 537 return -ENOMEM;
549 } 538
550 abb->info = info; 539 abb->info = info;
551 540
552 volt_table = devm_kzalloc(dev, sizeof(unsigned int) * num_entries, 541 volt_table = devm_kzalloc(dev, sizeof(unsigned int) * num_entries,
553 GFP_KERNEL); 542 GFP_KERNEL);
554 if (!volt_table) { 543 if (!volt_table)
555 dev_err(dev, "Can't allocate voltage table for '%s' property\n",
556 pname);
557 return -ENOMEM; 544 return -ENOMEM;
558 }
559 545
560 abb->rdesc.n_voltages = num_entries; 546 abb->rdesc.n_voltages = num_entries;
561 abb->rdesc.volt_table = volt_table; 547 abb->rdesc.volt_table = volt_table;
562 /* We do not know where the OPP voltage is at the moment */ 548 /* We do not know where the OPP voltage is at the moment */
563 abb->current_info_idx = -EINVAL; 549 abb->current_info_idx = -EINVAL;
564 550
565 abb_info = prop->value;
566 for (i = 0; i < num_entries; i++, info++, volt_table++) { 551 for (i = 0; i < num_entries; i++, info++, volt_table++) {
567 u32 efuse_offset, rbb_mask, fbb_mask, vset_mask; 552 u32 efuse_offset, rbb_mask, fbb_mask, vset_mask;
568 u32 efuse_val; 553 u32 efuse_val;
569 554
570 /* NOTE: num_values should equal to entries picked up here */ 555 /* NOTE: num_values should equal to entries picked up here */
571 *volt_table = be32_to_cpup(abb_info++); 556 of_property_read_u32_index(dev->of_node, pname, i * num_values,
572 info->opp_sel = be32_to_cpup(abb_info++); 557 volt_table);
573 efuse_offset = be32_to_cpup(abb_info++); 558 of_property_read_u32_index(dev->of_node, pname,
574 rbb_mask = be32_to_cpup(abb_info++); 559 i * num_values + 1, &info->opp_sel);
575 fbb_mask = be32_to_cpup(abb_info++); 560 of_property_read_u32_index(dev->of_node, pname,
576 vset_mask = be32_to_cpup(abb_info++); 561 i * num_values + 2, &efuse_offset);
562 of_property_read_u32_index(dev->of_node, pname,
563 i * num_values + 3, &rbb_mask);
564 of_property_read_u32_index(dev->of_node, pname,
565 i * num_values + 4, &fbb_mask);
566 of_property_read_u32_index(dev->of_node, pname,
567 i * num_values + 5, &vset_mask);
577 568
578 dev_dbg(dev, 569 dev_dbg(dev,
579 "[%d]v=%d ABB=%d ef=0x%x rbb=0x%x fbb=0x%x vset=0x%x\n", 570 "[%d]v=%d ABB=%d ef=0x%x rbb=0x%x fbb=0x%x vset=0x%x\n",
@@ -648,8 +639,8 @@ static struct regulator_ops ti_abb_reg_ops = {
648/* Default ABB block offsets, IF this changes in future, create new one */ 639/* Default ABB block offsets, IF this changes in future, create new one */
649static const struct ti_abb_reg abb_regs_v1 = { 640static const struct ti_abb_reg abb_regs_v1 = {
650 /* WARNING: registers are wrongly documented in TRM */ 641 /* WARNING: registers are wrongly documented in TRM */
651 .setup_reg = 0x04, 642 .setup_off = 0x04,
652 .control_reg = 0x00, 643 .control_off = 0x00,
653 644
654 .sr2_wtcnt_value_mask = (0xff << 8), 645 .sr2_wtcnt_value_mask = (0xff << 8),
655 .fbb_sel_mask = (0x01 << 2), 646 .fbb_sel_mask = (0x01 << 2),
@@ -661,8 +652,8 @@ static const struct ti_abb_reg abb_regs_v1 = {
661}; 652};
662 653
663static const struct ti_abb_reg abb_regs_v2 = { 654static const struct ti_abb_reg abb_regs_v2 = {
664 .setup_reg = 0x00, 655 .setup_off = 0x00,
665 .control_reg = 0x04, 656 .control_off = 0x04,
666 657
667 .sr2_wtcnt_value_mask = (0xff << 8), 658 .sr2_wtcnt_value_mask = (0xff << 8),
668 .fbb_sel_mask = (0x01 << 2), 659 .fbb_sel_mask = (0x01 << 2),
@@ -673,9 +664,20 @@ static const struct ti_abb_reg abb_regs_v2 = {
673 .opp_sel_mask = (0x03 << 0), 664 .opp_sel_mask = (0x03 << 0),
674}; 665};
675 666
667static const struct ti_abb_reg abb_regs_generic = {
668 .sr2_wtcnt_value_mask = (0xff << 8),
669 .fbb_sel_mask = (0x01 << 2),
670 .rbb_sel_mask = (0x01 << 1),
671 .sr2_en_mask = (0x01 << 0),
672
673 .opp_change_mask = (0x01 << 2),
674 .opp_sel_mask = (0x03 << 0),
675};
676
676static const struct of_device_id ti_abb_of_match[] = { 677static const struct of_device_id ti_abb_of_match[] = {
677 {.compatible = "ti,abb-v1", .data = &abb_regs_v1}, 678 {.compatible = "ti,abb-v1", .data = &abb_regs_v1},
678 {.compatible = "ti,abb-v2", .data = &abb_regs_v2}, 679 {.compatible = "ti,abb-v2", .data = &abb_regs_v2},
680 {.compatible = "ti,abb-v3", .data = &abb_regs_generic},
679 { }, 681 { },
680}; 682};
681 683
@@ -722,11 +724,29 @@ static int ti_abb_probe(struct platform_device *pdev)
722 abb->regs = match->data; 724 abb->regs = match->data;
723 725
724 /* Map ABB resources */ 726 /* Map ABB resources */
725 pname = "base-address"; 727 if (abb->regs->setup_off || abb->regs->control_off) {
726 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, pname); 728 pname = "base-address";
727 abb->base = devm_ioremap_resource(dev, res); 729 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, pname);
728 if (IS_ERR(abb->base)) 730 abb->base = devm_ioremap_resource(dev, res);
729 return PTR_ERR(abb->base); 731 if (IS_ERR(abb->base))
732 return PTR_ERR(abb->base);
733
734 abb->setup_reg = abb->base + abb->regs->setup_off;
735 abb->control_reg = abb->base + abb->regs->control_off;
736
737 } else {
738 pname = "control-address";
739 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, pname);
740 abb->control_reg = devm_ioremap_resource(dev, res);
741 if (IS_ERR(abb->control_reg))
742 return PTR_ERR(abb->control_reg);
743
744 pname = "setup-address";
745 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, pname);
746 abb->setup_reg = devm_ioremap_resource(dev, res);
747 if (IS_ERR(abb->setup_reg))
748 return PTR_ERR(abb->setup_reg);
749 }
730 750
731 pname = "int-address"; 751 pname = "int-address";
732 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, pname); 752 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, pname);
@@ -860,7 +880,7 @@ skip_opt:
860 platform_set_drvdata(pdev, rdev); 880 platform_set_drvdata(pdev, rdev);
861 881
862 /* Enable the ldo if not already done by bootloader */ 882 /* Enable the ldo if not already done by bootloader */
863 ti_abb_rmw(abb->regs->sr2_en_mask, 1, abb->regs->setup_reg, abb->base); 883 ti_abb_rmw(abb->regs->sr2_en_mask, 1, abb->setup_reg);
864 884
865 return 0; 885 return 0;
866} 886}