Lines Matching +full:reg +full:- +full:data
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>
60 void __iomem *reg; member
131 .reg = (void *)CLK_DIS, \
140 .reg = (void *)TBG_SEL, \
161 .reg = (void *)_reg, \
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"),
327 static unsigned int get_div(void __iomem *reg, int shift) in get_div() argument
331 val = (readl(reg) >> shift) & 0x7; in get_div()
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()
354 unsigned int *reg, in armada_3700_pm_dvfs_update_regs() argument
358 *reg = ARMADA_37XX_NB_L0L1; in armada_3700_pm_dvfs_update_regs()
360 *reg = ARMADA_37XX_NB_L2L3; in armada_3700_pm_dvfs_update_regs()
369 unsigned int val, reg = ARMADA_37XX_NB_DYN_MOD; in armada_3700_pm_dvfs_is_enabled() local
374 regmap_read(base, reg, &val); in armada_3700_pm_dvfs_is_enabled()
381 unsigned int reg = ARMADA_37XX_NB_CPU_LOAD; in armada_3700_pm_dvfs_get_cpu_div() local
390 regmap_read(base, reg, &load_level); in armada_3700_pm_dvfs_get_cpu_div()
397 armada_3700_pm_dvfs_update_regs(load_level, ®, &offset); in armada_3700_pm_dvfs_get_cpu_div()
399 regmap_read(base, reg, &div); in armada_3700_pm_dvfs_get_cpu_div()
406 unsigned int reg = ARMADA_37XX_NB_CPU_LOAD; in armada_3700_pm_dvfs_get_cpu_parent() local
415 regmap_read(base, reg, &load_level); in armada_3700_pm_dvfs_get_cpu_parent()
422 armada_3700_pm_dvfs_update_regs(load_level, ®, &offset); in armada_3700_pm_dvfs_get_cpu_parent()
424 regmap_read(base, reg, &sel); in armada_3700_pm_dvfs_get_cpu_parent()
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()
461 struct regmap *base = pm_cpu->nb_pm_base; in clk_pm_cpu_determine_rate()
462 unsigned int div = req->best_parent_rate / req->rate; in clk_pm_cpu_determine_rate()
466 return -EINVAL; in clk_pm_cpu_determine_rate()
469 unsigned int reg, val, offset = ARMADA_37XX_NB_TBG_DIV_OFF; in clk_pm_cpu_determine_rate() local
471 armada_3700_pm_dvfs_update_regs(load_level, ®, &offset); in clk_pm_cpu_determine_rate()
473 regmap_read(base, reg, &val); in clk_pm_cpu_determine_rate()
483 req->rate = req->best_parent_rate / div; in clk_pm_cpu_determine_rate()
490 return -EINVAL; in clk_pm_cpu_determine_rate()
506 * frequency in-between. The sequence therefore becomes:
530 pm_cpu->l1_expiration = jiffies; in clk_pm_cpu_set_rate_wa()
532 pm_cpu->l1_expiration = jiffies + msecs_to_jiffies(20); in clk_pm_cpu_set_rate_wa()
547 if (pm_cpu->l1_expiration && time_is_before_eq_jiffies(pm_cpu->l1_expiration)) in clk_pm_cpu_set_rate_wa()
556 pm_cpu->l1_expiration = 0; in clk_pm_cpu_set_rate_wa()
563 struct regmap *base = pm_cpu->nb_pm_base; in clk_pm_cpu_set_rate()
569 return -EINVAL; in clk_pm_cpu_set_rate()
572 unsigned int reg, mask, val, in clk_pm_cpu_set_rate() local
575 armada_3700_pm_dvfs_update_regs(load_level, ®, &offset); in clk_pm_cpu_set_rate()
577 regmap_read(base, reg, &val); in clk_pm_cpu_set_rate()
587 reg = ARMADA_37XX_NB_CPU_LOAD; in clk_pm_cpu_set_rate()
594 regmap_update_bits(base, reg, mask, load_level); in clk_pm_cpu_set_rate()
601 return -EINVAL; in clk_pm_cpu_set_rate()
612 { .compatible = "marvell,armada-3700-periph-clock-nb",
613 .data = data_nb, },
614 { .compatible = "marvell,armada-3700-periph-clock-sb",
615 .data = data_sb, },
619 static int armada_3700_add_composite_clk(const struct clk_periph_data *data, in armada_3700_add_composite_clk() argument
620 void __iomem *reg, spinlock_t *lock, in armada_3700_add_composite_clk() argument
627 if (data->mux_hw) { in armada_3700_add_composite_clk()
630 mux_hw = data->mux_hw; in armada_3700_add_composite_clk()
632 mux->lock = lock; in armada_3700_add_composite_clk()
633 mux_ops = mux_hw->init->ops; in armada_3700_add_composite_clk()
634 mux->reg = reg + (u64)mux->reg; in armada_3700_add_composite_clk()
637 if (data->gate_hw) { in armada_3700_add_composite_clk()
640 gate_hw = data->gate_hw; in armada_3700_add_composite_clk()
642 gate->lock = lock; in armada_3700_add_composite_clk()
643 gate_ops = gate_hw->init->ops; in armada_3700_add_composite_clk()
644 gate->reg = reg + (u64)gate->reg; in armada_3700_add_composite_clk()
645 gate->flags = CLK_GATE_SET_TO_DISABLE; in armada_3700_add_composite_clk()
648 if (data->rate_hw) { in armada_3700_add_composite_clk()
649 rate_hw = data->rate_hw; in armada_3700_add_composite_clk()
650 rate_ops = rate_hw->init->ops; in armada_3700_add_composite_clk()
651 if (data->is_double_div) { in armada_3700_add_composite_clk()
655 rate->reg1 = reg + (u64)rate->reg1; in armada_3700_add_composite_clk()
656 rate->reg2 = reg + (u64)rate->reg2; in armada_3700_add_composite_clk()
662 rate->reg = reg + (u64)rate->reg; in armada_3700_add_composite_clk()
663 for (clkt = rate->table; clkt->div; clkt++) in armada_3700_add_composite_clk()
665 rate->width = order_base_2(table_size); in armada_3700_add_composite_clk()
666 rate->lock = lock; in armada_3700_add_composite_clk()
670 if (data->muxrate_hw) { in armada_3700_add_composite_clk()
672 struct clk_hw *muxrate_hw = data->muxrate_hw; in armada_3700_add_composite_clk()
676 pmcpu_clk->reg_mux = reg + (u64)pmcpu_clk->reg_mux; in armada_3700_add_composite_clk()
677 pmcpu_clk->reg_div = reg + (u64)pmcpu_clk->reg_div; in armada_3700_add_composite_clk()
681 mux_ops = muxrate_hw->init->ops; in armada_3700_add_composite_clk()
682 rate_ops = muxrate_hw->init->ops; in armada_3700_add_composite_clk()
685 "marvell,armada-3700-nb-pm"); in armada_3700_add_composite_clk()
686 pmcpu_clk->nb_pm_base = map; in armada_3700_add_composite_clk()
689 *hw = clk_hw_register_composite(dev, data->name, data->parent_names, in armada_3700_add_composite_clk()
690 data->num_parents, mux_hw, in armada_3700_add_composite_clk()
699 struct clk_periph_driver_data *data = dev_get_drvdata(dev); in armada_3700_periph_clock_suspend() local
701 data->tbg_sel = readl(data->reg + TBG_SEL); in armada_3700_periph_clock_suspend()
702 data->div_sel0 = readl(data->reg + DIV_SEL0); in armada_3700_periph_clock_suspend()
703 data->div_sel1 = readl(data->reg + DIV_SEL1); in armada_3700_periph_clock_suspend()
704 data->div_sel2 = readl(data->reg + DIV_SEL2); in armada_3700_periph_clock_suspend()
705 data->clk_sel = readl(data->reg + CLK_SEL); in armada_3700_periph_clock_suspend()
706 data->clk_dis = readl(data->reg + CLK_DIS); in armada_3700_periph_clock_suspend()
713 struct clk_periph_driver_data *data = dev_get_drvdata(dev); in armada_3700_periph_clock_resume() local
715 /* Follow the same order than what the Cortex-M3 does (ATF code) */ in armada_3700_periph_clock_resume()
716 writel(data->clk_dis, data->reg + CLK_DIS); in armada_3700_periph_clock_resume()
717 writel(data->div_sel0, data->reg + DIV_SEL0); in armada_3700_periph_clock_resume()
718 writel(data->div_sel1, data->reg + DIV_SEL1); in armada_3700_periph_clock_resume()
719 writel(data->div_sel2, data->reg + DIV_SEL2); in armada_3700_periph_clock_resume()
720 writel(data->tbg_sel, data->reg + TBG_SEL); in armada_3700_periph_clock_resume()
721 writel(data->clk_sel, data->reg + CLK_SEL); in armada_3700_periph_clock_resume()
734 struct device_node *np = pdev->dev.of_node; in armada_3700_periph_clock_probe()
735 const struct clk_periph_data *data; in armada_3700_periph_clock_probe() local
736 struct device *dev = &pdev->dev; in armada_3700_periph_clock_probe()
739 data = of_device_get_match_data(dev); in armada_3700_periph_clock_probe()
740 if (!data) in armada_3700_periph_clock_probe()
741 return -ENODEV; in armada_3700_periph_clock_probe()
743 while (data[num_periph].name) in armada_3700_periph_clock_probe()
748 return -ENOMEM; in armada_3700_periph_clock_probe()
750 driver_data->hw_data = devm_kzalloc(dev, in armada_3700_periph_clock_probe()
751 struct_size(driver_data->hw_data, in armada_3700_periph_clock_probe()
754 if (!driver_data->hw_data) in armada_3700_periph_clock_probe()
755 return -ENOMEM; in armada_3700_periph_clock_probe()
756 driver_data->hw_data->num = num_periph; in armada_3700_periph_clock_probe()
758 driver_data->reg = devm_platform_ioremap_resource(pdev, 0); in armada_3700_periph_clock_probe()
759 if (IS_ERR(driver_data->reg)) in armada_3700_periph_clock_probe()
760 return PTR_ERR(driver_data->reg); in armada_3700_periph_clock_probe()
762 spin_lock_init(&driver_data->lock); in armada_3700_periph_clock_probe()
765 struct clk_hw **hw = &driver_data->hw_data->hws[i]; in armada_3700_periph_clock_probe()
766 if (armada_3700_add_composite_clk(&data[i], driver_data->reg, in armada_3700_periph_clock_probe()
767 &driver_data->lock, dev, hw)) in armada_3700_periph_clock_probe()
769 data[i].name); in armada_3700_periph_clock_probe()
773 driver_data->hw_data); in armada_3700_periph_clock_probe()
776 clk_hw_unregister(driver_data->hw_data->hws[i]); in armada_3700_periph_clock_probe()
786 struct clk_periph_driver_data *data = platform_get_drvdata(pdev); in armada_3700_periph_clock_remove() local
787 struct clk_hw_onecell_data *hw_data = data->hw_data; in armada_3700_periph_clock_remove()
790 of_clk_del_provider(pdev->dev.of_node); in armada_3700_periph_clock_remove()
792 for (i = 0; i < hw_data->num; i++) in armada_3700_periph_clock_remove()
793 clk_hw_unregister(hw_data->hws[i]); in armada_3700_periph_clock_remove()
800 .name = "marvell-armada-3700-periph-clock",