1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19#include <linux/init.h>
20#include <linux/kernel.h>
21#include <linux/io.h>
22#include <linux/sh_clk.h>
23#include <linux/clkdev.h>
24#include <mach/common.h>
25
26#define FRQCRA 0xe6150000
27#define FRQCRB 0xe6150004
28#define FRQCRD 0xe61500e4
29#define VCLKCR1 0xe6150008
30#define VCLKCR2 0xe615000C
31#define VCLKCR3 0xe615001C
32#define ZBCKCR 0xe6150010
33#define FLCKCR 0xe6150014
34#define SD0CKCR 0xe6150074
35#define SD1CKCR 0xe6150078
36#define SD2CKCR 0xe615007C
37#define FSIACKCR 0xe6150018
38#define FSIBCKCR 0xe6150090
39#define SUBCKCR 0xe6150080
40#define SPUACKCR 0xe6150084
41#define SPUVCKCR 0xe6150094
42#define MSUCKCR 0xe6150088
43#define HSICKCR 0xe615008C
44#define MFCK1CR 0xe6150098
45#define MFCK2CR 0xe615009C
46#define DSITCKCR 0xe6150060
47#define DSI0PCKCR 0xe6150064
48#define DSI1PCKCR 0xe6150068
49#define DSI0PHYCR 0xe615006C
50#define DSI1PHYCR 0xe6150070
51#define PLLECR 0xe61500d0
52#define PLL0CR 0xe61500d8
53#define PLL1CR 0xe6150028
54#define PLL2CR 0xe615002c
55#define PLL3CR 0xe61500dc
56#define SMSTPCR0 0xe6150130
57#define SMSTPCR1 0xe6150134
58#define SMSTPCR2 0xe6150138
59#define SMSTPCR3 0xe615013c
60#define SMSTPCR4 0xe6150140
61#define SMSTPCR5 0xe6150144
62#define CKSCR 0xe61500c0
63
64
65static struct clk r_clk = {
66 .rate = 32768,
67};
68
69
70
71
72
73struct clk sh73a0_extal1_clk = {
74 .rate = 26000000,
75};
76
77
78
79
80
81struct clk sh73a0_extal2_clk = {
82 .rate = 48000000,
83};
84
85
86static unsigned long div2_recalc(struct clk *clk)
87{
88 return clk->parent->rate / 2;
89}
90
91static struct clk_ops div2_clk_ops = {
92 .recalc = div2_recalc,
93};
94
95
96static struct clk extal1_div2_clk = {
97 .ops = &div2_clk_ops,
98 .parent = &sh73a0_extal1_clk,
99};
100
101
102static struct clk extal2_div2_clk = {
103 .ops = &div2_clk_ops,
104 .parent = &sh73a0_extal2_clk,
105};
106
107static struct clk_ops main_clk_ops = {
108 .recalc = followparent_recalc,
109};
110
111
112static struct clk main_clk = {
113 .ops = &main_clk_ops,
114};
115
116
117static unsigned long pll_recalc(struct clk *clk)
118{
119 unsigned long mult = 1;
120
121 if (__raw_readl(PLLECR) & (1 << clk->enable_bit)) {
122 mult = (((__raw_readl(clk->enable_reg) >> 24) & 0x3f) + 1);
123
124 switch (clk->enable_bit) {
125 case 1:
126 case 2:
127 if (__raw_readl(clk->enable_reg) & (1 << 20))
128 mult *= 2;
129 }
130 }
131
132 return clk->parent->rate * mult;
133}
134
135static struct clk_ops pll_clk_ops = {
136 .recalc = pll_recalc,
137};
138
139static struct clk pll0_clk = {
140 .ops = &pll_clk_ops,
141 .flags = CLK_ENABLE_ON_INIT,
142 .parent = &main_clk,
143 .enable_reg = (void __iomem *)PLL0CR,
144 .enable_bit = 0,
145};
146
147static struct clk pll1_clk = {
148 .ops = &pll_clk_ops,
149 .flags = CLK_ENABLE_ON_INIT,
150 .parent = &main_clk,
151 .enable_reg = (void __iomem *)PLL1CR,
152 .enable_bit = 1,
153};
154
155static struct clk pll2_clk = {
156 .ops = &pll_clk_ops,
157 .flags = CLK_ENABLE_ON_INIT,
158 .parent = &main_clk,
159 .enable_reg = (void __iomem *)PLL2CR,
160 .enable_bit = 2,
161};
162
163static struct clk pll3_clk = {
164 .ops = &pll_clk_ops,
165 .flags = CLK_ENABLE_ON_INIT,
166 .parent = &main_clk,
167 .enable_reg = (void __iomem *)PLL3CR,
168 .enable_bit = 3,
169};
170
171
172static struct clk pll1_div2_clk = {
173 .ops = &div2_clk_ops,
174 .parent = &pll1_clk,
175};
176
177static struct clk *main_clks[] = {
178 &r_clk,
179 &sh73a0_extal1_clk,
180 &sh73a0_extal2_clk,
181 &extal1_div2_clk,
182 &extal2_div2_clk,
183 &main_clk,
184 &pll0_clk,
185 &pll1_clk,
186 &pll2_clk,
187 &pll3_clk,
188 &pll1_div2_clk,
189};
190
191static void div4_kick(struct clk *clk)
192{
193 unsigned long value;
194
195
196 value = __raw_readl(FRQCRB);
197 value |= (1 << 31);
198 __raw_writel(value, FRQCRB);
199}
200
201static int divisors[] = { 2, 3, 4, 6, 8, 12, 16, 18,
202 24, 0, 36, 48, 7 };
203
204static struct clk_div_mult_table div4_div_mult_table = {
205 .divisors = divisors,
206 .nr_divisors = ARRAY_SIZE(divisors),
207};
208
209static struct clk_div4_table div4_table = {
210 .div_mult_table = &div4_div_mult_table,
211 .kick = div4_kick,
212};
213
214enum { DIV4_I, DIV4_ZG, DIV4_M3, DIV4_B, DIV4_M1, DIV4_M2,
215 DIV4_Z, DIV4_ZTR, DIV4_ZT, DIV4_ZX, DIV4_HP, DIV4_NR };
216
217#define DIV4(_reg, _bit, _mask, _flags) \
218 SH_CLK_DIV4(&pll1_clk, _reg, _bit, _mask, _flags)
219
220static struct clk div4_clks[DIV4_NR] = {
221 [DIV4_I] = DIV4(FRQCRA, 20, 0xfff, CLK_ENABLE_ON_INIT),
222 [DIV4_ZG] = DIV4(FRQCRA, 16, 0xbff, CLK_ENABLE_ON_INIT),
223 [DIV4_M3] = DIV4(FRQCRA, 12, 0xfff, CLK_ENABLE_ON_INIT),
224 [DIV4_B] = DIV4(FRQCRA, 8, 0xfff, CLK_ENABLE_ON_INIT),
225 [DIV4_M1] = DIV4(FRQCRA, 4, 0xfff, 0),
226 [DIV4_M2] = DIV4(FRQCRA, 0, 0xfff, 0),
227 [DIV4_Z] = DIV4(FRQCRB, 24, 0xbff, 0),
228 [DIV4_ZTR] = DIV4(FRQCRB, 20, 0xfff, 0),
229 [DIV4_ZT] = DIV4(FRQCRB, 16, 0xfff, 0),
230 [DIV4_ZX] = DIV4(FRQCRB, 12, 0xfff, 0),
231 [DIV4_HP] = DIV4(FRQCRB, 4, 0xfff, 0),
232};
233
234enum { DIV6_VCK1, DIV6_VCK2, DIV6_VCK3, DIV6_ZB1,
235 DIV6_FLCTL, DIV6_SDHI0, DIV6_SDHI1, DIV6_SDHI2,
236 DIV6_FSIA, DIV6_FSIB, DIV6_SUB,
237 DIV6_SPUA, DIV6_SPUV, DIV6_MSU,
238 DIV6_HSI, DIV6_MFG1, DIV6_MFG2,
239 DIV6_DSIT, DIV6_DSI0P, DIV6_DSI1P,
240 DIV6_NR };
241
242static struct clk div6_clks[DIV6_NR] = {
243 [DIV6_VCK1] = SH_CLK_DIV6(&pll1_div2_clk, VCLKCR1, 0),
244 [DIV6_VCK2] = SH_CLK_DIV6(&pll1_div2_clk, VCLKCR2, 0),
245 [DIV6_VCK3] = SH_CLK_DIV6(&pll1_div2_clk, VCLKCR3, 0),
246 [DIV6_ZB1] = SH_CLK_DIV6(&pll1_div2_clk, ZBCKCR, 0),
247 [DIV6_FLCTL] = SH_CLK_DIV6(&pll1_div2_clk, FLCKCR, 0),
248 [DIV6_SDHI0] = SH_CLK_DIV6(&pll1_div2_clk, SD0CKCR, 0),
249 [DIV6_SDHI1] = SH_CLK_DIV6(&pll1_div2_clk, SD1CKCR, 0),
250 [DIV6_SDHI2] = SH_CLK_DIV6(&pll1_div2_clk, SD2CKCR, 0),
251 [DIV6_FSIA] = SH_CLK_DIV6(&pll1_div2_clk, FSIACKCR, 0),
252 [DIV6_FSIB] = SH_CLK_DIV6(&pll1_div2_clk, FSIBCKCR, 0),
253 [DIV6_SUB] = SH_CLK_DIV6(&sh73a0_extal2_clk, SUBCKCR, 0),
254 [DIV6_SPUA] = SH_CLK_DIV6(&pll1_div2_clk, SPUACKCR, 0),
255 [DIV6_SPUV] = SH_CLK_DIV6(&pll1_div2_clk, SPUVCKCR, 0),
256 [DIV6_MSU] = SH_CLK_DIV6(&pll1_div2_clk, MSUCKCR, 0),
257 [DIV6_HSI] = SH_CLK_DIV6(&pll1_div2_clk, HSICKCR, 0),
258 [DIV6_MFG1] = SH_CLK_DIV6(&pll1_div2_clk, MFCK1CR, 0),
259 [DIV6_MFG2] = SH_CLK_DIV6(&pll1_div2_clk, MFCK2CR, 0),
260 [DIV6_DSIT] = SH_CLK_DIV6(&pll1_div2_clk, DSITCKCR, 0),
261 [DIV6_DSI0P] = SH_CLK_DIV6(&pll1_div2_clk, DSI0PCKCR, 0),
262 [DIV6_DSI1P] = SH_CLK_DIV6(&pll1_div2_clk, DSI1PCKCR, 0),
263};
264
265enum { MSTP001,
266 MSTP129, MSTP128, MSTP127, MSTP126, MSTP125, MSTP118, MSTP116, MSTP100,
267 MSTP219,
268 MSTP207, MSTP206, MSTP204, MSTP203, MSTP202, MSTP201, MSTP200,
269 MSTP331, MSTP329, MSTP325, MSTP323, MSTP318,
270 MSTP314, MSTP313, MSTP312, MSTP311,
271 MSTP411, MSTP410, MSTP403,
272 MSTP_NR };
273
274#define MSTP(_parent, _reg, _bit, _flags) \
275 SH_CLK_MSTP32(_parent, _reg, _bit, _flags)
276
277static struct clk mstp_clks[MSTP_NR] = {
278 [MSTP001] = MSTP(&div4_clks[DIV4_HP], SMSTPCR0, 1, 0),
279 [MSTP129] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 29, 0),
280 [MSTP128] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 28, 0),
281 [MSTP127] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 27, 0),
282 [MSTP126] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 26, 0),
283 [MSTP125] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR1, 25, 0),
284 [MSTP118] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 18, 0),
285 [MSTP116] = MSTP(&div4_clks[DIV4_HP], SMSTPCR1, 16, 0),
286 [MSTP100] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 0, 0),
287 [MSTP219] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 19, 0),
288 [MSTP207] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 7, 0),
289 [MSTP206] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 6, 0),
290 [MSTP204] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 4, 0),
291 [MSTP203] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 3, 0),
292 [MSTP202] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 2, 0),
293 [MSTP201] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 1, 0),
294 [MSTP200] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 0, 0),
295 [MSTP331] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 31, 0),
296 [MSTP329] = MSTP(&r_clk, SMSTPCR3, 29, 0),
297 [MSTP325] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 25, 0),
298 [MSTP323] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 23, 0),
299 [MSTP318] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 18, 0),
300 [MSTP314] = MSTP(&div6_clks[DIV6_SDHI0], SMSTPCR3, 14, 0),
301 [MSTP313] = MSTP(&div6_clks[DIV6_SDHI1], SMSTPCR3, 13, 0),
302 [MSTP312] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 12, 0),
303 [MSTP311] = MSTP(&div6_clks[DIV6_SDHI2], SMSTPCR3, 11, 0),
304 [MSTP411] = MSTP(&div4_clks[DIV4_HP], SMSTPCR4, 11, 0),
305 [MSTP410] = MSTP(&div4_clks[DIV4_HP], SMSTPCR4, 10, 0),
306 [MSTP403] = MSTP(&r_clk, SMSTPCR4, 3, 0),
307};
308
309#define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk }
310#define CLKDEV_DEV_ID(_id, _clk) { .dev_id = _id, .clk = _clk }
311#define CLKDEV_ICK_ID(_cid, _did, _clk) { .con_id = _cid, .dev_id = _did, .clk = _clk }
312
313static struct clk_lookup lookups[] = {
314
315 CLKDEV_CON_ID("r_clk", &r_clk),
316
317
318 CLKDEV_CON_ID("vck1_clk", &div6_clks[DIV6_VCK1]),
319 CLKDEV_CON_ID("vck2_clk", &div6_clks[DIV6_VCK2]),
320 CLKDEV_CON_ID("vck3_clk", &div6_clks[DIV6_VCK3]),
321 CLKDEV_CON_ID("sdhi0_clk", &div6_clks[DIV6_SDHI0]),
322 CLKDEV_CON_ID("sdhi1_clk", &div6_clks[DIV6_SDHI1]),
323 CLKDEV_CON_ID("sdhi2_clk", &div6_clks[DIV6_SDHI2]),
324 CLKDEV_ICK_ID("dsit_clk", "sh-mipi-dsi.0", &div6_clks[DIV6_DSIT]),
325 CLKDEV_ICK_ID("dsit_clk", "sh-mipi-dsi.1", &div6_clks[DIV6_DSIT]),
326 CLKDEV_ICK_ID("dsi0p_clk", "sh-mipi-dsi.0", &div6_clks[DIV6_DSI0P]),
327 CLKDEV_ICK_ID("dsi1p_clk", "sh-mipi-dsi.1", &div6_clks[DIV6_DSI1P]),
328
329
330 CLKDEV_DEV_ID("i2c-sh_mobile.2", &mstp_clks[MSTP001]),
331 CLKDEV_DEV_ID("sh_mobile_ceu.1", &mstp_clks[MSTP129]),
332 CLKDEV_DEV_ID("sh-mobile-csi2.1", &mstp_clks[MSTP128]),
333 CLKDEV_DEV_ID("sh_mobile_ceu.0", &mstp_clks[MSTP127]),
334 CLKDEV_DEV_ID("sh-mobile-csi2.0", &mstp_clks[MSTP126]),
335 CLKDEV_DEV_ID("sh_tmu.0", &mstp_clks[MSTP125]),
336 CLKDEV_DEV_ID("sh_tmu.1", &mstp_clks[MSTP125]),
337 CLKDEV_DEV_ID("sh-mipi-dsi.0", &mstp_clks[MSTP118]),
338 CLKDEV_DEV_ID("i2c-sh_mobile.0", &mstp_clks[MSTP116]),
339 CLKDEV_DEV_ID("sh_mobile_lcdc_fb.0", &mstp_clks[MSTP100]),
340 CLKDEV_DEV_ID("sh-sci.7", &mstp_clks[MSTP219]),
341 CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[MSTP207]),
342 CLKDEV_DEV_ID("sh-sci.8", &mstp_clks[MSTP206]),
343 CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[MSTP204]),
344 CLKDEV_DEV_ID("sh-sci.1", &mstp_clks[MSTP203]),
345 CLKDEV_DEV_ID("sh-sci.2", &mstp_clks[MSTP202]),
346 CLKDEV_DEV_ID("sh-sci.3", &mstp_clks[MSTP201]),
347 CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP200]),
348 CLKDEV_DEV_ID("sh-sci.6", &mstp_clks[MSTP331]),
349 CLKDEV_DEV_ID("sh_cmt.10", &mstp_clks[MSTP329]),
350 CLKDEV_DEV_ID("sh_irda.0", &mstp_clks[MSTP325]),
351 CLKDEV_DEV_ID("i2c-sh_mobile.1", &mstp_clks[MSTP323]),
352 CLKDEV_DEV_ID("sh-dma-engine.0", &mstp_clks[MSTP318]),
353 CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP314]),
354 CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP313]),
355 CLKDEV_DEV_ID("sh_mmcif.0", &mstp_clks[MSTP312]),
356 CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[MSTP311]),
357 CLKDEV_DEV_ID("i2c-sh_mobile.3", &mstp_clks[MSTP411]),
358 CLKDEV_DEV_ID("i2c-sh_mobile.4", &mstp_clks[MSTP410]),
359 CLKDEV_DEV_ID("sh_keysc.0", &mstp_clks[MSTP403]),
360};
361
362void __init sh73a0_clock_init(void)
363{
364 int k, ret = 0;
365
366
367 __raw_writel(0x108, SD0CKCR);
368 __raw_writel(0x108, SD1CKCR);
369 __raw_writel(0x108, SD2CKCR);
370
371
372 switch ((__raw_readl(CKSCR) >> 24) & 0x03) {
373 case 0:
374 main_clk.parent = &sh73a0_extal1_clk;
375 break;
376 case 1:
377 main_clk.parent = &extal1_div2_clk;
378 break;
379 case 2:
380 main_clk.parent = &sh73a0_extal2_clk;
381 break;
382 case 3:
383 main_clk.parent = &extal2_div2_clk;
384 break;
385 }
386
387 for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++)
388 ret = clk_register(main_clks[k]);
389
390 if (!ret)
391 ret = sh_clk_div4_register(div4_clks, DIV4_NR, &div4_table);
392
393 if (!ret)
394 ret = sh_clk_div6_register(div6_clks, DIV6_NR);
395
396 if (!ret)
397 ret = sh_clk_mstp32_register(mstp_clks, MSTP_NR);
398
399 clkdev_add_table(lookups, ARRAY_SIZE(lookups));
400
401 if (!ret)
402 clk_init();
403 else
404 panic("failed to setup sh73a0 clocks\n");
405}
406