Lines Matching +full:min +full:- +full:div

1 // SPDX-License-Identifier: GPL-2.0-or-later
6 * Based on clk-programmable & clk-peripheral drivers by Boris BREZILLON.
10 #include <linux/clk-provider.h>
43 spin_lock_irqsave(gck->lock, flags); in clk_generated_set()
44 regmap_write(gck->regmap, gck->layout->offset, in clk_generated_set()
45 (gck->id & gck->layout->pid_mask)); in clk_generated_set()
46 regmap_update_bits(gck->regmap, gck->layout->offset, in clk_generated_set()
47 AT91_PMC_PCR_GCKDIV_MASK | gck->layout->gckcss_mask | in clk_generated_set()
48 gck->layout->cmd | enable, in clk_generated_set()
49 field_prep(gck->layout->gckcss_mask, gck->parent_id) | in clk_generated_set()
50 gck->layout->cmd | in clk_generated_set()
51 FIELD_PREP(AT91_PMC_PCR_GCKDIV_MASK, gck->gckdiv) | in clk_generated_set()
53 spin_unlock_irqrestore(gck->lock, flags); in clk_generated_set()
63 __func__, gck->gckdiv, gck->parent_id); in clk_generated_enable()
75 spin_lock_irqsave(gck->lock, flags); in clk_generated_disable()
76 regmap_write(gck->regmap, gck->layout->offset, in clk_generated_disable()
77 (gck->id & gck->layout->pid_mask)); in clk_generated_disable()
78 regmap_update_bits(gck->regmap, gck->layout->offset, in clk_generated_disable()
79 gck->layout->cmd | AT91_PMC_PCR_GCKEN, in clk_generated_disable()
80 gck->layout->cmd); in clk_generated_disable()
81 spin_unlock_irqrestore(gck->lock, flags); in clk_generated_disable()
90 spin_lock_irqsave(gck->lock, flags); in clk_generated_is_enabled()
91 regmap_write(gck->regmap, gck->layout->offset, in clk_generated_is_enabled()
92 (gck->id & gck->layout->pid_mask)); in clk_generated_is_enabled()
93 regmap_read(gck->regmap, gck->layout->offset, &status); in clk_generated_is_enabled()
94 spin_unlock_irqrestore(gck->lock, flags); in clk_generated_is_enabled()
105 return DIV_ROUND_CLOSEST(parent_rate, gck->gckdiv + 1); in clk_generated_recalc_rate()
110 unsigned long parent_rate, u32 div, in clk_generated_best_diff() argument
116 if (!div) in clk_generated_best_diff()
119 tmp_rate = parent_rate / div; in clk_generated_best_diff()
121 if (tmp_rate < req->min_rate || tmp_rate > req->max_rate) in clk_generated_best_diff()
124 tmp_diff = abs(req->rate - tmp_rate); in clk_generated_best_diff()
129 req->best_parent_rate = parent_rate; in clk_generated_best_diff()
130 req->best_parent_hw = parent; in clk_generated_best_diff()
139 long best_rate = -EINVAL; in clk_generated_determine_rate()
141 int best_diff = -1; in clk_generated_determine_rate()
143 u32 div; in clk_generated_determine_rate() local
146 if (gck->range.max && req->rate > gck->range.max) in clk_generated_determine_rate()
147 req->rate = gck->range.max; in clk_generated_determine_rate()
148 if (gck->range.min && req->rate < gck->range.min) in clk_generated_determine_rate()
149 req->rate = gck->range.min; in clk_generated_determine_rate()
152 if (gck->chg_pid == i) in clk_generated_determine_rate()
162 (gck->range.max && min_rate > gck->range.max)) in clk_generated_determine_rate()
165 div = DIV_ROUND_CLOSEST(parent_rate, req->rate); in clk_generated_determine_rate()
166 if (div > GENERATED_MAX_DIV + 1) in clk_generated_determine_rate()
167 div = GENERATED_MAX_DIV + 1; in clk_generated_determine_rate()
169 clk_generated_best_diff(req, parent, parent_rate, div, in clk_generated_determine_rate()
186 if (gck->chg_pid < 0) in clk_generated_determine_rate()
189 parent = clk_hw_get_parent_by_index(hw, gck->chg_pid); in clk_generated_determine_rate()
193 for (div = 1; div < GENERATED_MAX_DIV + 2; div++) { in clk_generated_determine_rate()
196 clk_hw_forward_rate_request(hw, req, parent, &req_parent, req->rate * div); in clk_generated_determine_rate()
199 clk_generated_best_diff(req, parent, req_parent.rate, div, in clk_generated_determine_rate()
209 __clk_get_name((req->best_parent_hw)->clk), in clk_generated_determine_rate()
210 req->best_parent_rate); in clk_generated_determine_rate()
212 if (best_rate < 0 || (gck->range.max && best_rate > gck->range.max)) in clk_generated_determine_rate()
213 return -EINVAL; in clk_generated_determine_rate()
215 req->rate = best_rate; in clk_generated_determine_rate()
225 return -EINVAL; in clk_generated_set_parent()
227 if (gck->mux_table) in clk_generated_set_parent()
228 gck->parent_id = clk_mux_index_to_val(gck->mux_table, 0, index); in clk_generated_set_parent()
230 gck->parent_id = index; in clk_generated_set_parent()
239 return gck->parent_id; in clk_generated_get_parent()
248 u32 div; in clk_generated_set_rate() local
251 return -EINVAL; in clk_generated_set_rate()
253 if (gck->range.max && rate > gck->range.max) in clk_generated_set_rate()
254 return -EINVAL; in clk_generated_set_rate()
256 div = DIV_ROUND_CLOSEST(parent_rate, rate); in clk_generated_set_rate()
257 if (div > GENERATED_MAX_DIV + 1 || !div) in clk_generated_set_rate()
258 return -EINVAL; in clk_generated_set_rate()
260 gck->gckdiv = div - 1; in clk_generated_set_rate()
268 gck->pms.status = clk_generated_is_enabled(&gck->hw); in clk_generated_save_context()
277 if (gck->pms.status) in clk_generated_restore_context()
278 clk_generated_set(gck, gck->pms.status); in clk_generated_restore_context()
295 * clk_generated_startup - Initialize a given clock to its default parent and
308 spin_lock_irqsave(gck->lock, flags); in clk_generated_startup()
309 regmap_write(gck->regmap, gck->layout->offset, in clk_generated_startup()
310 (gck->id & gck->layout->pid_mask)); in clk_generated_startup()
311 regmap_read(gck->regmap, gck->layout->offset, &tmp); in clk_generated_startup()
312 spin_unlock_irqrestore(gck->lock, flags); in clk_generated_startup()
314 gck->parent_id = field_get(gck->layout->gckcss_mask, tmp); in clk_generated_startup()
315 gck->gckdiv = FIELD_GET(AT91_PMC_PCR_GCKDIV_MASK, tmp); in clk_generated_startup()
333 return ERR_PTR(-ENOMEM); in at91_clk_register_generated()
337 return ERR_PTR(-ENOMEM); in at91_clk_register_generated()
350 gck->id = id; in at91_clk_register_generated()
351 gck->hw.init = &init; in at91_clk_register_generated()
352 gck->regmap = regmap; in at91_clk_register_generated()
353 gck->lock = lock; in at91_clk_register_generated()
354 gck->range = *range; in at91_clk_register_generated()
355 gck->chg_pid = chg_pid; in at91_clk_register_generated()
356 gck->layout = layout; in at91_clk_register_generated()
357 gck->mux_table = mux_table; in at91_clk_register_generated()
360 hw = &gck->hw; in at91_clk_register_generated()
361 ret = clk_hw_register(NULL, &gck->hw); in at91_clk_register_generated()