Lines Matching +full:rate +full:- +full:np +full:- +full:ms

1 // SPDX-License-Identifier: GPL-2.0+
7 * Gregory CLEMENT <gregory.clement@free-electrons.com>
11 * TBG-A-P --| | | | | | ______
12 * TBG-B-P --| Mux |--| /div1 |--| /div2 |--| Gate |--> perip_clk
13 * TBG-A-S --| | | | | | |______|
14 * TBG-B-S --|_____| |_______| |_______|
20 #include <linux/clk-provider.h>
201 .parent_names = (const char *[]){ "TBG-A-P", \
202 "TBG-B-P", "TBG-A-S", "TBG-B-S"}, \
211 .parent_names = (const char *[]){ "TBG-A-P", \
212 "TBG-B-P", "TBG-A-S", "TBG-B-S"}, \
237 .parent_names = (const char *[]){ "TBG-A-P", \
238 "TBG-B-P", "TBG-A-S", "TBG-B-S"}, \
245 .parent_names = (const char *[]){ "TBG-A-P", \
246 "TBG-B-P", "TBG-A-S", "TBG-B-S"}, \
284 REF_CLK_GATE_DIV(ddr_phy, "TBG-A-S"),
343 div = get_div(double_div->reg1, double_div->shift1); in clk_double_div_recalc_rate()
344 div *= get_div(double_div->reg2, double_div->shift2); in clk_double_div_recalc_rate()
434 if (armada_3700_pm_dvfs_is_enabled(pm_cpu->nb_pm_base)) { in clk_pm_cpu_get_parent()
435 val = armada_3700_pm_dvfs_get_cpu_parent(pm_cpu->nb_pm_base); in clk_pm_cpu_get_parent()
437 val = readl(pm_cpu->reg_mux) >> pm_cpu->shift_mux; in clk_pm_cpu_get_parent()
438 val &= pm_cpu->mask_mux; in clk_pm_cpu_get_parent()
450 if (armada_3700_pm_dvfs_is_enabled(pm_cpu->nb_pm_base)) in clk_pm_cpu_recalc_rate()
451 div = armada_3700_pm_dvfs_get_cpu_div(pm_cpu->nb_pm_base); in clk_pm_cpu_recalc_rate()
453 div = get_div(pm_cpu->reg_div, pm_cpu->shift_div); in clk_pm_cpu_recalc_rate()
457 static long clk_pm_cpu_round_rate(struct clk_hw *hw, unsigned long rate, in clk_pm_cpu_round_rate() argument
461 struct regmap *base = pm_cpu->nb_pm_base; in clk_pm_cpu_round_rate()
462 unsigned int div = *parent_rate / rate; in clk_pm_cpu_round_rate()
466 return -EINVAL; in clk_pm_cpu_round_rate()
487 return -EINVAL; in clk_pm_cpu_round_rate()
503 * frequency in-between. The sequence therefore becomes:
505 * 2. Sleep 20ms for stabling VDD voltage
509 unsigned int new_level, unsigned long rate, in clk_pm_cpu_set_rate_wa() argument
522 * remember when 20ms will expire. If from L0, set the value so that in clk_pm_cpu_set_rate_wa()
527 pm_cpu->l1_expiration = jiffies; in clk_pm_cpu_set_rate_wa()
529 pm_cpu->l1_expiration = jiffies + msecs_to_jiffies(20); in clk_pm_cpu_set_rate_wa()
537 if (rate < 1000*1000*1000) in clk_pm_cpu_set_rate_wa()
541 * We are going to L0 with rate >= 1GHz. Check whether we have been at in clk_pm_cpu_set_rate_wa()
542 * L1 for long enough time. If not, go to L1 for 20ms. in clk_pm_cpu_set_rate_wa()
544 if (pm_cpu->l1_expiration && time_is_before_eq_jiffies(pm_cpu->l1_expiration)) in clk_pm_cpu_set_rate_wa()
553 pm_cpu->l1_expiration = 0; in clk_pm_cpu_set_rate_wa()
556 static int clk_pm_cpu_set_rate(struct clk_hw *hw, unsigned long rate, in clk_pm_cpu_set_rate() argument
560 struct regmap *base = pm_cpu->nb_pm_base; in clk_pm_cpu_set_rate()
561 unsigned int div = parent_rate / rate; in clk_pm_cpu_set_rate()
566 return -EINVAL; in clk_pm_cpu_set_rate()
589 clk_pm_cpu_set_rate_wa(pm_cpu, load_level, rate, base); in clk_pm_cpu_set_rate()
593 return rate; in clk_pm_cpu_set_rate()
598 return -EINVAL; in clk_pm_cpu_set_rate()
609 { .compatible = "marvell,armada-3700-periph-clock-nb",
611 { .compatible = "marvell,armada-3700-periph-clock-sb",
624 if (data->mux_hw) { in armada_3700_add_composite_clk()
627 mux_hw = data->mux_hw; in armada_3700_add_composite_clk()
629 mux->lock = lock; in armada_3700_add_composite_clk()
630 mux_ops = mux_hw->init->ops; in armada_3700_add_composite_clk()
631 mux->reg = reg + (u64)mux->reg; in armada_3700_add_composite_clk()
634 if (data->gate_hw) { in armada_3700_add_composite_clk()
637 gate_hw = data->gate_hw; in armada_3700_add_composite_clk()
639 gate->lock = lock; in armada_3700_add_composite_clk()
640 gate_ops = gate_hw->init->ops; in armada_3700_add_composite_clk()
641 gate->reg = reg + (u64)gate->reg; in armada_3700_add_composite_clk()
642 gate->flags = CLK_GATE_SET_TO_DISABLE; in armada_3700_add_composite_clk()
645 if (data->rate_hw) { in armada_3700_add_composite_clk()
646 rate_hw = data->rate_hw; in armada_3700_add_composite_clk()
647 rate_ops = rate_hw->init->ops; in armada_3700_add_composite_clk()
648 if (data->is_double_div) { in armada_3700_add_composite_clk()
649 struct clk_double_div *rate; in armada_3700_add_composite_clk() local
651 rate = to_clk_double_div(rate_hw); in armada_3700_add_composite_clk()
652 rate->reg1 = reg + (u64)rate->reg1; in armada_3700_add_composite_clk()
653 rate->reg2 = reg + (u64)rate->reg2; in armada_3700_add_composite_clk()
655 struct clk_divider *rate = to_clk_divider(rate_hw); in armada_3700_add_composite_clk() local
659 rate->reg = reg + (u64)rate->reg; in armada_3700_add_composite_clk()
660 for (clkt = rate->table; clkt->div; clkt++) in armada_3700_add_composite_clk()
662 rate->width = order_base_2(table_size); in armada_3700_add_composite_clk()
663 rate->lock = lock; in armada_3700_add_composite_clk()
667 if (data->muxrate_hw) { in armada_3700_add_composite_clk()
669 struct clk_hw *muxrate_hw = data->muxrate_hw; in armada_3700_add_composite_clk()
673 pmcpu_clk->reg_mux = reg + (u64)pmcpu_clk->reg_mux; in armada_3700_add_composite_clk()
674 pmcpu_clk->reg_div = reg + (u64)pmcpu_clk->reg_div; in armada_3700_add_composite_clk()
678 mux_ops = muxrate_hw->init->ops; in armada_3700_add_composite_clk()
679 rate_ops = muxrate_hw->init->ops; in armada_3700_add_composite_clk()
682 "marvell,armada-3700-nb-pm"); in armada_3700_add_composite_clk()
683 pmcpu_clk->nb_pm_base = map; in armada_3700_add_composite_clk()
686 *hw = clk_hw_register_composite(dev, data->name, data->parent_names, in armada_3700_add_composite_clk()
687 data->num_parents, mux_hw, in armada_3700_add_composite_clk()
698 data->tbg_sel = readl(data->reg + TBG_SEL); in armada_3700_periph_clock_suspend()
699 data->div_sel0 = readl(data->reg + DIV_SEL0); in armada_3700_periph_clock_suspend()
700 data->div_sel1 = readl(data->reg + DIV_SEL1); in armada_3700_periph_clock_suspend()
701 data->div_sel2 = readl(data->reg + DIV_SEL2); in armada_3700_periph_clock_suspend()
702 data->clk_sel = readl(data->reg + CLK_SEL); in armada_3700_periph_clock_suspend()
703 data->clk_dis = readl(data->reg + CLK_DIS); in armada_3700_periph_clock_suspend()
712 /* Follow the same order than what the Cortex-M3 does (ATF code) */ in armada_3700_periph_clock_resume()
713 writel(data->clk_dis, data->reg + CLK_DIS); in armada_3700_periph_clock_resume()
714 writel(data->div_sel0, data->reg + DIV_SEL0); in armada_3700_periph_clock_resume()
715 writel(data->div_sel1, data->reg + DIV_SEL1); in armada_3700_periph_clock_resume()
716 writel(data->div_sel2, data->reg + DIV_SEL2); in armada_3700_periph_clock_resume()
717 writel(data->tbg_sel, data->reg + TBG_SEL); in armada_3700_periph_clock_resume()
718 writel(data->clk_sel, data->reg + CLK_SEL); in armada_3700_periph_clock_resume()
731 struct device_node *np = pdev->dev.of_node; in armada_3700_periph_clock_probe() local
733 struct device *dev = &pdev->dev; in armada_3700_periph_clock_probe()
738 return -ENODEV; in armada_3700_periph_clock_probe()
745 return -ENOMEM; in armada_3700_periph_clock_probe()
747 driver_data->hw_data = devm_kzalloc(dev, in armada_3700_periph_clock_probe()
748 struct_size(driver_data->hw_data, in armada_3700_periph_clock_probe()
751 if (!driver_data->hw_data) in armada_3700_periph_clock_probe()
752 return -ENOMEM; in armada_3700_periph_clock_probe()
753 driver_data->hw_data->num = num_periph; in armada_3700_periph_clock_probe()
755 driver_data->reg = devm_platform_ioremap_resource(pdev, 0); in armada_3700_periph_clock_probe()
756 if (IS_ERR(driver_data->reg)) in armada_3700_periph_clock_probe()
757 return PTR_ERR(driver_data->reg); in armada_3700_periph_clock_probe()
759 spin_lock_init(&driver_data->lock); in armada_3700_periph_clock_probe()
762 struct clk_hw **hw = &driver_data->hw_data->hws[i]; in armada_3700_periph_clock_probe()
763 if (armada_3700_add_composite_clk(&data[i], driver_data->reg, in armada_3700_periph_clock_probe()
764 &driver_data->lock, dev, hw)) in armada_3700_periph_clock_probe()
769 ret = of_clk_add_hw_provider(np, of_clk_hw_onecell_get, in armada_3700_periph_clock_probe()
770 driver_data->hw_data); in armada_3700_periph_clock_probe()
773 clk_hw_unregister(driver_data->hw_data->hws[i]); in armada_3700_periph_clock_probe()
784 struct clk_hw_onecell_data *hw_data = data->hw_data; in armada_3700_periph_clock_remove()
787 of_clk_del_provider(pdev->dev.of_node); in armada_3700_periph_clock_remove()
789 for (i = 0; i < hw_data->num; i++) in armada_3700_periph_clock_remove()
790 clk_hw_unregister(hw_data->hws[i]); in armada_3700_periph_clock_remove()
797 .name = "marvell-armada-3700-periph-clock",