aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-omap2/clkt_clksel.c
diff options
context:
space:
mode:
authorPaul Walmsley <paul@pwsan.com>2012-09-23 19:27:43 -0400
committerPaul Walmsley <paul@pwsan.com>2012-09-23 19:27:43 -0400
commit4fb85d35bcec842e0f20437aea277157973aa45f (patch)
treed3b865af2f4066f68828806b231e4bb5b4de9ec8 /arch/arm/mach-omap2/clkt_clksel.c
parent1e2ee2a60df5c3ab74dd1c9155fb01b5bc6f807d (diff)
parenta86c0b9867940bd0ba78f109686079b4051a463d (diff)
Merge branch 'clock_devel_3.7' into hwmod_prcm_clock_a_3.7
Conflicts: arch/arm/mach-omap2/clkt34xx_dpll3m2.c arch/arm/mach-omap2/clkt_clksel.c arch/arm/mach-omap2/clock.c
Diffstat (limited to 'arch/arm/mach-omap2/clkt_clksel.c')
-rw-r--r--arch/arm/mach-omap2/clkt_clksel.c86
1 files changed, 55 insertions, 31 deletions
diff --git a/arch/arm/mach-omap2/clkt_clksel.c b/arch/arm/mach-omap2/clkt_clksel.c
index 19a980956d44..eaed3900a83c 100644
--- a/arch/arm/mach-omap2/clkt_clksel.c
+++ b/arch/arm/mach-omap2/clkt_clksel.c
@@ -72,7 +72,7 @@ static const struct clksel *_get_clksel_by_parent(struct clk *clk,
72 if (!clks->parent) { 72 if (!clks->parent) {
73 /* This indicates a data problem */ 73 /* This indicates a data problem */
74 WARN(1, "clock: %s: could not find parent clock %s in clksel array\n", 74 WARN(1, "clock: %s: could not find parent clock %s in clksel array\n",
75 clk->name, src_clk->name); 75 __clk_get_name(clk), __clk_get_name(src_clk));
76 return NULL; 76 return NULL;
77 } 77 }
78 78
@@ -127,7 +127,8 @@ static u8 _get_div_and_fieldval(struct clk *src_clk, struct clk *clk,
127 if (max_div == 0) { 127 if (max_div == 0) {
128 /* This indicates an error in the clksel data */ 128 /* This indicates an error in the clksel data */
129 WARN(1, "clock: %s: could not find divisor for parent %s\n", 129 WARN(1, "clock: %s: could not find divisor for parent %s\n",
130 clk->name, src_clk->parent->name); 130 __clk_get_name(clk),
131 __clk_get_name(__clk_get_parent(src_clk)));
131 return 0; 132 return 0;
132 } 133 }
133 134
@@ -176,8 +177,10 @@ static u32 _clksel_to_divisor(struct clk *clk, u32 field_val)
176{ 177{
177 const struct clksel *clks; 178 const struct clksel *clks;
178 const struct clksel_rate *clkr; 179 const struct clksel_rate *clkr;
180 struct clk *parent;
179 181
180 clks = _get_clksel_by_parent(clk, clk->parent); 182 parent = __clk_get_parent(clk);
183 clks = _get_clksel_by_parent(clk, parent);
181 if (!clks) 184 if (!clks)
182 return 0; 185 return 0;
183 186
@@ -191,8 +194,8 @@ static u32 _clksel_to_divisor(struct clk *clk, u32 field_val)
191 194
192 if (!clkr->div) { 195 if (!clkr->div) {
193 /* This indicates a data error */ 196 /* This indicates a data error */
194 WARN(1, "clock: %s: could not find fieldval %d parent %s\n", 197 WARN(1, "clock: %s: could not find fieldval %d for parent %s\n",
195 clk->name, field_val, clk->parent->name); 198 __clk_get_name(clk), field_val, __clk_get_name(parent));
196 return 0; 199 return 0;
197 } 200 }
198 201
@@ -213,11 +216,13 @@ static u32 _divisor_to_clksel(struct clk *clk, u32 div)
213{ 216{
214 const struct clksel *clks; 217 const struct clksel *clks;
215 const struct clksel_rate *clkr; 218 const struct clksel_rate *clkr;
219 struct clk *parent;
216 220
217 /* should never happen */ 221 /* should never happen */
218 WARN_ON(div == 0); 222 WARN_ON(div == 0);
219 223
220 clks = _get_clksel_by_parent(clk, clk->parent); 224 parent = __clk_get_parent(clk);
225 clks = _get_clksel_by_parent(clk, parent);
221 if (!clks) 226 if (!clks)
222 return ~0; 227 return ~0;
223 228
@@ -230,8 +235,8 @@ static u32 _divisor_to_clksel(struct clk *clk, u32 div)
230 } 235 }
231 236
232 if (!clkr->div) { 237 if (!clkr->div) {
233 pr_err("clock: %s: could not find divisor %d parent %s\n", 238 pr_err("clock: %s: could not find divisor %d for parent %s\n",
234 clk->name, div, clk->parent->name); 239 __clk_get_name(clk), div, __clk_get_name(parent));
235 return ~0; 240 return ~0;
236 } 241 }
237 242
@@ -281,16 +286,23 @@ u32 omap2_clksel_round_rate_div(struct clk *clk, unsigned long target_rate,
281 const struct clksel *clks; 286 const struct clksel *clks;
282 const struct clksel_rate *clkr; 287 const struct clksel_rate *clkr;
283 u32 last_div = 0; 288 u32 last_div = 0;
289 struct clk *parent;
290 unsigned long parent_rate;
291 const char *clk_name;
292
293 parent = __clk_get_parent(clk);
294 parent_rate = __clk_get_rate(parent);
295 clk_name = __clk_get_name(clk);
284 296
285 if (!clk->clksel || !clk->clksel_mask) 297 if (!clk->clksel || !clk->clksel_mask)
286 return ~0; 298 return ~0;
287 299
288 pr_debug("clock: clksel_round_rate_div: %s target_rate %ld\n", 300 pr_debug("clock: clksel_round_rate_div: %s target_rate %ld\n",
289 clk->name, target_rate); 301 clk_name, target_rate);
290 302
291 *new_div = 1; 303 *new_div = 1;
292 304
293 clks = _get_clksel_by_parent(clk, clk->parent); 305 clks = _get_clksel_by_parent(clk, parent);
294 if (!clks) 306 if (!clks)
295 return ~0; 307 return ~0;
296 308
@@ -300,29 +312,29 @@ u32 omap2_clksel_round_rate_div(struct clk *clk, unsigned long target_rate,
300 312
301 /* Sanity check */ 313 /* Sanity check */
302 if (clkr->div <= last_div) 314 if (clkr->div <= last_div)
303 pr_err("clock: %s: clksel_rate table not sorted", 315 pr_err("clock: %s: clksel_rate table not sorted\n",
304 clk->name); 316 clk_name);
305 317
306 last_div = clkr->div; 318 last_div = clkr->div;
307 319
308 test_rate = clk->parent->rate / clkr->div; 320 test_rate = parent_rate / clkr->div;
309 321
310 if (test_rate <= target_rate) 322 if (test_rate <= target_rate)
311 break; /* found it */ 323 break; /* found it */
312 } 324 }
313 325
314 if (!clkr->div) { 326 if (!clkr->div) {
315 pr_err("clock: %s: could not find divisor for target rate %ld parent %s\n", 327 pr_err("clock: %s: could not find divisor for target rate %ld for parent %s\n",
316 clk->name, target_rate, clk->parent->name); 328 clk_name, target_rate, __clk_get_name(parent));
317 return ~0; 329 return ~0;
318 } 330 }
319 331
320 *new_div = clkr->div; 332 *new_div = clkr->div;
321 333
322 pr_debug("clock: new_div = %d, new_rate = %ld\n", *new_div, 334 pr_debug("clock: new_div = %d, new_rate = %ld\n", *new_div,
323 (clk->parent->rate / clkr->div)); 335 (parent_rate / clkr->div));
324 336
325 return clk->parent->rate / clkr->div; 337 return parent_rate / clkr->div;
326} 338}
327 339
328/* 340/*
@@ -344,10 +356,15 @@ void omap2_init_clksel_parent(struct clk *clk)
344 const struct clksel *clks; 356 const struct clksel *clks;
345 const struct clksel_rate *clkr; 357 const struct clksel_rate *clkr;
346 u32 r, found = 0; 358 u32 r, found = 0;
359 struct clk *parent;
360 const char *clk_name;
347 361
348 if (!clk->clksel || !clk->clksel_mask) 362 if (!clk->clksel || !clk->clksel_mask)
349 return; 363 return;
350 364
365 parent = __clk_get_parent(clk);
366 clk_name = __clk_get_name(clk);
367
351 r = __raw_readl(clk->clksel_reg) & clk->clksel_mask; 368 r = __raw_readl(clk->clksel_reg) & clk->clksel_mask;
352 r >>= __ffs(clk->clksel_mask); 369 r >>= __ffs(clk->clksel_mask);
353 370
@@ -357,11 +374,13 @@ void omap2_init_clksel_parent(struct clk *clk)
357 continue; 374 continue;
358 375
359 if (clkr->val == r) { 376 if (clkr->val == r) {
360 if (clk->parent != clks->parent) { 377 if (parent != clks->parent) {
361 pr_debug("clock: %s: inited parent to %s (was %s)\n", 378 pr_debug("clock: %s: inited parent to %s (was %s)\n",
362 clk->name, clks->parent->name, 379 clk_name,
363 ((clk->parent) ? 380 __clk_get_name(clks->parent),
364 clk->parent->name : "NULL")); 381 ((parent) ?
382 __clk_get_name(parent) :
383 "NULL"));
365 clk_reparent(clk, clks->parent); 384 clk_reparent(clk, clks->parent);
366 }; 385 };
367 found = 1; 386 found = 1;
@@ -371,7 +390,7 @@ void omap2_init_clksel_parent(struct clk *clk)
371 390
372 /* This indicates a data error */ 391 /* This indicates a data error */
373 WARN(!found, "clock: %s: init parent: could not find regval %0x\n", 392 WARN(!found, "clock: %s: init parent: could not find regval %0x\n",
374 clk->name, r); 393 clk_name, r);
375 394
376 return; 395 return;
377} 396}
@@ -389,15 +408,17 @@ unsigned long omap2_clksel_recalc(struct clk *clk)
389{ 408{
390 unsigned long rate; 409 unsigned long rate;
391 u32 div = 0; 410 u32 div = 0;
411 struct clk *parent;
392 412
393 div = _read_divisor(clk); 413 div = _read_divisor(clk);
394 if (div == 0) 414 if (div == 0)
395 return clk->rate; 415 return __clk_get_rate(clk);
396 416
397 rate = clk->parent->rate / div; 417 parent = __clk_get_parent(clk);
418 rate = __clk_get_rate(parent) / div;
398 419
399 pr_debug("clock: %s: recalc'd rate is %ld (div %d)\n", clk->name, 420 pr_debug("clock: %s: recalc'd rate is %ld (div %d)\n",
400 rate, div); 421 __clk_get_name(clk), rate, div);
401 422
402 return rate; 423 return rate;
403} 424}
@@ -452,9 +473,10 @@ int omap2_clksel_set_rate(struct clk *clk, unsigned long rate)
452 473
453 _write_clksel_reg(clk, field_val); 474 _write_clksel_reg(clk, field_val);
454 475
455 clk->rate = clk->parent->rate / new_div; 476 clk->rate = __clk_get_rate(__clk_get_parent(clk)) / new_div;
456 477
457 pr_debug("clock: %s: set rate to %ld\n", clk->name, clk->rate); 478 pr_debug("clock: %s: set rate to %ld\n", __clk_get_name(clk),
479 __clk_get_rate(clk));
458 480
459 return 0; 481 return 0;
460} 482}
@@ -496,13 +518,15 @@ int omap2_clksel_set_parent(struct clk *clk, struct clk *new_parent)
496 clk_reparent(clk, new_parent); 518 clk_reparent(clk, new_parent);
497 519
498 /* CLKSEL clocks follow their parents' rates, divided by a divisor */ 520 /* CLKSEL clocks follow their parents' rates, divided by a divisor */
499 clk->rate = new_parent->rate; 521 clk->rate = __clk_get_rate(new_parent);
500 522
501 if (parent_div > 0) 523 if (parent_div > 0)
502 clk->rate /= parent_div; 524 __clk_get_rate(clk) /= parent_div;
503 525
504 pr_debug("clock: %s: set parent to %s (new rate %ld)\n", 526 pr_debug("clock: %s: set parent to %s (new rate %ld)\n",
505 clk->name, clk->parent->name, clk->rate); 527 __clk_get_name(clk),
528 __clk_get_name(__clk_get_parent(clk)),
529 __clk_get_rate(clk));
506 530
507 return 0; 531 return 0;
508} 532}