Commit | Line | Data |
---|---|---|
fea88a0c NI |
1 | /* |
2 | * arch/sh/kernel/cpu/sh4a/clock-sh7734.c | |
3 | * | |
4 | * Clock framework for SH7734 | |
5 | * | |
6 | * Copyright (C) 2011, 2012 Nobuhiro Iwamatsu <nobuhiro.iwamatsu.yj@renesas.com> | |
7 | * Copyright (C) 2011, 2012 Renesas Solutions Corp. | |
8 | * | |
9 | * This file is subject to the terms and conditions of the GNU General Public | |
10 | * License. See the file "COPYING" in the main directory of this archive | |
11 | * for more details. | |
12 | */ | |
13 | ||
14 | #include <linux/init.h> | |
15 | #include <linux/kernel.h> | |
16 | #include <linux/io.h> | |
17 | #include <linux/clkdev.h> | |
18 | #include <linux/delay.h> | |
19 | #include <asm/clock.h> | |
20 | #include <asm/freq.h> | |
21 | ||
22 | static struct clk extal_clk = { | |
23 | .rate = 33333333, | |
24 | }; | |
25 | ||
26 | #define MODEMR (0xFFCC0020) | |
27 | #define MODEMR_MASK (0x6) | |
28 | #define MODEMR_533MHZ (0x2) | |
29 | ||
30 | static unsigned long pll_recalc(struct clk *clk) | |
31 | { | |
32 | int mode = 12; | |
33 | u32 r = __raw_readl(MODEMR); | |
34 | ||
35 | if ((r & MODEMR_MASK) & MODEMR_533MHZ) | |
36 | mode = 16; | |
37 | ||
38 | return clk->parent->rate * mode; | |
39 | } | |
40 | ||
41 | static struct sh_clk_ops pll_clk_ops = { | |
42 | .recalc = pll_recalc, | |
43 | }; | |
44 | ||
45 | static struct clk pll_clk = { | |
46 | .ops = &pll_clk_ops, | |
47 | .parent = &extal_clk, | |
48 | .flags = CLK_ENABLE_ON_INIT, | |
49 | }; | |
50 | ||
51 | static struct clk *main_clks[] = { | |
52 | &extal_clk, | |
53 | &pll_clk, | |
54 | }; | |
55 | ||
56 | static int multipliers[] = { 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }; | |
57 | static int divisors[] = { 1, 3, 2, 3, 4, 6, 8, 9, 12, 16, 18, 24 }; | |
58 | ||
59 | static struct clk_div_mult_table div4_div_mult_table = { | |
60 | .divisors = divisors, | |
61 | .nr_divisors = ARRAY_SIZE(divisors), | |
62 | .multipliers = multipliers, | |
63 | .nr_multipliers = ARRAY_SIZE(multipliers), | |
64 | }; | |
65 | ||
66 | static struct clk_div4_table div4_table = { | |
67 | .div_mult_table = &div4_div_mult_table, | |
68 | }; | |
69 | ||
70 | enum { DIV4_I, DIV4_S, DIV4_B, DIV4_M, DIV4_S1, DIV4_P, DIV4_NR }; | |
71 | ||
72 | #define DIV4(_reg, _bit, _mask, _flags) \ | |
73 | SH_CLK_DIV4(&pll_clk, _reg, _bit, _mask, _flags) | |
74 | ||
75 | struct clk div4_clks[DIV4_NR] = { | |
76 | [DIV4_I] = DIV4(FRQMR1, 28, 0x0003, CLK_ENABLE_ON_INIT), | |
77 | [DIV4_S] = DIV4(FRQMR1, 20, 0x000C, CLK_ENABLE_ON_INIT), | |
78 | [DIV4_B] = DIV4(FRQMR1, 16, 0x0140, CLK_ENABLE_ON_INIT), | |
79 | [DIV4_M] = DIV4(FRQMR1, 12, 0x0004, CLK_ENABLE_ON_INIT), | |
80 | [DIV4_S1] = DIV4(FRQMR1, 4, 0x0030, CLK_ENABLE_ON_INIT), | |
81 | [DIV4_P] = DIV4(FRQMR1, 0, 0x0140, CLK_ENABLE_ON_INIT), | |
82 | }; | |
83 | ||
84 | #define MSTPCR0 0xFFC80030 | |
85 | #define MSTPCR1 0xFFC80034 | |
86 | #define MSTPCR3 0xFFC8003C | |
87 | ||
88 | enum { | |
89 | MSTP030, MSTP029, /* IIC */ | |
90 | MSTP026, MSTP025, MSTP024, /* SCIF */ | |
91 | MSTP023, | |
92 | MSTP022, MSTP021, | |
93 | MSTP019, /* HSCIF */ | |
94 | MSTP016, MSTP015, MSTP014, /* TMU / TIMER */ | |
95 | MSTP012, MSTP011, MSTP010, MSTP009, MSTP008, /* SSI */ | |
96 | MSTP007, /* HSPI */ | |
97 | MSTP115, /* ADMAC */ | |
98 | MSTP114, /* GETHER */ | |
99 | MSTP111, /* DMAC */ | |
100 | MSTP109, /* VIDEOIN1 */ | |
101 | MSTP108, /* VIDEOIN0 */ | |
102 | MSTP107, /* RGPVBG */ | |
103 | MSTP106, /* 2DG */ | |
104 | MSTP103, /* VIEW */ | |
105 | MSTP100, /* USB */ | |
106 | MSTP331, /* MMC */ | |
107 | MSTP330, /* MIMLB */ | |
108 | MSTP323, /* SDHI0 */ | |
109 | MSTP322, /* SDHI1 */ | |
110 | MSTP321, /* SDHI2 */ | |
111 | MSTP320, /* RQSPI */ | |
112 | MSTP319, /* SRC0 */ | |
113 | MSTP318, /* SRC1 */ | |
114 | MSTP317, /* RSPI */ | |
115 | MSTP316, /* RCAN0 */ | |
116 | MSTP315, /* RCAN1 */ | |
117 | MSTP314, /* FLTCL */ | |
118 | MSTP313, /* ADC */ | |
119 | MSTP312, /* MTU */ | |
120 | MSTP304, /* IE-BUS */ | |
121 | MSTP303, /* RTC */ | |
122 | MSTP302, /* HIF */ | |
123 | MSTP301, /* STIF0 */ | |
124 | MSTP300, /* STIF1 */ | |
125 | MSTP_NR }; | |
126 | ||
127 | static struct clk mstp_clks[MSTP_NR] = { | |
128 | /* MSTPCR0 */ | |
129 | [MSTP030] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 30, 0), | |
130 | [MSTP029] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 29, 0), | |
131 | [MSTP026] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 26, 0), | |
132 | [MSTP025] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 25, 0), | |
133 | [MSTP024] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 24, 0), | |
134 | [MSTP023] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 23, 0), | |
135 | [MSTP022] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 22, 0), | |
136 | [MSTP021] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 21, 0), | |
137 | [MSTP019] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 19, 0), | |
138 | [MSTP016] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 16, 0), | |
139 | [MSTP015] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 15, 0), | |
140 | [MSTP014] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 14, 0), | |
141 | [MSTP012] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 12, 0), | |
142 | [MSTP011] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 11, 0), | |
143 | [MSTP010] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 10, 0), | |
144 | [MSTP009] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 9, 0), | |
145 | [MSTP008] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 8, 0), | |
146 | [MSTP007] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 7, 0), | |
147 | ||
148 | /* MSTPCR1 */ | |
149 | [MSTP115] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR1, 15, 0), | |
150 | [MSTP114] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR1, 14, 0), | |
151 | [MSTP111] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR1, 11, 0), | |
152 | [MSTP109] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR1, 9, 0), | |
153 | [MSTP108] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR1, 8, 0), | |
154 | [MSTP107] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR1, 7, 0), | |
155 | [MSTP106] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR1, 6, 0), | |
156 | [MSTP103] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR1, 3, 0), | |
157 | [MSTP100] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR1, 0, 0), | |
158 | ||
159 | /* MSTPCR3 */ | |
160 | [MSTP331] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR3, 31, 0), | |
161 | [MSTP330] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR3, 30, 0), | |
162 | [MSTP323] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR3, 23, 0), | |
163 | [MSTP322] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR3, 22, 0), | |
164 | [MSTP321] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR3, 21, 0), | |
165 | [MSTP320] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR3, 20, 0), | |
166 | [MSTP319] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR3, 19, 0), | |
167 | [MSTP318] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR3, 18, 0), | |
168 | [MSTP317] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR3, 17, 0), | |
169 | [MSTP316] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR3, 16, 0), | |
170 | [MSTP315] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR3, 15, 0), | |
171 | [MSTP314] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR3, 14, 0), | |
172 | [MSTP313] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR3, 13, 0), | |
173 | [MSTP312] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR3, 12, 0), | |
174 | [MSTP304] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR3, 4, 0), | |
175 | [MSTP303] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR3, 3, 0), | |
176 | [MSTP302] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR3, 2, 0), | |
177 | [MSTP301] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR3, 1, 0), | |
178 | [MSTP300] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR3, 0, 0), | |
179 | }; | |
180 | ||
181 | static struct clk_lookup lookups[] = { | |
182 | /* main clocks */ | |
183 | CLKDEV_CON_ID("extal", &extal_clk), | |
184 | CLKDEV_CON_ID("pll_clk", &pll_clk), | |
185 | ||
186 | /* clocks */ | |
187 | CLKDEV_CON_ID("cpu_clk", &div4_clks[DIV4_I]), | |
188 | CLKDEV_CON_ID("shyway_clk", &div4_clks[DIV4_S]), | |
189 | CLKDEV_CON_ID("ddr_clk", &div4_clks[DIV4_M]), | |
190 | CLKDEV_CON_ID("bus_clk", &div4_clks[DIV4_B]), | |
191 | CLKDEV_CON_ID("shyway_clk1", &div4_clks[DIV4_S1]), | |
192 | CLKDEV_CON_ID("peripheral_clk", &div4_clks[DIV4_P]), | |
193 | ||
194 | /* MSTP32 clocks */ | |
195 | CLKDEV_DEV_ID("i2c-sh7734.0", &mstp_clks[MSTP030]), | |
196 | CLKDEV_DEV_ID("i2c-sh7734.1", &mstp_clks[MSTP029]), | |
197 | CLKDEV_ICK_ID("sci_fck", "sh-sci.0", &mstp_clks[MSTP026]), | |
198 | CLKDEV_ICK_ID("sci_fck", "sh-sci.1", &mstp_clks[MSTP025]), | |
199 | CLKDEV_ICK_ID("sci_fck", "sh-sci.2", &mstp_clks[MSTP024]), | |
200 | CLKDEV_ICK_ID("sci_fck", "sh-sci.3", &mstp_clks[MSTP023]), | |
201 | CLKDEV_ICK_ID("sci_fck", "sh-sci.4", &mstp_clks[MSTP022]), | |
202 | CLKDEV_ICK_ID("sci_fck", "sh-sci.5", &mstp_clks[MSTP021]), | |
203 | CLKDEV_CON_ID("hscif", &mstp_clks[MSTP019]), | |
204 | CLKDEV_ICK_ID("tmu_fck", "sh_tmu.0", &mstp_clks[MSTP016]), | |
205 | CLKDEV_ICK_ID("tmu_fck", "sh_tmu.1", &mstp_clks[MSTP016]), | |
206 | CLKDEV_ICK_ID("tmu_fck", "sh_tmu.2", &mstp_clks[MSTP016]), | |
207 | CLKDEV_ICK_ID("tmu_fck", "sh_tmu.3", &mstp_clks[MSTP015]), | |
208 | CLKDEV_ICK_ID("tmu_fck", "sh_tmu.4", &mstp_clks[MSTP015]), | |
209 | CLKDEV_ICK_ID("tmu_fck", "sh_tmu.5", &mstp_clks[MSTP015]), | |
210 | CLKDEV_ICK_ID("tmu_fck", "sh_tmu.6", &mstp_clks[MSTP014]), | |
211 | CLKDEV_ICK_ID("tmu_fck", "sh_tmu.7", &mstp_clks[MSTP014]), | |
212 | CLKDEV_ICK_ID("tmu_fck", "sh_tmu.8", &mstp_clks[MSTP014]), | |
213 | CLKDEV_CON_ID("ssi0", &mstp_clks[MSTP012]), | |
214 | CLKDEV_CON_ID("ssi1", &mstp_clks[MSTP011]), | |
215 | CLKDEV_CON_ID("ssi2", &mstp_clks[MSTP010]), | |
216 | CLKDEV_CON_ID("ssi3", &mstp_clks[MSTP009]), | |
217 | CLKDEV_CON_ID("sss", &mstp_clks[MSTP008]), | |
218 | CLKDEV_CON_ID("hspi", &mstp_clks[MSTP007]), | |
219 | CLKDEV_CON_ID("usb_fck", &mstp_clks[MSTP100]), | |
220 | CLKDEV_CON_ID("videoin0", &mstp_clks[MSTP109]), | |
221 | CLKDEV_CON_ID("videoin1", &mstp_clks[MSTP108]), | |
222 | CLKDEV_CON_ID("rgpvg", &mstp_clks[MSTP107]), | |
223 | CLKDEV_CON_ID("2dg", &mstp_clks[MSTP106]), | |
224 | CLKDEV_CON_ID("view", &mstp_clks[MSTP103]), | |
225 | ||
226 | CLKDEV_CON_ID("mmc0", &mstp_clks[MSTP331]), | |
227 | CLKDEV_CON_ID("mimlb0", &mstp_clks[MSTP330]), | |
228 | CLKDEV_CON_ID("sdhi0", &mstp_clks[MSTP323]), | |
229 | CLKDEV_CON_ID("sdhi1", &mstp_clks[MSTP322]), | |
230 | CLKDEV_CON_ID("sdhi2", &mstp_clks[MSTP321]), | |
231 | CLKDEV_CON_ID("rqspi0", &mstp_clks[MSTP320]), | |
232 | CLKDEV_CON_ID("src0", &mstp_clks[MSTP319]), | |
233 | CLKDEV_CON_ID("src1", &mstp_clks[MSTP318]), | |
234 | CLKDEV_CON_ID("rsp0", &mstp_clks[MSTP317]), | |
235 | CLKDEV_CON_ID("rcan0", &mstp_clks[MSTP316]), | |
236 | CLKDEV_CON_ID("rcan1", &mstp_clks[MSTP315]), | |
237 | CLKDEV_CON_ID("fltcl0", &mstp_clks[MSTP314]), | |
238 | CLKDEV_CON_ID("adc0", &mstp_clks[MSTP313]), | |
239 | CLKDEV_CON_ID("mtu0", &mstp_clks[MSTP312]), | |
240 | CLKDEV_CON_ID("iebus0", &mstp_clks[MSTP304]), | |
241 | CLKDEV_DEV_ID("sh-eth.0", &mstp_clks[MSTP114]), | |
242 | CLKDEV_CON_ID("rtc0", &mstp_clks[MSTP303]), | |
243 | CLKDEV_CON_ID("hif0", &mstp_clks[MSTP302]), | |
244 | CLKDEV_CON_ID("stif0", &mstp_clks[MSTP301]), | |
245 | CLKDEV_CON_ID("stif1", &mstp_clks[MSTP300]), | |
246 | }; | |
247 | ||
248 | int __init arch_clk_init(void) | |
249 | { | |
250 | int i, ret = 0; | |
251 | ||
252 | for (i = 0; i < ARRAY_SIZE(main_clks); i++) | |
253 | ret |= clk_register(main_clks[i]); | |
254 | ||
255 | for (i = 0; i < ARRAY_SIZE(lookups); i++) | |
256 | clkdev_add(&lookups[i]); | |
257 | ||
258 | if (!ret) | |
259 | ret = sh_clk_div4_register(div4_clks, ARRAY_SIZE(div4_clks), | |
260 | &div4_table); | |
261 | ||
262 | if (!ret) | |
ad3337cb | 263 | ret = sh_clk_mstp_register(mstp_clks, MSTP_NR); |
fea88a0c NI |
264 | |
265 | return ret; | |
266 | } |