aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorPaul Walmsley <paul@pwsan.com>2010-01-26 22:13:03 -0500
committerPaul Walmsley <paul@pwsan.com>2010-01-26 22:13:03 -0500
commit0b96af683026ab9ca4dd52f9005a1a4fc582e914 (patch)
treebe435bd2d23d1607f034185763bf5840d244bab1 /arch
parent98c4545749234393ec918b703f48eb708658a23d (diff)
OMAP2/3/4 clock: move DPLL clock functions into mach-omap2/clkt_dpll.c
Move all DPLL-related clock functions from mach-omap2/clock.c to mach-omap2/clkt_dpll.c. This is intended to make the clock code easier to understand, since all of the functions needed to manage DPLLs are now located in their own file, rather than being mixed with other, unrelated functions. Clock debugging is also now more finely-grained, since the DEBUG macro can now be defined for DPLLs alone. This should reduce unnecessary console noise when debugging. Also, if at some future point the mach-omap2/ directory is split into OMAP2/3/4 variants, this clkt file can be moved to the plat-omap/ directory to be shared. Thanks to Alexander Shishkin <virtuoso@slind.org> for his comments to improve the patch description. Signed-off-by: Paul Walmsley <paul@pwsan.com> Cc: Alexander Shishkin <virtuoso@slind.org>
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/mach-omap2/Makefile3
-rw-r--r--arch/arm/mach-omap2/clkt_dpll.c386
-rw-r--r--arch/arm/mach-omap2/clock.c355
3 files changed, 388 insertions, 356 deletions
diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
index 7d46fde2ce6..1a135c8e7f1 100644
--- a/arch/arm/mach-omap2/Makefile
+++ b/arch/arm/mach-omap2/Makefile
@@ -8,7 +8,8 @@ obj-y := id.o io.o control.o mux.o devices.o serial.o gpmc.o timer-gp.o
8omap-2-3-common = irq.o sdrc.o omap_hwmod.o 8omap-2-3-common = irq.o sdrc.o omap_hwmod.o
9omap-3-4-common = dpll3xxx.o 9omap-3-4-common = dpll3xxx.o
10prcm-common = prcm.o powerdomain.o 10prcm-common = prcm.o powerdomain.o
11clock-common = clock.o clock_common_data.o clockdomain.o 11clock-common = clock.o clock_common_data.o \
12 clockdomain.o clkt_dpll.o
12 13
13obj-$(CONFIG_ARCH_OMAP2) += $(omap-2-3-common) $(prcm-common) $(clock-common) 14obj-$(CONFIG_ARCH_OMAP2) += $(omap-2-3-common) $(prcm-common) $(clock-common)
14obj-$(CONFIG_ARCH_OMAP3) += $(omap-2-3-common) $(prcm-common) $(clock-common) \ 15obj-$(CONFIG_ARCH_OMAP3) += $(omap-2-3-common) $(prcm-common) $(clock-common) \
diff --git a/arch/arm/mach-omap2/clkt_dpll.c b/arch/arm/mach-omap2/clkt_dpll.c
new file mode 100644
index 00000000000..9eee0e67d5d
--- /dev/null
+++ b/arch/arm/mach-omap2/clkt_dpll.c
@@ -0,0 +1,386 @@
1/*
2 * OMAP2/3/4 DPLL clock functions
3 *
4 * Copyright (C) 2005-2008 Texas Instruments, Inc.
5 * Copyright (C) 2004-2010 Nokia Corporation
6 *
7 * Contacts:
8 * Richard Woodruff <r-woodruff2@ti.com>
9 * Paul Walmsley
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as
13 * published by the Free Software Foundation.
14 */
15#undef DEBUG
16
17#include <linux/kernel.h>
18#include <linux/errno.h>
19#include <linux/clk.h>
20#include <linux/io.h>
21
22#include <asm/div64.h>
23
24#include <plat/clock.h>
25
26#include "clock.h"
27#include "cm.h"
28#include "cm-regbits-24xx.h"
29#include "cm-regbits-34xx.h"
30
31/* DPLL rate rounding: minimum DPLL multiplier, divider values */
32#define DPLL_MIN_MULTIPLIER 1
33#define DPLL_MIN_DIVIDER 1
34
35/* Possible error results from _dpll_test_mult */
36#define DPLL_MULT_UNDERFLOW -1
37
38/*
39 * Scale factor to mitigate roundoff errors in DPLL rate rounding.
40 * The higher the scale factor, the greater the risk of arithmetic overflow,
41 * but the closer the rounded rate to the target rate. DPLL_SCALE_FACTOR
42 * must be a power of DPLL_SCALE_BASE.
43 */
44#define DPLL_SCALE_FACTOR 64
45#define DPLL_SCALE_BASE 2
46#define DPLL_ROUNDING_VAL ((DPLL_SCALE_BASE / 2) * \
47 (DPLL_SCALE_FACTOR / DPLL_SCALE_BASE))
48
49/* DPLL valid Fint frequency band limits - from 34xx TRM Section 4.7.6.2 */
50#define DPLL_FINT_BAND1_MIN 750000
51#define DPLL_FINT_BAND1_MAX 2100000
52#define DPLL_FINT_BAND2_MIN 7500000
53#define DPLL_FINT_BAND2_MAX 21000000
54
55/* _dpll_test_fint() return codes */
56#define DPLL_FINT_UNDERFLOW -1
57#define DPLL_FINT_INVALID -2
58
59/* Private functions */
60
61/*
62 * _dpll_test_fint - test whether an Fint value is valid for the DPLL
63 * @clk: DPLL struct clk to test
64 * @n: divider value (N) to test
65 *
66 * Tests whether a particular divider @n will result in a valid DPLL
67 * internal clock frequency Fint. See the 34xx TRM 4.7.6.2 "DPLL Jitter
68 * Correction". Returns 0 if OK, -1 if the enclosing loop can terminate
69 * (assuming that it is counting N upwards), or -2 if the enclosing loop
70 * should skip to the next iteration (again assuming N is increasing).
71 */
72static int _dpll_test_fint(struct clk *clk, u8 n)
73{
74 struct dpll_data *dd;
75 long fint;
76 int ret = 0;
77
78 dd = clk->dpll_data;
79
80 /* DPLL divider must result in a valid jitter correction val */
81 fint = clk->parent->rate / (n + 1);
82 if (fint < DPLL_FINT_BAND1_MIN) {
83
84 pr_debug("rejecting n=%d due to Fint failure, "
85 "lowering max_divider\n", n);
86 dd->max_divider = n;
87 ret = DPLL_FINT_UNDERFLOW;
88
89 } else if (fint > DPLL_FINT_BAND1_MAX &&
90 fint < DPLL_FINT_BAND2_MIN) {
91
92 pr_debug("rejecting n=%d due to Fint failure\n", n);
93 ret = DPLL_FINT_INVALID;
94
95 } else if (fint > DPLL_FINT_BAND2_MAX) {
96
97 pr_debug("rejecting n=%d due to Fint failure, "
98 "boosting min_divider\n", n);
99 dd->min_divider = n;
100 ret = DPLL_FINT_INVALID;
101
102 }
103
104 return ret;
105}
106
107static unsigned long _dpll_compute_new_rate(unsigned long parent_rate,
108 unsigned int m, unsigned int n)
109{
110 unsigned long long num;
111
112 num = (unsigned long long)parent_rate * m;
113 do_div(num, n);
114 return num;
115}
116
117/*
118 * _dpll_test_mult - test a DPLL multiplier value
119 * @m: pointer to the DPLL m (multiplier) value under test
120 * @n: current DPLL n (divider) value under test
121 * @new_rate: pointer to storage for the resulting rounded rate
122 * @target_rate: the desired DPLL rate
123 * @parent_rate: the DPLL's parent clock rate
124 *
125 * This code tests a DPLL multiplier value, ensuring that the
126 * resulting rate will not be higher than the target_rate, and that
127 * the multiplier value itself is valid for the DPLL. Initially, the
128 * integer pointed to by the m argument should be prescaled by
129 * multiplying by DPLL_SCALE_FACTOR. The code will replace this with
130 * a non-scaled m upon return. This non-scaled m will result in a
131 * new_rate as close as possible to target_rate (but not greater than
132 * target_rate) given the current (parent_rate, n, prescaled m)
133 * triple. Returns DPLL_MULT_UNDERFLOW in the event that the
134 * non-scaled m attempted to underflow, which can allow the calling
135 * function to bail out early; or 0 upon success.
136 */
137static int _dpll_test_mult(int *m, int n, unsigned long *new_rate,
138 unsigned long target_rate,
139 unsigned long parent_rate)
140{
141 int r = 0, carry = 0;
142
143 /* Unscale m and round if necessary */
144 if (*m % DPLL_SCALE_FACTOR >= DPLL_ROUNDING_VAL)
145 carry = 1;
146 *m = (*m / DPLL_SCALE_FACTOR) + carry;
147
148 /*
149 * The new rate must be <= the target rate to avoid programming
150 * a rate that is impossible for the hardware to handle
151 */
152 *new_rate = _dpll_compute_new_rate(parent_rate, *m, n);
153 if (*new_rate > target_rate) {
154 (*m)--;
155 *new_rate = 0;
156 }
157
158 /* Guard against m underflow */
159 if (*m < DPLL_MIN_MULTIPLIER) {
160 *m = DPLL_MIN_MULTIPLIER;
161 *new_rate = 0;
162 r = DPLL_MULT_UNDERFLOW;
163 }
164
165 if (*new_rate == 0)
166 *new_rate = _dpll_compute_new_rate(parent_rate, *m, n);
167
168 return r;
169}
170
171/* Public functions */
172
173void omap2_init_dpll_parent(struct clk *clk)
174{
175 u32 v;
176 struct dpll_data *dd;
177
178 dd = clk->dpll_data;
179 if (!dd)
180 return;
181
182 /* Return bypass rate if DPLL is bypassed */
183 v = __raw_readl(dd->control_reg);
184 v &= dd->enable_mask;
185 v >>= __ffs(dd->enable_mask);
186
187 /* Reparent in case the dpll is in bypass */
188 if (cpu_is_omap24xx()) {
189 if (v == OMAP2XXX_EN_DPLL_LPBYPASS ||
190 v == OMAP2XXX_EN_DPLL_FRBYPASS)
191 clk_reparent(clk, dd->clk_bypass);
192 } else if (cpu_is_omap34xx()) {
193 if (v == OMAP3XXX_EN_DPLL_LPBYPASS ||
194 v == OMAP3XXX_EN_DPLL_FRBYPASS)
195 clk_reparent(clk, dd->clk_bypass);
196 } else if (cpu_is_omap44xx()) {
197 if (v == OMAP4XXX_EN_DPLL_LPBYPASS ||
198 v == OMAP4XXX_EN_DPLL_FRBYPASS ||
199 v == OMAP4XXX_EN_DPLL_MNBYPASS)
200 clk_reparent(clk, dd->clk_bypass);
201 }
202 return;
203}
204
205/**
206 * omap2_get_dpll_rate - returns the current DPLL CLKOUT rate
207 * @clk: struct clk * of a DPLL
208 *
209 * DPLLs can be locked or bypassed - basically, enabled or disabled.
210 * When locked, the DPLL output depends on the M and N values. When
211 * bypassed, on OMAP2xxx, the output rate is either the 32KiHz clock
212 * or sys_clk. Bypass rates on OMAP3 depend on the DPLL: DPLLs 1 and
213 * 2 are bypassed with dpll1_fclk and dpll2_fclk respectively
214 * (generated by DPLL3), while DPLL 3, 4, and 5 bypass rates are sys_clk.
215 * Returns the current DPLL CLKOUT rate (*not* CLKOUTX2) if the DPLL is
216 * locked, or the appropriate bypass rate if the DPLL is bypassed, or 0
217 * if the clock @clk is not a DPLL.
218 */
219u32 omap2_get_dpll_rate(struct clk *clk)
220{
221 long long dpll_clk;
222 u32 dpll_mult, dpll_div, v;
223 struct dpll_data *dd;
224
225 dd = clk->dpll_data;
226 if (!dd)
227 return 0;
228
229 /* Return bypass rate if DPLL is bypassed */
230 v = __raw_readl(dd->control_reg);
231 v &= dd->enable_mask;
232 v >>= __ffs(dd->enable_mask);
233
234 if (cpu_is_omap24xx()) {
235 if (v == OMAP2XXX_EN_DPLL_LPBYPASS ||
236 v == OMAP2XXX_EN_DPLL_FRBYPASS)
237 return dd->clk_bypass->rate;
238 } else if (cpu_is_omap34xx()) {
239 if (v == OMAP3XXX_EN_DPLL_LPBYPASS ||
240 v == OMAP3XXX_EN_DPLL_FRBYPASS)
241 return dd->clk_bypass->rate;
242 } else if (cpu_is_omap44xx()) {
243 if (v == OMAP4XXX_EN_DPLL_LPBYPASS ||
244 v == OMAP4XXX_EN_DPLL_FRBYPASS ||
245 v == OMAP4XXX_EN_DPLL_MNBYPASS)
246 return dd->clk_bypass->rate;
247 }
248
249 v = __raw_readl(dd->mult_div1_reg);
250 dpll_mult = v & dd->mult_mask;
251 dpll_mult >>= __ffs(dd->mult_mask);
252 dpll_div = v & dd->div1_mask;
253 dpll_div >>= __ffs(dd->div1_mask);
254
255 dpll_clk = (long long)dd->clk_ref->rate * dpll_mult;
256 do_div(dpll_clk, dpll_div + 1);
257
258 return dpll_clk;
259}
260
261/* DPLL rate rounding code */
262
263/**
264 * omap2_dpll_set_rate_tolerance: set the error tolerance during rate rounding
265 * @clk: struct clk * of the DPLL
266 * @tolerance: maximum rate error tolerance
267 *
268 * Set the maximum DPLL rate error tolerance for the rate rounding
269 * algorithm. The rate tolerance is an attempt to balance DPLL power
270 * saving (the least divider value "n") vs. rate fidelity (the least
271 * difference between the desired DPLL target rate and the rounded
272 * rate out of the algorithm). So, increasing the tolerance is likely
273 * to decrease DPLL power consumption and increase DPLL rate error.
274 * Returns -EINVAL if provided a null clock ptr or a clk that is not a
275 * DPLL; or 0 upon success.
276 */
277int omap2_dpll_set_rate_tolerance(struct clk *clk, unsigned int tolerance)
278{
279 if (!clk || !clk->dpll_data)
280 return -EINVAL;
281
282 clk->dpll_data->rate_tolerance = tolerance;
283
284 return 0;
285}
286
287/**
288 * omap2_dpll_round_rate - round a target rate for an OMAP DPLL
289 * @clk: struct clk * for a DPLL
290 * @target_rate: desired DPLL clock rate
291 *
292 * Given a DPLL, a desired target rate, and a rate tolerance, round
293 * the target rate to a possible, programmable rate for this DPLL.
294 * Rate tolerance is assumed to be set by the caller before this
295 * function is called. Attempts to select the minimum possible n
296 * within the tolerance to reduce power consumption. Stores the
297 * computed (m, n) in the DPLL's dpll_data structure so set_rate()
298 * will not need to call this (expensive) function again. Returns ~0
299 * if the target rate cannot be rounded, either because the rate is
300 * too low or because the rate tolerance is set too tightly; or the
301 * rounded rate upon success.
302 */
303long omap2_dpll_round_rate(struct clk *clk, unsigned long target_rate)
304{
305 int m, n, r, e, scaled_max_m;
306 unsigned long scaled_rt_rp, new_rate;
307 int min_e = -1, min_e_m = -1, min_e_n = -1;
308 struct dpll_data *dd;
309
310 if (!clk || !clk->dpll_data)
311 return ~0;
312
313 dd = clk->dpll_data;
314
315 pr_debug("clock: starting DPLL round_rate for clock %s, target rate "
316 "%ld\n", clk->name, target_rate);
317
318 scaled_rt_rp = target_rate / (dd->clk_ref->rate / DPLL_SCALE_FACTOR);
319 scaled_max_m = dd->max_multiplier * DPLL_SCALE_FACTOR;
320
321 dd->last_rounded_rate = 0;
322
323 for (n = dd->min_divider; n <= dd->max_divider; n++) {
324
325 /* Is the (input clk, divider) pair valid for the DPLL? */
326 r = _dpll_test_fint(clk, n);
327 if (r == DPLL_FINT_UNDERFLOW)
328 break;
329 else if (r == DPLL_FINT_INVALID)
330 continue;
331
332 /* Compute the scaled DPLL multiplier, based on the divider */
333 m = scaled_rt_rp * n;
334
335 /*
336 * Since we're counting n up, a m overflow means we
337 * can bail out completely (since as n increases in
338 * the next iteration, there's no way that m can
339 * increase beyond the current m)
340 */
341 if (m > scaled_max_m)
342 break;
343
344 r = _dpll_test_mult(&m, n, &new_rate, target_rate,
345 dd->clk_ref->rate);
346
347 /* m can't be set low enough for this n - try with a larger n */
348 if (r == DPLL_MULT_UNDERFLOW)
349 continue;
350
351 e = target_rate - new_rate;
352 pr_debug("clock: n = %d: m = %d: rate error is %d "
353 "(new_rate = %ld)\n", n, m, e, new_rate);
354
355 if (min_e == -1 ||
356 min_e >= (int)(abs(e) - dd->rate_tolerance)) {
357 min_e = e;
358 min_e_m = m;
359 min_e_n = n;
360
361 pr_debug("clock: found new least error %d\n", min_e);
362
363 /* We found good settings -- bail out now */
364 if (min_e <= dd->rate_tolerance)
365 break;
366 }
367 }
368
369 if (min_e < 0) {
370 pr_debug("clock: error: target rate or tolerance too low\n");
371 return ~0;
372 }
373
374 dd->last_rounded_m = min_e_m;
375 dd->last_rounded_n = min_e_n;
376 dd->last_rounded_rate = _dpll_compute_new_rate(dd->clk_ref->rate,
377 min_e_m, min_e_n);
378
379 pr_debug("clock: final least error: e = %d, m = %d, n = %d\n",
380 min_e, min_e_m, min_e_n);
381 pr_debug("clock: final rate: %ld (target rate: %ld)\n",
382 dd->last_rounded_rate, target_rate);
383
384 return dd->last_rounded_rate;
385}
386
diff --git a/arch/arm/mach-omap2/clock.c b/arch/arm/mach-omap2/clock.c
index d88b25565a4..98196285e80 100644
--- a/arch/arm/mach-omap2/clock.c
+++ b/arch/arm/mach-omap2/clock.c
@@ -28,10 +28,7 @@
28#include <plat/clockdomain.h> 28#include <plat/clockdomain.h>
29#include <plat/cpu.h> 29#include <plat/cpu.h>
30#include <plat/prcm.h> 30#include <plat/prcm.h>
31#include <asm/div64.h>
32 31
33#include <plat/sdrc.h>
34#include "sdrc.h"
35#include "clock.h" 32#include "clock.h"
36#include "prm.h" 33#include "prm.h"
37#include "prm-regbits-24xx.h" 34#include "prm-regbits-24xx.h"
@@ -39,72 +36,12 @@
39#include "cm-regbits-24xx.h" 36#include "cm-regbits-24xx.h"
40#include "cm-regbits-34xx.h" 37#include "cm-regbits-34xx.h"
41 38
42/* DPLL rate rounding: minimum DPLL multiplier, divider values */
43#define DPLL_MIN_MULTIPLIER 1
44#define DPLL_MIN_DIVIDER 1
45
46/* Possible error results from _dpll_test_mult */
47#define DPLL_MULT_UNDERFLOW -1
48
49/*
50 * Scale factor to mitigate roundoff errors in DPLL rate rounding.
51 * The higher the scale factor, the greater the risk of arithmetic overflow,
52 * but the closer the rounded rate to the target rate. DPLL_SCALE_FACTOR
53 * must be a power of DPLL_SCALE_BASE.
54 */
55#define DPLL_SCALE_FACTOR 64
56#define DPLL_SCALE_BASE 2
57#define DPLL_ROUNDING_VAL ((DPLL_SCALE_BASE / 2) * \
58 (DPLL_SCALE_FACTOR / DPLL_SCALE_BASE))
59
60/* DPLL valid Fint frequency band limits - from 34xx TRM Section 4.7.6.2 */
61#define DPLL_FINT_BAND1_MIN 750000
62#define DPLL_FINT_BAND1_MAX 2100000
63#define DPLL_FINT_BAND2_MIN 7500000
64#define DPLL_FINT_BAND2_MAX 21000000
65
66/* _dpll_test_fint() return codes */
67#define DPLL_FINT_UNDERFLOW -1
68#define DPLL_FINT_INVALID -2
69
70u8 cpu_mask; 39u8 cpu_mask;
71 40
72/*------------------------------------------------------------------------- 41/*-------------------------------------------------------------------------
73 * OMAP2/3/4 specific clock functions 42 * OMAP2/3/4 specific clock functions
74 *-------------------------------------------------------------------------*/ 43 *-------------------------------------------------------------------------*/
75 44
76void omap2_init_dpll_parent(struct clk *clk)
77{
78 u32 v;
79 struct dpll_data *dd;
80
81 dd = clk->dpll_data;
82 if (!dd)
83 return;
84
85 /* Return bypass rate if DPLL is bypassed */
86 v = __raw_readl(dd->control_reg);
87 v &= dd->enable_mask;
88 v >>= __ffs(dd->enable_mask);
89
90 /* Reparent in case the dpll is in bypass */
91 if (cpu_is_omap24xx()) {
92 if (v == OMAP2XXX_EN_DPLL_LPBYPASS ||
93 v == OMAP2XXX_EN_DPLL_FRBYPASS)
94 clk_reparent(clk, dd->clk_bypass);
95 } else if (cpu_is_omap34xx()) {
96 if (v == OMAP3XXX_EN_DPLL_LPBYPASS ||
97 v == OMAP3XXX_EN_DPLL_FRBYPASS)
98 clk_reparent(clk, dd->clk_bypass);
99 } else if (cpu_is_omap44xx()) {
100 if (v == OMAP4XXX_EN_DPLL_LPBYPASS ||
101 v == OMAP4XXX_EN_DPLL_FRBYPASS ||
102 v == OMAP4XXX_EN_DPLL_MNBYPASS)
103 clk_reparent(clk, dd->clk_bypass);
104 }
105 return;
106}
107
108/** 45/**
109 * _omap2xxx_clk_commit - commit clock parent/rate changes in hardware 46 * _omap2xxx_clk_commit - commit clock parent/rate changes in hardware
110 * @clk: struct clk * 47 * @clk: struct clk *
@@ -127,52 +64,6 @@ static void _omap2xxx_clk_commit(struct clk *clk)
127 prm_read_mod_reg(OMAP24XX_GR_MOD, OMAP2_PRCM_CLKCFG_CTRL_OFFSET); 64 prm_read_mod_reg(OMAP24XX_GR_MOD, OMAP2_PRCM_CLKCFG_CTRL_OFFSET);
128} 65}
129 66
130/*
131 * _dpll_test_fint - test whether an Fint value is valid for the DPLL
132 * @clk: DPLL struct clk to test
133 * @n: divider value (N) to test
134 *
135 * Tests whether a particular divider @n will result in a valid DPLL
136 * internal clock frequency Fint. See the 34xx TRM 4.7.6.2 "DPLL Jitter
137 * Correction". Returns 0 if OK, -1 if the enclosing loop can terminate
138 * (assuming that it is counting N upwards), or -2 if the enclosing loop
139 * should skip to the next iteration (again assuming N is increasing).
140 */
141static int _dpll_test_fint(struct clk *clk, u8 n)
142{
143 struct dpll_data *dd;
144 long fint;
145 int ret = 0;
146
147 dd = clk->dpll_data;
148
149 /* DPLL divider must result in a valid jitter correction val */
150 fint = clk->parent->rate / (n + 1);
151 if (fint < DPLL_FINT_BAND1_MIN) {
152
153 pr_debug("rejecting n=%d due to Fint failure, "
154 "lowering max_divider\n", n);
155 dd->max_divider = n;
156 ret = DPLL_FINT_UNDERFLOW;
157
158 } else if (fint > DPLL_FINT_BAND1_MAX &&
159 fint < DPLL_FINT_BAND2_MIN) {
160
161 pr_debug("rejecting n=%d due to Fint failure\n", n);
162 ret = DPLL_FINT_INVALID;
163
164 } else if (fint > DPLL_FINT_BAND2_MAX) {
165
166 pr_debug("rejecting n=%d due to Fint failure, "
167 "boosting min_divider\n", n);
168 dd->min_divider = n;
169 ret = DPLL_FINT_INVALID;
170
171 }
172
173 return ret;
174}
175
176/** 67/**
177 * omap2_init_clk_clkdm - look up a clockdomain name, store pointer in clk 68 * omap2_init_clk_clkdm - look up a clockdomain name, store pointer in clk
178 * @clk: OMAP clock struct ptr to use 69 * @clk: OMAP clock struct ptr to use
@@ -243,62 +134,6 @@ void omap2_init_clksel_parent(struct clk *clk)
243} 134}
244 135
245/** 136/**
246 * omap2_get_dpll_rate - returns the current DPLL CLKOUT rate
247 * @clk: struct clk * of a DPLL
248 *
249 * DPLLs can be locked or bypassed - basically, enabled or disabled.
250 * When locked, the DPLL output depends on the M and N values. When
251 * bypassed, on OMAP2xxx, the output rate is either the 32KiHz clock
252 * or sys_clk. Bypass rates on OMAP3 depend on the DPLL: DPLLs 1 and
253 * 2 are bypassed with dpll1_fclk and dpll2_fclk respectively
254 * (generated by DPLL3), while DPLL 3, 4, and 5 bypass rates are sys_clk.
255 * Returns the current DPLL CLKOUT rate (*not* CLKOUTX2) if the DPLL is
256 * locked, or the appropriate bypass rate if the DPLL is bypassed, or 0
257 * if the clock @clk is not a DPLL.
258 */
259u32 omap2_get_dpll_rate(struct clk *clk)
260{
261 long long dpll_clk;
262 u32 dpll_mult, dpll_div, v;
263 struct dpll_data *dd;
264
265 dd = clk->dpll_data;
266 if (!dd)
267 return 0;
268
269 /* Return bypass rate if DPLL is bypassed */
270 v = __raw_readl(dd->control_reg);
271 v &= dd->enable_mask;
272 v >>= __ffs(dd->enable_mask);
273
274 if (cpu_is_omap24xx()) {
275 if (v == OMAP2XXX_EN_DPLL_LPBYPASS ||
276 v == OMAP2XXX_EN_DPLL_FRBYPASS)
277 return dd->clk_bypass->rate;
278 } else if (cpu_is_omap34xx()) {
279 if (v == OMAP3XXX_EN_DPLL_LPBYPASS ||
280 v == OMAP3XXX_EN_DPLL_FRBYPASS)
281 return dd->clk_bypass->rate;
282 } else if (cpu_is_omap44xx()) {
283 if (v == OMAP4XXX_EN_DPLL_LPBYPASS ||
284 v == OMAP4XXX_EN_DPLL_FRBYPASS ||
285 v == OMAP4XXX_EN_DPLL_MNBYPASS)
286 return dd->clk_bypass->rate;
287 }
288
289 v = __raw_readl(dd->mult_div1_reg);
290 dpll_mult = v & dd->mult_mask;
291 dpll_mult >>= __ffs(dd->mult_mask);
292 dpll_div = v & dd->div1_mask;
293 dpll_div >>= __ffs(dd->div1_mask);
294
295 dpll_clk = (long long)dd->clk_ref->rate * dpll_mult;
296 do_div(dpll_clk, dpll_div + 1);
297
298 return dpll_clk;
299}
300
301/**
302 * omap2_clk_dflt_find_companion - find companion clock to @clk 137 * omap2_clk_dflt_find_companion - find companion clock to @clk
303 * @clk: struct clk * to find the companion clock of 138 * @clk: struct clk * to find the companion clock of
304 * @other_reg: void __iomem ** to return the companion clock CM_*CLKEN va in 139 * @other_reg: void __iomem ** to return the companion clock CM_*CLKEN va in
@@ -858,196 +693,6 @@ int omap2_clk_set_parent(struct clk *clk, struct clk *new_parent)
858 return 0; 693 return 0;
859} 694}
860 695
861/* DPLL rate rounding code */
862
863/**
864 * omap2_dpll_set_rate_tolerance: set the error tolerance during rate rounding
865 * @clk: struct clk * of the DPLL
866 * @tolerance: maximum rate error tolerance
867 *
868 * Set the maximum DPLL rate error tolerance for the rate rounding
869 * algorithm. The rate tolerance is an attempt to balance DPLL power
870 * saving (the least divider value "n") vs. rate fidelity (the least
871 * difference between the desired DPLL target rate and the rounded
872 * rate out of the algorithm). So, increasing the tolerance is likely
873 * to decrease DPLL power consumption and increase DPLL rate error.
874 * Returns -EINVAL if provided a null clock ptr or a clk that is not a
875 * DPLL; or 0 upon success.
876 */
877int omap2_dpll_set_rate_tolerance(struct clk *clk, unsigned int tolerance)
878{
879 if (!clk || !clk->dpll_data)
880 return -EINVAL;
881
882 clk->dpll_data->rate_tolerance = tolerance;
883
884 return 0;
885}
886
887static unsigned long _dpll_compute_new_rate(unsigned long parent_rate,
888 unsigned int m, unsigned int n)
889{
890 unsigned long long num;
891
892 num = (unsigned long long)parent_rate * m;
893 do_div(num, n);
894 return num;
895}
896
897/*
898 * _dpll_test_mult - test a DPLL multiplier value
899 * @m: pointer to the DPLL m (multiplier) value under test
900 * @n: current DPLL n (divider) value under test
901 * @new_rate: pointer to storage for the resulting rounded rate
902 * @target_rate: the desired DPLL rate
903 * @parent_rate: the DPLL's parent clock rate
904 *
905 * This code tests a DPLL multiplier value, ensuring that the
906 * resulting rate will not be higher than the target_rate, and that
907 * the multiplier value itself is valid for the DPLL. Initially, the
908 * integer pointed to by the m argument should be prescaled by
909 * multiplying by DPLL_SCALE_FACTOR. The code will replace this with
910 * a non-scaled m upon return. This non-scaled m will result in a
911 * new_rate as close as possible to target_rate (but not greater than
912 * target_rate) given the current (parent_rate, n, prescaled m)
913 * triple. Returns DPLL_MULT_UNDERFLOW in the event that the
914 * non-scaled m attempted to underflow, which can allow the calling
915 * function to bail out early; or 0 upon success.
916 */
917static int _dpll_test_mult(int *m, int n, unsigned long *new_rate,
918 unsigned long target_rate,
919 unsigned long parent_rate)
920{
921 int r = 0, carry = 0;
922
923 /* Unscale m and round if necessary */
924 if (*m % DPLL_SCALE_FACTOR >= DPLL_ROUNDING_VAL)
925 carry = 1;
926 *m = (*m / DPLL_SCALE_FACTOR) + carry;
927
928 /*
929 * The new rate must be <= the target rate to avoid programming
930 * a rate that is impossible for the hardware to handle
931 */
932 *new_rate = _dpll_compute_new_rate(parent_rate, *m, n);
933 if (*new_rate > target_rate) {
934 (*m)--;
935 *new_rate = 0;
936 }
937
938 /* Guard against m underflow */
939 if (*m < DPLL_MIN_MULTIPLIER) {
940 *m = DPLL_MIN_MULTIPLIER;
941 *new_rate = 0;
942 r = DPLL_MULT_UNDERFLOW;
943 }
944
945 if (*new_rate == 0)
946 *new_rate = _dpll_compute_new_rate(parent_rate, *m, n);
947
948 return r;
949}
950
951/**
952 * omap2_dpll_round_rate - round a target rate for an OMAP DPLL
953 * @clk: struct clk * for a DPLL
954 * @target_rate: desired DPLL clock rate
955 *
956 * Given a DPLL, a desired target rate, and a rate tolerance, round
957 * the target rate to a possible, programmable rate for this DPLL.
958 * Rate tolerance is assumed to be set by the caller before this
959 * function is called. Attempts to select the minimum possible n
960 * within the tolerance to reduce power consumption. Stores the
961 * computed (m, n) in the DPLL's dpll_data structure so set_rate()
962 * will not need to call this (expensive) function again. Returns ~0
963 * if the target rate cannot be rounded, either because the rate is
964 * too low or because the rate tolerance is set too tightly; or the
965 * rounded rate upon success.
966 */
967long omap2_dpll_round_rate(struct clk *clk, unsigned long target_rate)
968{
969 int m, n, r, e, scaled_max_m;
970 unsigned long scaled_rt_rp, new_rate;
971 int min_e = -1, min_e_m = -1, min_e_n = -1;
972 struct dpll_data *dd;
973
974 if (!clk || !clk->dpll_data)
975 return ~0;
976
977 dd = clk->dpll_data;
978
979 pr_debug("clock: starting DPLL round_rate for clock %s, target rate "
980 "%ld\n", clk->name, target_rate);
981
982 scaled_rt_rp = target_rate / (dd->clk_ref->rate / DPLL_SCALE_FACTOR);
983 scaled_max_m = dd->max_multiplier * DPLL_SCALE_FACTOR;
984
985 dd->last_rounded_rate = 0;
986
987 for (n = dd->min_divider; n <= dd->max_divider; n++) {
988
989 /* Is the (input clk, divider) pair valid for the DPLL? */
990 r = _dpll_test_fint(clk, n);
991 if (r == DPLL_FINT_UNDERFLOW)
992 break;
993 else if (r == DPLL_FINT_INVALID)
994 continue;
995
996 /* Compute the scaled DPLL multiplier, based on the divider */
997 m = scaled_rt_rp * n;
998
999 /*
1000 * Since we're counting n up, a m overflow means we
1001 * can bail out completely (since as n increases in
1002 * the next iteration, there's no way that m can
1003 * increase beyond the current m)
1004 */
1005 if (m > scaled_max_m)
1006 break;
1007
1008 r = _dpll_test_mult(&m, n, &new_rate, target_rate,
1009 dd->clk_ref->rate);
1010
1011 /* m can't be set low enough for this n - try with a larger n */
1012 if (r == DPLL_MULT_UNDERFLOW)
1013 continue;
1014
1015 e = target_rate - new_rate;
1016 pr_debug("clock: n = %d: m = %d: rate error is %d "
1017 "(new_rate = %ld)\n", n, m, e, new_rate);
1018
1019 if (min_e == -1 ||
1020 min_e >= (int)(abs(e) - dd->rate_tolerance)) {
1021 min_e = e;
1022 min_e_m = m;
1023 min_e_n = n;
1024
1025 pr_debug("clock: found new least error %d\n", min_e);
1026
1027 /* We found good settings -- bail out now */
1028 if (min_e <= dd->rate_tolerance)
1029 break;
1030 }
1031 }
1032
1033 if (min_e < 0) {
1034 pr_debug("clock: error: target rate or tolerance too low\n");
1035 return ~0;
1036 }
1037
1038 dd->last_rounded_m = min_e_m;
1039 dd->last_rounded_n = min_e_n;
1040 dd->last_rounded_rate = _dpll_compute_new_rate(dd->clk_ref->rate,
1041 min_e_m, min_e_n);
1042
1043 pr_debug("clock: final least error: e = %d, m = %d, n = %d\n",
1044 min_e, min_e_m, min_e_n);
1045 pr_debug("clock: final rate: %ld (target rate: %ld)\n",
1046 dd->last_rounded_rate, target_rate);
1047
1048 return dd->last_rounded_rate;
1049}
1050
1051/*------------------------------------------------------------------------- 696/*-------------------------------------------------------------------------
1052 * Omap2 clock reset and init functions 697 * Omap2 clock reset and init functions
1053 *-------------------------------------------------------------------------*/ 698 *-------------------------------------------------------------------------*/