2 * arch/sh/kernel/cpu/sh4a/clock-sh7786.c
4 * SH7786 support for the clock framework
6 * Copyright (C) 2008, 2009 Renesas Solutions Corp.
7 * Kuninori Morimoto <morimoto.kuninori@renesas.com>
10 * Copyright (C) 2007 Paul Mundt
12 * This file is subject to the terms and conditions of the GNU General Public
13 * License. See the file "COPYING" in the main directory of this archive
16 #include <linux/init.h>
17 #include <linux/kernel.h>
18 #include <asm/clock.h>
22 static int ifc_divisors
[] = { 1, 2, 4, 1 };
23 static int sfc_divisors
[] = { 1, 1, 4, 1 };
24 static int bfc_divisors
[] = { 1, 1, 1, 1, 1, 12, 16, 1,
25 24, 32, 1, 1, 1, 1, 1, 1 };
26 static int mfc_divisors
[] = { 1, 1, 4, 1 };
27 static int pfc_divisors
[] = { 1, 1, 1, 1, 1, 1, 16, 1,
28 24, 32, 1, 48, 1, 1, 1, 1 };
30 static void master_clk_init(struct clk
*clk
)
32 clk
->rate
*= pfc_divisors
[ctrl_inl(FRQMR1
) & 0x000f];
35 static struct clk_ops sh7786_master_clk_ops
= {
36 .init
= master_clk_init
,
39 static unsigned long module_clk_recalc(struct clk
*clk
)
41 int idx
= (ctrl_inl(FRQMR1
) & 0x000f);
42 return clk
->parent
->rate
/ pfc_divisors
[idx
];
45 static struct clk_ops sh7786_module_clk_ops
= {
46 .recalc
= module_clk_recalc
,
49 static unsigned long bus_clk_recalc(struct clk
*clk
)
51 int idx
= ((ctrl_inl(FRQMR1
) >> 16) & 0x000f);
52 return clk
->parent
->rate
/ bfc_divisors
[idx
];
55 static struct clk_ops sh7786_bus_clk_ops
= {
56 .recalc
= bus_clk_recalc
,
59 static unsigned long cpu_clk_recalc(struct clk
*clk
)
61 int idx
= ((ctrl_inl(FRQMR1
) >> 28) & 0x0003);
62 return clk
->parent
->rate
/ ifc_divisors
[idx
];
65 static struct clk_ops sh7786_cpu_clk_ops
= {
66 .recalc
= cpu_clk_recalc
,
69 static struct clk_ops
*sh7786_clk_ops
[] = {
70 &sh7786_master_clk_ops
,
71 &sh7786_module_clk_ops
,
76 void __init
arch_init_clk_ops(struct clk_ops
**ops
, int idx
)
78 if (idx
< ARRAY_SIZE(sh7786_clk_ops
))
79 *ops
= sh7786_clk_ops
[idx
];
82 static unsigned long shyway_clk_recalc(struct clk
*clk
)
84 int idx
= ((ctrl_inl(FRQMR1
) >> 20) & 0x0003);
85 return clk
->parent
->rate
/ sfc_divisors
[idx
];
88 static struct clk_ops sh7786_shyway_clk_ops
= {
89 .recalc
= shyway_clk_recalc
,
92 static struct clk sh7786_shyway_clk
= {
94 .flags
= CLK_ENABLE_ON_INIT
,
95 .ops
= &sh7786_shyway_clk_ops
,
98 static unsigned long ddr_clk_recalc(struct clk
*clk
)
100 int idx
= ((ctrl_inl(FRQMR1
) >> 12) & 0x0003);
101 return clk
->parent
->rate
/ mfc_divisors
[idx
];
104 static struct clk_ops sh7786_ddr_clk_ops
= {
105 .recalc
= ddr_clk_recalc
,
108 static struct clk sh7786_ddr_clk
= {
110 .flags
= CLK_ENABLE_ON_INIT
,
111 .ops
= &sh7786_ddr_clk_ops
,
115 * Additional SH7786-specific on-chip clocks that aren't already part of the
118 static struct clk
*sh7786_onchip_clocks
[] = {
123 int __init
arch_clk_init(void)
130 clk
= clk_get(NULL
, "master_clk");
131 for (i
= 0; i
< ARRAY_SIZE(sh7786_onchip_clocks
); i
++) {
132 struct clk
*clkp
= sh7786_onchip_clocks
[i
];
135 ret
|= clk_register(clkp
);