17 #include <linux/kernel.h>
18 #include <linux/errno.h>
22 #include <asm/div64.h>
24 #include <plat/clock.h>
32 #define DPLL_MIN_MULTIPLIER 2
33 #define DPLL_MIN_DIVIDER 1
36 #define DPLL_MULT_UNDERFLOW -1
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))
50 #define OMAP3430_DPLL_FINT_BAND1_MIN 750000
51 #define OMAP3430_DPLL_FINT_BAND1_MAX 2100000
52 #define OMAP3430_DPLL_FINT_BAND2_MIN 7500000
53 #define OMAP3430_DPLL_FINT_BAND2_MAX 21000000
59 #define OMAP3PLUS_DPLL_FINT_JTYPE_MIN 500000
60 #define OMAP3PLUS_DPLL_FINT_JTYPE_MAX 2500000
61 #define OMAP3PLUS_DPLL_FINT_MIN 32000
62 #define OMAP3PLUS_DPLL_FINT_MAX 52000000
65 #define DPLL_FINT_UNDERFLOW -1
66 #define DPLL_FINT_INVALID -2
81 static int _dpll_test_fint(
struct clk *
clk,
u8 n)
84 long fint, fint_min, fint_max;
94 WARN(1,
"No fint limits available for OMAP2!\n");
107 if (fint < fint_min) {
108 pr_debug(
"rejecting n=%d due to Fint failure, lowering max_divider\n",
112 }
else if (fint > fint_max) {
113 pr_debug(
"rejecting n=%d due to Fint failure, boosting min_divider\n",
119 pr_debug(
"rejecting n=%d due to Fint failure\n", n);
126 static unsigned long _dpll_compute_new_rate(
unsigned long parent_rate,
127 unsigned int m,
unsigned int n)
129 unsigned long long num;
131 num = (
unsigned long long)parent_rate * m;
156 static int _dpll_test_mult(
int *
m,
int n,
unsigned long *new_rate,
157 unsigned long target_rate,
158 unsigned long parent_rate)
160 int r = 0, carry = 0;
171 *new_rate = _dpll_compute_new_rate(parent_rate, *m, n);
172 if (*new_rate > target_rate) {
185 *new_rate = _dpll_compute_new_rate(parent_rate, *m, n);
195 struct dpll_data *
dd;
202 v &= dd->enable_mask;
203 v >>=
__ffs(dd->enable_mask);
240 u32 dpll_mult, dpll_div,
v;
241 struct dpll_data *
dd;
249 v &= dd->enable_mask;
250 v >>=
__ffs(dd->enable_mask);
268 dpll_mult = v & dd->mult_mask;
269 dpll_mult >>=
__ffs(dd->mult_mask);
270 dpll_div = v & dd->div1_mask;
271 dpll_div >>=
__ffs(dd->div1_mask);
274 do_div(dpll_clk, dpll_div + 1);
295 int m,
n,
r, scaled_max_m;
296 unsigned long scaled_rt_rp;
297 unsigned long new_rate = 0;
298 struct dpll_data *
dd;
299 unsigned long ref_rate;
300 const char *clk_name;
302 if (!clk || !clk->dpll_data)
309 pr_debug(
"clock: %s: starting DPLL round_rate, target rate %ld\n",
310 clk_name, target_rate);
315 dd->last_rounded_rate = 0;
317 for (n = dd->min_divider; n <= dd->max_divider; n++) {
320 r = _dpll_test_fint(clk, n);
327 m = scaled_rt_rp *
n;
335 if (m > scaled_max_m)
338 r = _dpll_test_mult(&m, n, &new_rate, target_rate,
345 pr_debug(
"clock: %s: m = %d: n = %d: new_rate = %ld\n",
346 clk_name, m, n, new_rate);
348 if (target_rate == new_rate) {
349 dd->last_rounded_m =
m;
350 dd->last_rounded_n =
n;
351 dd->last_rounded_rate = target_rate;
356 if (target_rate != new_rate) {
357 pr_debug(
"clock: %s: cannot round to rate %ld\n",
358 clk_name, target_rate);