Lines Matching +full:mux +full:- +full:clock
1 // SPDX-License-Identifier: GPL-2.0
8 #include <linux/clk-provider.h>
18 #include "clk-mux.h"
35 struct mtk_clk_mux *mux = to_mtk_clk_mux(hw); in mtk_clk_mux_enable_setclr() local
38 if (mux->lock) in mtk_clk_mux_enable_setclr()
39 spin_lock_irqsave(mux->lock, flags); in mtk_clk_mux_enable_setclr()
41 __acquire(mux->lock); in mtk_clk_mux_enable_setclr()
43 regmap_write(mux->regmap, mux->data->clr_ofs, in mtk_clk_mux_enable_setclr()
44 BIT(mux->data->gate_shift)); in mtk_clk_mux_enable_setclr()
47 * If the parent has been changed when the clock was disabled, it will in mtk_clk_mux_enable_setclr()
48 * not be effective yet. Set the update bit to ensure the mux gets in mtk_clk_mux_enable_setclr()
51 if (mux->reparent && mux->data->upd_shift >= 0) { in mtk_clk_mux_enable_setclr()
52 regmap_write(mux->regmap, mux->data->upd_ofs, in mtk_clk_mux_enable_setclr()
53 BIT(mux->data->upd_shift)); in mtk_clk_mux_enable_setclr()
54 mux->reparent = false; in mtk_clk_mux_enable_setclr()
57 if (mux->lock) in mtk_clk_mux_enable_setclr()
58 spin_unlock_irqrestore(mux->lock, flags); in mtk_clk_mux_enable_setclr()
60 __release(mux->lock); in mtk_clk_mux_enable_setclr()
67 struct mtk_clk_mux *mux = to_mtk_clk_mux(hw); in mtk_clk_mux_disable_setclr() local
69 regmap_write(mux->regmap, mux->data->set_ofs, in mtk_clk_mux_disable_setclr()
70 BIT(mux->data->gate_shift)); in mtk_clk_mux_disable_setclr()
75 struct mtk_clk_mux *mux = to_mtk_clk_mux(hw); in mtk_clk_mux_is_enabled() local
78 regmap_read(mux->regmap, mux->data->mux_ofs, &val); in mtk_clk_mux_is_enabled()
80 return (val & BIT(mux->data->gate_shift)) == 0; in mtk_clk_mux_is_enabled()
85 struct mtk_clk_mux *mux = to_mtk_clk_mux(hw); in mtk_clk_mux_get_parent() local
86 u32 mask = GENMASK(mux->data->mux_width - 1, 0); in mtk_clk_mux_get_parent()
89 regmap_read(mux->regmap, mux->data->mux_ofs, &val); in mtk_clk_mux_get_parent()
90 val = (val >> mux->data->mux_shift) & mask; in mtk_clk_mux_get_parent()
92 if (mux->data->parent_index) { in mtk_clk_mux_get_parent()
95 for (i = 0; i < mux->data->num_parents; i++) in mtk_clk_mux_get_parent()
96 if (mux->data->parent_index[i] == val) in mtk_clk_mux_get_parent()
100 return mux->data->num_parents + 1; in mtk_clk_mux_get_parent()
108 struct mtk_clk_mux *mux = to_mtk_clk_mux(hw); in mtk_clk_mux_set_parent_setclr_lock() local
109 u32 mask = GENMASK(mux->data->mux_width - 1, 0); in mtk_clk_mux_set_parent_setclr_lock()
113 if (mux->lock) in mtk_clk_mux_set_parent_setclr_lock()
114 spin_lock_irqsave(mux->lock, flags); in mtk_clk_mux_set_parent_setclr_lock()
116 __acquire(mux->lock); in mtk_clk_mux_set_parent_setclr_lock()
118 if (mux->data->parent_index) in mtk_clk_mux_set_parent_setclr_lock()
119 index = mux->data->parent_index[index]; in mtk_clk_mux_set_parent_setclr_lock()
121 regmap_read(mux->regmap, mux->data->mux_ofs, &orig); in mtk_clk_mux_set_parent_setclr_lock()
122 val = (orig & ~(mask << mux->data->mux_shift)) in mtk_clk_mux_set_parent_setclr_lock()
123 | (index << mux->data->mux_shift); in mtk_clk_mux_set_parent_setclr_lock()
126 regmap_write(mux->regmap, mux->data->clr_ofs, in mtk_clk_mux_set_parent_setclr_lock()
127 mask << mux->data->mux_shift); in mtk_clk_mux_set_parent_setclr_lock()
128 regmap_write(mux->regmap, mux->data->set_ofs, in mtk_clk_mux_set_parent_setclr_lock()
129 index << mux->data->mux_shift); in mtk_clk_mux_set_parent_setclr_lock()
131 if (mux->data->upd_shift >= 0) { in mtk_clk_mux_set_parent_setclr_lock()
132 regmap_write(mux->regmap, mux->data->upd_ofs, in mtk_clk_mux_set_parent_setclr_lock()
133 BIT(mux->data->upd_shift)); in mtk_clk_mux_set_parent_setclr_lock()
134 mux->reparent = true; in mtk_clk_mux_set_parent_setclr_lock()
138 if (mux->lock) in mtk_clk_mux_set_parent_setclr_lock()
139 spin_unlock_irqrestore(mux->lock, flags); in mtk_clk_mux_set_parent_setclr_lock()
141 __release(mux->lock); in mtk_clk_mux_set_parent_setclr_lock()
149 struct mtk_clk_mux *mux = to_mtk_clk_mux(hw); in mtk_clk_mux_determine_rate() local
151 return clk_mux_determine_rate_flags(hw, req, mux->data->flags); in mtk_clk_mux_determine_rate()
172 const struct mtk_mux *mux, in mtk_clk_register_mux() argument
182 return ERR_PTR(-ENOMEM); in mtk_clk_register_mux()
184 init.name = mux->name; in mtk_clk_register_mux()
185 init.flags = mux->flags; in mtk_clk_register_mux()
186 init.parent_names = mux->parent_names; in mtk_clk_register_mux()
187 init.num_parents = mux->num_parents; in mtk_clk_register_mux()
188 init.ops = mux->ops; in mtk_clk_register_mux()
190 clk_mux->regmap = regmap; in mtk_clk_register_mux()
191 clk_mux->data = mux; in mtk_clk_register_mux()
192 clk_mux->lock = lock; in mtk_clk_register_mux()
193 clk_mux->hw.init = &init; in mtk_clk_register_mux()
195 ret = clk_hw_register(dev, &clk_mux->hw); in mtk_clk_register_mux()
201 return &clk_mux->hw; in mtk_clk_register_mux()
206 struct mtk_clk_mux *mux; in mtk_clk_unregister_mux() local
210 mux = to_mtk_clk_mux(hw); in mtk_clk_unregister_mux()
213 kfree(mux); in mtk_clk_unregister_mux()
233 const struct mtk_mux *mux = &muxes[i]; in mtk_clk_register_muxes() local
235 if (!IS_ERR_OR_NULL(clk_data->hws[mux->id])) { in mtk_clk_register_muxes()
236 pr_warn("%pOF: Trying to register duplicate clock ID: %d\n", in mtk_clk_register_muxes()
237 node, mux->id); in mtk_clk_register_muxes()
241 hw = mtk_clk_register_mux(dev, mux, regmap, lock); in mtk_clk_register_muxes()
244 pr_err("Failed to register clk %s: %pe\n", mux->name, in mtk_clk_register_muxes()
249 clk_data->hws[mux->id] = hw; in mtk_clk_register_muxes()
255 while (--i >= 0) { in mtk_clk_register_muxes()
256 const struct mtk_mux *mux = &muxes[i]; in mtk_clk_register_muxes() local
258 if (IS_ERR_OR_NULL(clk_data->hws[mux->id])) in mtk_clk_register_muxes()
261 mtk_clk_unregister_mux(clk_data->hws[mux->id]); in mtk_clk_register_muxes()
262 clk_data->hws[mux->id] = ERR_PTR(-ENOENT); in mtk_clk_register_muxes()
277 for (i = num; i > 0; i--) { in mtk_clk_unregister_muxes()
278 const struct mtk_mux *mux = &muxes[i - 1]; in mtk_clk_unregister_muxes() local
280 if (IS_ERR_OR_NULL(clk_data->hws[mux->id])) in mtk_clk_unregister_muxes()
283 mtk_clk_unregister_mux(clk_data->hws[mux->id]); in mtk_clk_unregister_muxes()
284 clk_data->hws[mux->id] = ERR_PTR(-ENOENT); in mtk_clk_unregister_muxes()
290 * This clock notifier is called when the frequency of the parent
291 * PLL clock is to be changed. The idea is to switch the parent to a
292 * stable clock, such as the main oscillator, while the PLL frequency
299 struct clk_hw *hw = __clk_get_hw(data->clk); in mtk_clk_mux_notifier_cb()
305 mux_nb->original_index = mux_nb->ops->get_parent(hw); in mtk_clk_mux_notifier_cb()
306 ret = mux_nb->ops->set_parent(hw, mux_nb->bypass_index); in mtk_clk_mux_notifier_cb()
310 ret = mux_nb->ops->set_parent(hw, mux_nb->original_index); in mtk_clk_mux_notifier_cb()
320 mux_nb->nb.notifier_call = mtk_clk_mux_notifier_cb; in devm_mtk_clk_mux_notifier_register()
322 return devm_clk_notifier_register(dev, clk, &mux_nb->nb); in devm_mtk_clk_mux_notifier_register()