aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/mach-omap2/clock.c67
-rw-r--r--arch/arm/mach-omap2/clock24xx.h1
-rw-r--r--arch/arm/mach-omap2/clock34xx.h5
-rw-r--r--arch/arm/plat-omap/include/mach/clock.h1
4 files changed, 72 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 }
diff --git a/arch/arm/mach-omap2/clock24xx.h b/arch/arm/mach-omap2/clock24xx.h
index 32dd8573e56b..7731ab6acd18 100644
--- a/arch/arm/mach-omap2/clock24xx.h
+++ b/arch/arm/mach-omap2/clock24xx.h
@@ -666,6 +666,7 @@ static struct dpll_data dpll_dd = {
666 .mult_mask = OMAP24XX_DPLL_MULT_MASK, 666 .mult_mask = OMAP24XX_DPLL_MULT_MASK,
667 .div1_mask = OMAP24XX_DPLL_DIV_MASK, 667 .div1_mask = OMAP24XX_DPLL_DIV_MASK,
668 .max_multiplier = 1024, 668 .max_multiplier = 1024,
669 .min_divider = 1,
669 .max_divider = 16, 670 .max_divider = 16,
670 .rate_tolerance = DEFAULT_DPLL_RATE_TOLERANCE 671 .rate_tolerance = DEFAULT_DPLL_RATE_TOLERANCE
671}; 672};
diff --git a/arch/arm/mach-omap2/clock34xx.h b/arch/arm/mach-omap2/clock34xx.h
index 7ee131202625..aadd296c05a2 100644
--- a/arch/arm/mach-omap2/clock34xx.h
+++ b/arch/arm/mach-omap2/clock34xx.h
@@ -268,6 +268,7 @@ static struct dpll_data dpll1_dd = {
268 .idlest_reg = OMAP_CM_REGADDR(MPU_MOD, OMAP3430_CM_IDLEST_PLL), 268 .idlest_reg = OMAP_CM_REGADDR(MPU_MOD, OMAP3430_CM_IDLEST_PLL),
269 .idlest_mask = OMAP3430_ST_MPU_CLK_MASK, 269 .idlest_mask = OMAP3430_ST_MPU_CLK_MASK,
270 .max_multiplier = OMAP3_MAX_DPLL_MULT, 270 .max_multiplier = OMAP3_MAX_DPLL_MULT,
271 .min_divider = 1,
271 .max_divider = OMAP3_MAX_DPLL_DIV, 272 .max_divider = OMAP3_MAX_DPLL_DIV,
272 .rate_tolerance = DEFAULT_DPLL_RATE_TOLERANCE 273 .rate_tolerance = DEFAULT_DPLL_RATE_TOLERANCE
273}; 274};
@@ -341,6 +342,7 @@ static struct dpll_data dpll2_dd = {
341 .idlest_reg = OMAP_CM_REGADDR(OMAP3430_IVA2_MOD, OMAP3430_CM_IDLEST_PLL), 342 .idlest_reg = OMAP_CM_REGADDR(OMAP3430_IVA2_MOD, OMAP3430_CM_IDLEST_PLL),
342 .idlest_mask = OMAP3430_ST_IVA2_CLK_MASK, 343 .idlest_mask = OMAP3430_ST_IVA2_CLK_MASK,
343 .max_multiplier = OMAP3_MAX_DPLL_MULT, 344 .max_multiplier = OMAP3_MAX_DPLL_MULT,
345 .min_divider = 1,
344 .max_divider = OMAP3_MAX_DPLL_DIV, 346 .max_divider = OMAP3_MAX_DPLL_DIV,
345 .rate_tolerance = DEFAULT_DPLL_RATE_TOLERANCE 347 .rate_tolerance = DEFAULT_DPLL_RATE_TOLERANCE
346}; 348};
@@ -400,6 +402,7 @@ static struct dpll_data dpll3_dd = {
400 .idlest_reg = OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST), 402 .idlest_reg = OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST),
401 .idlest_mask = OMAP3430_ST_CORE_CLK_MASK, 403 .idlest_mask = OMAP3430_ST_CORE_CLK_MASK,
402 .max_multiplier = OMAP3_MAX_DPLL_MULT, 404 .max_multiplier = OMAP3_MAX_DPLL_MULT,
405 .min_divider = 1,
403 .max_divider = OMAP3_MAX_DPLL_DIV, 406 .max_divider = OMAP3_MAX_DPLL_DIV,
404 .rate_tolerance = DEFAULT_DPLL_RATE_TOLERANCE 407 .rate_tolerance = DEFAULT_DPLL_RATE_TOLERANCE
405}; 408};
@@ -591,6 +594,7 @@ static struct dpll_data dpll4_dd = {
591 .idlest_reg = OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST), 594 .idlest_reg = OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST),
592 .idlest_mask = OMAP3430_ST_PERIPH_CLK_MASK, 595 .idlest_mask = OMAP3430_ST_PERIPH_CLK_MASK,
593 .max_multiplier = OMAP3_MAX_DPLL_MULT, 596 .max_multiplier = OMAP3_MAX_DPLL_MULT,
597 .min_divider = 1,
594 .max_divider = OMAP3_MAX_DPLL_DIV, 598 .max_divider = OMAP3_MAX_DPLL_DIV,
595 .rate_tolerance = DEFAULT_DPLL_RATE_TOLERANCE 599 .rate_tolerance = DEFAULT_DPLL_RATE_TOLERANCE
596}; 600};
@@ -930,6 +934,7 @@ static struct dpll_data dpll5_dd = {
930 .idlest_reg = OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST2), 934 .idlest_reg = OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST2),
931 .idlest_mask = OMAP3430ES2_ST_PERIPH2_CLK_MASK, 935 .idlest_mask = OMAP3430ES2_ST_PERIPH2_CLK_MASK,
932 .max_multiplier = OMAP3_MAX_DPLL_MULT, 936 .max_multiplier = OMAP3_MAX_DPLL_MULT,
937 .min_divider = 1,
933 .max_divider = OMAP3_MAX_DPLL_DIV, 938 .max_divider = OMAP3_MAX_DPLL_DIV,
934 .rate_tolerance = DEFAULT_DPLL_RATE_TOLERANCE 939 .rate_tolerance = DEFAULT_DPLL_RATE_TOLERANCE
935}; 940};
diff --git a/arch/arm/plat-omap/include/mach/clock.h b/arch/arm/plat-omap/include/mach/clock.h
index 611df52a3242..cd69111cd33f 100644
--- a/arch/arm/plat-omap/include/mach/clock.h
+++ b/arch/arm/plat-omap/include/mach/clock.h
@@ -43,6 +43,7 @@ struct dpll_data {
43 unsigned long last_rounded_rate; 43 unsigned long last_rounded_rate;
44 u16 last_rounded_m; 44 u16 last_rounded_m;
45 u8 last_rounded_n; 45 u8 last_rounded_n;
46 u8 min_divider;
46 u8 max_divider; 47 u8 max_divider;
47 u32 max_tolerance; 48 u32 max_tolerance;
48 u16 max_multiplier; 49 u16 max_multiplier;