aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-tegra/tegra20_clocks.c
diff options
context:
space:
mode:
authorPrashant Gaikwad <pgaikwad@nvidia.com>2012-08-06 02:27:43 -0400
committerStephen Warren <swarren@nvidia.com>2012-09-06 13:47:20 -0400
commit92fe58f07f6e51185497785aed632d0e676afe6e (patch)
tree3791468579de25fa4ada69abacdaf9666a8b7657 /arch/arm/mach-tegra/tegra20_clocks.c
parent96a1bd1e11ade7be969d275edd4c06749684cdba (diff)
ARM: tegra: Port tegra to generic clock framework
This patch converts tegra clock code to generic clock framework in following way: - Implement clk_ops as required by generic clk framework. (tegraXX_clocks.c) - Use platform specific struct clk_tegra in clk_ops implementation instead of struct clk. - Initialize all clock data statically. (tegraXX_clocks_data.c) Legacy framework did not have recalc_rate and is_enabled functions. Implemented these functions. Removed init function. It's functionality is splitted into recalc_rate and is_enabled. Static initialization is used since slab is not up in .init_early and clock is needed to be initialized before clockevent/clocksource initialization. Macros redefined for clk_tegra. Also, single struct clk_tegra is used for all type of clocks (PLL, peripheral etc.). This is to move quickly to generic common clock framework so that other dependent features will not be blocked (such as DT binding). Enabling COMMON_CLOCK config moved to ARCH_TEGRA since it is enabled for both Tegra20 and Tegra30. Signed-off-by: Prashant Gaikwad <pgaikwad@nvidia.com> Signed-off-by: Stephen Warren <swarren@nvidia.com>
Diffstat (limited to 'arch/arm/mach-tegra/tegra20_clocks.c')
-rw-r--r--arch/arm/mach-tegra/tegra20_clocks.c1062
1 files changed, 565 insertions, 497 deletions
diff --git a/arch/arm/mach-tegra/tegra20_clocks.c b/arch/arm/mach-tegra/tegra20_clocks.c
index 4a32030a4d9..a1e0f8a26b3 100644
--- a/arch/arm/mach-tegra/tegra20_clocks.c
+++ b/arch/arm/mach-tegra/tegra20_clocks.c
@@ -1,7 +1,8 @@
1/* 1/*
2 * arch/arm/mach-tegra/tegra2_clocks.c 2 * arch/arm/mach-tegra/tegra20_clocks.c
3 * 3 *
4 * Copyright (C) 2010 Google, Inc. 4 * Copyright (C) 2010 Google, Inc.
5 * Copyright (c) 2010-2012 NVIDIA CORPORATION. All rights reserved.
5 * 6 *
6 * Author: 7 * Author:
7 * Colin Cross <ccross@google.com> 8 * Colin Cross <ccross@google.com>
@@ -98,7 +99,7 @@
98#define PLL_OUT_CLKEN (1<<1) 99#define PLL_OUT_CLKEN (1<<1)
99#define PLL_OUT_RESET_DISABLE (1<<0) 100#define PLL_OUT_RESET_DISABLE (1<<0)
100 101
101#define PLL_MISC(c) (((c)->flags & PLL_ALT_MISC_REG) ? 0x4 : 0xc) 102#define PLL_MISC(c) (((c)->flags & PLL_ALT_MISC_REG) ? 0x4 : 0xc)
102 103
103#define PLL_MISC_DCCON_SHIFT 20 104#define PLL_MISC_DCCON_SHIFT 20
104#define PLL_MISC_CPCON_SHIFT 8 105#define PLL_MISC_CPCON_SHIFT 8
@@ -191,7 +192,8 @@ static unsigned long clk_measure_input_freq(void)
191 } else if (clock_autodetect >= 1587 - 3 && clock_autodetect <= 1587 + 3) { 192 } else if (clock_autodetect >= 1587 - 3 && clock_autodetect <= 1587 + 3) {
192 return 26000000; 193 return 26000000;
193 } else { 194 } else {
194 pr_err("%s: Unexpected clock autodetect value %d", __func__, clock_autodetect); 195 pr_err("%s: Unexpected clock autodetect value %d",
196 __func__, clock_autodetect);
195 BUG(); 197 BUG();
196 return 0; 198 return 0;
197 } 199 }
@@ -230,12 +232,21 @@ static int clk_div16_get_divider(unsigned long parent_rate, unsigned long rate)
230} 232}
231 233
232/* clk_m functions */ 234/* clk_m functions */
233static unsigned long tegra2_clk_m_autodetect_rate(struct clk *c) 235static unsigned long tegra20_clk_m_recalc_rate(struct clk_hw *hw,
236 unsigned long prate)
234{ 237{
235 u32 auto_clock_control = clk_readl(OSC_CTRL) & ~OSC_CTRL_OSC_FREQ_MASK; 238 if (!to_clk_tegra(hw)->fixed_rate)
239 to_clk_tegra(hw)->fixed_rate = clk_measure_input_freq();
240 return to_clk_tegra(hw)->fixed_rate;
241}
242
243static void tegra20_clk_m_init(struct clk_hw *hw)
244{
245 struct clk_tegra *c = to_clk_tegra(hw);
246 u32 osc_ctrl = clk_readl(OSC_CTRL);
247 u32 auto_clock_control = osc_ctrl & ~OSC_CTRL_OSC_FREQ_MASK;
236 248
237 c->rate = clk_measure_input_freq(); 249 switch (c->fixed_rate) {
238 switch (c->rate) {
239 case 12000000: 250 case 12000000:
240 auto_clock_control |= OSC_CTRL_OSC_FREQ_12MHZ; 251 auto_clock_control |= OSC_CTRL_OSC_FREQ_12MHZ;
241 break; 252 break;
@@ -249,35 +260,14 @@ static unsigned long tegra2_clk_m_autodetect_rate(struct clk *c)
249 auto_clock_control |= OSC_CTRL_OSC_FREQ_26MHZ; 260 auto_clock_control |= OSC_CTRL_OSC_FREQ_26MHZ;
250 break; 261 break;
251 default: 262 default:
252 pr_err("%s: Unexpected clock rate %ld", __func__, c->rate);
253 BUG(); 263 BUG();
254 } 264 }
255 clk_writel(auto_clock_control, OSC_CTRL); 265 clk_writel(auto_clock_control, OSC_CTRL);
256 return c->rate;
257}
258
259static void tegra2_clk_m_init(struct clk *c)
260{
261 pr_debug("%s on clock %s\n", __func__, c->name);
262 tegra2_clk_m_autodetect_rate(c);
263}
264
265static int tegra2_clk_m_enable(struct clk *c)
266{
267 pr_debug("%s on clock %s\n", __func__, c->name);
268 return 0;
269}
270
271static void tegra2_clk_m_disable(struct clk *c)
272{
273 pr_debug("%s on clock %s\n", __func__, c->name);
274 BUG();
275} 266}
276 267
277struct clk_ops tegra_clk_m_ops = { 268struct clk_ops tegra_clk_m_ops = {
278 .init = tegra2_clk_m_init, 269 .init = tegra20_clk_m_init,
279 .enable = tegra2_clk_m_enable, 270 .recalc_rate = tegra20_clk_m_recalc_rate,
280 .disable = tegra2_clk_m_disable,
281}; 271};
282 272
283/* super clock functions */ 273/* super clock functions */
@@ -286,161 +276,108 @@ struct clk_ops tegra_clk_m_ops = {
286 * can't lower the voltage when using the clock skip, but we can if we 276 * can't lower the voltage when using the clock skip, but we can if we
287 * lower the PLL frequency. 277 * lower the PLL frequency.
288 */ 278 */
289static void tegra2_super_clk_init(struct clk *c) 279static int tegra20_super_clk_is_enabled(struct clk_hw *hw)
290{ 280{
281 struct clk_tegra *c = to_clk_tegra(hw);
291 u32 val; 282 u32 val;
292 int source; 283
293 int shift;
294 const struct clk_mux_sel *sel;
295 val = clk_readl(c->reg + SUPER_CLK_MUX); 284 val = clk_readl(c->reg + SUPER_CLK_MUX);
296 c->state = ON;
297 BUG_ON(((val & SUPER_STATE_MASK) != SUPER_STATE_RUN) && 285 BUG_ON(((val & SUPER_STATE_MASK) != SUPER_STATE_RUN) &&
298 ((val & SUPER_STATE_MASK) != SUPER_STATE_IDLE)); 286 ((val & SUPER_STATE_MASK) != SUPER_STATE_IDLE));
299 shift = ((val & SUPER_STATE_MASK) == SUPER_STATE_IDLE) ? 287 c->state = ON;
300 SUPER_IDLE_SOURCE_SHIFT : SUPER_RUN_SOURCE_SHIFT; 288 return c->state;
301 source = (val >> shift) & SUPER_SOURCE_MASK;
302 for (sel = c->inputs; sel->input != NULL; sel++) {
303 if (sel->value == source)
304 break;
305 }
306 BUG_ON(sel->input == NULL);
307 c->parent = sel->input;
308} 289}
309 290
310static int tegra2_super_clk_enable(struct clk *c) 291static int tegra20_super_clk_enable(struct clk_hw *hw)
311{ 292{
293 struct clk_tegra *c = to_clk_tegra(hw);
312 clk_writel(0, c->reg + SUPER_CLK_DIVIDER); 294 clk_writel(0, c->reg + SUPER_CLK_DIVIDER);
313 return 0; 295 return 0;
314} 296}
315 297
316static void tegra2_super_clk_disable(struct clk *c) 298static void tegra20_super_clk_disable(struct clk_hw *hw)
317{ 299{
318 pr_debug("%s on clock %s\n", __func__, c->name); 300 pr_debug("%s on clock %s\n", __func__, __clk_get_name(hw->clk));
319 301
320 /* oops - don't disable the CPU clock! */ 302 /* oops - don't disable the CPU clock! */
321 BUG(); 303 BUG();
322} 304}
323 305
324static int tegra2_super_clk_set_parent(struct clk *c, struct clk *p) 306static u8 tegra20_super_clk_get_parent(struct clk_hw *hw)
325{ 307{
326 u32 val; 308 struct clk_tegra *c = to_clk_tegra(hw);
327 const struct clk_mux_sel *sel; 309 int val = clk_readl(c->reg + SUPER_CLK_MUX);
310 int source;
328 int shift; 311 int shift;
329 312
330 val = clk_readl(c->reg + SUPER_CLK_MUX);
331 BUG_ON(((val & SUPER_STATE_MASK) != SUPER_STATE_RUN) && 313 BUG_ON(((val & SUPER_STATE_MASK) != SUPER_STATE_RUN) &&
332 ((val & SUPER_STATE_MASK) != SUPER_STATE_IDLE)); 314 ((val & SUPER_STATE_MASK) != SUPER_STATE_IDLE));
333 shift = ((val & SUPER_STATE_MASK) == SUPER_STATE_IDLE) ? 315 shift = ((val & SUPER_STATE_MASK) == SUPER_STATE_IDLE) ?
334 SUPER_IDLE_SOURCE_SHIFT : SUPER_RUN_SOURCE_SHIFT; 316 SUPER_IDLE_SOURCE_SHIFT : SUPER_RUN_SOURCE_SHIFT;
335 for (sel = c->inputs; sel->input != NULL; sel++) { 317 source = (val >> shift) & SUPER_SOURCE_MASK;
336 if (sel->input == p) { 318 return source;
337 val &= ~(SUPER_SOURCE_MASK << shift); 319}
338 val |= sel->value << shift;
339 320
340 if (c->refcnt) 321static int tegra20_super_clk_set_parent(struct clk_hw *hw, u8 index)
341 clk_enable(p); 322{
323 struct clk_tegra *c = to_clk_tegra(hw);
324 u32 val = clk_readl(c->reg + SUPER_CLK_MUX);
325 int shift;
342 326
343 clk_writel(val, c->reg); 327 BUG_ON(((val & SUPER_STATE_MASK) != SUPER_STATE_RUN) &&
328 ((val & SUPER_STATE_MASK) != SUPER_STATE_IDLE));
329 shift = ((val & SUPER_STATE_MASK) == SUPER_STATE_IDLE) ?
330 SUPER_IDLE_SOURCE_SHIFT : SUPER_RUN_SOURCE_SHIFT;
331 val &= ~(SUPER_SOURCE_MASK << shift);
332 val |= index << shift;
344 333
345 if (c->refcnt && c->parent) 334 clk_writel(val, c->reg);
346 clk_disable(c->parent);
347 335
348 clk_reparent(c, p); 336 return 0;
349 return 0;
350 }
351 }
352 return -EINVAL;
353} 337}
354 338
355/* 339/* FIX ME: Need to switch parents to change the source PLL rate */
356 * Super clocks have "clock skippers" instead of dividers. Dividing using 340static unsigned long tegra20_super_clk_recalc_rate(struct clk_hw *hw,
357 * a clock skipper does not allow the voltage to be scaled down, so instead 341 unsigned long prate)
358 * adjust the rate of the parent clock. This requires that the parent of a
359 * super clock have no other children, otherwise the rate will change
360 * underneath the other children.
361 */
362static int tegra2_super_clk_set_rate(struct clk *c, unsigned long rate)
363{ 342{
364 return clk_set_rate(c->parent, rate); 343 return prate;
365} 344}
366 345
367struct clk_ops tegra_super_ops = { 346static long tegra20_super_clk_round_rate(struct clk_hw *hw, unsigned long rate,
368 .init = tegra2_super_clk_init, 347 unsigned long *prate)
369 .enable = tegra2_super_clk_enable,
370 .disable = tegra2_super_clk_disable,
371 .set_parent = tegra2_super_clk_set_parent,
372 .set_rate = tegra2_super_clk_set_rate,
373};
374
375/* virtual cpu clock functions */
376/* some clocks can not be stopped (cpu, memory bus) while the SoC is running.
377 To change the frequency of these clocks, the parent pll may need to be
378 reprogrammed, so the clock must be moved off the pll, the pll reprogrammed,
379 and then the clock moved back to the pll. To hide this sequence, a virtual
380 clock handles it.
381 */
382static void tegra2_cpu_clk_init(struct clk *c)
383{ 348{
349 return *prate;
384} 350}
385 351
386static int tegra2_cpu_clk_enable(struct clk *c) 352static int tegra20_super_clk_set_rate(struct clk_hw *hw, unsigned long rate,
353 unsigned long parent_rate)
387{ 354{
388 return 0; 355 return 0;
389} 356}
390 357
391static void tegra2_cpu_clk_disable(struct clk *c) 358struct clk_ops tegra_super_ops = {
392{ 359 .is_enabled = tegra20_super_clk_is_enabled,
393 pr_debug("%s on clock %s\n", __func__, c->name); 360 .enable = tegra20_super_clk_enable,
394 361 .disable = tegra20_super_clk_disable,
395 /* oops - don't disable the CPU clock! */ 362 .set_parent = tegra20_super_clk_set_parent,
396 BUG(); 363 .get_parent = tegra20_super_clk_get_parent,
397} 364 .set_rate = tegra20_super_clk_set_rate,
365 .round_rate = tegra20_super_clk_round_rate,
366 .recalc_rate = tegra20_super_clk_recalc_rate,
367};
398 368
399static int tegra2_cpu_clk_set_rate(struct clk *c, unsigned long rate) 369static u8 tegra20_cop_clk_get_parent(struct clk_hw *hw)
400{ 370{
401 int ret; 371 return 0;
402 /*
403 * Take an extra reference to the main pll so it doesn't turn
404 * off when we move the cpu off of it
405 */
406 clk_enable(c->u.cpu.main);
407
408 ret = clk_set_parent(c->parent, c->u.cpu.backup);
409 if (ret) {
410 pr_err("Failed to switch cpu to clock %s\n", c->u.cpu.backup->name);
411 goto out;
412 }
413
414 if (rate == clk_get_rate(c->u.cpu.backup))
415 goto out;
416
417 ret = clk_set_rate(c->u.cpu.main, rate);
418 if (ret) {
419 pr_err("Failed to change cpu pll to %lu\n", rate);
420 goto out;
421 }
422
423 ret = clk_set_parent(c->parent, c->u.cpu.main);
424 if (ret) {
425 pr_err("Failed to switch cpu to clock %s\n", c->u.cpu.main->name);
426 goto out;
427 }
428
429out:
430 clk_disable(c->u.cpu.main);
431 return ret;
432} 372}
433 373
434struct clk_ops tegra_cpu_ops = { 374struct clk_ops tegra_cop_ops = {
435 .init = tegra2_cpu_clk_init, 375 .get_parent = tegra20_cop_clk_get_parent,
436 .enable = tegra2_cpu_clk_enable,
437 .disable = tegra2_cpu_clk_disable,
438 .set_rate = tegra2_cpu_clk_set_rate,
439}; 376};
440 377
441/* virtual cop clock functions. Used to acquire the fake 'cop' clock to 378/* virtual cop clock functions. Used to acquire the fake 'cop' clock to
442 * reset the COP block (i.e. AVP) */ 379 * reset the COP block (i.e. AVP) */
443static void tegra2_cop_clk_reset(struct clk *c, bool assert) 380void tegra2_cop_clk_reset(struct clk_hw *hw, bool assert)
444{ 381{
445 unsigned long reg = assert ? RST_DEVICES_SET : RST_DEVICES_CLR; 382 unsigned long reg = assert ? RST_DEVICES_SET : RST_DEVICES_CLR;
446 383
@@ -448,23 +385,21 @@ static void tegra2_cop_clk_reset(struct clk *c, bool assert)
448 clk_writel(1 << 1, reg); 385 clk_writel(1 << 1, reg);
449} 386}
450 387
451struct clk_ops tegra_cop_ops = {
452 .reset = tegra2_cop_clk_reset,
453};
454
455/* bus clock functions */ 388/* bus clock functions */
456static void tegra2_bus_clk_init(struct clk *c) 389static int tegra20_bus_clk_is_enabled(struct clk_hw *hw)
457{ 390{
391 struct clk_tegra *c = to_clk_tegra(hw);
458 u32 val = clk_readl(c->reg); 392 u32 val = clk_readl(c->reg);
393
459 c->state = ((val >> c->reg_shift) & BUS_CLK_DISABLE) ? OFF : ON; 394 c->state = ((val >> c->reg_shift) & BUS_CLK_DISABLE) ? OFF : ON;
460 c->div = ((val >> c->reg_shift) & BUS_CLK_DIV_MASK) + 1; 395 return c->state;
461 c->mul = 1;
462} 396}
463 397
464static int tegra2_bus_clk_enable(struct clk *c) 398static int tegra20_bus_clk_enable(struct clk_hw *hw)
465{ 399{
466 u32 val; 400 struct clk_tegra *c = to_clk_tegra(hw);
467 unsigned long flags; 401 unsigned long flags;
402 u32 val;
468 403
469 spin_lock_irqsave(&clock_register_lock, flags); 404 spin_lock_irqsave(&clock_register_lock, flags);
470 405
@@ -477,10 +412,11 @@ static int tegra2_bus_clk_enable(struct clk *c)
477 return 0; 412 return 0;
478} 413}
479 414
480static void tegra2_bus_clk_disable(struct clk *c) 415static void tegra20_bus_clk_disable(struct clk_hw *hw)
481{ 416{
482 u32 val; 417 struct clk_tegra *c = to_clk_tegra(hw);
483 unsigned long flags; 418 unsigned long flags;
419 u32 val;
484 420
485 spin_lock_irqsave(&clock_register_lock, flags); 421 spin_lock_irqsave(&clock_register_lock, flags);
486 422
@@ -491,12 +427,31 @@ static void tegra2_bus_clk_disable(struct clk *c)
491 spin_unlock_irqrestore(&clock_register_lock, flags); 427 spin_unlock_irqrestore(&clock_register_lock, flags);
492} 428}
493 429
494static int tegra2_bus_clk_set_rate(struct clk *c, unsigned long rate) 430static unsigned long tegra20_bus_clk_recalc_rate(struct clk_hw *hw,
431 unsigned long prate)
495{ 432{
496 u32 val; 433 struct clk_tegra *c = to_clk_tegra(hw);
497 unsigned long parent_rate = clk_get_rate(c->parent); 434 u32 val = clk_readl(c->reg);
498 unsigned long flags; 435 u64 rate = prate;
436
437 c->div = ((val >> c->reg_shift) & BUS_CLK_DIV_MASK) + 1;
438 c->mul = 1;
439
440 if (c->mul != 0 && c->div != 0) {
441 rate *= c->mul;
442 rate += c->div - 1; /* round up */
443 do_div(rate, c->div);
444 }
445 return rate;
446}
447
448static int tegra20_bus_clk_set_rate(struct clk_hw *hw, unsigned long rate,
449 unsigned long parent_rate)
450{
451 struct clk_tegra *c = to_clk_tegra(hw);
499 int ret = -EINVAL; 452 int ret = -EINVAL;
453 unsigned long flags;
454 u32 val;
500 int i; 455 int i;
501 456
502 spin_lock_irqsave(&clock_register_lock, flags); 457 spin_lock_irqsave(&clock_register_lock, flags);
@@ -519,21 +474,56 @@ static int tegra2_bus_clk_set_rate(struct clk *c, unsigned long rate)
519 return ret; 474 return ret;
520} 475}
521 476
477static long tegra20_bus_clk_round_rate(struct clk_hw *hw, unsigned long rate,
478 unsigned long *prate)
479{
480 unsigned long parent_rate = *prate;
481 s64 divider;
482
483 if (rate >= parent_rate)
484 return rate;
485
486 divider = parent_rate;
487 divider += rate - 1;
488 do_div(divider, rate);
489
490 if (divider < 0)
491 return divider;
492
493 if (divider > 4)
494 divider = 4;
495 do_div(parent_rate, divider);
496
497 return parent_rate;
498}
499
522struct clk_ops tegra_bus_ops = { 500struct clk_ops tegra_bus_ops = {
523 .init = tegra2_bus_clk_init, 501 .is_enabled = tegra20_bus_clk_is_enabled,
524 .enable = tegra2_bus_clk_enable, 502 .enable = tegra20_bus_clk_enable,
525 .disable = tegra2_bus_clk_disable, 503 .disable = tegra20_bus_clk_disable,
526 .set_rate = tegra2_bus_clk_set_rate, 504 .set_rate = tegra20_bus_clk_set_rate,
505 .round_rate = tegra20_bus_clk_round_rate,
506 .recalc_rate = tegra20_bus_clk_recalc_rate,
527}; 507};
528 508
529/* Blink output functions */ 509/* Blink output functions */
530 510static int tegra20_blink_clk_is_enabled(struct clk_hw *hw)
531static void tegra2_blink_clk_init(struct clk *c)
532{ 511{
512 struct clk_tegra *c = to_clk_tegra(hw);
533 u32 val; 513 u32 val;
534 514
535 val = pmc_readl(PMC_CTRL); 515 val = pmc_readl(PMC_CTRL);
536 c->state = (val & PMC_CTRL_BLINK_ENB) ? ON : OFF; 516 c->state = (val & PMC_CTRL_BLINK_ENB) ? ON : OFF;
517 return c->state;
518}
519
520static unsigned long tegra20_blink_clk_recalc_rate(struct clk_hw *hw,
521 unsigned long prate)
522{
523 struct clk_tegra *c = to_clk_tegra(hw);
524 u64 rate = prate;
525 u32 val;
526
537 c->mul = 1; 527 c->mul = 1;
538 val = pmc_readl(c->reg); 528 val = pmc_readl(c->reg);
539 529
@@ -550,9 +540,16 @@ static void tegra2_blink_clk_init(struct clk *c)
550 } else { 540 } else {
551 c->div = 1; 541 c->div = 1;
552 } 542 }
543
544 if (c->mul != 0 && c->div != 0) {
545 rate *= c->mul;
546 rate += c->div - 1; /* round up */
547 do_div(rate, c->div);
548 }
549 return rate;
553} 550}
554 551
555static int tegra2_blink_clk_enable(struct clk *c) 552static int tegra20_blink_clk_enable(struct clk_hw *hw)
556{ 553{
557 u32 val; 554 u32 val;
558 555
@@ -565,7 +562,7 @@ static int tegra2_blink_clk_enable(struct clk *c)
565 return 0; 562 return 0;
566} 563}
567 564
568static void tegra2_blink_clk_disable(struct clk *c) 565static void tegra20_blink_clk_disable(struct clk_hw *hw)
569{ 566{
570 u32 val; 567 u32 val;
571 568
@@ -576,9 +573,11 @@ static void tegra2_blink_clk_disable(struct clk *c)
576 pmc_writel(val & ~PMC_DPD_PADS_ORIDE_BLINK_ENB, PMC_DPD_PADS_ORIDE); 573 pmc_writel(val & ~PMC_DPD_PADS_ORIDE_BLINK_ENB, PMC_DPD_PADS_ORIDE);
577} 574}
578 575
579static int tegra2_blink_clk_set_rate(struct clk *c, unsigned long rate) 576static int tegra20_blink_clk_set_rate(struct clk_hw *hw, unsigned long rate,
577 unsigned long parent_rate)
580{ 578{
581 unsigned long parent_rate = clk_get_rate(c->parent); 579 struct clk_tegra *c = to_clk_tegra(hw);
580
582 if (rate >= parent_rate) { 581 if (rate >= parent_rate) {
583 c->div = 1; 582 c->div = 1;
584 pmc_writel(0, c->reg); 583 pmc_writel(0, c->reg);
@@ -601,31 +600,74 @@ static int tegra2_blink_clk_set_rate(struct clk *c, unsigned long rate)
601 return 0; 600 return 0;
602} 601}
603 602
603static long tegra20_blink_clk_round_rate(struct clk_hw *hw, unsigned long rate,
604 unsigned long *prate)
605{
606 int div;
607 int mul;
608 long round_rate = *prate;
609
610 mul = 1;
611
612 if (rate >= *prate) {
613 div = 1;
614 } else {
615 div = DIV_ROUND_UP(*prate / 8, rate);
616 div *= 8;
617 }
618
619 round_rate *= mul;
620 round_rate += div - 1;
621 do_div(round_rate, div);
622
623 return round_rate;
624}
625
604struct clk_ops tegra_blink_clk_ops = { 626struct clk_ops tegra_blink_clk_ops = {
605 .init = &tegra2_blink_clk_init, 627 .is_enabled = tegra20_blink_clk_is_enabled,
606 .enable = &tegra2_blink_clk_enable, 628 .enable = tegra20_blink_clk_enable,
607 .disable = &tegra2_blink_clk_disable, 629 .disable = tegra20_blink_clk_disable,
608 .set_rate = &tegra2_blink_clk_set_rate, 630 .set_rate = tegra20_blink_clk_set_rate,
631 .round_rate = tegra20_blink_clk_round_rate,
632 .recalc_rate = tegra20_blink_clk_recalc_rate,
609}; 633};
610 634
611/* PLL Functions */ 635/* PLL Functions */
612static int tegra2_pll_clk_wait_for_lock(struct clk *c) 636static int tegra20_pll_clk_wait_for_lock(struct clk_tegra *c)
613{ 637{
614 udelay(c->u.pll.lock_delay); 638 udelay(c->u.pll.lock_delay);
615
616 return 0; 639 return 0;
617} 640}
618 641
619static void tegra2_pll_clk_init(struct clk *c) 642static int tegra20_pll_clk_is_enabled(struct clk_hw *hw)
620{ 643{
644 struct clk_tegra *c = to_clk_tegra(hw);
621 u32 val = clk_readl(c->reg + PLL_BASE); 645 u32 val = clk_readl(c->reg + PLL_BASE);
622 646
623 c->state = (val & PLL_BASE_ENABLE) ? ON : OFF; 647 c->state = (val & PLL_BASE_ENABLE) ? ON : OFF;
648 return c->state;
649}
650
651static unsigned long tegra20_pll_clk_recalc_rate(struct clk_hw *hw,
652 unsigned long prate)
653{
654 struct clk_tegra *c = to_clk_tegra(hw);
655 u32 val = clk_readl(c->reg + PLL_BASE);
656 u64 rate = prate;
624 657
625 if (c->flags & PLL_FIXED && !(val & PLL_BASE_OVERRIDE)) { 658 if (c->flags & PLL_FIXED && !(val & PLL_BASE_OVERRIDE)) {
626 pr_warning("Clock %s has unknown fixed frequency\n", c->name); 659 const struct clk_pll_freq_table *sel;
627 c->mul = 1; 660 for (sel = c->u.pll.freq_table; sel->input_rate != 0; sel++) {
628 c->div = 1; 661 if (sel->input_rate == prate &&
662 sel->output_rate == c->u.pll.fixed_rate) {
663 c->mul = sel->n;
664 c->div = sel->m * sel->p;
665 break;
666 }
667 }
668 pr_err("Clock %s has unknown fixed frequency\n",
669 __clk_get_name(hw->clk));
670 BUG();
629 } else if (val & PLL_BASE_BYPASS) { 671 } else if (val & PLL_BASE_BYPASS) {
630 c->mul = 1; 672 c->mul = 1;
631 c->div = 1; 673 c->div = 1;
@@ -637,42 +679,63 @@ static void tegra2_pll_clk_init(struct clk *c)
637 else 679 else
638 c->div *= (val & PLL_BASE_DIVP_MASK) ? 2 : 1; 680 c->div *= (val & PLL_BASE_DIVP_MASK) ? 2 : 1;
639 } 681 }
682
683 if (c->mul != 0 && c->div != 0) {
684 rate *= c->mul;
685 rate += c->div - 1; /* round up */
686 do_div(rate, c->div);
687 }
688 return rate;
640} 689}
641 690
642static int tegra2_pll_clk_enable(struct clk *c) 691static int tegra20_pll_clk_enable(struct clk_hw *hw)
643{ 692{
693 struct clk_tegra *c = to_clk_tegra(hw);
644 u32 val; 694 u32 val;
645 pr_debug("%s on clock %s\n", __func__, c->name); 695 pr_debug("%s on clock %s\n", __func__, __clk_get_name(hw->clk));
646 696
647 val = clk_readl(c->reg + PLL_BASE); 697 val = clk_readl(c->reg + PLL_BASE);
648 val &= ~PLL_BASE_BYPASS; 698 val &= ~PLL_BASE_BYPASS;
649 val |= PLL_BASE_ENABLE; 699 val |= PLL_BASE_ENABLE;
650 clk_writel(val, c->reg + PLL_BASE); 700 clk_writel(val, c->reg + PLL_BASE);
651 701
652 tegra2_pll_clk_wait_for_lock(c); 702 tegra20_pll_clk_wait_for_lock(c);
653 703
654 return 0; 704 return 0;
655} 705}
656 706
657static void tegra2_pll_clk_disable(struct clk *c) 707static void tegra20_pll_clk_disable(struct clk_hw *hw)
658{ 708{
709 struct clk_tegra *c = to_clk_tegra(hw);
659 u32 val; 710 u32 val;
660 pr_debug("%s on clock %s\n", __func__, c->name); 711 pr_debug("%s on clock %s\n", __func__, __clk_get_name(hw->clk));
661 712
662 val = clk_readl(c->reg); 713 val = clk_readl(c->reg);
663 val &= ~(PLL_BASE_BYPASS | PLL_BASE_ENABLE); 714 val &= ~(PLL_BASE_BYPASS | PLL_BASE_ENABLE);
664 clk_writel(val, c->reg); 715 clk_writel(val, c->reg);
665} 716}
666 717
667static int tegra2_pll_clk_set_rate(struct clk *c, unsigned long rate) 718static int tegra20_pll_clk_set_rate(struct clk_hw *hw, unsigned long rate,
719 unsigned long parent_rate)
668{ 720{
669 u32 val; 721 struct clk_tegra *c = to_clk_tegra(hw);
670 unsigned long input_rate; 722 unsigned long input_rate = parent_rate;
671 const struct clk_pll_freq_table *sel; 723 const struct clk_pll_freq_table *sel;
724 u32 val;
672 725
673 pr_debug("%s: %s %lu\n", __func__, c->name, rate); 726 pr_debug("%s: %s %lu\n", __func__, __clk_get_name(hw->clk), rate);
727
728 if (c->flags & PLL_FIXED) {
729 int ret = 0;
730 if (rate != c->u.pll.fixed_rate) {
731 pr_err("%s: Can not change %s fixed rate %lu to %lu\n",
732 __func__, __clk_get_name(hw->clk),
733 c->u.pll.fixed_rate, rate);
734 ret = -EINVAL;
735 }
736 return ret;
737 }
674 738
675 input_rate = clk_get_rate(c->parent);
676 for (sel = c->u.pll.freq_table; sel->input_rate != 0; sel++) { 739 for (sel = c->u.pll.freq_table; sel->input_rate != 0; sel++) {
677 if (sel->input_rate == input_rate && sel->output_rate == rate) { 740 if (sel->input_rate == input_rate && sel->output_rate == rate) {
678 c->mul = sel->n; 741 c->mul = sel->n;
@@ -703,41 +766,76 @@ static int tegra2_pll_clk_set_rate(struct clk *c, unsigned long rate)
703 } 766 }
704 767
705 if (c->state == ON) 768 if (c->state == ON)
706 tegra2_pll_clk_enable(c); 769 tegra20_pll_clk_enable(hw);
707
708 return 0; 770 return 0;
709 } 771 }
710 } 772 }
711 return -EINVAL; 773 return -EINVAL;
712} 774}
713 775
776static long tegra20_pll_clk_round_rate(struct clk_hw *hw, unsigned long rate,
777 unsigned long *prate)
778{
779 struct clk_tegra *c = to_clk_tegra(hw);
780 const struct clk_pll_freq_table *sel;
781 unsigned long input_rate = *prate;
782 unsigned long output_rate = *prate;
783 int mul;
784 int div;
785
786 if (c->flags & PLL_FIXED)
787 return c->u.pll.fixed_rate;
788
789 for (sel = c->u.pll.freq_table; sel->input_rate != 0; sel++)
790 if (sel->input_rate == input_rate && sel->output_rate == rate) {
791 mul = sel->n;
792 div = sel->m * sel->p;
793 break;
794 }
795
796 if (sel->input_rate == 0)
797 return -EINVAL;
798
799 output_rate *= mul;
800 output_rate += div - 1; /* round up */
801 do_div(output_rate, div);
802
803 return output_rate;
804}
805
714struct clk_ops tegra_pll_ops = { 806struct clk_ops tegra_pll_ops = {
715 .init = tegra2_pll_clk_init, 807 .is_enabled = tegra20_pll_clk_is_enabled,
716 .enable = tegra2_pll_clk_enable, 808 .enable = tegra20_pll_clk_enable,
717 .disable = tegra2_pll_clk_disable, 809 .disable = tegra20_pll_clk_disable,
718 .set_rate = tegra2_pll_clk_set_rate, 810 .set_rate = tegra20_pll_clk_set_rate,
811 .recalc_rate = tegra20_pll_clk_recalc_rate,
812 .round_rate = tegra20_pll_clk_round_rate,
719}; 813};
720 814
721static void tegra2_pllx_clk_init(struct clk *c) 815static void tegra20_pllx_clk_init(struct clk_hw *hw)
722{ 816{
723 tegra2_pll_clk_init(c); 817 struct clk_tegra *c = to_clk_tegra(hw);
724 818
725 if (tegra_sku_id == 7) 819 if (tegra_sku_id == 7)
726 c->max_rate = 750000000; 820 c->max_rate = 750000000;
727} 821}
728 822
729struct clk_ops tegra_pllx_ops = { 823struct clk_ops tegra_pllx_ops = {
730 .init = tegra2_pllx_clk_init, 824 .init = tegra20_pllx_clk_init,
731 .enable = tegra2_pll_clk_enable, 825 .is_enabled = tegra20_pll_clk_is_enabled,
732 .disable = tegra2_pll_clk_disable, 826 .enable = tegra20_pll_clk_enable,
733 .set_rate = tegra2_pll_clk_set_rate, 827 .disable = tegra20_pll_clk_disable,
828 .set_rate = tegra20_pll_clk_set_rate,
829 .recalc_rate = tegra20_pll_clk_recalc_rate,
830 .round_rate = tegra20_pll_clk_round_rate,
734}; 831};
735 832
736static int tegra2_plle_clk_enable(struct clk *c) 833static int tegra20_plle_clk_enable(struct clk_hw *hw)
737{ 834{
835 struct clk_tegra *c = to_clk_tegra(hw);
738 u32 val; 836 u32 val;
739 837
740 pr_debug("%s on clock %s\n", __func__, c->name); 838 pr_debug("%s on clock %s\n", __func__, __clk_get_name(hw->clk));
741 839
742 mdelay(1); 840 mdelay(1);
743 841
@@ -753,20 +851,35 @@ static int tegra2_plle_clk_enable(struct clk *c)
753} 851}
754 852
755struct clk_ops tegra_plle_ops = { 853struct clk_ops tegra_plle_ops = {
756 .init = tegra2_pll_clk_init, 854 .is_enabled = tegra20_pll_clk_is_enabled,
757 .enable = tegra2_plle_clk_enable, 855 .enable = tegra20_plle_clk_enable,
758 .set_rate = tegra2_pll_clk_set_rate, 856 .set_rate = tegra20_pll_clk_set_rate,
857 .recalc_rate = tegra20_pll_clk_recalc_rate,
858 .round_rate = tegra20_pll_clk_round_rate,
759}; 859};
760 860
761/* Clock divider ops */ 861/* Clock divider ops */
762static void tegra2_pll_div_clk_init(struct clk *c) 862static int tegra20_pll_div_clk_is_enabled(struct clk_hw *hw)
763{ 863{
864 struct clk_tegra *c = to_clk_tegra(hw);
764 u32 val = clk_readl(c->reg); 865 u32 val = clk_readl(c->reg);
765 u32 divu71; 866
766 val >>= c->reg_shift; 867 val >>= c->reg_shift;
767 c->state = (val & PLL_OUT_CLKEN) ? ON : OFF; 868 c->state = (val & PLL_OUT_CLKEN) ? ON : OFF;
768 if (!(val & PLL_OUT_RESET_DISABLE)) 869 if (!(val & PLL_OUT_RESET_DISABLE))
769 c->state = OFF; 870 c->state = OFF;
871 return c->state;
872}
873
874static unsigned long tegra20_pll_div_clk_recalc_rate(struct clk_hw *hw,
875 unsigned long prate)
876{
877 struct clk_tegra *c = to_clk_tegra(hw);
878 u64 rate = prate;
879 u32 val = clk_readl(c->reg);
880 u32 divu71;
881
882 val >>= c->reg_shift;
770 883
771 if (c->flags & DIV_U71) { 884 if (c->flags & DIV_U71) {
772 divu71 = (val & PLL_OUT_RATIO_MASK) >> PLL_OUT_RATIO_SHIFT; 885 divu71 = (val & PLL_OUT_RATIO_MASK) >> PLL_OUT_RATIO_SHIFT;
@@ -779,15 +892,23 @@ static void tegra2_pll_div_clk_init(struct clk *c)
779 c->div = 1; 892 c->div = 1;
780 c->mul = 1; 893 c->mul = 1;
781 } 894 }
895
896 rate *= c->mul;
897 rate += c->div - 1; /* round up */
898 do_div(rate, c->div);
899
900 return rate;
782} 901}
783 902
784static int tegra2_pll_div_clk_enable(struct clk *c) 903static int tegra20_pll_div_clk_enable(struct clk_hw *hw)
785{ 904{
786 u32 val; 905 struct clk_tegra *c = to_clk_tegra(hw);
787 u32 new_val;
788 unsigned long flags; 906 unsigned long flags;
907 u32 new_val;
908 u32 val;
909
910 pr_debug("%s: %s\n", __func__, __clk_get_name(hw->clk));
789 911
790 pr_debug("%s: %s\n", __func__, c->name);
791 if (c->flags & DIV_U71) { 912 if (c->flags & DIV_U71) {
792 spin_lock_irqsave(&clock_register_lock, flags); 913 spin_lock_irqsave(&clock_register_lock, flags);
793 val = clk_readl(c->reg); 914 val = clk_readl(c->reg);
@@ -813,13 +934,15 @@ static int tegra2_pll_div_clk_enable(struct clk *c)
813 return -EINVAL; 934 return -EINVAL;
814} 935}
815 936
816static void tegra2_pll_div_clk_disable(struct clk *c) 937static void tegra20_pll_div_clk_disable(struct clk_hw *hw)
817{ 938{
818 u32 val; 939 struct clk_tegra *c = to_clk_tegra(hw);
819 u32 new_val;
820 unsigned long flags; 940 unsigned long flags;
941 u32 new_val;
942 u32 val;
943
944 pr_debug("%s: %s\n", __func__, __clk_get_name(hw->clk));
821 945
822 pr_debug("%s: %s\n", __func__, c->name);
823 if (c->flags & DIV_U71) { 946 if (c->flags & DIV_U71) {
824 spin_lock_irqsave(&clock_register_lock, flags); 947 spin_lock_irqsave(&clock_register_lock, flags);
825 val = clk_readl(c->reg); 948 val = clk_readl(c->reg);
@@ -842,15 +965,17 @@ static void tegra2_pll_div_clk_disable(struct clk *c)
842 } 965 }
843} 966}
844 967
845static int tegra2_pll_div_clk_set_rate(struct clk *c, unsigned long rate) 968static int tegra20_pll_div_clk_set_rate(struct clk_hw *hw, unsigned long rate,
969 unsigned long parent_rate)
846{ 970{
847 u32 val; 971 struct clk_tegra *c = to_clk_tegra(hw);
848 u32 new_val;
849 int divider_u71;
850 unsigned long parent_rate = clk_get_rate(c->parent);
851 unsigned long flags; 972 unsigned long flags;
973 int divider_u71;
974 u32 new_val;
975 u32 val;
976
977 pr_debug("%s: %s %lu\n", __func__, __clk_get_name(hw->clk), rate);
852 978
853 pr_debug("%s: %s %lu\n", __func__, c->name, rate);
854 if (c->flags & DIV_U71) { 979 if (c->flags & DIV_U71) {
855 divider_u71 = clk_div71_get_divider(parent_rate, rate); 980 divider_u71 = clk_div71_get_divider(parent_rate, rate);
856 if (divider_u71 >= 0) { 981 if (divider_u71 >= 0) {
@@ -878,11 +1003,14 @@ static int tegra2_pll_div_clk_set_rate(struct clk *c, unsigned long rate)
878 return -EINVAL; 1003 return -EINVAL;
879} 1004}
880 1005
881static long tegra2_pll_div_clk_round_rate(struct clk *c, unsigned long rate) 1006static long tegra20_pll_div_clk_round_rate(struct clk_hw *hw, unsigned long rate,
1007 unsigned long *prate)
882{ 1008{
1009 struct clk_tegra *c = to_clk_tegra(hw);
1010 unsigned long parent_rate = *prate;
883 int divider; 1011 int divider;
884 unsigned long parent_rate = clk_get_rate(c->parent); 1012
885 pr_debug("%s: %s %lu\n", __func__, c->name, rate); 1013 pr_debug("%s: %s %lu\n", __func__, __clk_get_name(hw->clk), rate);
886 1014
887 if (c->flags & DIV_U71) { 1015 if (c->flags & DIV_U71) {
888 divider = clk_div71_get_divider(parent_rate, rate); 1016 divider = clk_div71_get_divider(parent_rate, rate);
@@ -896,60 +1024,24 @@ static long tegra2_pll_div_clk_round_rate(struct clk *c, unsigned long rate)
896} 1024}
897 1025
898struct clk_ops tegra_pll_div_ops = { 1026struct clk_ops tegra_pll_div_ops = {
899 .init = tegra2_pll_div_clk_init, 1027 .is_enabled = tegra20_pll_div_clk_is_enabled,
900 .enable = tegra2_pll_div_clk_enable, 1028 .enable = tegra20_pll_div_clk_enable,
901 .disable = tegra2_pll_div_clk_disable, 1029 .disable = tegra20_pll_div_clk_disable,
902 .set_rate = tegra2_pll_div_clk_set_rate, 1030 .set_rate = tegra20_pll_div_clk_set_rate,
903 .round_rate = tegra2_pll_div_clk_round_rate, 1031 .round_rate = tegra20_pll_div_clk_round_rate,
1032 .recalc_rate = tegra20_pll_div_clk_recalc_rate,
904}; 1033};
905 1034
906/* Periph clk ops */ 1035/* Periph clk ops */
907 1036
908static void tegra2_periph_clk_init(struct clk *c) 1037static int tegra20_periph_clk_is_enabled(struct clk_hw *hw)
909{ 1038{
910 u32 val = clk_readl(c->reg); 1039 struct clk_tegra *c = to_clk_tegra(hw);
911 const struct clk_mux_sel *mux = NULL;
912 const struct clk_mux_sel *sel;
913 u32 shift;
914 u32 mask;
915
916 if (c->flags & MUX_PWM) {
917 shift = PERIPH_CLK_SOURCE_PWM_SHIFT;
918 mask = PERIPH_CLK_SOURCE_PWM_MASK;
919 } else {
920 shift = PERIPH_CLK_SOURCE_SHIFT;
921 mask = PERIPH_CLK_SOURCE_MASK;
922 }
923
924 if (c->flags & MUX) {
925 for (sel = c->inputs; sel->input != NULL; sel++) {
926 if ((val & mask) >> shift == sel->value)
927 mux = sel;
928 }
929 BUG_ON(!mux);
930
931 c->parent = mux->input;
932 } else {
933 c->parent = c->inputs[0].input;
934 }
935
936 if (c->flags & DIV_U71) {
937 u32 divu71 = val & PERIPH_CLK_SOURCE_DIVU71_MASK;
938 c->div = divu71 + 2;
939 c->mul = 2;
940 } else if (c->flags & DIV_U16) {
941 u32 divu16 = val & PERIPH_CLK_SOURCE_DIVU16_MASK;
942 c->div = divu16 + 1;
943 c->mul = 1;
944 } else {
945 c->div = 1;
946 c->mul = 1;
947 }
948 1040
949 c->state = ON; 1041 c->state = ON;
950 1042
951 if (!c->u.periph.clk_num) 1043 if (!c->u.periph.clk_num)
952 return; 1044 goto out;
953 1045
954 if (!(clk_readl(CLK_OUT_ENB + PERIPH_CLK_TO_ENB_REG(c)) & 1046 if (!(clk_readl(CLK_OUT_ENB + PERIPH_CLK_TO_ENB_REG(c)) &
955 PERIPH_CLK_TO_ENB_BIT(c))) 1047 PERIPH_CLK_TO_ENB_BIT(c)))
@@ -959,24 +1051,27 @@ static void tegra2_periph_clk_init(struct clk *c)
959 if (clk_readl(RST_DEVICES + PERIPH_CLK_TO_ENB_REG(c)) & 1051 if (clk_readl(RST_DEVICES + PERIPH_CLK_TO_ENB_REG(c)) &
960 PERIPH_CLK_TO_ENB_BIT(c)) 1052 PERIPH_CLK_TO_ENB_BIT(c))
961 c->state = OFF; 1053 c->state = OFF;
1054
1055out:
1056 return c->state;
962} 1057}
963 1058
964static int tegra2_periph_clk_enable(struct clk *c) 1059static int tegra20_periph_clk_enable(struct clk_hw *hw)
965{ 1060{
966 u32 val; 1061 struct clk_tegra *c = to_clk_tegra(hw);
967 unsigned long flags; 1062 unsigned long flags;
968 int refcount; 1063 u32 val;
969 pr_debug("%s on clock %s\n", __func__, c->name); 1064
1065 pr_debug("%s on clock %s\n", __func__, __clk_get_name(hw->clk));
970 1066
971 if (!c->u.periph.clk_num) 1067 if (!c->u.periph.clk_num)
972 return 0; 1068 return 0;
973 1069
974 spin_lock_irqsave(&clock_register_lock, flags); 1070 tegra_periph_clk_enable_refcount[c->u.periph.clk_num]++;
975 1071 if (tegra_periph_clk_enable_refcount[c->u.periph.clk_num] > 1)
976 refcount = tegra_periph_clk_enable_refcount[c->u.periph.clk_num]++; 1072 return 0;
977 1073
978 if (refcount > 1) 1074 spin_lock_irqsave(&clock_register_lock, flags);
979 goto out;
980 1075
981 clk_writel(PERIPH_CLK_TO_ENB_BIT(c), 1076 clk_writel(PERIPH_CLK_TO_ENB_BIT(c),
982 CLK_OUT_ENB_SET + PERIPH_CLK_TO_ENB_SET_REG(c)); 1077 CLK_OUT_ENB_SET + PERIPH_CLK_TO_ENB_SET_REG(c));
@@ -991,39 +1086,41 @@ static int tegra2_periph_clk_enable(struct clk *c)
991 clk_writel(val, c->reg); 1086 clk_writel(val, c->reg);
992 } 1087 }
993 1088
994out:
995 spin_unlock_irqrestore(&clock_register_lock, flags); 1089 spin_unlock_irqrestore(&clock_register_lock, flags);
996 1090
997 return 0; 1091 return 0;
998} 1092}
999 1093
1000static void tegra2_periph_clk_disable(struct clk *c) 1094static void tegra20_periph_clk_disable(struct clk_hw *hw)
1001{ 1095{
1096 struct clk_tegra *c = to_clk_tegra(hw);
1002 unsigned long flags; 1097 unsigned long flags;
1003 1098
1004 pr_debug("%s on clock %s\n", __func__, c->name); 1099 pr_debug("%s on clock %s\n", __func__, __clk_get_name(hw->clk));
1005 1100
1006 if (!c->u.periph.clk_num) 1101 if (!c->u.periph.clk_num)
1007 return; 1102 return;
1008 1103
1009 spin_lock_irqsave(&clock_register_lock, flags); 1104 tegra_periph_clk_enable_refcount[c->u.periph.clk_num]--;
1010 1105
1011 if (c->refcnt) 1106 if (tegra_periph_clk_enable_refcount[c->u.periph.clk_num] > 0)
1012 tegra_periph_clk_enable_refcount[c->u.periph.clk_num]--; 1107 return;
1013 1108
1014 if (tegra_periph_clk_enable_refcount[c->u.periph.clk_num] == 0) 1109 spin_lock_irqsave(&clock_register_lock, flags);
1015 clk_writel(PERIPH_CLK_TO_ENB_BIT(c), 1110
1016 CLK_OUT_ENB_CLR + PERIPH_CLK_TO_ENB_SET_REG(c)); 1111 clk_writel(PERIPH_CLK_TO_ENB_BIT(c),
1112 CLK_OUT_ENB_CLR + PERIPH_CLK_TO_ENB_SET_REG(c));
1017 1113
1018 spin_unlock_irqrestore(&clock_register_lock, flags); 1114 spin_unlock_irqrestore(&clock_register_lock, flags);
1019} 1115}
1020 1116
1021static void tegra2_periph_clk_reset(struct clk *c, bool assert) 1117void tegra2_periph_clk_reset(struct clk_hw *hw, bool assert)
1022{ 1118{
1119 struct clk_tegra *c = to_clk_tegra(hw);
1023 unsigned long base = assert ? RST_DEVICES_SET : RST_DEVICES_CLR; 1120 unsigned long base = assert ? RST_DEVICES_SET : RST_DEVICES_CLR;
1024 1121
1025 pr_debug("%s %s on clock %s\n", __func__, 1122 pr_debug("%s %s on clock %s\n", __func__,
1026 assert ? "assert" : "deassert", c->name); 1123 assert ? "assert" : "deassert", __clk_get_name(hw->clk));
1027 1124
1028 BUG_ON(!c->u.periph.clk_num); 1125 BUG_ON(!c->u.periph.clk_num);
1029 1126
@@ -1032,13 +1129,14 @@ static void tegra2_periph_clk_reset(struct clk *c, bool assert)
1032 base + PERIPH_CLK_TO_ENB_SET_REG(c)); 1129 base + PERIPH_CLK_TO_ENB_SET_REG(c));
1033} 1130}
1034 1131
1035static int tegra2_periph_clk_set_parent(struct clk *c, struct clk *p) 1132static int tegra20_periph_clk_set_parent(struct clk_hw *hw, u8 index)
1036{ 1133{
1134 struct clk_tegra *c = to_clk_tegra(hw);
1037 u32 val; 1135 u32 val;
1038 const struct clk_mux_sel *sel; 1136 u32 mask;
1039 u32 mask, shift; 1137 u32 shift;
1040 1138
1041 pr_debug("%s: %s %s\n", __func__, c->name, p->name); 1139 pr_debug("%s: %s %d\n", __func__, __clk_get_name(hw->clk), index);
1042 1140
1043 if (c->flags & MUX_PWM) { 1141 if (c->flags & MUX_PWM) {
1044 shift = PERIPH_CLK_SOURCE_PWM_SHIFT; 1142 shift = PERIPH_CLK_SOURCE_PWM_SHIFT;
@@ -1048,36 +1146,78 @@ static int tegra2_periph_clk_set_parent(struct clk *c, struct clk *p)
1048 mask = PERIPH_CLK_SOURCE_MASK; 1146 mask = PERIPH_CLK_SOURCE_MASK;
1049 } 1147 }
1050 1148
1051 for (sel = c->inputs; sel->input != NULL; sel++) { 1149 val = clk_readl(c->reg);
1052 if (sel->input == p) { 1150 val &= ~mask;
1053 val = clk_readl(c->reg); 1151 val |= (index) << shift;
1054 val &= ~mask;
1055 val |= (sel->value) << shift;
1056 1152
1057 if (c->refcnt) 1153 clk_writel(val, c->reg);
1058 clk_enable(p);
1059 1154
1060 clk_writel(val, c->reg); 1155 return 0;
1156}
1061 1157
1062 if (c->refcnt && c->parent) 1158static u8 tegra20_periph_clk_get_parent(struct clk_hw *hw)
1063 clk_disable(c->parent); 1159{
1160 struct clk_tegra *c = to_clk_tegra(hw);
1161 u32 val = clk_readl(c->reg);
1162 u32 mask;
1163 u32 shift;
1064 1164
1065 clk_reparent(c, p); 1165 if (c->flags & MUX_PWM) {
1066 return 0; 1166 shift = PERIPH_CLK_SOURCE_PWM_SHIFT;
1067 } 1167 mask = PERIPH_CLK_SOURCE_PWM_MASK;
1168 } else {
1169 shift = PERIPH_CLK_SOURCE_SHIFT;
1170 mask = PERIPH_CLK_SOURCE_MASK;
1068 } 1171 }
1069 1172
1070 return -EINVAL; 1173 if (c->flags & MUX)
1174 return (val & mask) >> shift;
1175 else
1176 return 0;
1071} 1177}
1072 1178
1073static int tegra2_periph_clk_set_rate(struct clk *c, unsigned long rate) 1179static unsigned long tegra20_periph_clk_recalc_rate(struct clk_hw *hw,
1180 unsigned long prate)
1074{ 1181{
1182 struct clk_tegra *c = to_clk_tegra(hw);
1183 unsigned long rate = prate;
1184 u32 val = clk_readl(c->reg);
1185
1186 if (c->flags & DIV_U71) {
1187 u32 divu71 = val & PERIPH_CLK_SOURCE_DIVU71_MASK;
1188 c->div = divu71 + 2;
1189 c->mul = 2;
1190 } else if (c->flags & DIV_U16) {
1191 u32 divu16 = val & PERIPH_CLK_SOURCE_DIVU16_MASK;
1192 c->div = divu16 + 1;
1193 c->mul = 1;
1194 } else {
1195 c->div = 1;
1196 c->mul = 1;
1197 return rate;
1198 }
1199
1200 if (c->mul != 0 && c->div != 0) {
1201 rate *= c->mul;
1202 rate += c->div - 1; /* round up */
1203 do_div(rate, c->div);
1204 }
1205
1206 return rate;
1207}
1208
1209static int tegra20_periph_clk_set_rate(struct clk_hw *hw, unsigned long rate,
1210 unsigned long parent_rate)
1211{
1212 struct clk_tegra *c = to_clk_tegra(hw);
1075 u32 val; 1213 u32 val;
1076 int divider; 1214 int divider;
1077 unsigned long parent_rate = clk_get_rate(c->parent); 1215
1216 val = clk_readl(c->reg);
1078 1217
1079 if (c->flags & DIV_U71) { 1218 if (c->flags & DIV_U71) {
1080 divider = clk_div71_get_divider(parent_rate, rate); 1219 divider = clk_div71_get_divider(parent_rate, rate);
1220
1081 if (divider >= 0) { 1221 if (divider >= 0) {
1082 val = clk_readl(c->reg); 1222 val = clk_readl(c->reg);
1083 val &= ~PERIPH_CLK_SOURCE_DIVU71_MASK; 1223 val &= ~PERIPH_CLK_SOURCE_DIVU71_MASK;
@@ -1103,15 +1243,21 @@ static int tegra2_periph_clk_set_rate(struct clk *c, unsigned long rate)
1103 c->mul = 1; 1243 c->mul = 1;
1104 return 0; 1244 return 0;
1105 } 1245 }
1246
1106 return -EINVAL; 1247 return -EINVAL;
1107} 1248}
1108 1249
1109static long tegra2_periph_clk_round_rate(struct clk *c, 1250static long tegra20_periph_clk_round_rate(struct clk_hw *hw,
1110 unsigned long rate) 1251 unsigned long rate, unsigned long *prate)
1111{ 1252{
1253 struct clk_tegra *c = to_clk_tegra(hw);
1254 unsigned long parent_rate = __clk_get_rate(__clk_get_parent(hw->clk));
1112 int divider; 1255 int divider;
1113 unsigned long parent_rate = clk_get_rate(c->parent); 1256
1114 pr_debug("%s: %s %lu\n", __func__, c->name, rate); 1257 pr_debug("%s: %s %lu\n", __func__, __clk_get_name(hw->clk), rate);
1258
1259 if (prate)
1260 parent_rate = *prate;
1115 1261
1116 if (c->flags & DIV_U71) { 1262 if (c->flags & DIV_U71) {
1117 divider = clk_div71_get_divider(parent_rate, rate); 1263 divider = clk_div71_get_divider(parent_rate, rate);
@@ -1129,44 +1275,27 @@ static long tegra2_periph_clk_round_rate(struct clk *c,
1129} 1275}
1130 1276
1131struct clk_ops tegra_periph_clk_ops = { 1277struct clk_ops tegra_periph_clk_ops = {
1132 .init = &tegra2_periph_clk_init, 1278 .is_enabled = tegra20_periph_clk_is_enabled,
1133 .enable = &tegra2_periph_clk_enable, 1279 .enable = tegra20_periph_clk_enable,
1134 .disable = &tegra2_periph_clk_disable, 1280 .disable = tegra20_periph_clk_disable,
1135 .set_parent = &tegra2_periph_clk_set_parent, 1281 .set_parent = tegra20_periph_clk_set_parent,
1136 .set_rate = &tegra2_periph_clk_set_rate, 1282 .get_parent = tegra20_periph_clk_get_parent,
1137 .round_rate = &tegra2_periph_clk_round_rate, 1283 .set_rate = tegra20_periph_clk_set_rate,
1138 .reset = &tegra2_periph_clk_reset, 1284 .round_rate = tegra20_periph_clk_round_rate,
1285 .recalc_rate = tegra20_periph_clk_recalc_rate,
1139}; 1286};
1140 1287
1141/* The SDMMC controllers have extra bits in the clock source register that
1142 * adjust the delay between the clock and data to compenstate for delays
1143 * on the PCB. */
1144void tegra2_sdmmc_tap_delay(struct clk *c, int delay)
1145{
1146 u32 reg;
1147 unsigned long flags;
1148
1149 spin_lock_irqsave(&c->spinlock, flags);
1150
1151 delay = clamp(delay, 0, 15);
1152 reg = clk_readl(c->reg);
1153 reg &= ~SDMMC_CLK_INT_FB_DLY_MASK;
1154 reg |= SDMMC_CLK_INT_FB_SEL;
1155 reg |= delay << SDMMC_CLK_INT_FB_DLY_SHIFT;
1156 clk_writel(reg, c->reg);
1157
1158 spin_unlock_irqrestore(&c->spinlock, flags);
1159}
1160
1161/* External memory controller clock ops */ 1288/* External memory controller clock ops */
1162static void tegra2_emc_clk_init(struct clk *c) 1289static void tegra20_emc_clk_init(struct clk_hw *hw)
1163{ 1290{
1164 tegra2_periph_clk_init(c); 1291 struct clk_tegra *c = to_clk_tegra(hw);
1165 c->max_rate = clk_get_rate_locked(c); 1292 c->max_rate = __clk_get_rate(hw->clk);
1166} 1293}
1167 1294
1168static long tegra2_emc_clk_round_rate(struct clk *c, unsigned long rate) 1295static long tegra20_emc_clk_round_rate(struct clk_hw *hw, unsigned long rate,
1296 unsigned long *prate)
1169{ 1297{
1298 struct clk_tegra *c = to_clk_tegra(hw);
1170 long emc_rate; 1299 long emc_rate;
1171 long clk_rate; 1300 long clk_rate;
1172 1301
@@ -1182,7 +1311,7 @@ static long tegra2_emc_clk_round_rate(struct clk *c, unsigned long rate)
1182 * The fastest rate the PLL will generate that is at most the 1311 * The fastest rate the PLL will generate that is at most the
1183 * requested rate. 1312 * requested rate.
1184 */ 1313 */
1185 clk_rate = tegra2_periph_clk_round_rate(c, emc_rate); 1314 clk_rate = tegra20_periph_clk_round_rate(hw, emc_rate, NULL);
1186 1315
1187 /* 1316 /*
1188 * If this fails, and emc_rate > clk_rate, it's because the maximum 1317 * If this fails, and emc_rate > clk_rate, it's because the maximum
@@ -1198,9 +1327,11 @@ static long tegra2_emc_clk_round_rate(struct clk *c, unsigned long rate)
1198 return emc_rate; 1327 return emc_rate;
1199} 1328}
1200 1329
1201static int tegra2_emc_clk_set_rate(struct clk *c, unsigned long rate) 1330static int tegra20_emc_clk_set_rate(struct clk_hw *hw, unsigned long rate,
1331 unsigned long parent_rate)
1202{ 1332{
1203 int ret; 1333 int ret;
1334
1204 /* 1335 /*
1205 * The Tegra2 memory controller has an interlock with the clock 1336 * The Tegra2 memory controller has an interlock with the clock
1206 * block that allows memory shadowed registers to be updated, 1337 * block that allows memory shadowed registers to be updated,
@@ -1211,116 +1342,145 @@ static int tegra2_emc_clk_set_rate(struct clk *c, unsigned long rate)
1211 if (ret < 0) 1342 if (ret < 0)
1212 return ret; 1343 return ret;
1213 1344
1214 ret = tegra2_periph_clk_set_rate(c, rate); 1345 ret = tegra20_periph_clk_set_rate(hw, rate, parent_rate);
1215 udelay(1); 1346 udelay(1);
1216 1347
1217 return ret; 1348 return ret;
1218} 1349}
1219 1350
1220struct clk_ops tegra_emc_clk_ops = { 1351struct clk_ops tegra_emc_clk_ops = {
1221 .init = &tegra2_emc_clk_init, 1352 .init = tegra20_emc_clk_init,
1222 .enable = &tegra2_periph_clk_enable, 1353 .is_enabled = tegra20_periph_clk_is_enabled,
1223 .disable = &tegra2_periph_clk_disable, 1354 .enable = tegra20_periph_clk_enable,
1224 .set_parent = &tegra2_periph_clk_set_parent, 1355 .disable = tegra20_periph_clk_disable,
1225 .set_rate = &tegra2_emc_clk_set_rate, 1356 .set_parent = tegra20_periph_clk_set_parent,
1226 .round_rate = &tegra2_emc_clk_round_rate, 1357 .get_parent = tegra20_periph_clk_get_parent,
1227 .reset = &tegra2_periph_clk_reset, 1358 .set_rate = tegra20_emc_clk_set_rate,
1359 .round_rate = tegra20_emc_clk_round_rate,
1360 .recalc_rate = tegra20_periph_clk_recalc_rate,
1228}; 1361};
1229 1362
1230/* Clock doubler ops */ 1363/* Clock doubler ops */
1231static void tegra2_clk_double_init(struct clk *c) 1364static int tegra20_clk_double_is_enabled(struct clk_hw *hw)
1232{ 1365{
1233 c->mul = 2; 1366 struct clk_tegra *c = to_clk_tegra(hw);
1234 c->div = 1; 1367
1235 c->state = ON; 1368 c->state = ON;
1236 1369
1237 if (!c->u.periph.clk_num) 1370 if (!c->u.periph.clk_num)
1238 return; 1371 goto out;
1239 1372
1240 if (!(clk_readl(CLK_OUT_ENB + PERIPH_CLK_TO_ENB_REG(c)) & 1373 if (!(clk_readl(CLK_OUT_ENB + PERIPH_CLK_TO_ENB_REG(c)) &
1241 PERIPH_CLK_TO_ENB_BIT(c))) 1374 PERIPH_CLK_TO_ENB_BIT(c)))
1242 c->state = OFF; 1375 c->state = OFF;
1376
1377out:
1378 return c->state;
1243}; 1379};
1244 1380
1245static int tegra2_clk_double_set_rate(struct clk *c, unsigned long rate) 1381static unsigned long tegra20_clk_double_recalc_rate(struct clk_hw *hw,
1382 unsigned long prate)
1246{ 1383{
1247 if (rate != 2 * clk_get_rate(c->parent)) 1384 struct clk_tegra *c = to_clk_tegra(hw);
1248 return -EINVAL; 1385 u64 rate = prate;
1386
1249 c->mul = 2; 1387 c->mul = 2;
1250 c->div = 1; 1388 c->div = 1;
1389
1390 rate *= c->mul;
1391 rate += c->div - 1; /* round up */
1392 do_div(rate, c->div);
1393
1394 return rate;
1395}
1396
1397static long tegra20_clk_double_round_rate(struct clk_hw *hw, unsigned long rate,
1398 unsigned long *prate)
1399{
1400 unsigned long output_rate = *prate;
1401
1402 do_div(output_rate, 2);
1403 return output_rate;
1404}
1405
1406static int tegra20_clk_double_set_rate(struct clk_hw *hw, unsigned long rate,
1407 unsigned long parent_rate)
1408{
1409 if (rate != 2 * parent_rate)
1410 return -EINVAL;
1251 return 0; 1411 return 0;
1252} 1412}
1253 1413
1254struct clk_ops tegra_clk_double_ops = { 1414struct clk_ops tegra_clk_double_ops = {
1255 .init = &tegra2_clk_double_init, 1415 .is_enabled = tegra20_clk_double_is_enabled,
1256 .enable = &tegra2_periph_clk_enable, 1416 .enable = tegra20_periph_clk_enable,
1257 .disable = &tegra2_periph_clk_disable, 1417 .disable = tegra20_periph_clk_disable,
1258 .set_rate = &tegra2_clk_double_set_rate, 1418 .set_rate = tegra20_clk_double_set_rate,
1419 .recalc_rate = tegra20_clk_double_recalc_rate,
1420 .round_rate = tegra20_clk_double_round_rate,
1259}; 1421};
1260 1422
1261/* Audio sync clock ops */ 1423/* Audio sync clock ops */
1262static void tegra2_audio_sync_clk_init(struct clk *c) 1424static int tegra20_audio_sync_clk_is_enabled(struct clk_hw *hw)
1263{ 1425{
1264 int source; 1426 struct clk_tegra *c = to_clk_tegra(hw);
1265 const struct clk_mux_sel *sel;
1266 u32 val = clk_readl(c->reg); 1427 u32 val = clk_readl(c->reg);
1428
1267 c->state = (val & (1<<4)) ? OFF : ON; 1429 c->state = (val & (1<<4)) ? OFF : ON;
1268 source = val & 0xf; 1430 return c->state;
1269 for (sel = c->inputs; sel->input != NULL; sel++)
1270 if (sel->value == source)
1271 break;
1272 BUG_ON(sel->input == NULL);
1273 c->parent = sel->input;
1274} 1431}
1275 1432
1276static int tegra2_audio_sync_clk_enable(struct clk *c) 1433static int tegra20_audio_sync_clk_enable(struct clk_hw *hw)
1277{ 1434{
1435 struct clk_tegra *c = to_clk_tegra(hw);
1436
1278 clk_writel(0, c->reg); 1437 clk_writel(0, c->reg);
1279 return 0; 1438 return 0;
1280} 1439}
1281 1440
1282static void tegra2_audio_sync_clk_disable(struct clk *c) 1441static void tegra20_audio_sync_clk_disable(struct clk_hw *hw)
1283{ 1442{
1443 struct clk_tegra *c = to_clk_tegra(hw);
1284 clk_writel(1, c->reg); 1444 clk_writel(1, c->reg);
1285} 1445}
1286 1446
1287static int tegra2_audio_sync_clk_set_parent(struct clk *c, struct clk *p) 1447static u8 tegra20_audio_sync_clk_get_parent(struct clk_hw *hw)
1288{ 1448{
1289 u32 val; 1449 struct clk_tegra *c = to_clk_tegra(hw);
1290 const struct clk_mux_sel *sel; 1450 u32 val = clk_readl(c->reg);
1291 for (sel = c->inputs; sel->input != NULL; sel++) { 1451 int source;
1292 if (sel->input == p) {
1293 val = clk_readl(c->reg);
1294 val &= ~0xf;
1295 val |= sel->value;
1296 1452
1297 if (c->refcnt) 1453 source = val & 0xf;
1298 clk_enable(p); 1454 return source;
1455}
1299 1456
1300 clk_writel(val, c->reg); 1457static int tegra20_audio_sync_clk_set_parent(struct clk_hw *hw, u8 index)
1458{
1459 struct clk_tegra *c = to_clk_tegra(hw);
1460 u32 val;
1301 1461
1302 if (c->refcnt && c->parent) 1462 val = clk_readl(c->reg);
1303 clk_disable(c->parent); 1463 val &= ~0xf;
1464 val |= index;
1304 1465
1305 clk_reparent(c, p); 1466 clk_writel(val, c->reg);
1306 return 0;
1307 }
1308 }
1309 1467
1310 return -EINVAL; 1468 return 0;
1311} 1469}
1312 1470
1313struct clk_ops tegra_audio_sync_clk_ops = { 1471struct clk_ops tegra_audio_sync_clk_ops = {
1314 .init = tegra2_audio_sync_clk_init, 1472 .is_enabled = tegra20_audio_sync_clk_is_enabled,
1315 .enable = tegra2_audio_sync_clk_enable, 1473 .enable = tegra20_audio_sync_clk_enable,
1316 .disable = tegra2_audio_sync_clk_disable, 1474 .disable = tegra20_audio_sync_clk_disable,
1317 .set_parent = tegra2_audio_sync_clk_set_parent, 1475 .set_parent = tegra20_audio_sync_clk_set_parent,
1476 .get_parent = tegra20_audio_sync_clk_get_parent,
1318}; 1477};
1319 1478
1320/* cdev1 and cdev2 (dap_mclk1 and dap_mclk2) ops */ 1479/* cdev1 and cdev2 (dap_mclk1 and dap_mclk2) ops */
1321 1480
1322static void tegra2_cdev_clk_init(struct clk *c) 1481static int tegra20_cdev_clk_is_enabled(struct clk_hw *hw)
1323{ 1482{
1483 struct clk_tegra *c = to_clk_tegra(hw);
1324 /* We could un-tristate the cdev1 or cdev2 pingroup here; this is 1484 /* We could un-tristate the cdev1 or cdev2 pingroup here; this is
1325 * currently done in the pinmux code. */ 1485 * currently done in the pinmux code. */
1326 c->state = ON; 1486 c->state = ON;
@@ -1330,10 +1490,12 @@ static void tegra2_cdev_clk_init(struct clk *c)
1330 if (!(clk_readl(CLK_OUT_ENB + PERIPH_CLK_TO_ENB_REG(c)) & 1490 if (!(clk_readl(CLK_OUT_ENB + PERIPH_CLK_TO_ENB_REG(c)) &
1331 PERIPH_CLK_TO_ENB_BIT(c))) 1491 PERIPH_CLK_TO_ENB_BIT(c)))
1332 c->state = OFF; 1492 c->state = OFF;
1493 return c->state;
1333} 1494}
1334 1495
1335static int tegra2_cdev_clk_enable(struct clk *c) 1496static int tegra20_cdev_clk_enable(struct clk_hw *hw)
1336{ 1497{
1498 struct clk_tegra *c = to_clk_tegra(hw);
1337 BUG_ON(!c->u.periph.clk_num); 1499 BUG_ON(!c->u.periph.clk_num);
1338 1500
1339 clk_writel(PERIPH_CLK_TO_ENB_BIT(c), 1501 clk_writel(PERIPH_CLK_TO_ENB_BIT(c),
@@ -1341,118 +1503,24 @@ static int tegra2_cdev_clk_enable(struct clk *c)
1341 return 0; 1503 return 0;
1342} 1504}
1343 1505
1344static void tegra2_cdev_clk_disable(struct clk *c) 1506static void tegra20_cdev_clk_disable(struct clk_hw *hw)
1345{ 1507{
1508 struct clk_tegra *c = to_clk_tegra(hw);
1346 BUG_ON(!c->u.periph.clk_num); 1509 BUG_ON(!c->u.periph.clk_num);
1347 1510
1348 clk_writel(PERIPH_CLK_TO_ENB_BIT(c), 1511 clk_writel(PERIPH_CLK_TO_ENB_BIT(c),
1349 CLK_OUT_ENB_CLR + PERIPH_CLK_TO_ENB_SET_REG(c)); 1512 CLK_OUT_ENB_CLR + PERIPH_CLK_TO_ENB_SET_REG(c));
1350} 1513}
1351 1514
1352struct clk_ops tegra_cdev_clk_ops = { 1515static unsigned long tegra20_cdev_recalc_rate(struct clk_hw *hw,
1353 .init = &tegra2_cdev_clk_init, 1516 unsigned long prate)
1354 .enable = &tegra2_cdev_clk_enable,
1355 .disable = &tegra2_cdev_clk_disable,
1356};
1357
1358/* shared bus ops */
1359/*
1360 * Some clocks may have multiple downstream users that need to request a
1361 * higher clock rate. Shared bus clocks provide a unique shared_bus_user
1362 * clock to each user. The frequency of the bus is set to the highest
1363 * enabled shared_bus_user clock, with a minimum value set by the
1364 * shared bus.
1365 */
1366static int tegra_clk_shared_bus_update(struct clk *bus)
1367{
1368 struct clk *c;
1369 unsigned long rate = bus->min_rate;
1370
1371 list_for_each_entry(c, &bus->shared_bus_list, u.shared_bus_user.node)
1372 if (c->u.shared_bus_user.enabled)
1373 rate = max(c->u.shared_bus_user.rate, rate);
1374
1375 if (rate == clk_get_rate_locked(bus))
1376 return 0;
1377
1378 return clk_set_rate_locked(bus, rate);
1379};
1380
1381static void tegra_clk_shared_bus_init(struct clk *c)
1382{
1383 unsigned long flags;
1384
1385 c->max_rate = c->parent->max_rate;
1386 c->u.shared_bus_user.rate = c->parent->max_rate;
1387 c->state = OFF;
1388 c->set = true;
1389
1390 spin_lock_irqsave(&c->parent->spinlock, flags);
1391
1392 list_add_tail(&c->u.shared_bus_user.node,
1393 &c->parent->shared_bus_list);
1394
1395 spin_unlock_irqrestore(&c->parent->spinlock, flags);
1396}
1397
1398static int tegra_clk_shared_bus_set_rate(struct clk *c, unsigned long rate)
1399{ 1517{
1400 unsigned long flags; 1518 return to_clk_tegra(hw)->fixed_rate;
1401 int ret;
1402 long new_rate = rate;
1403
1404 new_rate = clk_round_rate(c->parent, new_rate);
1405 if (new_rate < 0)
1406 return new_rate;
1407
1408 spin_lock_irqsave(&c->parent->spinlock, flags);
1409
1410 c->u.shared_bus_user.rate = new_rate;
1411 ret = tegra_clk_shared_bus_update(c->parent);
1412
1413 spin_unlock_irqrestore(&c->parent->spinlock, flags);
1414
1415 return ret;
1416}
1417
1418static long tegra_clk_shared_bus_round_rate(struct clk *c, unsigned long rate)
1419{
1420 return clk_round_rate(c->parent, rate);
1421} 1519}
1422 1520
1423static int tegra_clk_shared_bus_enable(struct clk *c) 1521struct clk_ops tegra_cdev_clk_ops = {
1424{ 1522 .is_enabled = tegra20_cdev_clk_is_enabled,
1425 unsigned long flags; 1523 .enable = tegra20_cdev_clk_enable,
1426 int ret; 1524 .disable = tegra20_cdev_clk_disable,
1427 1525 .recalc_rate = tegra20_cdev_recalc_rate,
1428 spin_lock_irqsave(&c->parent->spinlock, flags);
1429
1430 c->u.shared_bus_user.enabled = true;
1431 ret = tegra_clk_shared_bus_update(c->parent);
1432
1433 spin_unlock_irqrestore(&c->parent->spinlock, flags);
1434
1435 return ret;
1436}
1437
1438static void tegra_clk_shared_bus_disable(struct clk *c)
1439{
1440 unsigned long flags;
1441 int ret;
1442
1443 spin_lock_irqsave(&c->parent->spinlock, flags);
1444
1445 c->u.shared_bus_user.enabled = false;
1446 ret = tegra_clk_shared_bus_update(c->parent);
1447 WARN_ON_ONCE(ret);
1448
1449 spin_unlock_irqrestore(&c->parent->spinlock, flags);
1450}
1451
1452struct clk_ops tegra_clk_shared_bus_ops = {
1453 .init = tegra_clk_shared_bus_init,
1454 .enable = tegra_clk_shared_bus_enable,
1455 .disable = tegra_clk_shared_bus_disable,
1456 .set_rate = tegra_clk_shared_bus_set_rate,
1457 .round_rate = tegra_clk_shared_bus_round_rate,
1458}; 1526};