aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sh
diff options
context:
space:
mode:
authorMagnus Damm <damm@igel.co.jp>2008-07-17 06:02:23 -0400
committerPaul Mundt <lethal@linux-sh.org>2008-07-28 05:10:36 -0400
commit1312994c8008d66806d9452c15d50df86a031437 (patch)
tree47d8fc0e75b16091bb14e3b2309e6203cbcd0ab1 /arch/sh
parentaea167cbb5c9056295109e5e171d27e30e2be5bc (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/Makefile2
-rw-r--r--arch/sh/kernel/cpu/sh4a/clock-sh7343.c99
-rw-r--r--arch/sh/kernel/cpu/sh4a/clock-sh7722.c70
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
21clock-$(CONFIG_CPU_SUBTYPE_SH7770) := clock-sh7770.o 21clock-$(CONFIG_CPU_SUBTYPE_SH7770) := clock-sh7770.o
22clock-$(CONFIG_CPU_SUBTYPE_SH7780) := clock-sh7780.o 22clock-$(CONFIG_CPU_SUBTYPE_SH7780) := clock-sh7780.o
23clock-$(CONFIG_CPU_SUBTYPE_SH7785) := clock-sh7785.o 23clock-$(CONFIG_CPU_SUBTYPE_SH7785) := clock-sh7785.o
24clock-$(CONFIG_CPU_SUBTYPE_SH7343) := clock-sh7343.o 24clock-$(CONFIG_CPU_SUBTYPE_SH7343) := clock-sh7722.o
25clock-$(CONFIG_CPU_SUBTYPE_SH7722) := clock-sh7722.o 25clock-$(CONFIG_CPU_SUBTYPE_SH7722) := clock-sh7722.o
26clock-$(CONFIG_CPU_SUBTYPE_SH7723) := clock-sh7722.o 26clock-$(CONFIG_CPU_SUBTYPE_SH7723) := clock-sh7722.o
27clock-$(CONFIG_CPU_SUBTYPE_SH7366) := clock-sh7722.o 27clock-$(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 */
22static int multipliers[] = { 1, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
23static 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
27static void master_clk_init(struct clk *clk)
28{
29 clk->parent = clk_get(NULL, "cpu_clk");
30}
31
32static 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
38static struct clk_ops sh7343_master_clk_ops = {
39 .init = master_clk_init,
40 .recalc = master_clk_recalc,
41};
42
43static void module_clk_init(struct clk *clk)
44{
45 clk->parent = NULL;
46 clk->rate = CONFIG_SH_PCLK_FREQ;
47}
48
49static struct clk_ops sh7343_module_clk_ops = {
50 .init = module_clk_init,
51};
52
53static void bus_clk_init(struct clk *clk)
54{
55 clk->parent = clk_get(NULL, "cpu_clk");
56}
57
58static 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
64static struct clk_ops sh7343_bus_clk_ops = {
65 .init = bus_clk_init,
66 .recalc = bus_clk_recalc,
67};
68
69static 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
76static 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
83static struct clk_ops sh7343_cpu_clk_ops = {
84 .init = cpu_clk_init,
85 .recalc = cpu_clk_recalc,
86};
87
88static 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
95void __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
418static 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
432static 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
416static int sh7722_siu_start_stop(struct clk *clk, int enable) 440static 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
462static 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
438static void sh7722_video_enable(struct clk *clk) 471static 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
474static 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
488static 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
496static 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
503static struct clk_ops sh7722_video_clk_ops = { 507static 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
557static struct clk sh7722_video_clock = { 565static 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