42 #include <linux/kernel.h>
43 #include <linux/errno.h>
48 #include <plat/clock.h>
63 static const struct clksel *_get_clksel_by_parent(
struct clk *
clk,
66 const struct clksel *clks;
68 for (clks = clk->clksel; clks->
parent; clks++)
69 if (clks->parent == src_clk)
74 WARN(1,
"clock: %s: could not find parent clock %s in clksel array\n",
97 static u8 _get_div_and_fieldval(
struct clk *src_clk,
struct clk *clk,
100 const struct clksel *clks;
101 const struct clksel_rate *clkr, *max_clkr =
NULL;
104 clks = _get_clksel_by_parent(clk, src_clk);
117 for (clkr = clks->rates; clkr->div; clkr++) {
121 if (clkr->div > max_div) {
129 WARN(1,
"clock: %s: could not find divisor for parent %s\n",
135 *field_val = max_clkr->val;
153 static void _write_clksel_reg(
struct clk *clk,
u32 field_val)
158 v &= ~clk->clksel_mask;
159 v |= field_val <<
__ffs(clk->clksel_mask);
176 static u32 _clksel_to_divisor(
struct clk *clk,
u32 field_val)
178 const struct clksel *clks;
179 const struct clksel_rate *clkr;
183 clks = _get_clksel_by_parent(clk, parent);
187 for (clkr = clks->rates; clkr->div; clkr++) {
191 if (clkr->val == field_val)
197 WARN(1,
"clock: %s: could not find fieldval %d for parent %s\n",
215 static u32 _divisor_to_clksel(
struct clk *clk,
u32 div)
217 const struct clksel *clks;
218 const struct clksel_rate *clkr;
225 clks = _get_clksel_by_parent(clk, parent);
229 for (clkr = clks->rates; clkr->div; clkr++) {
233 if (clkr->div == div)
238 pr_err(
"clock: %s: could not find divisor %d for parent %s\n",
254 static u32 _read_divisor(
struct clk *clk)
258 if (!clk->clksel || !clk->clksel_mask)
262 v &= clk->clksel_mask;
263 v >>=
__ffs(clk->clksel_mask);
265 return _clksel_to_divisor(clk, v);
285 unsigned long test_rate;
286 const struct clksel *clks;
287 const struct clksel_rate *clkr;
290 unsigned long parent_rate;
291 const char *clk_name;
297 if (!clk->clksel || !clk->clksel_mask)
300 pr_debug(
"clock: clksel_round_rate_div: %s target_rate %ld\n",
301 clk_name, target_rate);
305 clks = _get_clksel_by_parent(clk, parent);
309 for (clkr = clks->rates; clkr->div; clkr++) {
314 if (clkr->div <= last_div)
315 pr_err(
"clock: %s: clksel_rate table not sorted\n",
318 last_div = clkr->div;
320 test_rate = parent_rate / clkr->div;
322 if (test_rate <= target_rate)
327 pr_err(
"clock: %s: could not find divisor for target rate %ld for parent %s\n",
332 *new_div = clkr->div;
334 pr_debug(
"clock: new_div = %d, new_rate = %ld\n", *new_div,
335 (parent_rate / clkr->div));
337 return parent_rate / clkr->div;
356 const struct clksel *clks;
357 const struct clksel_rate *clkr;
360 const char *clk_name;
362 if (!clk->clksel || !clk->clksel_mask)
368 r =
__raw_readl(clk->clksel_reg) & clk->clksel_mask;
369 r >>=
__ffs(clk->clksel_mask);
371 for (clks = clk->clksel; clks->
parent && !found; clks++) {
372 for (clkr = clks->rates; clkr->div && !found; clkr++) {
376 if (clkr->val == r) {
377 if (parent != clks->
parent) {
378 pr_debug(
"clock: %s: inited parent to %s (was %s)\n",
392 WARN(!found,
"clock: %s: init parent: could not find regval %0x\n",
413 div = _read_divisor(clk);
420 pr_debug(
"clock: %s: recalc'd rate is %ld (div %d)\n",
461 u32 field_val, validrate, new_div = 0;
463 if (!clk->clksel || !clk->clksel_mask)
467 if (validrate != rate)
470 field_val = _divisor_to_clksel(clk, new_div);
474 _write_clksel_reg(clk, field_val);
509 if (!clk->clksel || !clk->clksel_mask)
512 parent_div = _get_div_and_fieldval(new_parent, clk, &field_val);
516 _write_clksel_reg(clk, field_val);
526 pr_debug(
"clock: %s: set parent to %s (new rate %ld)\n",