aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-omap2/clock34xx.h
diff options
context:
space:
mode:
authorPaul Walmsley <paul@pwsan.com>2008-07-03 05:24:46 -0400
committerTony Lindgren <tony@atomide.com>2008-07-03 05:24:46 -0400
commit88b8ba90570067178d32c654ad95786041e86e86 (patch)
treec2ce719334f9fbbde2500b990bc1cc295226334a /arch/arm/mach-omap2/clock34xx.h
parent542313cc98e72d026d2df86f515699dfaface460 (diff)
ARM: OMAP2: Clock: New OMAP2/3 DPLL rate rounding algorithm
This patch adds a new rate rounding algorithm for DPLL clocks on the OMAP2/3 architecture. For a desired DPLL target rate, there may be several multiplier/divider (M, N) values which will generate a sufficiently close rate. Lower N values result in greater power economy. However, lower N values can cause the difference between the rounded rate and the target rate ("rate error") to be larger than it would be with a higher N. This can cause downstream devices to run more slowly than they otherwise would. This DPLL rate rounding algorithm: - attempts to find the lowest possible N (DPLL divider) to reach the target_rate (since, according to Richard Woodruff <r-woodruff@ti.com>, lower N values save more power than higher N values). - allows developers to set an upper bound on the error between the rounded rate and the desired target rate ("rate tolerance"), so an appropriate balance between rate fidelity and power savings can be set. This maximum rate error tolerance is set via omap2_set_dpll_rate_tolerance(). - never returns a rounded rate higher than the target rate. The rate rounding algorithm caches the last rounded M, N, and rate computation to avoid rounding the rate twice for each clk_set_rate() call. (This patch does not yet implement set_rate for DPLLs; that follows in a future patch.) The algorithm trades execution speed for rate accuracy. It will find the (M, N) set that results in the least rate error, within a specified rate tolerance. It does this by evaluating each divider setting - on OMAP3, this involves 128 steps. Another approach to DPLL rate rounding would be to bail out as soon as a valid rate is found within the rate tolerance, which would trade rate accuracy for execution speed. Alternate implementations welcome. This code is not yet used by the OMAP24XX DPLL clock, since it is currently defined as a composite clock, fusing the DPLL M,N and the M2 output divider. This patch also renames the existing OMAP24xx DPLL programming functions to highlight that they program both the DPLL and the DPLL's output multiplier. Signed-off-by: Paul Walmsley <paul@pwsan.com> Signed-off-by: Tony Lindgren <tony@atomide.com>
Diffstat (limited to 'arch/arm/mach-omap2/clock34xx.h')
-rw-r--r--arch/arm/mach-omap2/clock34xx.h36
1 files changed, 30 insertions, 6 deletions
diff --git a/arch/arm/mach-omap2/clock34xx.h b/arch/arm/mach-omap2/clock34xx.h
index e349d48ee807..05757eb032bc 100644
--- a/arch/arm/mach-omap2/clock34xx.h
+++ b/arch/arm/mach-omap2/clock34xx.h
@@ -35,6 +35,10 @@ static u32 omap3_dpll_autoidle_read(struct clk *clk);
35static int omap3_noncore_dpll_enable(struct clk *clk); 35static int omap3_noncore_dpll_enable(struct clk *clk);
36static void omap3_noncore_dpll_disable(struct clk *clk); 36static void omap3_noncore_dpll_disable(struct clk *clk);
37 37
38/* Maximum DPLL multiplier, divider values for OMAP3 */
39#define OMAP3_MAX_DPLL_MULT 2048
40#define OMAP3_MAX_DPLL_DIV 128
41
38/* 42/*
39 * DPLL1 supplies clock to the MPU. 43 * DPLL1 supplies clock to the MPU.
40 * DPLL2 supplies clock to the IVA2. 44 * DPLL2 supplies clock to the IVA2.
@@ -255,7 +259,7 @@ static const struct clksel_rate div16_dpll_rates[] = {
255/* DPLL1 */ 259/* DPLL1 */
256/* MPU clock source */ 260/* MPU clock source */
257/* Type: DPLL */ 261/* Type: DPLL */
258static const struct dpll_data dpll1_dd = { 262static struct dpll_data dpll1_dd = {
259 .mult_div1_reg = OMAP_CM_REGADDR(MPU_MOD, OMAP3430_CM_CLKSEL1_PLL), 263 .mult_div1_reg = OMAP_CM_REGADDR(MPU_MOD, OMAP3430_CM_CLKSEL1_PLL),
260 .mult_mask = OMAP3430_MPU_DPLL_MULT_MASK, 264 .mult_mask = OMAP3430_MPU_DPLL_MULT_MASK,
261 .div1_mask = OMAP3430_MPU_DPLL_DIV_MASK, 265 .div1_mask = OMAP3430_MPU_DPLL_DIV_MASK,
@@ -269,6 +273,9 @@ static const struct dpll_data dpll1_dd = {
269 .autoidle_mask = OMAP3430_AUTO_MPU_DPLL_MASK, 273 .autoidle_mask = OMAP3430_AUTO_MPU_DPLL_MASK,
270 .idlest_reg = OMAP_CM_REGADDR(MPU_MOD, OMAP3430_CM_IDLEST_PLL), 274 .idlest_reg = OMAP_CM_REGADDR(MPU_MOD, OMAP3430_CM_IDLEST_PLL),
271 .idlest_bit = OMAP3430_ST_MPU_CLK_SHIFT, 275 .idlest_bit = OMAP3430_ST_MPU_CLK_SHIFT,
276 .max_multiplier = OMAP3_MAX_DPLL_MULT,
277 .max_divider = OMAP3_MAX_DPLL_DIV,
278 .rate_tolerance = DEFAULT_DPLL_RATE_TOLERANCE
272}; 279};
273 280
274static struct clk dpll1_ck = { 281static struct clk dpll1_ck = {
@@ -276,6 +283,7 @@ static struct clk dpll1_ck = {
276 .parent = &sys_ck, 283 .parent = &sys_ck,
277 .dpll_data = &dpll1_dd, 284 .dpll_data = &dpll1_dd,
278 .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | ALWAYS_ENABLED, 285 .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | ALWAYS_ENABLED,
286 .round_rate = &omap2_dpll_round_rate,
279 .recalc = &omap3_dpll_recalc, 287 .recalc = &omap3_dpll_recalc,
280}; 288};
281 289
@@ -317,7 +325,7 @@ static struct clk dpll1_x2m2_ck = {
317/* IVA2 clock source */ 325/* IVA2 clock source */
318/* Type: DPLL */ 326/* Type: DPLL */
319 327
320static const struct dpll_data dpll2_dd = { 328static struct dpll_data dpll2_dd = {
321 .mult_div1_reg = OMAP_CM_REGADDR(OMAP3430_IVA2_MOD, OMAP3430_CM_CLKSEL1_PLL), 329 .mult_div1_reg = OMAP_CM_REGADDR(OMAP3430_IVA2_MOD, OMAP3430_CM_CLKSEL1_PLL),
322 .mult_mask = OMAP3430_IVA2_DPLL_MULT_MASK, 330 .mult_mask = OMAP3430_IVA2_DPLL_MULT_MASK,
323 .div1_mask = OMAP3430_IVA2_DPLL_DIV_MASK, 331 .div1_mask = OMAP3430_IVA2_DPLL_DIV_MASK,
@@ -331,7 +339,10 @@ static const struct dpll_data dpll2_dd = {
331 .autoidle_reg = OMAP_CM_REGADDR(OMAP3430_IVA2_MOD, OMAP3430_CM_AUTOIDLE_PLL), 339 .autoidle_reg = OMAP_CM_REGADDR(OMAP3430_IVA2_MOD, OMAP3430_CM_AUTOIDLE_PLL),
332 .autoidle_mask = OMAP3430_AUTO_IVA2_DPLL_MASK, 340 .autoidle_mask = OMAP3430_AUTO_IVA2_DPLL_MASK,
333 .idlest_reg = OMAP_CM_REGADDR(OMAP3430_IVA2_MOD, OMAP3430_CM_IDLEST_PLL), 341 .idlest_reg = OMAP_CM_REGADDR(OMAP3430_IVA2_MOD, OMAP3430_CM_IDLEST_PLL),
334 .idlest_bit = OMAP3430_ST_IVA2_CLK_SHIFT 342 .idlest_bit = OMAP3430_ST_IVA2_CLK_SHIFT,
343 .max_multiplier = OMAP3_MAX_DPLL_MULT,
344 .max_divider = OMAP3_MAX_DPLL_DIV,
345 .rate_tolerance = DEFAULT_DPLL_RATE_TOLERANCE
335}; 346};
336 347
337static struct clk dpll2_ck = { 348static struct clk dpll2_ck = {
@@ -341,6 +352,7 @@ static struct clk dpll2_ck = {
341 .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES, 352 .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES,
342 .enable = &omap3_noncore_dpll_enable, 353 .enable = &omap3_noncore_dpll_enable,
343 .disable = &omap3_noncore_dpll_disable, 354 .disable = &omap3_noncore_dpll_disable,
355 .round_rate = &omap2_dpll_round_rate,
344 .recalc = &omap3_dpll_recalc, 356 .recalc = &omap3_dpll_recalc,
345}; 357};
346 358
@@ -371,7 +383,7 @@ static struct clk dpll2_m2_ck = {
371 * Source clock for all interfaces and for some device fclks 383 * Source clock for all interfaces and for some device fclks
372 * REVISIT: Also supports fast relock bypass - not included below 384 * REVISIT: Also supports fast relock bypass - not included below
373 */ 385 */
374static const struct dpll_data dpll3_dd = { 386static struct dpll_data dpll3_dd = {
375 .mult_div1_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1), 387 .mult_div1_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL1),
376 .mult_mask = OMAP3430_CORE_DPLL_MULT_MASK, 388 .mult_mask = OMAP3430_CORE_DPLL_MULT_MASK,
377 .div1_mask = OMAP3430_CORE_DPLL_DIV_MASK, 389 .div1_mask = OMAP3430_CORE_DPLL_DIV_MASK,
@@ -382,6 +394,9 @@ static const struct dpll_data dpll3_dd = {
382 .recal_st_bit = OMAP3430_CORE_DPLL_ST_SHIFT, 394 .recal_st_bit = OMAP3430_CORE_DPLL_ST_SHIFT,
383 .autoidle_reg = OMAP_CM_REGADDR(PLL_MOD, CM_AUTOIDLE), 395 .autoidle_reg = OMAP_CM_REGADDR(PLL_MOD, CM_AUTOIDLE),
384 .autoidle_mask = OMAP3430_AUTO_CORE_DPLL_MASK, 396 .autoidle_mask = OMAP3430_AUTO_CORE_DPLL_MASK,
397 .max_multiplier = OMAP3_MAX_DPLL_MULT,
398 .max_divider = OMAP3_MAX_DPLL_DIV,
399 .rate_tolerance = DEFAULT_DPLL_RATE_TOLERANCE
385}; 400};
386 401
387static struct clk dpll3_ck = { 402static struct clk dpll3_ck = {
@@ -389,6 +404,7 @@ static struct clk dpll3_ck = {
389 .parent = &sys_ck, 404 .parent = &sys_ck,
390 .dpll_data = &dpll3_dd, 405 .dpll_data = &dpll3_dd,
391 .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | ALWAYS_ENABLED, 406 .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES | ALWAYS_ENABLED,
407 .round_rate = &omap2_dpll_round_rate,
392 .recalc = &omap3_dpll_recalc, 408 .recalc = &omap3_dpll_recalc,
393}; 409};
394 410
@@ -545,7 +561,7 @@ static struct clk emu_core_alwon_ck = {
545/* DPLL4 */ 561/* DPLL4 */
546/* Supplies 96MHz, 54Mhz TV DAC, DSS fclk, CAM sensor clock, emul trace clk */ 562/* Supplies 96MHz, 54Mhz TV DAC, DSS fclk, CAM sensor clock, emul trace clk */
547/* Type: DPLL */ 563/* Type: DPLL */
548static const struct dpll_data dpll4_dd = { 564static struct dpll_data dpll4_dd = {
549 .mult_div1_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL2), 565 .mult_div1_reg = OMAP_CM_REGADDR(PLL_MOD, CM_CLKSEL2),
550 .mult_mask = OMAP3430_PERIPH_DPLL_MULT_MASK, 566 .mult_mask = OMAP3430_PERIPH_DPLL_MULT_MASK,
551 .div1_mask = OMAP3430_PERIPH_DPLL_DIV_MASK, 567 .div1_mask = OMAP3430_PERIPH_DPLL_DIV_MASK,
@@ -559,6 +575,9 @@ static const struct dpll_data dpll4_dd = {
559 .autoidle_mask = OMAP3430_AUTO_PERIPH_DPLL_MASK, 575 .autoidle_mask = OMAP3430_AUTO_PERIPH_DPLL_MASK,
560 .idlest_reg = OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST), 576 .idlest_reg = OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST),
561 .idlest_bit = OMAP3430_ST_PERIPH_CLK_SHIFT, 577 .idlest_bit = OMAP3430_ST_PERIPH_CLK_SHIFT,
578 .max_multiplier = OMAP3_MAX_DPLL_MULT,
579 .max_divider = OMAP3_MAX_DPLL_DIV,
580 .rate_tolerance = DEFAULT_DPLL_RATE_TOLERANCE
562}; 581};
563 582
564static struct clk dpll4_ck = { 583static struct clk dpll4_ck = {
@@ -568,6 +587,7 @@ static struct clk dpll4_ck = {
568 .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES, 587 .flags = CLOCK_IN_OMAP343X | RATE_PROPAGATES,
569 .enable = &omap3_noncore_dpll_enable, 588 .enable = &omap3_noncore_dpll_enable,
570 .disable = &omap3_noncore_dpll_disable, 589 .disable = &omap3_noncore_dpll_disable,
590 .round_rate = &omap2_dpll_round_rate,
571 .recalc = &omap3_dpll_recalc, 591 .recalc = &omap3_dpll_recalc,
572}; 592};
573 593
@@ -843,7 +863,7 @@ static struct clk emu_per_alwon_ck = {
843/* Supplies 120MHz clock, USIM source clock */ 863/* Supplies 120MHz clock, USIM source clock */
844/* Type: DPLL */ 864/* Type: DPLL */
845/* 3430ES2 only */ 865/* 3430ES2 only */
846static const struct dpll_data dpll5_dd = { 866static struct dpll_data dpll5_dd = {
847 .mult_div1_reg = OMAP_CM_REGADDR(PLL_MOD, OMAP3430ES2_CM_CLKSEL4), 867 .mult_div1_reg = OMAP_CM_REGADDR(PLL_MOD, OMAP3430ES2_CM_CLKSEL4),
848 .mult_mask = OMAP3430ES2_PERIPH2_DPLL_MULT_MASK, 868 .mult_mask = OMAP3430ES2_PERIPH2_DPLL_MULT_MASK,
849 .div1_mask = OMAP3430ES2_PERIPH2_DPLL_DIV_MASK, 869 .div1_mask = OMAP3430ES2_PERIPH2_DPLL_DIV_MASK,
@@ -857,6 +877,9 @@ static const struct dpll_data dpll5_dd = {
857 .autoidle_mask = OMAP3430ES2_AUTO_PERIPH2_DPLL_MASK, 877 .autoidle_mask = OMAP3430ES2_AUTO_PERIPH2_DPLL_MASK,
858 .idlest_reg = OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST2), 878 .idlest_reg = OMAP_CM_REGADDR(PLL_MOD, CM_IDLEST2),
859 .idlest_bit = OMAP3430ES2_ST_PERIPH2_CLK_SHIFT, 879 .idlest_bit = OMAP3430ES2_ST_PERIPH2_CLK_SHIFT,
880 .max_multiplier = OMAP3_MAX_DPLL_MULT,
881 .max_divider = OMAP3_MAX_DPLL_DIV,
882 .rate_tolerance = DEFAULT_DPLL_RATE_TOLERANCE
860}; 883};
861 884
862static struct clk dpll5_ck = { 885static struct clk dpll5_ck = {
@@ -866,6 +889,7 @@ static struct clk dpll5_ck = {
866 .flags = CLOCK_IN_OMAP3430ES2 | RATE_PROPAGATES, 889 .flags = CLOCK_IN_OMAP3430ES2 | RATE_PROPAGATES,
867 .enable = &omap3_noncore_dpll_enable, 890 .enable = &omap3_noncore_dpll_enable,
868 .disable = &omap3_noncore_dpll_disable, 891 .disable = &omap3_noncore_dpll_disable,
892 .round_rate = &omap2_dpll_round_rate,
869 .recalc = &omap3_dpll_recalc, 893 .recalc = &omap3_dpll_recalc,
870}; 894};
871 895