aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-omap2/clock.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-omap2/clock.c')
-rw-r--r--arch/arm/mach-omap2/clock.c67
1 files changed, 65 insertions, 2 deletions
diff --git a/arch/arm/mach-omap2/clock.c b/arch/arm/mach-omap2/clock.c
index 76e20bcc4e8a..752e34787f21 100644
--- a/arch/arm/mach-omap2/clock.c
+++ b/arch/arm/mach-omap2/clock.c
@@ -58,12 +58,68 @@
58#define DPLL_ROUNDING_VAL ((DPLL_SCALE_BASE / 2) * \ 58#define DPLL_ROUNDING_VAL ((DPLL_SCALE_BASE / 2) * \
59 (DPLL_SCALE_FACTOR / DPLL_SCALE_BASE)) 59 (DPLL_SCALE_FACTOR / DPLL_SCALE_BASE))
60 60
61/* DPLL valid Fint frequency band limits - from 34xx TRM Section 4.7.6.2 */
62#define DPLL_FINT_BAND1_MIN 750000
63#define DPLL_FINT_BAND1_MAX 2100000
64#define DPLL_FINT_BAND2_MIN 7500000
65#define DPLL_FINT_BAND2_MAX 21000000
66
67/* _dpll_test_fint() return codes */
68#define DPLL_FINT_UNDERFLOW -1
69#define DPLL_FINT_INVALID -2
70
61u8 cpu_mask; 71u8 cpu_mask;
62 72
63/*------------------------------------------------------------------------- 73/*-------------------------------------------------------------------------
64 * OMAP2/3 specific clock functions 74 * OMAP2/3 specific clock functions
65 *-------------------------------------------------------------------------*/ 75 *-------------------------------------------------------------------------*/
66 76
77/*
78 * _dpll_test_fint - test whether an Fint value is valid for the DPLL
79 * @clk: DPLL struct clk to test
80 * @n: divider value (N) to test
81 *
82 * Tests whether a particular divider @n will result in a valid DPLL
83 * internal clock frequency Fint. See the 34xx TRM 4.7.6.2 "DPLL Jitter
84 * Correction". Returns 0 if OK, -1 if the enclosing loop can terminate
85 * (assuming that it is counting N upwards), or -2 if the enclosing loop
86 * should skip to the next iteration (again assuming N is increasing).
87 */
88static int _dpll_test_fint(struct clk *clk, u8 n)
89{
90 struct dpll_data *dd;
91 long fint;
92 int ret = 0;
93
94 dd = clk->dpll_data;
95
96 /* DPLL divider must result in a valid jitter correction val */
97 fint = clk->parent->rate / (n + 1);
98 if (fint < DPLL_FINT_BAND1_MIN) {
99
100 pr_debug("rejecting n=%d due to Fint failure, "
101 "lowering max_divider\n", n);
102 dd->max_divider = n;
103 ret = DPLL_FINT_UNDERFLOW;
104
105 } else if (fint > DPLL_FINT_BAND1_MAX &&
106 fint < DPLL_FINT_BAND2_MIN) {
107
108 pr_debug("rejecting n=%d due to Fint failure\n", n);
109 ret = DPLL_FINT_INVALID;
110
111 } else if (fint > DPLL_FINT_BAND2_MAX) {
112
113 pr_debug("rejecting n=%d due to Fint failure, "
114 "boosting min_divider\n", n);
115 dd->min_divider = n;
116 ret = DPLL_FINT_INVALID;
117
118 }
119
120 return ret;
121}
122
67/** 123/**
68 * omap2_init_clk_clkdm - look up a clockdomain name, store pointer in clk 124 * omap2_init_clk_clkdm - look up a clockdomain name, store pointer in clk
69 * @clk: OMAP clock struct ptr to use 125 * @clk: OMAP clock struct ptr to use
@@ -892,7 +948,14 @@ long omap2_dpll_round_rate(struct clk *clk, unsigned long target_rate)
892 948
893 dd->last_rounded_rate = 0; 949 dd->last_rounded_rate = 0;
894 950
895 for (n = DPLL_MIN_DIVIDER; n <= dd->max_divider; n++) { 951 for (n = dd->min_divider; n <= dd->max_divider; n++) {
952
953 /* Is the (input clk, divider) pair valid for the DPLL? */
954 r = _dpll_test_fint(clk, n);
955 if (r == DPLL_FINT_UNDERFLOW)
956 break;
957 else if (r == DPLL_FINT_INVALID)
958 continue;
896 959
897 /* Compute the scaled DPLL multiplier, based on the divider */ 960 /* Compute the scaled DPLL multiplier, based on the divider */
898 m = scaled_rt_rp * n; 961 m = scaled_rt_rp * n;
@@ -926,7 +989,7 @@ long omap2_dpll_round_rate(struct clk *clk, unsigned long target_rate)
926 pr_debug("clock: found new least error %d\n", min_e); 989 pr_debug("clock: found new least error %d\n", min_e);
927 990
928 /* We found good settings -- bail out now */ 991 /* We found good settings -- bail out now */
929 if (min_e <= clk->dpll_data->rate_tolerance) 992 if (min_e <= dd->rate_tolerance)
930 break; 993 break;
931 } 994 }
932 } 995 }