xref: /linux/arch/sh/kernel/cpu/sh2/clock-sh7619.c (revision 9d4436a6fbc8c5eccdfcb8f5884e0a7b4a57f6d2)
1*9d4436a6SYoshinori Sato /*
2*9d4436a6SYoshinori Sato  * arch/sh/kernel/cpu/sh2/clock-sh7619.c
3*9d4436a6SYoshinori Sato  *
4*9d4436a6SYoshinori Sato  * SH7619 support for the clock framework
5*9d4436a6SYoshinori Sato  *
6*9d4436a6SYoshinori Sato  *  Copyright (C) 2006  Yoshinori Sato
7*9d4436a6SYoshinori Sato  *
8*9d4436a6SYoshinori Sato  * Based on clock-sh4.c
9*9d4436a6SYoshinori Sato  *  Copyright (C) 2005  Paul Mundt
10*9d4436a6SYoshinori Sato  *
11*9d4436a6SYoshinori Sato  * This file is subject to the terms and conditions of the GNU General Public
12*9d4436a6SYoshinori Sato  * License.  See the file "COPYING" in the main directory of this archive
13*9d4436a6SYoshinori Sato  * for more details.
14*9d4436a6SYoshinori Sato  */
15*9d4436a6SYoshinori Sato #include <linux/init.h>
16*9d4436a6SYoshinori Sato #include <linux/kernel.h>
17*9d4436a6SYoshinori Sato #include <asm/clock.h>
18*9d4436a6SYoshinori Sato #include <asm/freq.h>
19*9d4436a6SYoshinori Sato #include <asm/io.h>
20*9d4436a6SYoshinori Sato 
21*9d4436a6SYoshinori Sato const static int pll1rate[]={1,2};
22*9d4436a6SYoshinori Sato const static int pfc_divisors[]={1,2,0,4};
23*9d4436a6SYoshinori Sato 
24*9d4436a6SYoshinori Sato #if (CONFIG_SH_CLK_MD == 1) || (CONFIG_SH_CLK_MD == 2)
25*9d4436a6SYoshinori Sato #define PLL2 (4)
26*9d4436a6SYoshinori Sato #elif (CONFIG_SH_CLK_MD == 5) || (CONFIG_SH_CLK_MD == 6)
27*9d4436a6SYoshinori Sato #define PLL2 (2)
28*9d4436a6SYoshinori Sato #else
29*9d4436a6SYoshinori Sato #error "Illigal Clock Mode!"
30*9d4436a6SYoshinori Sato #endif
31*9d4436a6SYoshinori Sato 
32*9d4436a6SYoshinori Sato static void master_clk_init(struct clk *clk)
33*9d4436a6SYoshinori Sato {
34*9d4436a6SYoshinori Sato 	clk->rate *= PLL2 * pll1rate[(ctrl_inw(FREQCR) >> 8) & 7];
35*9d4436a6SYoshinori Sato }
36*9d4436a6SYoshinori Sato 
37*9d4436a6SYoshinori Sato static struct clk_ops sh7619_master_clk_ops = {
38*9d4436a6SYoshinori Sato 	.init		= master_clk_init,
39*9d4436a6SYoshinori Sato };
40*9d4436a6SYoshinori Sato 
41*9d4436a6SYoshinori Sato static void module_clk_recalc(struct clk *clk)
42*9d4436a6SYoshinori Sato {
43*9d4436a6SYoshinori Sato 	int idx = (ctrl_inw(FREQCR) & 0x0007);
44*9d4436a6SYoshinori Sato 	clk->rate = clk->parent->rate / pfc_divisors[idx];
45*9d4436a6SYoshinori Sato }
46*9d4436a6SYoshinori Sato 
47*9d4436a6SYoshinori Sato static struct clk_ops sh7619_module_clk_ops = {
48*9d4436a6SYoshinori Sato 	.recalc		= module_clk_recalc,
49*9d4436a6SYoshinori Sato };
50*9d4436a6SYoshinori Sato 
51*9d4436a6SYoshinori Sato static void bus_clk_recalc(struct clk *clk)
52*9d4436a6SYoshinori Sato {
53*9d4436a6SYoshinori Sato 	clk->rate = clk->parent->rate / pll1rate[(ctrl_inw(FREQCR) >> 8) & 7];
54*9d4436a6SYoshinori Sato }
55*9d4436a6SYoshinori Sato 
56*9d4436a6SYoshinori Sato static struct clk_ops sh7619_bus_clk_ops = {
57*9d4436a6SYoshinori Sato 	.recalc		= bus_clk_recalc,
58*9d4436a6SYoshinori Sato };
59*9d4436a6SYoshinori Sato 
60*9d4436a6SYoshinori Sato static void cpu_clk_recalc(struct clk *clk)
61*9d4436a6SYoshinori Sato {
62*9d4436a6SYoshinori Sato 	clk->rate = clk->parent->rate;
63*9d4436a6SYoshinori Sato }
64*9d4436a6SYoshinori Sato 
65*9d4436a6SYoshinori Sato static struct clk_ops sh7619_cpu_clk_ops = {
66*9d4436a6SYoshinori Sato 	.recalc		= cpu_clk_recalc,
67*9d4436a6SYoshinori Sato };
68*9d4436a6SYoshinori Sato 
69*9d4436a6SYoshinori Sato static struct clk_ops *sh7619_clk_ops[] = {
70*9d4436a6SYoshinori Sato 	&sh7619_master_clk_ops,
71*9d4436a6SYoshinori Sato 	&sh7619_module_clk_ops,
72*9d4436a6SYoshinori Sato 	&sh7619_bus_clk_ops,
73*9d4436a6SYoshinori Sato 	&sh7619_cpu_clk_ops,
74*9d4436a6SYoshinori Sato };
75*9d4436a6SYoshinori Sato 
76*9d4436a6SYoshinori Sato void __init arch_init_clk_ops(struct clk_ops **ops, int idx)
77*9d4436a6SYoshinori Sato {
78*9d4436a6SYoshinori Sato 	if (idx < ARRAY_SIZE(sh7619_clk_ops))
79*9d4436a6SYoshinori Sato 		*ops = sh7619_clk_ops[idx];
80*9d4436a6SYoshinori Sato }
81*9d4436a6SYoshinori Sato 
82