diff options
author | Magnus Damm <damm@igel.co.jp> | 2008-07-17 06:02:23 -0400 |
---|---|---|
committer | Paul Mundt <lethal@linux-sh.org> | 2008-07-28 05:10:36 -0400 |
commit | 1312994c8008d66806d9452c15d50df86a031437 (patch) | |
tree | 47d8fc0e75b16091bb14e3b2309e6203cbcd0ab1 /arch/sh | |
parent | aea167cbb5c9056295109e5e171d27e30e2be5bc (diff) |
sh: Merge sh7343 and sh7722 clock code
This code makes sh7343 share the sh7722 clock code. Instead of just using
the good and very old sh7343 clock implmentation, switch to the new MSTPCR
enabled clock code. SIU clocks are disabled on sh7343 for now.
With this change all SuperH Mobile devices now use the same clock code.
Signed-off-by: Magnus Damm <damm@igel.co.jp>
Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'arch/sh')
-rw-r--r-- | arch/sh/kernel/cpu/sh4a/Makefile | 2 | ||||
-rw-r--r-- | arch/sh/kernel/cpu/sh4a/clock-sh7343.c | 99 | ||||
-rw-r--r-- | arch/sh/kernel/cpu/sh4a/clock-sh7722.c | 70 |
3 files changed, 41 insertions, 130 deletions
diff --git a/arch/sh/kernel/cpu/sh4a/Makefile b/arch/sh/kernel/cpu/sh4a/Makefile index a880e7968750..9381ad8da263 100644 --- a/arch/sh/kernel/cpu/sh4a/Makefile +++ b/arch/sh/kernel/cpu/sh4a/Makefile | |||
@@ -21,7 +21,7 @@ clock-$(CONFIG_CPU_SUBTYPE_SH7763) := clock-sh7763.o | |||
21 | clock-$(CONFIG_CPU_SUBTYPE_SH7770) := clock-sh7770.o | 21 | clock-$(CONFIG_CPU_SUBTYPE_SH7770) := clock-sh7770.o |
22 | clock-$(CONFIG_CPU_SUBTYPE_SH7780) := clock-sh7780.o | 22 | clock-$(CONFIG_CPU_SUBTYPE_SH7780) := clock-sh7780.o |
23 | clock-$(CONFIG_CPU_SUBTYPE_SH7785) := clock-sh7785.o | 23 | clock-$(CONFIG_CPU_SUBTYPE_SH7785) := clock-sh7785.o |
24 | clock-$(CONFIG_CPU_SUBTYPE_SH7343) := clock-sh7343.o | 24 | clock-$(CONFIG_CPU_SUBTYPE_SH7343) := clock-sh7722.o |
25 | clock-$(CONFIG_CPU_SUBTYPE_SH7722) := clock-sh7722.o | 25 | clock-$(CONFIG_CPU_SUBTYPE_SH7722) := clock-sh7722.o |
26 | clock-$(CONFIG_CPU_SUBTYPE_SH7723) := clock-sh7722.o | 26 | clock-$(CONFIG_CPU_SUBTYPE_SH7723) := clock-sh7722.o |
27 | clock-$(CONFIG_CPU_SUBTYPE_SH7366) := clock-sh7722.o | 27 | clock-$(CONFIG_CPU_SUBTYPE_SH7366) := clock-sh7722.o |
diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7343.c b/arch/sh/kernel/cpu/sh4a/clock-sh7343.c deleted file mode 100644 index 7adc4f16e95a..000000000000 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7343.c +++ /dev/null | |||
@@ -1,99 +0,0 @@ | |||
1 | /* | ||
2 | * arch/sh/kernel/cpu/sh4a/clock-sh7343.c | ||
3 | * | ||
4 | * SH7343/SH7722 support for the clock framework | ||
5 | * | ||
6 | * Copyright (C) 2006 Paul Mundt | ||
7 | * | ||
8 | * This file is subject to the terms and conditions of the GNU General Public | ||
9 | * License. See the file "COPYING" in the main directory of this archive | ||
10 | * for more details. | ||
11 | */ | ||
12 | #include <linux/init.h> | ||
13 | #include <linux/kernel.h> | ||
14 | #include <linux/io.h> | ||
15 | #include <asm/clock.h> | ||
16 | #include <asm/freq.h> | ||
17 | |||
18 | /* | ||
19 | * SH7343/SH7722 uses a common set of multipliers and divisors, so this | ||
20 | * is quite simple.. | ||
21 | */ | ||
22 | static int multipliers[] = { 1, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1 }; | ||
23 | static int divisors[] = { 1, 3, 2, 5, 3, 4, 5, 6, 8, 10, 12, 16, 20 }; | ||
24 | |||
25 | #define pll_calc() (((ctrl_inl(FRQCR) >> 24) & 0x1f) + 1) | ||
26 | |||
27 | static void master_clk_init(struct clk *clk) | ||
28 | { | ||
29 | clk->parent = clk_get(NULL, "cpu_clk"); | ||
30 | } | ||
31 | |||
32 | static void master_clk_recalc(struct clk *clk) | ||
33 | { | ||
34 | int idx = (ctrl_inl(FRQCR) & 0x000f); | ||
35 | clk->rate *= clk->parent->rate * multipliers[idx] / divisors[idx]; | ||
36 | } | ||
37 | |||
38 | static struct clk_ops sh7343_master_clk_ops = { | ||
39 | .init = master_clk_init, | ||
40 | .recalc = master_clk_recalc, | ||
41 | }; | ||
42 | |||
43 | static void module_clk_init(struct clk *clk) | ||
44 | { | ||
45 | clk->parent = NULL; | ||
46 | clk->rate = CONFIG_SH_PCLK_FREQ; | ||
47 | } | ||
48 | |||
49 | static struct clk_ops sh7343_module_clk_ops = { | ||
50 | .init = module_clk_init, | ||
51 | }; | ||
52 | |||
53 | static void bus_clk_init(struct clk *clk) | ||
54 | { | ||
55 | clk->parent = clk_get(NULL, "cpu_clk"); | ||
56 | } | ||
57 | |||
58 | static void bus_clk_recalc(struct clk *clk) | ||
59 | { | ||
60 | int idx = (ctrl_inl(FRQCR) >> 8) & 0x000f; | ||
61 | clk->rate = clk->parent->rate * multipliers[idx] / divisors[idx]; | ||
62 | } | ||
63 | |||
64 | static struct clk_ops sh7343_bus_clk_ops = { | ||
65 | .init = bus_clk_init, | ||
66 | .recalc = bus_clk_recalc, | ||
67 | }; | ||
68 | |||
69 | static void cpu_clk_init(struct clk *clk) | ||
70 | { | ||
71 | clk->parent = clk_get(NULL, "module_clk"); | ||
72 | clk->flags |= CLK_RATE_PROPAGATES; | ||
73 | clk_set_rate(clk, clk_get_rate(clk)); | ||
74 | } | ||
75 | |||
76 | static void cpu_clk_recalc(struct clk *clk) | ||
77 | { | ||
78 | int idx = (ctrl_inl(FRQCR) >> 20) & 0x000f; | ||
79 | clk->rate = clk->parent->rate * pll_calc() * | ||
80 | multipliers[idx] / divisors[idx]; | ||
81 | } | ||
82 | |||
83 | static struct clk_ops sh7343_cpu_clk_ops = { | ||
84 | .init = cpu_clk_init, | ||
85 | .recalc = cpu_clk_recalc, | ||
86 | }; | ||
87 | |||
88 | static struct clk_ops *sh7343_clk_ops[] = { | ||
89 | &sh7343_master_clk_ops, | ||
90 | &sh7343_module_clk_ops, | ||
91 | &sh7343_bus_clk_ops, | ||
92 | &sh7343_cpu_clk_ops, | ||
93 | }; | ||
94 | |||
95 | void __init arch_init_clk_ops(struct clk_ops **ops, int idx) | ||
96 | { | ||
97 | if (idx < ARRAY_SIZE(sh7343_clk_ops)) | ||
98 | *ops = sh7343_clk_ops[idx]; | ||
99 | } | ||
diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7722.c b/arch/sh/kernel/cpu/sh4a/clock-sh7722.c index 2f50f8a1f878..db913855c2fd 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7722.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7722.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * arch/sh/kernel/cpu/sh4a/clock-sh7722.c | 2 | * arch/sh/kernel/cpu/sh4a/clock-sh7722.c |
3 | * | 3 | * |
4 | * SH7722 & SH7366 support for the clock framework | 4 | * SH7343, SH7722, SH7723 & SH7366 support for the clock framework |
5 | * | 5 | * |
6 | * Copyright (c) 2006-2007 Nomad Global Solutions Inc | 6 | * Copyright (c) 2006-2007 Nomad Global Solutions Inc |
7 | * Based on code for sh7343 by Paul Mundt | 7 | * Based on code for sh7343 by Paul Mundt |
@@ -413,6 +413,30 @@ static struct clk_ops sh7722_frqcr_clk_ops = { | |||
413 | * | 413 | * |
414 | */ | 414 | */ |
415 | 415 | ||
416 | #ifndef CONFIG_CPU_SUBTYPE_SH7343 | ||
417 | |||
418 | static int sh7722_siu_set_rate(struct clk *clk, unsigned long rate, int algo_id) | ||
419 | { | ||
420 | unsigned long r; | ||
421 | int div; | ||
422 | |||
423 | r = ctrl_inl(clk->arch_flags); | ||
424 | div = sh7722_find_divisors(clk->parent->rate, rate); | ||
425 | if (div < 0) | ||
426 | return div; | ||
427 | r = (r & ~0xF) | div; | ||
428 | ctrl_outl(r, clk->arch_flags); | ||
429 | return 0; | ||
430 | } | ||
431 | |||
432 | static void sh7722_siu_recalc(struct clk *clk) | ||
433 | { | ||
434 | unsigned long r; | ||
435 | |||
436 | r = ctrl_inl(clk->arch_flags); | ||
437 | clk->rate = clk->parent->rate * 2 / divisors2[r & 0xF]; | ||
438 | } | ||
439 | |||
416 | static int sh7722_siu_start_stop(struct clk *clk, int enable) | 440 | static int sh7722_siu_start_stop(struct clk *clk, int enable) |
417 | { | 441 | { |
418 | unsigned long r; | 442 | unsigned long r; |
@@ -435,6 +459,15 @@ static void sh7722_siu_disable(struct clk *clk) | |||
435 | sh7722_siu_start_stop(clk, 0); | 459 | sh7722_siu_start_stop(clk, 0); |
436 | } | 460 | } |
437 | 461 | ||
462 | static struct clk_ops sh7722_siu_clk_ops = { | ||
463 | .recalc = sh7722_siu_recalc, | ||
464 | .set_rate = sh7722_siu_set_rate, | ||
465 | .enable = sh7722_siu_enable, | ||
466 | .disable = sh7722_siu_disable, | ||
467 | }; | ||
468 | |||
469 | #endif /* CONFIG_CPU_SUBTYPE_SH7343 */ | ||
470 | |||
438 | static void sh7722_video_enable(struct clk *clk) | 471 | static void sh7722_video_enable(struct clk *clk) |
439 | { | 472 | { |
440 | unsigned long r; | 473 | unsigned long r; |
@@ -471,35 +504,6 @@ static void sh7722_video_recalc(struct clk *clk) | |||
471 | clk->rate = clk->parent->rate / ((r & 0x3F) + 1); | 504 | clk->rate = clk->parent->rate / ((r & 0x3F) + 1); |
472 | } | 505 | } |
473 | 506 | ||
474 | static int sh7722_siu_set_rate(struct clk *clk, unsigned long rate, int algo_id) | ||
475 | { | ||
476 | unsigned long r; | ||
477 | int div; | ||
478 | |||
479 | r = ctrl_inl(clk->arch_flags); | ||
480 | div = sh7722_find_divisors(clk->parent->rate, rate); | ||
481 | if (div < 0) | ||
482 | return div; | ||
483 | r = (r & ~0xF) | div; | ||
484 | ctrl_outl(r, clk->arch_flags); | ||
485 | return 0; | ||
486 | } | ||
487 | |||
488 | static void sh7722_siu_recalc(struct clk *clk) | ||
489 | { | ||
490 | unsigned long r; | ||
491 | |||
492 | r = ctrl_inl(clk->arch_flags); | ||
493 | clk->rate = clk->parent->rate * 2 / divisors2[r & 0xF]; | ||
494 | } | ||
495 | |||
496 | static struct clk_ops sh7722_siu_clk_ops = { | ||
497 | .recalc = sh7722_siu_recalc, | ||
498 | .set_rate = sh7722_siu_set_rate, | ||
499 | .enable = sh7722_siu_enable, | ||
500 | .disable = sh7722_siu_disable, | ||
501 | }; | ||
502 | |||
503 | static struct clk_ops sh7722_video_clk_ops = { | 507 | static struct clk_ops sh7722_video_clk_ops = { |
504 | .recalc = sh7722_video_recalc, | 508 | .recalc = sh7722_video_recalc, |
505 | .set_rate = sh7722_video_set_rate, | 509 | .set_rate = sh7722_video_set_rate, |
@@ -529,6 +533,9 @@ static struct clk sh7722_sdram_clock = { | |||
529 | .ops = &sh7722_frqcr_clk_ops, | 533 | .ops = &sh7722_frqcr_clk_ops, |
530 | }; | 534 | }; |
531 | 535 | ||
536 | |||
537 | #ifndef CONFIG_CPU_SUBTYPE_SH7343 | ||
538 | |||
532 | /* | 539 | /* |
533 | * these three clocks - SIU A, SIU B, IrDA - share the same clk_ops | 540 | * these three clocks - SIU A, SIU B, IrDA - share the same clk_ops |
534 | * methods of clk_ops determine which register they should access by | 541 | * methods of clk_ops determine which register they should access by |
@@ -553,6 +560,7 @@ static struct clk sh7722_irda_clock = { | |||
553 | .ops = &sh7722_siu_clk_ops, | 560 | .ops = &sh7722_siu_clk_ops, |
554 | }; | 561 | }; |
555 | #endif | 562 | #endif |
563 | #endif /* CONFIG_CPU_SUBTYPE_SH7343 */ | ||
556 | 564 | ||
557 | static struct clk sh7722_video_clock = { | 565 | static struct clk sh7722_video_clock = { |
558 | .name = "video_clk", | 566 | .name = "video_clk", |
@@ -673,11 +681,13 @@ static struct clk *sh7722_clocks[] = { | |||
673 | &sh7722_sh_clock, | 681 | &sh7722_sh_clock, |
674 | &sh7722_peripheral_clock, | 682 | &sh7722_peripheral_clock, |
675 | &sh7722_sdram_clock, | 683 | &sh7722_sdram_clock, |
684 | #ifndef CONFIG_CPU_SUBTYPE_SH7343 | ||
676 | &sh7722_siu_a_clock, | 685 | &sh7722_siu_a_clock, |
677 | &sh7722_siu_b_clock, | 686 | &sh7722_siu_b_clock, |
678 | #if defined(CONFIG_CPU_SUBTYPE_SH7722) | 687 | #if defined(CONFIG_CPU_SUBTYPE_SH7722) |
679 | &sh7722_irda_clock, | 688 | &sh7722_irda_clock, |
680 | #endif | 689 | #endif |
690 | #endif | ||
681 | &sh7722_video_clock, | 691 | &sh7722_video_clock, |
682 | }; | 692 | }; |
683 | 693 | ||