Lines Matching +full:ignore +full:- +full:power +full:- +full:on +full:- +full:sel

1 // SPDX-License-Identifier: GPL-2.0-only
8 * Copyright (C) 2012-2013 Texas Instruments, Inc.
27 * FAST_OPP: sets ABB LDO to Forward Body-Bias
28 * SLOW_OPP: sets ABB LDO to Reverse Body-Bias
35 * struct ti_abb_info - ABB information per voltage setting
48 * struct ti_abb_reg - Register description for ABB block
51 * @sr2_wtcnt_value_mask: setup register- sr2_wtcnt_value mask
52 * @fbb_sel_mask: setup register- FBB sel mask
53 * @rbb_sel_mask: setup register- RBB sel mask
54 * @sr2_en_mask: setup register- enable mask
55 * @opp_change_mask: control register - mask to trigger LDOVBB change
56 * @opp_sel_mask: control register - mask for mode to operate
74 * struct ti_abb - ABB instance data
84 * @txdone_mask: mask on int_base for tranxdone interrupt
114 * ti_abb_rmw() - handy wrapper to set specific register bits
134 * ti_abb_check_txdone() - handy wrapper to check ABB tranxdone status
141 return !!(readl(abb->int_base) & abb->txdone_mask); in ti_abb_check_txdone()
145 * ti_abb_clear_txdone() - handy wrapper to clear ABB tranxdone status
150 writel(abb->txdone_mask, abb->int_base); in ti_abb_clear_txdone()
154 * ti_abb_wait_txdone() - waits for ABB tranxdone event
158 * Return: 0 on success or -ETIMEDOUT if the event is not cleared on time.
165 while (timeout++ <= abb->settling_time) { in ti_abb_wait_txdone()
174 __func__, timeout, readl(abb->int_base)); in ti_abb_wait_txdone()
175 return -ETIMEDOUT; in ti_abb_wait_txdone()
179 * ti_abb_clear_all_txdone() - clears ABB tranxdone event
183 * Return: 0 on success or -ETIMEDOUT if the event is not cleared on time.
190 while (timeout++ <= abb->settling_time) { in ti_abb_clear_all_txdone()
201 __func__, timeout, readl(abb->int_base)); in ti_abb_clear_all_txdone()
202 return -ETIMEDOUT; in ti_abb_clear_all_txdone()
206 * ti_abb_program_ldovbb() - program LDOVBB register for override value
216 val = readl(abb->ldo_base); in ti_abb_program_ldovbb()
218 val &= ~(abb->ldovbb_override_mask | abb->ldovbb_vset_mask); in ti_abb_program_ldovbb()
220 switch (info->opp_sel) { in ti_abb_program_ldovbb()
223 val |= abb->ldovbb_override_mask; in ti_abb_program_ldovbb()
224 val |= info->vset << __ffs(abb->ldovbb_vset_mask); in ti_abb_program_ldovbb()
228 writel(val, abb->ldo_base); in ti_abb_program_ldovbb()
232 * ti_abb_set_opp() - Setup ABB and LDO VBB for required bias
237 * Return: 0 on success or appropriate error value when fails
242 const struct ti_abb_reg *regs = abb->regs; in ti_abb_set_opp()
243 struct device *dev = &rdev->dev; in ti_abb_set_opp()
250 ti_abb_rmw(regs->fbb_sel_mask | regs->rbb_sel_mask, 0, abb->setup_reg); in ti_abb_set_opp()
252 switch (info->opp_sel) { in ti_abb_set_opp()
254 ti_abb_rmw(regs->rbb_sel_mask, 1, abb->setup_reg); in ti_abb_set_opp()
257 ti_abb_rmw(regs->fbb_sel_mask, 1, abb->setup_reg); in ti_abb_set_opp()
262 ti_abb_rmw(regs->opp_sel_mask, info->opp_sel, abb->control_reg); in ti_abb_set_opp()
266 * XXX: Do not switch sequence - for !bypass, LDO override reset *must* in ti_abb_set_opp()
269 if (abb->ldo_base && info->opp_sel != TI_ABB_NOMINAL_OPP) in ti_abb_set_opp()
273 ti_abb_rmw(regs->opp_change_mask, 1, abb->control_reg); in ti_abb_set_opp()
286 * XXX: Do not switch sequence - for bypass, LDO override reset *must* in ti_abb_set_opp()
289 if (abb->ldo_base && info->opp_sel == TI_ABB_NOMINAL_OPP) in ti_abb_set_opp()
297 * ti_abb_set_voltage_sel() - regulator accessor function to set ABB LDO
299 * @sel: selector to index into required ABB LDO settings (maps to
302 * Return: 0 on success or appropriate error value when fails
304 static int ti_abb_set_voltage_sel(struct regulator_dev *rdev, unsigned int sel) in ti_abb_set_voltage_sel() argument
306 const struct regulator_desc *desc = rdev->desc; in ti_abb_set_voltage_sel()
308 struct device *dev = &rdev->dev; in ti_abb_set_voltage_sel()
315 return -ENODEV; in ti_abb_set_voltage_sel()
318 if (!desc->n_voltages || !abb->info) { in ti_abb_set_voltage_sel()
322 return -EINVAL; in ti_abb_set_voltage_sel()
325 if (sel >= desc->n_voltages) { in ti_abb_set_voltage_sel()
326 dev_err(dev, "%s: sel idx(%d) >= n_voltages(%d)\n", __func__, in ti_abb_set_voltage_sel()
327 sel, desc->n_voltages); in ti_abb_set_voltage_sel()
328 return -EINVAL; in ti_abb_set_voltage_sel()
332 if (sel == abb->current_info_idx) { in ti_abb_set_voltage_sel()
333 dev_dbg(dev, "%s: Already at sel=%d\n", __func__, sel); in ti_abb_set_voltage_sel()
337 info = &abb->info[sel]; in ti_abb_set_voltage_sel()
344 if (abb->current_info_idx == -EINVAL) in ti_abb_set_voltage_sel()
348 oinfo = &abb->info[abb->current_info_idx]; in ti_abb_set_voltage_sel()
351 sel, abb->current_info_idx); in ti_abb_set_voltage_sel()
360 abb->current_info_idx = sel; in ti_abb_set_voltage_sel()
364 __func__, desc->volt_table[sel], sel, in ti_abb_set_voltage_sel()
365 info->opp_sel, ret); in ti_abb_set_voltage_sel()
370 * ti_abb_get_voltage_sel() - Regulator accessor to get current ABB LDO setting
373 * Return: 0 on success or appropriate error value when fails
377 const struct regulator_desc *desc = rdev->desc; in ti_abb_get_voltage_sel()
379 struct device *dev = &rdev->dev; in ti_abb_get_voltage_sel()
384 return -ENODEV; in ti_abb_get_voltage_sel()
387 if (!desc->n_voltages || !abb->info) { in ti_abb_get_voltage_sel()
391 return -EINVAL; in ti_abb_get_voltage_sel()
394 if (abb->current_info_idx >= (int)desc->n_voltages) { in ti_abb_get_voltage_sel()
396 __func__, abb->current_info_idx, desc->n_voltages); in ti_abb_get_voltage_sel()
397 return -EINVAL; in ti_abb_get_voltage_sel()
400 return abb->current_info_idx; in ti_abb_get_voltage_sel()
404 * ti_abb_init_timings() - setup ABB clock timing for the current platform
414 const struct ti_abb_reg *regs = abb->regs; in ti_abb_init_timings()
416 char *pname = "ti,settling-time"; in ti_abb_init_timings()
419 ret = of_property_read_u32(dev->of_node, pname, &abb->settling_time); in ti_abb_init_timings()
426 if (!abb->settling_time) { in ti_abb_init_timings()
428 return -EINVAL; in ti_abb_init_timings()
431 pname = "ti,clock-cycles"; in ti_abb_init_timings()
432 ret = of_property_read_u32(dev->of_node, pname, &clock_cycles); in ti_abb_init_timings()
440 return -EINVAL; in ti_abb_init_timings()
443 abb->clk = devm_clk_get(dev, NULL); in ti_abb_init_timings()
444 if (IS_ERR(abb->clk)) { in ti_abb_init_timings()
445 ret = PTR_ERR(abb->clk); in ti_abb_init_timings()
455 * This value depends on: in ti_abb_init_timings()
456 * settling time of ldo in micro-seconds (varies per OMAP family) in ti_abb_init_timings()
461 * ldo settling time (in micro-seconds) in ti_abb_init_timings()
462 * SR2_WTCNT_VALUE = ------------------------------------------ in ti_abb_init_timings()
474 clk_rate = DIV_ROUND_CLOSEST(clk_get_rate(abb->clk), 1000000); in ti_abb_init_timings()
480 sr2_wt_cnt_val = DIV_ROUND_CLOSEST(abb->settling_time * 10, cycle_rate); in ti_abb_init_timings()
483 clk_get_rate(abb->clk), sr2_wt_cnt_val); in ti_abb_init_timings()
485 ti_abb_rmw(regs->sr2_wtcnt_value_mask, sr2_wt_cnt_val, abb->setup_reg); in ti_abb_init_timings()
491 * ti_abb_init_table() - Initialize ABB table from device tree
496 * Return: 0 on success or appropriate error value when fails
507 struct regulation_constraints *c = &rinit_data->constraints; in ti_abb_init_table()
510 * Each abb_info is a set of n-tuple, where n is num_values, consisting in ti_abb_init_table()
514 num_entries = of_property_count_u32_elems(dev->of_node, pname); in ti_abb_init_table()
523 return -EINVAL; in ti_abb_init_table()
529 return -ENOMEM; in ti_abb_init_table()
531 abb->info = info; in ti_abb_init_table()
536 return -ENOMEM; in ti_abb_init_table()
538 abb->rdesc.n_voltages = num_entries; in ti_abb_init_table()
539 abb->rdesc.volt_table = volt_table; in ti_abb_init_table()
541 abb->current_info_idx = -EINVAL; in ti_abb_init_table()
548 of_property_read_u32_index(dev->of_node, pname, i * num_values, in ti_abb_init_table()
550 of_property_read_u32_index(dev->of_node, pname, in ti_abb_init_table()
551 i * num_values + 1, &info->opp_sel); in ti_abb_init_table()
552 of_property_read_u32_index(dev->of_node, pname, in ti_abb_init_table()
554 of_property_read_u32_index(dev->of_node, pname, in ti_abb_init_table()
556 of_property_read_u32_index(dev->of_node, pname, in ti_abb_init_table()
558 of_property_read_u32_index(dev->of_node, pname, in ti_abb_init_table()
563 i, *volt_table, info->opp_sel, efuse_offset, rbb_mask, in ti_abb_init_table()
572 if (!abb->efuse_base) { in ti_abb_init_table()
573 /* Ignore invalid data, but warn to help cleanup */ in ti_abb_init_table()
580 efuse_val = readl(abb->efuse_base + efuse_offset); in ti_abb_init_table()
584 info->opp_sel = TI_ABB_SLOW_OPP; in ti_abb_init_table()
586 info->opp_sel = TI_ABB_FAST_OPP; in ti_abb_init_table()
588 info->opp_sel = TI_ABB_NOMINAL_OPP; in ti_abb_init_table()
592 i, *volt_table, efuse_val, info->opp_sel); in ti_abb_init_table()
595 if (!abb->ldo_base) { in ti_abb_init_table()
601 info->vset = (efuse_val & vset_mask) >> __ffs(vset_mask); in ti_abb_init_table()
602 dev_dbg(dev, "[%d]v=%d vset=%x\n", i, *volt_table, info->vset); in ti_abb_init_table()
604 switch (info->opp_sel) { in ti_abb_init_table()
612 __func__, i, *volt_table, info->opp_sel); in ti_abb_init_table()
613 return -EINVAL; in ti_abb_init_table()
618 c->min_uV = min_uV; in ti_abb_init_table()
619 c->max_uV = max_uV; in ti_abb_init_table()
670 {.compatible = "ti,abb-v1", .data = &abb_regs_v1},
671 {.compatible = "ti,abb-v2", .data = &abb_regs_v2},
672 {.compatible = "ti,abb-v3", .data = &abb_regs_generic},
679 * ti_abb_probe() - Initialize an ABB ldo instance
682 * Initializes an individual ABB LDO for required Body-Bias. ABB is used to
683 * additional bias supply to SoC modules for power savings or mandatory stability
686 * Return: 0 on success or appropriate error value when fails
690 struct device *dev = &pdev->dev; in ti_abb_probe()
706 return -ENODEV; in ti_abb_probe()
708 if (!match->data) { in ti_abb_probe()
710 return -EINVAL; in ti_abb_probe()
715 return -ENOMEM; in ti_abb_probe()
716 abb->regs = match->data; in ti_abb_probe()
719 if (abb->regs->setup_off || abb->regs->control_off) { in ti_abb_probe()
720 abb->base = devm_platform_ioremap_resource_byname(pdev, "base-address"); in ti_abb_probe()
721 if (IS_ERR(abb->base)) in ti_abb_probe()
722 return PTR_ERR(abb->base); in ti_abb_probe()
724 abb->setup_reg = abb->base + abb->regs->setup_off; in ti_abb_probe()
725 abb->control_reg = abb->base + abb->regs->control_off; in ti_abb_probe()
728 abb->control_reg = devm_platform_ioremap_resource_byname(pdev, "control-address"); in ti_abb_probe()
729 if (IS_ERR(abb->control_reg)) in ti_abb_probe()
730 return PTR_ERR(abb->control_reg); in ti_abb_probe()
732 abb->setup_reg = devm_platform_ioremap_resource_byname(pdev, "setup-address"); in ti_abb_probe()
733 if (IS_ERR(abb->setup_reg)) in ti_abb_probe()
734 return PTR_ERR(abb->setup_reg); in ti_abb_probe()
737 pname = "int-address"; in ti_abb_probe()
741 return -ENODEV; in ti_abb_probe()
745 * shared between regulator-abb-{ivahd,dspeve,gpu} driver in ti_abb_probe()
750 abb->int_base = devm_ioremap(dev, res->start, in ti_abb_probe()
752 if (!abb->int_base) { in ti_abb_probe()
754 return -ENOMEM; in ti_abb_probe()
758 pname = "efuse-address"; in ti_abb_probe()
762 ret = -ENODEV; in ti_abb_probe()
767 * We may have shared efuse register offsets which are read-only in ti_abb_probe()
770 abb->efuse_base = devm_ioremap(dev, res->start, in ti_abb_probe()
772 if (!abb->efuse_base) { in ti_abb_probe()
774 return -ENOMEM; in ti_abb_probe()
777 pname = "ldo-address"; in ti_abb_probe()
781 ret = -ENODEV; in ti_abb_probe()
784 abb->ldo_base = devm_ioremap_resource(dev, res); in ti_abb_probe()
785 if (IS_ERR(abb->ldo_base)) in ti_abb_probe()
786 return PTR_ERR(abb->ldo_base); in ti_abb_probe()
789 pname = "ti,ldovbb-override-mask"; in ti_abb_probe()
791 of_property_read_u32(pdev->dev.of_node, pname, in ti_abb_probe()
792 &abb->ldovbb_override_mask); in ti_abb_probe()
797 if (!abb->ldovbb_override_mask) { in ti_abb_probe()
799 return -EINVAL; in ti_abb_probe()
802 pname = "ti,ldovbb-vset-mask"; in ti_abb_probe()
804 of_property_read_u32(pdev->dev.of_node, pname, in ti_abb_probe()
805 &abb->ldovbb_vset_mask); in ti_abb_probe()
810 if (!abb->ldovbb_vset_mask) { in ti_abb_probe()
812 return -EINVAL; in ti_abb_probe()
816 pname = "ti,tranxdone-status-mask"; in ti_abb_probe()
818 of_property_read_u32(pdev->dev.of_node, pname, in ti_abb_probe()
819 &abb->txdone_mask); in ti_abb_probe()
824 if (!abb->txdone_mask) { in ti_abb_probe()
826 return -EINVAL; in ti_abb_probe()
829 initdata = of_get_regulator_init_data(dev, pdev->dev.of_node, in ti_abb_probe()
830 &abb->rdesc); in ti_abb_probe()
834 return -ENOMEM; in ti_abb_probe()
847 desc = &abb->rdesc; in ti_abb_probe()
848 desc->name = dev_name(dev); in ti_abb_probe()
849 desc->owner = THIS_MODULE; in ti_abb_probe()
850 desc->type = REGULATOR_VOLTAGE; in ti_abb_probe()
851 desc->ops = &ti_abb_reg_ops; in ti_abb_probe()
853 c = &initdata->constraints; in ti_abb_probe()
854 if (desc->n_voltages > 1) in ti_abb_probe()
855 c->valid_ops_mask |= REGULATOR_CHANGE_VOLTAGE; in ti_abb_probe()
856 c->always_on = true; in ti_abb_probe()
861 config.of_node = pdev->dev.of_node; in ti_abb_probe()
873 ti_abb_rmw(abb->regs->sr2_en_mask, 1, abb->setup_reg); in ti_abb_probe()