aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-omap2/clock.c
diff options
context:
space:
mode:
authorRussell King <rmk@dyn-67.arm.linux.org.uk>2009-03-19 08:39:58 -0400
committerRussell King <rmk+kernel@arm.linux.org.uk>2009-03-19 08:39:58 -0400
commit14b6848bc0134b8838d374c423df3edda9b1490e (patch)
tree724dc912efe84f432d33a798502811c5f5295774 /arch/arm/mach-omap2/clock.c
parent05d9881bc4c6f172997b7a59e4a1a95910c4ebd7 (diff)
parent4da3782151300237db3abe070f716922889252e0 (diff)
Merge branch 'omap-clks3' into devel
Conflicts: arch/arm/mach-omap2/clock.c
Diffstat (limited to 'arch/arm/mach-omap2/clock.c')
-rw-r--r--arch/arm/mach-omap2/clock.c499
1 files changed, 283 insertions, 216 deletions
diff --git a/arch/arm/mach-omap2/clock.c b/arch/arm/mach-omap2/clock.c
index ce4d46a4a838..4247a1534411 100644
--- a/arch/arm/mach-omap2/clock.c
+++ b/arch/arm/mach-omap2/clock.c
@@ -26,11 +26,10 @@
26 26
27#include <mach/clock.h> 27#include <mach/clock.h>
28#include <mach/clockdomain.h> 28#include <mach/clockdomain.h>
29#include <mach/sram.h>
30#include <mach/cpu.h> 29#include <mach/cpu.h>
31#include <asm/div64.h> 30#include <asm/div64.h>
32 31
33#include "memory.h" 32#include <mach/sdrc.h>
34#include "sdrc.h" 33#include "sdrc.h"
35#include "clock.h" 34#include "clock.h"
36#include "prm.h" 35#include "prm.h"
@@ -46,7 +45,7 @@
46#define DPLL_MIN_DIVIDER 1 45#define DPLL_MIN_DIVIDER 1
47 46
48/* Possible error results from _dpll_test_mult */ 47/* Possible error results from _dpll_test_mult */
49#define DPLL_MULT_UNDERFLOW (1 << 0) 48#define DPLL_MULT_UNDERFLOW -1
50 49
51/* 50/*
52 * Scale factor to mitigate roundoff errors in DPLL rate rounding. 51 * Scale factor to mitigate roundoff errors in DPLL rate rounding.
@@ -59,6 +58,16 @@
59#define DPLL_ROUNDING_VAL ((DPLL_SCALE_BASE / 2) * \ 58#define DPLL_ROUNDING_VAL ((DPLL_SCALE_BASE / 2) * \
60 (DPLL_SCALE_FACTOR / DPLL_SCALE_BASE)) 59 (DPLL_SCALE_FACTOR / DPLL_SCALE_BASE))
61 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
62u8 cpu_mask; 71u8 cpu_mask;
63 72
64/*------------------------------------------------------------------------- 73/*-------------------------------------------------------------------------
@@ -66,6 +75,74 @@ u8 cpu_mask;
66 *-------------------------------------------------------------------------*/ 75 *-------------------------------------------------------------------------*/
67 76
68/** 77/**
78 * _omap2xxx_clk_commit - commit clock parent/rate changes in hardware
79 * @clk: struct clk *
80 *
81 * If @clk has the DELAYED_APP flag set, meaning that parent/rate changes
82 * don't take effect until the VALID_CONFIG bit is written, write the
83 * VALID_CONFIG bit and wait for the write to complete. No return value.
84 */
85static void _omap2xxx_clk_commit(struct clk *clk)
86{
87 if (!cpu_is_omap24xx())
88 return;
89
90 if (!(clk->flags & DELAYED_APP))
91 return;
92
93 prm_write_mod_reg(OMAP24XX_VALID_CONFIG, OMAP24XX_GR_MOD,
94 OMAP24XX_PRCM_CLKCFG_CTRL_OFFSET);
95 /* OCP barrier */
96 prm_read_mod_reg(OMAP24XX_GR_MOD, OMAP24XX_PRCM_CLKCFG_CTRL_OFFSET);
97}
98
99/*
100 * _dpll_test_fint - test whether an Fint value is valid for the DPLL
101 * @clk: DPLL struct clk to test
102 * @n: divider value (N) to test
103 *
104 * Tests whether a particular divider @n will result in a valid DPLL
105 * internal clock frequency Fint. See the 34xx TRM 4.7.6.2 "DPLL Jitter
106 * Correction". Returns 0 if OK, -1 if the enclosing loop can terminate
107 * (assuming that it is counting N upwards), or -2 if the enclosing loop
108 * should skip to the next iteration (again assuming N is increasing).
109 */
110static int _dpll_test_fint(struct clk *clk, u8 n)
111{
112 struct dpll_data *dd;
113 long fint;
114 int ret = 0;
115
116 dd = clk->dpll_data;
117
118 /* DPLL divider must result in a valid jitter correction val */
119 fint = clk->parent->rate / (n + 1);
120 if (fint < DPLL_FINT_BAND1_MIN) {
121
122 pr_debug("rejecting n=%d due to Fint failure, "
123 "lowering max_divider\n", n);
124 dd->max_divider = n;
125 ret = DPLL_FINT_UNDERFLOW;
126
127 } else if (fint > DPLL_FINT_BAND1_MAX &&
128 fint < DPLL_FINT_BAND2_MIN) {
129
130 pr_debug("rejecting n=%d due to Fint failure\n", n);
131 ret = DPLL_FINT_INVALID;
132
133 } else if (fint > DPLL_FINT_BAND2_MAX) {
134
135 pr_debug("rejecting n=%d due to Fint failure, "
136 "boosting min_divider\n", n);
137 dd->min_divider = n;
138 ret = DPLL_FINT_INVALID;
139
140 }
141
142 return ret;
143}
144
145/**
69 * omap2_init_clk_clkdm - look up a clockdomain name, store pointer in clk 146 * omap2_init_clk_clkdm - look up a clockdomain name, store pointer in clk
70 * @clk: OMAP clock struct ptr to use 147 * @clk: OMAP clock struct ptr to use
71 * 148 *
@@ -120,7 +197,7 @@ void omap2_init_clksel_parent(struct clk *clk)
120 clk->name, clks->parent->name, 197 clk->name, clks->parent->name,
121 ((clk->parent) ? 198 ((clk->parent) ?
122 clk->parent->name : "NULL")); 199 clk->parent->name : "NULL"));
123 clk->parent = clks->parent; 200 clk_reparent(clk, clks->parent);
124 }; 201 };
125 found = 1; 202 found = 1;
126 } 203 }
@@ -134,25 +211,52 @@ void omap2_init_clksel_parent(struct clk *clk)
134 return; 211 return;
135} 212}
136 213
137/* Returns the DPLL rate */ 214/**
215 * omap2_get_dpll_rate - returns the current DPLL CLKOUT rate
216 * @clk: struct clk * of a DPLL
217 *
218 * DPLLs can be locked or bypassed - basically, enabled or disabled.
219 * When locked, the DPLL output depends on the M and N values. When
220 * bypassed, on OMAP2xxx, the output rate is either the 32KiHz clock
221 * or sys_clk. Bypass rates on OMAP3 depend on the DPLL: DPLLs 1 and
222 * 2 are bypassed with dpll1_fclk and dpll2_fclk respectively
223 * (generated by DPLL3), while DPLL 3, 4, and 5 bypass rates are sys_clk.
224 * Returns the current DPLL CLKOUT rate (*not* CLKOUTX2) if the DPLL is
225 * locked, or the appropriate bypass rate if the DPLL is bypassed, or 0
226 * if the clock @clk is not a DPLL.
227 */
138u32 omap2_get_dpll_rate(struct clk *clk) 228u32 omap2_get_dpll_rate(struct clk *clk)
139{ 229{
140 long long dpll_clk; 230 long long dpll_clk;
141 u32 dpll_mult, dpll_div, dpll; 231 u32 dpll_mult, dpll_div, v;
142 struct dpll_data *dd; 232 struct dpll_data *dd;
143 233
144 dd = clk->dpll_data; 234 dd = clk->dpll_data;
145 /* REVISIT: What do we return on error? */
146 if (!dd) 235 if (!dd)
147 return 0; 236 return 0;
148 237
149 dpll = __raw_readl(dd->mult_div1_reg); 238 /* Return bypass rate if DPLL is bypassed */
150 dpll_mult = dpll & dd->mult_mask; 239 v = __raw_readl(dd->control_reg);
240 v &= dd->enable_mask;
241 v >>= __ffs(dd->enable_mask);
242
243 if (cpu_is_omap24xx()) {
244 if (v == OMAP2XXX_EN_DPLL_LPBYPASS ||
245 v == OMAP2XXX_EN_DPLL_FRBYPASS)
246 return dd->clk_bypass->rate;
247 } else if (cpu_is_omap34xx()) {
248 if (v == OMAP3XXX_EN_DPLL_LPBYPASS ||
249 v == OMAP3XXX_EN_DPLL_FRBYPASS)
250 return dd->clk_bypass->rate;
251 }
252
253 v = __raw_readl(dd->mult_div1_reg);
254 dpll_mult = v & dd->mult_mask;
151 dpll_mult >>= __ffs(dd->mult_mask); 255 dpll_mult >>= __ffs(dd->mult_mask);
152 dpll_div = dpll & dd->div1_mask; 256 dpll_div = v & dd->div1_mask;
153 dpll_div >>= __ffs(dd->div1_mask); 257 dpll_div >>= __ffs(dd->div1_mask);
154 258
155 dpll_clk = (long long)clk->parent->rate * dpll_mult; 259 dpll_clk = (long long)dd->clk_ref->rate * dpll_mult;
156 do_div(dpll_clk, dpll_div + 1); 260 do_div(dpll_clk, dpll_div + 1);
157 261
158 return dpll_clk; 262 return dpll_clk;
@@ -162,14 +266,11 @@ u32 omap2_get_dpll_rate(struct clk *clk)
162 * Used for clocks that have the same value as the parent clock, 266 * Used for clocks that have the same value as the parent clock,
163 * divided by some factor 267 * divided by some factor
164 */ 268 */
165void omap2_fixed_divisor_recalc(struct clk *clk) 269unsigned long omap2_fixed_divisor_recalc(struct clk *clk)
166{ 270{
167 WARN_ON(!clk->fixed_div); 271 WARN_ON(!clk->fixed_div);
168 272
169 clk->rate = clk->parent->rate / clk->fixed_div; 273 return clk->parent->rate / clk->fixed_div;
170
171 if (clk->flags & RATE_PROPAGATES)
172 propagate_rate(clk);
173} 274}
174 275
175/** 276/**
@@ -190,11 +291,10 @@ int omap2_wait_clock_ready(void __iomem *reg, u32 mask, const char *name)
190 * 24xx uses 0 to indicate not ready, and 1 to indicate ready. 291 * 24xx uses 0 to indicate not ready, and 1 to indicate ready.
191 * 34xx reverses this, just to keep us on our toes 292 * 34xx reverses this, just to keep us on our toes
192 */ 293 */
193 if (cpu_mask & (RATE_IN_242X | RATE_IN_243X)) { 294 if (cpu_mask & (RATE_IN_242X | RATE_IN_243X))
194 ena = mask; 295 ena = mask;
195 } else if (cpu_mask & RATE_IN_343X) { 296 else if (cpu_mask & RATE_IN_343X)
196 ena = 0; 297 ena = 0;
197 }
198 298
199 /* Wait for lock */ 299 /* Wait for lock */
200 while (((__raw_readl(reg) & mask) != ena) && 300 while (((__raw_readl(reg) & mask) != ena) &&
@@ -228,31 +328,12 @@ static void omap2_clk_wait_ready(struct clk *clk)
228 * it and pull it into struct clk itself somehow. 328 * it and pull it into struct clk itself somehow.
229 */ 329 */
230 reg = clk->enable_reg; 330 reg = clk->enable_reg;
231 if ((((u32)reg & 0xff) >= CM_FCLKEN1) &&
232 (((u32)reg & 0xff) <= OMAP24XX_CM_FCLKEN2))
233 other_reg = (void __iomem *)(((u32)reg & ~0xf0) | 0x10); /* CM_ICLKEN* */
234 else if ((((u32)reg & 0xff) >= CM_ICLKEN1) &&
235 (((u32)reg & 0xff) <= OMAP24XX_CM_ICLKEN4))
236 other_reg = (void __iomem *)(((u32)reg & ~0xf0) | 0x00); /* CM_FCLKEN* */
237 else
238 return;
239 331
240 /* REVISIT: What are the appropriate exclusions for 34XX? */ 332 /*
241 /* No check for DSS or cam clocks */ 333 * Convert CM_ICLKEN* <-> CM_FCLKEN*. This conversion assumes
242 if (cpu_is_omap24xx() && ((u32)reg & 0x0f) == 0) { /* CM_{F,I}CLKEN1 */ 334 * it's just a matter of XORing the bits.
243 if (clk->enable_bit == OMAP24XX_EN_DSS2_SHIFT || 335 */
244 clk->enable_bit == OMAP24XX_EN_DSS1_SHIFT || 336 other_reg = (void __iomem *)((u32)reg ^ (CM_FCLKEN ^ CM_ICLKEN));
245 clk->enable_bit == OMAP24XX_EN_CAM_SHIFT)
246 return;
247 }
248
249 /* REVISIT: What are the appropriate exclusions for 34XX? */
250 /* OMAP3: ignore DSS-mod clocks */
251 if (cpu_is_omap34xx() &&
252 (((u32)reg & ~0xff) == (u32)OMAP_CM_REGADDR(OMAP3430_DSS_MOD, 0) ||
253 ((((u32)reg & ~0xff) == (u32)OMAP_CM_REGADDR(CORE_MOD, 0)) &&
254 clk->enable_bit == OMAP3430_EN_SSI_SHIFT)))
255 return;
256 337
257 /* Check if both functional and interface clocks 338 /* Check if both functional and interface clocks
258 * are running. */ 339 * are running. */
@@ -264,18 +345,9 @@ static void omap2_clk_wait_ready(struct clk *clk)
264 omap2_wait_clock_ready(st_reg, bit, clk->name); 345 omap2_wait_clock_ready(st_reg, bit, clk->name);
265} 346}
266 347
267/* Enables clock without considering parent dependencies or use count 348static int omap2_dflt_clk_enable(struct clk *clk)
268 * REVISIT: Maybe change this to use clk->enable like on omap1?
269 */
270int _omap2_clk_enable(struct clk *clk)
271{ 349{
272 u32 regval32; 350 u32 v;
273
274 if (clk->flags & (ALWAYS_ENABLED | PARENT_CONTROLS_CLOCK))
275 return 0;
276
277 if (clk->enable)
278 return clk->enable(clk);
279 351
280 if (unlikely(clk->enable_reg == NULL)) { 352 if (unlikely(clk->enable_reg == NULL)) {
281 printk(KERN_ERR "clock.c: Enable for %s without enable code\n", 353 printk(KERN_ERR "clock.c: Enable for %s without enable code\n",
@@ -283,33 +355,38 @@ int _omap2_clk_enable(struct clk *clk)
283 return 0; /* REVISIT: -EINVAL */ 355 return 0; /* REVISIT: -EINVAL */
284 } 356 }
285 357
286 regval32 = __raw_readl(clk->enable_reg); 358 v = __raw_readl(clk->enable_reg);
287 if (clk->flags & INVERT_ENABLE) 359 if (clk->flags & INVERT_ENABLE)
288 regval32 &= ~(1 << clk->enable_bit); 360 v &= ~(1 << clk->enable_bit);
289 else 361 else
290 regval32 |= (1 << clk->enable_bit); 362 v |= (1 << clk->enable_bit);
291 __raw_writel(regval32, clk->enable_reg); 363 __raw_writel(v, clk->enable_reg);
292 wmb(); 364 v = __raw_readl(clk->enable_reg); /* OCP barrier */
293
294 omap2_clk_wait_ready(clk);
295 365
296 return 0; 366 return 0;
297} 367}
298 368
299/* Disables clock without considering parent dependencies or use count */ 369static int omap2_dflt_clk_enable_wait(struct clk *clk)
300void _omap2_clk_disable(struct clk *clk)
301{ 370{
302 u32 regval32; 371 int ret;
303
304 if (clk->flags & (ALWAYS_ENABLED | PARENT_CONTROLS_CLOCK))
305 return;
306 372
307 if (clk->disable) { 373 if (!clk->enable_reg) {
308 clk->disable(clk); 374 printk(KERN_ERR "clock.c: Enable for %s without enable code\n",
309 return; 375 clk->name);
376 return 0; /* REVISIT: -EINVAL */
310 } 377 }
311 378
312 if (clk->enable_reg == NULL) { 379 ret = omap2_dflt_clk_enable(clk);
380 if (ret == 0)
381 omap2_clk_wait_ready(clk);
382 return ret;
383}
384
385static void omap2_dflt_clk_disable(struct clk *clk)
386{
387 u32 v;
388
389 if (!clk->enable_reg) {
313 /* 390 /*
314 * 'Independent' here refers to a clock which is not 391 * 'Independent' here refers to a clock which is not
315 * controlled by its parent. 392 * controlled by its parent.
@@ -319,20 +396,44 @@ void _omap2_clk_disable(struct clk *clk)
319 return; 396 return;
320 } 397 }
321 398
322 regval32 = __raw_readl(clk->enable_reg); 399 v = __raw_readl(clk->enable_reg);
323 if (clk->flags & INVERT_ENABLE) 400 if (clk->flags & INVERT_ENABLE)
324 regval32 |= (1 << clk->enable_bit); 401 v |= (1 << clk->enable_bit);
325 else 402 else
326 regval32 &= ~(1 << clk->enable_bit); 403 v &= ~(1 << clk->enable_bit);
327 __raw_writel(regval32, clk->enable_reg); 404 __raw_writel(v, clk->enable_reg);
328 wmb(); 405 /* No OCP barrier needed here since it is a disable operation */
406}
407
408const struct clkops clkops_omap2_dflt_wait = {
409 .enable = omap2_dflt_clk_enable_wait,
410 .disable = omap2_dflt_clk_disable,
411};
412
413const struct clkops clkops_omap2_dflt = {
414 .enable = omap2_dflt_clk_enable,
415 .disable = omap2_dflt_clk_disable,
416};
417
418/* Enables clock without considering parent dependencies or use count
419 * REVISIT: Maybe change this to use clk->enable like on omap1?
420 */
421static int _omap2_clk_enable(struct clk *clk)
422{
423 return clk->ops->enable(clk);
424}
425
426/* Disables clock without considering parent dependencies or use count */
427static void _omap2_clk_disable(struct clk *clk)
428{
429 clk->ops->disable(clk);
329} 430}
330 431
331void omap2_clk_disable(struct clk *clk) 432void omap2_clk_disable(struct clk *clk)
332{ 433{
333 if (clk->usecount > 0 && !(--clk->usecount)) { 434 if (clk->usecount > 0 && !(--clk->usecount)) {
334 _omap2_clk_disable(clk); 435 _omap2_clk_disable(clk);
335 if (likely((u32)clk->parent)) 436 if (clk->parent)
336 omap2_clk_disable(clk->parent); 437 omap2_clk_disable(clk->parent);
337 if (clk->clkdm) 438 if (clk->clkdm)
338 omap2_clkdm_clk_disable(clk->clkdm, clk); 439 omap2_clkdm_clk_disable(clk->clkdm, clk);
@@ -345,30 +446,29 @@ int omap2_clk_enable(struct clk *clk)
345 int ret = 0; 446 int ret = 0;
346 447
347 if (clk->usecount++ == 0) { 448 if (clk->usecount++ == 0) {
348 if (likely((u32)clk->parent))
349 ret = omap2_clk_enable(clk->parent);
350
351 if (unlikely(ret != 0)) {
352 clk->usecount--;
353 return ret;
354 }
355
356 if (clk->clkdm) 449 if (clk->clkdm)
357 omap2_clkdm_clk_enable(clk->clkdm, clk); 450 omap2_clkdm_clk_enable(clk->clkdm, clk);
358 451
359 ret = _omap2_clk_enable(clk); 452 if (clk->parent) {
360 453 ret = omap2_clk_enable(clk->parent);
361 if (unlikely(ret != 0)) { 454 if (ret)
362 if (clk->clkdm) 455 goto err;
363 omap2_clkdm_clk_disable(clk->clkdm, clk); 456 }
364 457
365 if (clk->parent) { 458 ret = _omap2_clk_enable(clk);
459 if (ret) {
460 if (clk->parent)
366 omap2_clk_disable(clk->parent); 461 omap2_clk_disable(clk->parent);
367 clk->usecount--; 462
368 } 463 goto err;
369 } 464 }
370 } 465 }
466 return ret;
371 467
468err:
469 if (clk->clkdm)
470 omap2_clkdm_clk_disable(clk->clkdm, clk);
471 clk->usecount--;
372 return ret; 472 return ret;
373} 473}
374 474
@@ -376,24 +476,22 @@ int omap2_clk_enable(struct clk *clk)
376 * Used for clocks that are part of CLKSEL_xyz governed clocks. 476 * Used for clocks that are part of CLKSEL_xyz governed clocks.
377 * REVISIT: Maybe change to use clk->enable() functions like on omap1? 477 * REVISIT: Maybe change to use clk->enable() functions like on omap1?
378 */ 478 */
379void omap2_clksel_recalc(struct clk *clk) 479unsigned long omap2_clksel_recalc(struct clk *clk)
380{ 480{
481 unsigned long rate;
381 u32 div = 0; 482 u32 div = 0;
382 483
383 pr_debug("clock: recalc'ing clksel clk %s\n", clk->name); 484 pr_debug("clock: recalc'ing clksel clk %s\n", clk->name);
384 485
385 div = omap2_clksel_get_divisor(clk); 486 div = omap2_clksel_get_divisor(clk);
386 if (div == 0) 487 if (div == 0)
387 return; 488 return clk->rate;
388 489
389 if (unlikely(clk->rate == clk->parent->rate / div)) 490 rate = clk->parent->rate / div;
390 return;
391 clk->rate = clk->parent->rate / div;
392 491
393 pr_debug("clock: new clock rate is %ld (div %d)\n", clk->rate, div); 492 pr_debug("clock: new clock rate is %ld (div %d)\n", rate, div);
394 493
395 if (unlikely(clk->flags & RATE_PROPAGATES)) 494 return rate;
396 propagate_rate(clk);
397} 495}
398 496
399/** 497/**
@@ -405,8 +503,8 @@ void omap2_clksel_recalc(struct clk *clk)
405 * the element associated with the supplied parent clock address. 503 * the element associated with the supplied parent clock address.
406 * Returns a pointer to the struct clksel on success or NULL on error. 504 * Returns a pointer to the struct clksel on success or NULL on error.
407 */ 505 */
408const struct clksel *omap2_get_clksel_by_parent(struct clk *clk, 506static const struct clksel *omap2_get_clksel_by_parent(struct clk *clk,
409 struct clk *src_clk) 507 struct clk *src_clk)
410{ 508{
411 const struct clksel *clks; 509 const struct clksel *clks;
412 510
@@ -455,7 +553,7 @@ u32 omap2_clksel_round_rate_div(struct clk *clk, unsigned long target_rate,
455 *new_div = 1; 553 *new_div = 1;
456 554
457 clks = omap2_get_clksel_by_parent(clk, clk->parent); 555 clks = omap2_get_clksel_by_parent(clk, clk->parent);
458 if (clks == NULL) 556 if (!clks)
459 return ~0; 557 return ~0;
460 558
461 for (clkr = clks->rates; clkr->div; clkr++) { 559 for (clkr = clks->rates; clkr->div; clkr++) {
@@ -514,7 +612,7 @@ long omap2_clksel_round_rate(struct clk *clk, unsigned long target_rate)
514/* Given a clock and a rate apply a clock specific rounding function */ 612/* Given a clock and a rate apply a clock specific rounding function */
515long omap2_clk_round_rate(struct clk *clk, unsigned long rate) 613long omap2_clk_round_rate(struct clk *clk, unsigned long rate)
516{ 614{
517 if (clk->round_rate != NULL) 615 if (clk->round_rate)
518 return clk->round_rate(clk, rate); 616 return clk->round_rate(clk, rate);
519 617
520 if (clk->flags & RATE_FIXED) 618 if (clk->flags & RATE_FIXED)
@@ -540,7 +638,7 @@ u32 omap2_clksel_to_divisor(struct clk *clk, u32 field_val)
540 const struct clksel_rate *clkr; 638 const struct clksel_rate *clkr;
541 639
542 clks = omap2_get_clksel_by_parent(clk, clk->parent); 640 clks = omap2_get_clksel_by_parent(clk, clk->parent);
543 if (clks == NULL) 641 if (!clks)
544 return 0; 642 return 0;
545 643
546 for (clkr = clks->rates; clkr->div; clkr++) { 644 for (clkr = clks->rates; clkr->div; clkr++) {
@@ -576,7 +674,7 @@ u32 omap2_divisor_to_clksel(struct clk *clk, u32 div)
576 WARN_ON(div == 0); 674 WARN_ON(div == 0);
577 675
578 clks = omap2_get_clksel_by_parent(clk, clk->parent); 676 clks = omap2_get_clksel_by_parent(clk, clk->parent);
579 if (clks == NULL) 677 if (!clks)
580 return ~0; 678 return ~0;
581 679
582 for (clkr = clks->rates; clkr->div; clkr++) { 680 for (clkr = clks->rates; clkr->div; clkr++) {
@@ -595,23 +693,6 @@ u32 omap2_divisor_to_clksel(struct clk *clk, u32 div)
595} 693}
596 694
597/** 695/**
598 * omap2_get_clksel - find clksel register addr & field mask for a clk
599 * @clk: struct clk to use
600 * @field_mask: ptr to u32 to store the register field mask
601 *
602 * Returns the address of the clksel register upon success or NULL on error.
603 */
604void __iomem *omap2_get_clksel(struct clk *clk, u32 *field_mask)
605{
606 if (unlikely((clk->clksel_reg == NULL) || (clk->clksel_mask == NULL)))
607 return NULL;
608
609 *field_mask = clk->clksel_mask;
610
611 return clk->clksel_reg;
612}
613
614/**
615 * omap2_clksel_get_divisor - get current divider applied to parent clock. 696 * omap2_clksel_get_divisor - get current divider applied to parent clock.
616 * @clk: OMAP struct clk to use. 697 * @clk: OMAP struct clk to use.
617 * 698 *
@@ -619,49 +700,41 @@ void __iomem *omap2_get_clksel(struct clk *clk, u32 *field_mask)
619 */ 700 */
620u32 omap2_clksel_get_divisor(struct clk *clk) 701u32 omap2_clksel_get_divisor(struct clk *clk)
621{ 702{
622 u32 field_mask, field_val; 703 u32 v;
623 void __iomem *div_addr;
624 704
625 div_addr = omap2_get_clksel(clk, &field_mask); 705 if (!clk->clksel_mask)
626 if (div_addr == NULL)
627 return 0; 706 return 0;
628 707
629 field_val = __raw_readl(div_addr) & field_mask; 708 v = __raw_readl(clk->clksel_reg) & clk->clksel_mask;
630 field_val >>= __ffs(field_mask); 709 v >>= __ffs(clk->clksel_mask);
631 710
632 return omap2_clksel_to_divisor(clk, field_val); 711 return omap2_clksel_to_divisor(clk, v);
633} 712}
634 713
635int omap2_clksel_set_rate(struct clk *clk, unsigned long rate) 714int omap2_clksel_set_rate(struct clk *clk, unsigned long rate)
636{ 715{
637 u32 field_mask, field_val, reg_val, validrate, new_div = 0; 716 u32 v, field_val, validrate, new_div = 0;
638 void __iomem *div_addr;
639 717
640 validrate = omap2_clksel_round_rate_div(clk, rate, &new_div); 718 if (!clk->clksel_mask)
641 if (validrate != rate)
642 return -EINVAL; 719 return -EINVAL;
643 720
644 div_addr = omap2_get_clksel(clk, &field_mask); 721 validrate = omap2_clksel_round_rate_div(clk, rate, &new_div);
645 if (div_addr == NULL) 722 if (validrate != rate)
646 return -EINVAL; 723 return -EINVAL;
647 724
648 field_val = omap2_divisor_to_clksel(clk, new_div); 725 field_val = omap2_divisor_to_clksel(clk, new_div);
649 if (field_val == ~0) 726 if (field_val == ~0)
650 return -EINVAL; 727 return -EINVAL;
651 728
652 reg_val = __raw_readl(div_addr); 729 v = __raw_readl(clk->clksel_reg);
653 reg_val &= ~field_mask; 730 v &= ~clk->clksel_mask;
654 reg_val |= (field_val << __ffs(field_mask)); 731 v |= field_val << __ffs(clk->clksel_mask);
655 __raw_writel(reg_val, div_addr); 732 __raw_writel(v, clk->clksel_reg);
656 wmb(); 733 v = __raw_readl(clk->clksel_reg); /* OCP barrier */
657 734
658 clk->rate = clk->parent->rate / new_div; 735 clk->rate = clk->parent->rate / new_div;
659 736
660 if (clk->flags & DELAYED_APP && cpu_is_omap24xx()) { 737 _omap2xxx_clk_commit(clk);
661 prm_write_mod_reg(OMAP24XX_VALID_CONFIG,
662 OMAP24XX_GR_MOD, OMAP24XX_PRCM_CLKCFG_CTRL_OFFSET);
663 wmb();
664 }
665 738
666 return 0; 739 return 0;
667} 740}
@@ -680,31 +753,24 @@ int omap2_clk_set_rate(struct clk *clk, unsigned long rate)
680 return -EINVAL; 753 return -EINVAL;
681 754
682 /* dpll_ck, core_ck, virt_prcm_set; plus all clksel clocks */ 755 /* dpll_ck, core_ck, virt_prcm_set; plus all clksel clocks */
683 if (clk->set_rate != NULL) 756 if (clk->set_rate)
684 ret = clk->set_rate(clk, rate); 757 ret = clk->set_rate(clk, rate);
685 758
686 if (unlikely(ret == 0 && (clk->flags & RATE_PROPAGATES)))
687 propagate_rate(clk);
688
689 return ret; 759 return ret;
690} 760}
691 761
692/* 762/*
693 * Converts encoded control register address into a full address 763 * Converts encoded control register address into a full address
694 * On error, *src_addr will be returned as 0. 764 * On error, the return value (parent_div) will be 0.
695 */ 765 */
696static u32 omap2_clksel_get_src_field(void __iomem **src_addr, 766static u32 _omap2_clksel_get_src_field(struct clk *src_clk, struct clk *clk,
697 struct clk *src_clk, u32 *field_mask, 767 u32 *field_val)
698 struct clk *clk, u32 *parent_div)
699{ 768{
700 const struct clksel *clks; 769 const struct clksel *clks;
701 const struct clksel_rate *clkr; 770 const struct clksel_rate *clkr;
702 771
703 *parent_div = 0;
704 *src_addr = NULL;
705
706 clks = omap2_get_clksel_by_parent(clk, src_clk); 772 clks = omap2_get_clksel_by_parent(clk, src_clk);
707 if (clks == NULL) 773 if (!clks)
708 return 0; 774 return 0;
709 775
710 for (clkr = clks->rates; clkr->div; clkr++) { 776 for (clkr = clks->rates; clkr->div; clkr++) {
@@ -722,47 +788,35 @@ static u32 omap2_clksel_get_src_field(void __iomem **src_addr,
722 /* Should never happen. Add a clksel mask to the struct clk. */ 788 /* Should never happen. Add a clksel mask to the struct clk. */
723 WARN_ON(clk->clksel_mask == 0); 789 WARN_ON(clk->clksel_mask == 0);
724 790
725 *field_mask = clk->clksel_mask; 791 *field_val = clkr->val;
726 *src_addr = clk->clksel_reg;
727 *parent_div = clkr->div;
728 792
729 return clkr->val; 793 return clkr->div;
730} 794}
731 795
732int omap2_clk_set_parent(struct clk *clk, struct clk *new_parent) 796int omap2_clk_set_parent(struct clk *clk, struct clk *new_parent)
733{ 797{
734 void __iomem *src_addr; 798 u32 field_val, v, parent_div;
735 u32 field_val, field_mask, reg_val, parent_div;
736 799
737 if (unlikely(clk->flags & CONFIG_PARTICIPANT)) 800 if (clk->flags & CONFIG_PARTICIPANT)
738 return -EINVAL; 801 return -EINVAL;
739 802
740 if (!clk->clksel) 803 if (!clk->clksel)
741 return -EINVAL; 804 return -EINVAL;
742 805
743 field_val = omap2_clksel_get_src_field(&src_addr, new_parent, 806 parent_div = _omap2_clksel_get_src_field(new_parent, clk, &field_val);
744 &field_mask, clk, &parent_div); 807 if (!parent_div)
745 if (src_addr == NULL)
746 return -EINVAL; 808 return -EINVAL;
747 809
748 if (clk->usecount > 0)
749 omap2_clk_disable(clk);
750
751 /* Set new source value (previous dividers if any in effect) */ 810 /* Set new source value (previous dividers if any in effect) */
752 reg_val = __raw_readl(src_addr) & ~field_mask; 811 v = __raw_readl(clk->clksel_reg);
753 reg_val |= (field_val << __ffs(field_mask)); 812 v &= ~clk->clksel_mask;
754 __raw_writel(reg_val, src_addr); 813 v |= field_val << __ffs(clk->clksel_mask);
755 wmb(); 814 __raw_writel(v, clk->clksel_reg);
756 815 v = __raw_readl(clk->clksel_reg); /* OCP barrier */
757 if (clk->flags & DELAYED_APP && cpu_is_omap24xx()) {
758 __raw_writel(OMAP24XX_VALID_CONFIG, OMAP24XX_PRCM_CLKCFG_CTRL);
759 wmb();
760 }
761 816
762 clk->parent = new_parent; 817 _omap2xxx_clk_commit(clk);
763 818
764 if (clk->usecount > 0) 819 clk_reparent(clk, new_parent);
765 omap2_clk_enable(clk);
766 820
767 /* CLKSEL clocks follow their parents' rates, divided by a divisor */ 821 /* CLKSEL clocks follow their parents' rates, divided by a divisor */
768 clk->rate = new_parent->rate; 822 clk->rate = new_parent->rate;
@@ -773,9 +827,6 @@ int omap2_clk_set_parent(struct clk *clk, struct clk *new_parent)
773 pr_debug("clock: set parent of %s to %s (new rate %ld)\n", 827 pr_debug("clock: set parent of %s to %s (new rate %ld)\n",
774 clk->name, clk->parent->name, clk->rate); 828 clk->name, clk->parent->name, clk->rate);
775 829
776 if (unlikely(clk->flags & RATE_PROPAGATES))
777 propagate_rate(clk);
778
779 return 0; 830 return 0;
780} 831}
781 832
@@ -805,7 +856,8 @@ int omap2_dpll_set_rate_tolerance(struct clk *clk, unsigned int tolerance)
805 return 0; 856 return 0;
806} 857}
807 858
808static unsigned long _dpll_compute_new_rate(unsigned long parent_rate, unsigned int m, unsigned int n) 859static unsigned long _dpll_compute_new_rate(unsigned long parent_rate,
860 unsigned int m, unsigned int n)
809{ 861{
810 unsigned long long num; 862 unsigned long long num;
811 863
@@ -838,7 +890,7 @@ static int _dpll_test_mult(int *m, int n, unsigned long *new_rate,
838 unsigned long target_rate, 890 unsigned long target_rate,
839 unsigned long parent_rate) 891 unsigned long parent_rate)
840{ 892{
841 int flags = 0, carry = 0; 893 int r = 0, carry = 0;
842 894
843 /* Unscale m and round if necessary */ 895 /* Unscale m and round if necessary */
844 if (*m % DPLL_SCALE_FACTOR >= DPLL_ROUNDING_VAL) 896 if (*m % DPLL_SCALE_FACTOR >= DPLL_ROUNDING_VAL)
@@ -859,13 +911,13 @@ static int _dpll_test_mult(int *m, int n, unsigned long *new_rate,
859 if (*m < DPLL_MIN_MULTIPLIER) { 911 if (*m < DPLL_MIN_MULTIPLIER) {
860 *m = DPLL_MIN_MULTIPLIER; 912 *m = DPLL_MIN_MULTIPLIER;
861 *new_rate = 0; 913 *new_rate = 0;
862 flags = DPLL_MULT_UNDERFLOW; 914 r = DPLL_MULT_UNDERFLOW;
863 } 915 }
864 916
865 if (*new_rate == 0) 917 if (*new_rate == 0)
866 *new_rate = _dpll_compute_new_rate(parent_rate, *m, n); 918 *new_rate = _dpll_compute_new_rate(parent_rate, *m, n);
867 919
868 return flags; 920 return r;
869} 921}
870 922
871/** 923/**
@@ -889,54 +941,65 @@ long omap2_dpll_round_rate(struct clk *clk, unsigned long target_rate)
889 int m, n, r, e, scaled_max_m; 941 int m, n, r, e, scaled_max_m;
890 unsigned long scaled_rt_rp, new_rate; 942 unsigned long scaled_rt_rp, new_rate;
891 int min_e = -1, min_e_m = -1, min_e_n = -1; 943 int min_e = -1, min_e_m = -1, min_e_n = -1;
944 struct dpll_data *dd;
892 945
893 if (!clk || !clk->dpll_data) 946 if (!clk || !clk->dpll_data)
894 return ~0; 947 return ~0;
895 948
949 dd = clk->dpll_data;
950
896 pr_debug("clock: starting DPLL round_rate for clock %s, target rate " 951 pr_debug("clock: starting DPLL round_rate for clock %s, target rate "
897 "%ld\n", clk->name, target_rate); 952 "%ld\n", clk->name, target_rate);
898 953
899 scaled_rt_rp = target_rate / (clk->parent->rate / DPLL_SCALE_FACTOR); 954 scaled_rt_rp = target_rate / (dd->clk_ref->rate / DPLL_SCALE_FACTOR);
900 scaled_max_m = clk->dpll_data->max_multiplier * DPLL_SCALE_FACTOR; 955 scaled_max_m = dd->max_multiplier * DPLL_SCALE_FACTOR;
901 956
902 clk->dpll_data->last_rounded_rate = 0; 957 dd->last_rounded_rate = 0;
903 958
904 for (n = clk->dpll_data->max_divider; n >= DPLL_MIN_DIVIDER; n--) { 959 for (n = dd->min_divider; n <= dd->max_divider; n++) {
960
961 /* Is the (input clk, divider) pair valid for the DPLL? */
962 r = _dpll_test_fint(clk, n);
963 if (r == DPLL_FINT_UNDERFLOW)
964 break;
965 else if (r == DPLL_FINT_INVALID)
966 continue;
905 967
906 /* Compute the scaled DPLL multiplier, based on the divider */ 968 /* Compute the scaled DPLL multiplier, based on the divider */
907 m = scaled_rt_rp * n; 969 m = scaled_rt_rp * n;
908 970
909 /* 971 /*
910 * Since we're counting n down, a m overflow means we can 972 * Since we're counting n up, a m overflow means we
911 * can immediately skip to the next n 973 * can bail out completely (since as n increases in
974 * the next iteration, there's no way that m can
975 * increase beyond the current m)
912 */ 976 */
913 if (m > scaled_max_m) 977 if (m > scaled_max_m)
914 continue; 978 break;
915 979
916 r = _dpll_test_mult(&m, n, &new_rate, target_rate, 980 r = _dpll_test_mult(&m, n, &new_rate, target_rate,
917 clk->parent->rate); 981 dd->clk_ref->rate);
982
983 /* m can't be set low enough for this n - try with a larger n */
984 if (r == DPLL_MULT_UNDERFLOW)
985 continue;
918 986
919 e = target_rate - new_rate; 987 e = target_rate - new_rate;
920 pr_debug("clock: n = %d: m = %d: rate error is %d " 988 pr_debug("clock: n = %d: m = %d: rate error is %d "
921 "(new_rate = %ld)\n", n, m, e, new_rate); 989 "(new_rate = %ld)\n", n, m, e, new_rate);
922 990
923 if (min_e == -1 || 991 if (min_e == -1 ||
924 min_e >= (int)(abs(e) - clk->dpll_data->rate_tolerance)) { 992 min_e >= (int)(abs(e) - dd->rate_tolerance)) {
925 min_e = e; 993 min_e = e;
926 min_e_m = m; 994 min_e_m = m;
927 min_e_n = n; 995 min_e_n = n;
928 996
929 pr_debug("clock: found new least error %d\n", min_e); 997 pr_debug("clock: found new least error %d\n", min_e);
930 }
931 998
932 /* 999 /* We found good settings -- bail out now */
933 * Since we're counting n down, a m underflow means we 1000 if (min_e <= dd->rate_tolerance)
934 * can bail out completely (since as n decreases in 1001 break;
935 * the next iteration, there's no way that m can 1002 }
936 * increase beyond the current m)
937 */
938 if (r & DPLL_MULT_UNDERFLOW)
939 break;
940 } 1003 }
941 1004
942 if (min_e < 0) { 1005 if (min_e < 0) {
@@ -944,17 +1007,17 @@ long omap2_dpll_round_rate(struct clk *clk, unsigned long target_rate)
944 return ~0; 1007 return ~0;
945 } 1008 }
946 1009
947 clk->dpll_data->last_rounded_m = min_e_m; 1010 dd->last_rounded_m = min_e_m;
948 clk->dpll_data->last_rounded_n = min_e_n; 1011 dd->last_rounded_n = min_e_n;
949 clk->dpll_data->last_rounded_rate = 1012 dd->last_rounded_rate = _dpll_compute_new_rate(dd->clk_ref->rate,
950 _dpll_compute_new_rate(clk->parent->rate, min_e_m, min_e_n); 1013 min_e_m, min_e_n);
951 1014
952 pr_debug("clock: final least error: e = %d, m = %d, n = %d\n", 1015 pr_debug("clock: final least error: e = %d, m = %d, n = %d\n",
953 min_e, min_e_m, min_e_n); 1016 min_e, min_e_m, min_e_n);
954 pr_debug("clock: final rate: %ld (target rate: %ld)\n", 1017 pr_debug("clock: final rate: %ld (target rate: %ld)\n",
955 clk->dpll_data->last_rounded_rate, target_rate); 1018 dd->last_rounded_rate, target_rate);
956 1019
957 return clk->dpll_data->last_rounded_rate; 1020 return dd->last_rounded_rate;
958} 1021}
959 1022
960/*------------------------------------------------------------------------- 1023/*-------------------------------------------------------------------------
@@ -973,6 +1036,10 @@ void omap2_clk_disable_unused(struct clk *clk)
973 return; 1036 return;
974 1037
975 printk(KERN_INFO "Disabling unused clock \"%s\"\n", clk->name); 1038 printk(KERN_INFO "Disabling unused clock \"%s\"\n", clk->name);
976 _omap2_clk_disable(clk); 1039 if (cpu_is_omap34xx()) {
1040 omap2_clk_enable(clk);
1041 omap2_clk_disable(clk);
1042 } else
1043 _omap2_clk_disable(clk);
977} 1044}
978#endif 1045#endif