Lines Matching +full:abs +full:- +full:range
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>
24 struct clk_range range; member
43 __func__, gck->gckdiv, gck->parent_id); in clk_generated_enable()
45 spin_lock_irqsave(gck->lock, flags); in clk_generated_enable()
46 regmap_write(gck->regmap, gck->layout->offset, in clk_generated_enable()
47 (gck->id & gck->layout->pid_mask)); in clk_generated_enable()
48 regmap_update_bits(gck->regmap, gck->layout->offset, in clk_generated_enable()
49 AT91_PMC_PCR_GCKDIV_MASK | gck->layout->gckcss_mask | in clk_generated_enable()
50 gck->layout->cmd | AT91_PMC_PCR_GCKEN, in clk_generated_enable()
51 field_prep(gck->layout->gckcss_mask, gck->parent_id) | in clk_generated_enable()
52 gck->layout->cmd | in clk_generated_enable()
53 FIELD_PREP(AT91_PMC_PCR_GCKDIV_MASK, gck->gckdiv) | in clk_generated_enable()
55 spin_unlock_irqrestore(gck->lock, flags); in clk_generated_enable()
64 spin_lock_irqsave(gck->lock, flags); in clk_generated_disable()
65 regmap_write(gck->regmap, gck->layout->offset, in clk_generated_disable()
66 (gck->id & gck->layout->pid_mask)); in clk_generated_disable()
67 regmap_update_bits(gck->regmap, gck->layout->offset, in clk_generated_disable()
68 gck->layout->cmd | AT91_PMC_PCR_GCKEN, in clk_generated_disable()
69 gck->layout->cmd); in clk_generated_disable()
70 spin_unlock_irqrestore(gck->lock, flags); in clk_generated_disable()
79 spin_lock_irqsave(gck->lock, flags); in clk_generated_is_enabled()
80 regmap_write(gck->regmap, gck->layout->offset, in clk_generated_is_enabled()
81 (gck->id & gck->layout->pid_mask)); in clk_generated_is_enabled()
82 regmap_read(gck->regmap, gck->layout->offset, &status); in clk_generated_is_enabled()
83 spin_unlock_irqrestore(gck->lock, flags); in clk_generated_is_enabled()
94 return DIV_ROUND_CLOSEST(parent_rate, gck->gckdiv + 1); in clk_generated_recalc_rate()
109 tmp_diff = abs(req->rate - tmp_rate); in clk_generated_best_diff()
114 req->best_parent_rate = parent_rate; in clk_generated_best_diff()
115 req->best_parent_hw = parent; in clk_generated_best_diff()
125 long best_rate = -EINVAL; in clk_generated_determine_rate()
127 int best_diff = -1; in clk_generated_determine_rate()
131 /* do not look for a rate that is outside of our range */ in clk_generated_determine_rate()
132 if (gck->range.max && req->rate > gck->range.max) in clk_generated_determine_rate()
133 req->rate = gck->range.max; in clk_generated_determine_rate()
134 if (gck->range.min && req->rate < gck->range.min) in clk_generated_determine_rate()
135 req->rate = gck->range.min; in clk_generated_determine_rate()
138 if (gck->chg_pid == i) in clk_generated_determine_rate()
148 (gck->range.max && min_rate > gck->range.max)) in clk_generated_determine_rate()
151 div = DIV_ROUND_CLOSEST(parent_rate, req->rate); in clk_generated_determine_rate()
172 if (gck->chg_pid < 0) in clk_generated_determine_rate()
175 parent = clk_hw_get_parent_by_index(hw, gck->chg_pid); in clk_generated_determine_rate()
180 req_parent.rate = req->rate * div; in clk_generated_determine_rate()
193 __clk_get_name((req->best_parent_hw)->clk), in clk_generated_determine_rate()
194 req->best_parent_rate); in clk_generated_determine_rate()
196 if (best_rate < 0 || (gck->range.max && best_rate > gck->range.max)) in clk_generated_determine_rate()
197 return -EINVAL; in clk_generated_determine_rate()
199 req->rate = best_rate; in clk_generated_determine_rate()
209 return -EINVAL; in clk_generated_set_parent()
211 if (gck->mux_table) in clk_generated_set_parent()
212 gck->parent_id = clk_mux_index_to_val(gck->mux_table, 0, index); in clk_generated_set_parent()
214 gck->parent_id = index; in clk_generated_set_parent()
223 return gck->parent_id; in clk_generated_get_parent()
235 return -EINVAL; in clk_generated_set_rate()
237 if (gck->range.max && rate > gck->range.max) in clk_generated_set_rate()
238 return -EINVAL; in clk_generated_set_rate()
242 return -EINVAL; in clk_generated_set_rate()
244 gck->gckdiv = div - 1; in clk_generated_set_rate()
260 * clk_generated_startup - Initialize a given clock to its default parent and
273 spin_lock_irqsave(gck->lock, flags); in clk_generated_startup()
274 regmap_write(gck->regmap, gck->layout->offset, in clk_generated_startup()
275 (gck->id & gck->layout->pid_mask)); in clk_generated_startup()
276 regmap_read(gck->regmap, gck->layout->offset, &tmp); in clk_generated_startup()
277 spin_unlock_irqrestore(gck->lock, flags); in clk_generated_startup()
279 gck->parent_id = field_get(gck->layout->gckcss_mask, tmp); in clk_generated_startup()
280 gck->gckdiv = FIELD_GET(AT91_PMC_PCR_GCKDIV_MASK, tmp); in clk_generated_startup()
288 const struct clk_range *range, in at91_clk_register_generated() argument
298 return ERR_PTR(-ENOMEM); in at91_clk_register_generated()
308 gck->id = id; in at91_clk_register_generated()
309 gck->hw.init = &init; in at91_clk_register_generated()
310 gck->regmap = regmap; in at91_clk_register_generated()
311 gck->lock = lock; in at91_clk_register_generated()
312 gck->range = *range; in at91_clk_register_generated()
313 gck->chg_pid = chg_pid; in at91_clk_register_generated()
314 gck->layout = layout; in at91_clk_register_generated()
315 gck->mux_table = mux_table; in at91_clk_register_generated()
318 hw = &gck->hw; in at91_clk_register_generated()
319 ret = clk_hw_register(NULL, &gck->hw); in at91_clk_register_generated()