Lines Matching +full:pll +full:- +full:reset
1 // SPDX-License-Identifier: GPL-2.0-or-later
5 * Maxime Ripard <maxime.ripard@free-electrons.com>
9 #include <linux/clk-provider.h>
22 struct ccu_reset reset; member
33 if (common->features & CCU_FEATURE_LOCK_REG) in ccu_helper_wait_for_lock()
34 addr = common->base + common->lock_reg; in ccu_helper_wait_for_lock()
36 addr = common->base + common->reg; in ccu_helper_wait_for_lock()
49 clk_hw_get_rate_range(&common->hw, &min_rate, &max_rate); in ccu_is_better_rate()
57 if (common->features & CCU_FEATURE_CLOSEST_RATE) in ccu_is_better_rate()
58 return abs(current_rate - target_rate) < abs(best_rate - target_rate); in ccu_is_better_rate()
65 * This clock notifier is called when the frequency of a PLL clock is
66 * changed. In common PLL designs, changes to the dividers take effect
69 * the feedback loop for the PLL to stablize.
71 * Sometimes when the PLL clock rate is changed, the decrease in the
73 * The PLL clock rate will spike, and in some cases, might lock up
85 struct ccu_pll_nb *pll = to_ccu_pll_nb(nb); in ccu_pll_notifier_cb() local
91 ccu_gate_helper_disable(pll->common, pll->enable); in ccu_pll_notifier_cb()
93 ret = ccu_gate_helper_enable(pll->common, pll->enable); in ccu_pll_notifier_cb()
97 ccu_helper_wait_for_lock(pll->common, pll->lock); in ccu_pll_notifier_cb()
105 pll_nb->clk_nb.notifier_call = ccu_pll_notifier_cb; in ccu_pll_notifier_register()
107 return clk_notifier_register(pll_nb->common->hw.clk, in ccu_pll_notifier_register()
108 &pll_nb->clk_nb); in ccu_pll_notifier_register()
116 struct ccu_reset *reset; in sunxi_ccu_probe() local
119 ccu->desc = desc; in sunxi_ccu_probe()
121 spin_lock_init(&ccu->lock); in sunxi_ccu_probe()
123 for (i = 0; i < desc->num_ccu_clks; i++) { in sunxi_ccu_probe()
124 struct ccu_common *cclk = desc->ccu_clks[i]; in sunxi_ccu_probe()
129 cclk->base = reg; in sunxi_ccu_probe()
130 cclk->lock = &ccu->lock; in sunxi_ccu_probe()
133 for (i = 0; i < desc->hw_clks->num ; i++) { in sunxi_ccu_probe()
134 struct clk_hw *hw = desc->hw_clks->hws[i]; in sunxi_ccu_probe()
140 name = hw->init->name; in sunxi_ccu_probe()
146 pr_err("Couldn't register clock %d - %s\n", i, name); in sunxi_ccu_probe()
151 for (i = 0; i < desc->num_ccu_clks; i++) { in sunxi_ccu_probe()
152 struct ccu_common *cclk = desc->ccu_clks[i]; in sunxi_ccu_probe()
157 if (cclk->max_rate) in sunxi_ccu_probe()
158 clk_hw_set_rate_range(&cclk->hw, cclk->min_rate, in sunxi_ccu_probe()
159 cclk->max_rate); in sunxi_ccu_probe()
161 WARN(cclk->min_rate, in sunxi_ccu_probe()
162 "No max_rate, ignoring min_rate of clock %d - %s\n", in sunxi_ccu_probe()
163 i, clk_hw_get_name(&cclk->hw)); in sunxi_ccu_probe()
167 desc->hw_clks); in sunxi_ccu_probe()
171 reset = &ccu->reset; in sunxi_ccu_probe()
172 reset->rcdev.of_node = node; in sunxi_ccu_probe()
173 reset->rcdev.ops = &ccu_reset_ops; in sunxi_ccu_probe()
174 reset->rcdev.owner = dev ? dev->driver->owner : THIS_MODULE; in sunxi_ccu_probe()
175 reset->rcdev.nr_resets = desc->num_resets; in sunxi_ccu_probe()
176 reset->base = reg; in sunxi_ccu_probe()
177 reset->lock = &ccu->lock; in sunxi_ccu_probe()
178 reset->reset_map = desc->resets; in sunxi_ccu_probe()
180 ret = reset_controller_register(&reset->rcdev); in sunxi_ccu_probe()
189 while (--i >= 0) { in sunxi_ccu_probe()
190 struct clk_hw *hw = desc->hw_clks->hws[i]; in sunxi_ccu_probe()
202 const struct sunxi_ccu_desc *desc = ccu->desc; in devm_sunxi_ccu_release()
205 reset_controller_unregister(&ccu->reset.rcdev); in devm_sunxi_ccu_release()
206 of_clk_del_provider(dev->of_node); in devm_sunxi_ccu_release()
208 for (i = 0; i < desc->hw_clks->num; i++) { in devm_sunxi_ccu_release()
209 struct clk_hw *hw = desc->hw_clks->hws[i]; in devm_sunxi_ccu_release()
225 return -ENOMEM; in devm_sunxi_ccu_probe()
227 ret = sunxi_ccu_probe(ccu, dev, dev->of_node, reg, desc); in devm_sunxi_ccu_probe()