]> Pileus Git - ~andy/linux/blob - arch/arm/mach-shmobile/clock-r8a7740.c
Merge branch 'rmobile/bonito' into rmobile-latest
[~andy/linux] / arch / arm / mach-shmobile / clock-r8a7740.c
1 /*
2  * R8A7740 processor support
3  *
4  * Copyright (C) 2011  Renesas Solutions Corp.
5  * Copyright (C) 2011  Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
20 #include <linux/init.h>
21 #include <linux/kernel.h>
22 #include <linux/io.h>
23 #include <linux/sh_clk.h>
24 #include <linux/clkdev.h>
25 #include <mach/common.h>
26 #include <mach/r8a7740.h>
27
28 /*
29  *        |  MDx  |  XTAL1/EXTAL1   |  System   | EXTALR |
30  *  Clock |-------+-----------------+  clock    | 32.768 |   RCLK
31  *  Mode  | 2/1/0 | src         MHz |  source   |  KHz   |  source
32  * -------+-------+-----------------+-----------+--------+----------
33  *    0   | 0 0 0 | External  20~50 | XTAL1     |    O   |  EXTALR
34  *    1   | 0 0 1 | Crystal   20~30 | XTAL1     |    O   |  EXTALR
35  *    2   | 0 1 0 | External  40~50 | XTAL1 / 2 |    O   |  EXTALR
36  *    3   | 0 1 1 | Crystal   40~50 | XTAL1 / 2 |    O   |  EXTALR
37  *    4   | 1 0 0 | External  20~50 | XTAL1     |    x   |  XTAL1 / 1024
38  *    5   | 1 0 1 | Crystal   20~30 | XTAL1     |    x   |  XTAL1 / 1024
39  *    6   | 1 1 0 | External  40~50 | XTAL1 / 2 |    x   |  XTAL1 / 2048
40  *    7   | 1 1 1 | Crystal   40~50 | XTAL1 / 2 |    x   |  XTAL1 / 2048
41  */
42
43 /* CPG registers */
44 #define FRQCRA          0xe6150000
45 #define FRQCRB          0xe6150004
46 #define FRQCRC          0xe61500e0
47 #define PLLC01CR        0xe6150028
48
49 #define SUBCKCR         0xe6150080
50
51 #define MSTPSR0         0xe6150030
52 #define MSTPSR1         0xe6150038
53 #define MSTPSR2         0xe6150040
54 #define MSTPSR3         0xe6150048
55 #define MSTPSR4         0xe615004c
56 #define SMSTPCR0        0xe6150130
57 #define SMSTPCR1        0xe6150134
58 #define SMSTPCR2        0xe6150138
59 #define SMSTPCR3        0xe615013c
60 #define SMSTPCR4        0xe6150140
61
62 /* Fixed 32 KHz root clock from EXTALR pin */
63 static struct clk extalr_clk = {
64         .rate   = 32768,
65 };
66
67 /*
68  * 25MHz default rate for the EXTAL1 root input clock.
69  * If needed, reset this with clk_set_rate() from the platform code.
70  */
71 static struct clk extal1_clk = {
72         .rate   = 25000000,
73 };
74
75 /*
76  * 48MHz default rate for the EXTAL2 root input clock.
77  * If needed, reset this with clk_set_rate() from the platform code.
78  */
79 static struct clk extal2_clk = {
80         .rate   = 48000000,
81 };
82
83 /*
84  * 27MHz default rate for the DV_CLKI root input clock.
85  * If needed, reset this with clk_set_rate() from the platform code.
86  */
87 static struct clk dv_clk = {
88         .rate   = 27000000,
89 };
90
91 static unsigned long div_recalc(struct clk *clk)
92 {
93         return clk->parent->rate / (int)(clk->priv);
94 }
95
96 static struct clk_ops div_clk_ops = {
97         .recalc = div_recalc,
98 };
99
100 /* extal1 / 2 */
101 static struct clk extal1_div2_clk = {
102         .ops    = &div_clk_ops,
103         .priv   = (void *)2,
104         .parent = &extal1_clk,
105 };
106
107 /* extal1 / 1024 */
108 static struct clk extal1_div1024_clk = {
109         .ops    = &div_clk_ops,
110         .priv   = (void *)1024,
111         .parent = &extal1_clk,
112 };
113
114 /* extal1 / 2 / 1024 */
115 static struct clk extal1_div2048_clk = {
116         .ops    = &div_clk_ops,
117         .priv   = (void *)1024,
118         .parent = &extal1_div2_clk,
119 };
120
121 /* extal2 / 2 */
122 static struct clk extal2_div2_clk = {
123         .ops    = &div_clk_ops,
124         .priv   = (void *)2,
125         .parent = &extal2_clk,
126 };
127
128 static struct clk_ops followparent_clk_ops = {
129         .recalc = followparent_recalc,
130 };
131
132 /* Main clock */
133 static struct clk system_clk = {
134         .ops    = &followparent_clk_ops,
135 };
136
137 static struct clk system_div2_clk = {
138         .ops    = &div_clk_ops,
139         .priv   = (void *)2,
140         .parent = &system_clk,
141 };
142
143 /* r_clk */
144 static struct clk r_clk = {
145         .ops    = &followparent_clk_ops,
146 };
147
148 /* PLLC0/PLLC1 */
149 static unsigned long pllc01_recalc(struct clk *clk)
150 {
151         unsigned long mult = 1;
152
153         if (__raw_readl(PLLC01CR) & (1 << 14))
154                 mult = ((__raw_readl(clk->enable_reg) >> 24) & 0x7f) + 1;
155
156         return clk->parent->rate * mult;
157 }
158
159 static struct clk_ops pllc01_clk_ops = {
160         .recalc         = pllc01_recalc,
161 };
162
163 static struct clk pllc0_clk = {
164         .ops            = &pllc01_clk_ops,
165         .flags          = CLK_ENABLE_ON_INIT,
166         .parent         = &system_clk,
167         .enable_reg     = (void __iomem *)FRQCRC,
168 };
169
170 static struct clk pllc1_clk = {
171         .ops            = &pllc01_clk_ops,
172         .flags          = CLK_ENABLE_ON_INIT,
173         .parent         = &system_div2_clk,
174         .enable_reg     = (void __iomem *)FRQCRA,
175 };
176
177 /* PLLC1 / 2 */
178 static struct clk pllc1_div2_clk = {
179         .ops            = &div_clk_ops,
180         .priv           = (void *)2,
181         .parent         = &pllc1_clk,
182 };
183
184 struct clk *main_clks[] = {
185         &extalr_clk,
186         &extal1_clk,
187         &extal2_clk,
188         &extal1_div2_clk,
189         &extal1_div1024_clk,
190         &extal1_div2048_clk,
191         &extal2_div2_clk,
192         &dv_clk,
193         &system_clk,
194         &system_div2_clk,
195         &r_clk,
196         &pllc0_clk,
197         &pllc1_clk,
198         &pllc1_div2_clk,
199 };
200
201 static void div4_kick(struct clk *clk)
202 {
203         unsigned long value;
204
205         /* set KICK bit in FRQCRB to update hardware setting */
206         value = __raw_readl(FRQCRB);
207         value |= (1 << 31);
208         __raw_writel(value, FRQCRB);
209 }
210
211 static int divisors[] = { 2, 3, 4, 6, 8, 12, 16, 18,
212                           24, 32, 36, 48, 0, 72, 96, 0 };
213
214 static struct clk_div_mult_table div4_div_mult_table = {
215         .divisors = divisors,
216         .nr_divisors = ARRAY_SIZE(divisors),
217 };
218
219 static struct clk_div4_table div4_table = {
220         .div_mult_table = &div4_div_mult_table,
221         .kick = div4_kick,
222 };
223
224 enum {
225         DIV4_I, DIV4_ZG, DIV4_B, DIV4_M1, DIV4_HP,
226         DIV4_HPP, DIV4_S, DIV4_ZB, DIV4_M3, DIV4_CP,
227         DIV4_NR
228 };
229
230 struct clk div4_clks[DIV4_NR] = {
231         [DIV4_I]        = SH_CLK_DIV4(&pllc1_clk, FRQCRA, 20, 0x6fff, CLK_ENABLE_ON_INIT),
232         [DIV4_ZG]       = SH_CLK_DIV4(&pllc1_clk, FRQCRA, 16, 0x6fff, CLK_ENABLE_ON_INIT),
233         [DIV4_B]        = SH_CLK_DIV4(&pllc1_clk, FRQCRA,  8, 0x6fff, CLK_ENABLE_ON_INIT),
234         [DIV4_M1]       = SH_CLK_DIV4(&pllc1_clk, FRQCRA,  4, 0x6fff, CLK_ENABLE_ON_INIT),
235         [DIV4_HP]       = SH_CLK_DIV4(&pllc1_clk, FRQCRB,  4, 0x6fff, 0),
236         [DIV4_HPP]      = SH_CLK_DIV4(&pllc1_clk, FRQCRC, 20, 0x6fff, 0),
237         [DIV4_S]        = SH_CLK_DIV4(&pllc1_clk, FRQCRC, 12, 0x6fff, 0),
238         [DIV4_ZB]       = SH_CLK_DIV4(&pllc1_clk, FRQCRC,  8, 0x6fff, 0),
239         [DIV4_M3]       = SH_CLK_DIV4(&pllc1_clk, FRQCRC,  4, 0x6fff, 0),
240         [DIV4_CP]       = SH_CLK_DIV4(&pllc1_clk, FRQCRC,  0, 0x6fff, 0),
241 };
242
243 enum {
244         DIV6_SUB,
245         DIV6_NR
246 };
247
248 static struct clk div6_clks[DIV6_NR] = {
249         [DIV6_SUB]      = SH_CLK_DIV6(&pllc1_div2_clk, SUBCKCR, 0),
250 };
251
252 enum {
253         MSTP125,
254         MSTP116, MSTP111, MSTP100, MSTP117,
255
256         MSTP230,
257         MSTP222,
258         MSTP207, MSTP206, MSTP204, MSTP203, MSTP202, MSTP201, MSTP200,
259
260         MSTP329, MSTP323,
261
262         MSTP_NR
263 };
264
265 static struct clk mstp_clks[MSTP_NR] = {
266         [MSTP125] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR1, 25, 0), /* TMU0 */
267         [MSTP117] = SH_CLK_MSTP32(&div4_clks[DIV4_B],   SMSTPCR1, 17, 0), /* LCDC1 */
268         [MSTP116] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR1, 16, 0), /* IIC0 */
269         [MSTP111] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR1, 11, 0), /* TMU1 */
270         [MSTP100] = SH_CLK_MSTP32(&div4_clks[DIV4_B],   SMSTPCR1,  0, 0), /* LCDC0 */
271
272         [MSTP230] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR2, 30, 0), /* SCIFA6 */
273         [MSTP222] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR2, 22, 0), /* SCIFA7 */
274         [MSTP207] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR2,  7, 0), /* SCIFA5 */
275         [MSTP206] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR2,  6, 0), /* SCIFB */
276         [MSTP204] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR2,  4, 0), /* SCIFA0 */
277         [MSTP203] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR2,  3, 0), /* SCIFA1 */
278         [MSTP202] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR2,  2, 0), /* SCIFA2 */
279         [MSTP201] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR2,  1, 0), /* SCIFA3 */
280         [MSTP200] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR2,  0, 0), /* SCIFA4 */
281
282         [MSTP329] = SH_CLK_MSTP32(&r_clk,               SMSTPCR3, 29, 0), /* CMT10 */
283         [MSTP323] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR3, 23, 0), /* IIC1 */
284 };
285
286 static struct clk_lookup lookups[] = {
287         /* main clocks */
288         CLKDEV_CON_ID("extalr",                 &extalr_clk),
289         CLKDEV_CON_ID("extal1",                 &extal1_clk),
290         CLKDEV_CON_ID("extal2",                 &extal2_clk),
291         CLKDEV_CON_ID("extal1_div2",            &extal1_div2_clk),
292         CLKDEV_CON_ID("extal1_div1024",         &extal1_div1024_clk),
293         CLKDEV_CON_ID("extal1_div2048",         &extal1_div2048_clk),
294         CLKDEV_CON_ID("extal2_div2",            &extal2_div2_clk),
295         CLKDEV_CON_ID("dv_clk",                 &dv_clk),
296         CLKDEV_CON_ID("system_clk",             &system_clk),
297         CLKDEV_CON_ID("system_div2_clk",        &system_div2_clk),
298         CLKDEV_CON_ID("r_clk",                  &r_clk),
299         CLKDEV_CON_ID("pllc0_clk",              &pllc0_clk),
300         CLKDEV_CON_ID("pllc1_clk",              &pllc1_clk),
301         CLKDEV_CON_ID("pllc1_div2_clk",         &pllc1_div2_clk),
302
303         /* DIV4 clocks */
304         CLKDEV_CON_ID("i_clk",                  &div4_clks[DIV4_I]),
305         CLKDEV_CON_ID("zg_clk",                 &div4_clks[DIV4_ZG]),
306         CLKDEV_CON_ID("b_clk",                  &div4_clks[DIV4_B]),
307         CLKDEV_CON_ID("m1_clk",                 &div4_clks[DIV4_M1]),
308         CLKDEV_CON_ID("hp_clk",                 &div4_clks[DIV4_HP]),
309         CLKDEV_CON_ID("hpp_clk",                &div4_clks[DIV4_HPP]),
310         CLKDEV_CON_ID("s_clk",                  &div4_clks[DIV4_S]),
311         CLKDEV_CON_ID("zb_clk",                 &div4_clks[DIV4_ZB]),
312         CLKDEV_CON_ID("m3_clk",                 &div4_clks[DIV4_M3]),
313         CLKDEV_CON_ID("cp_clk",                 &div4_clks[DIV4_CP]),
314
315         /* DIV6 clocks */
316         CLKDEV_CON_ID("sub_clk",                &div6_clks[DIV6_SUB]),
317
318         /* MSTP32 clocks */
319         CLKDEV_DEV_ID("sh_mobile_lcdc_fb.0",    &mstp_clks[MSTP100]),
320         CLKDEV_DEV_ID("sh_tmu.1",               &mstp_clks[MSTP111]),
321         CLKDEV_DEV_ID("i2c-sh_mobile.0",        &mstp_clks[MSTP116]),
322         CLKDEV_DEV_ID("sh_mobile_lcdc_fb.1",    &mstp_clks[MSTP117]),
323         CLKDEV_DEV_ID("sh_tmu.0",               &mstp_clks[MSTP125]),
324
325         CLKDEV_DEV_ID("sh-sci.4",               &mstp_clks[MSTP200]),
326         CLKDEV_DEV_ID("sh-sci.3",               &mstp_clks[MSTP201]),
327         CLKDEV_DEV_ID("sh-sci.2",               &mstp_clks[MSTP202]),
328         CLKDEV_DEV_ID("sh-sci.1",               &mstp_clks[MSTP203]),
329         CLKDEV_DEV_ID("sh-sci.0",               &mstp_clks[MSTP204]),
330         CLKDEV_DEV_ID("sh-sci.8",               &mstp_clks[MSTP206]),
331         CLKDEV_DEV_ID("sh-sci.5",               &mstp_clks[MSTP207]),
332
333         CLKDEV_DEV_ID("sh-sci.7",               &mstp_clks[MSTP222]),
334         CLKDEV_DEV_ID("sh-sci.6",               &mstp_clks[MSTP230]),
335
336         CLKDEV_DEV_ID("sh_cmt.10",              &mstp_clks[MSTP329]),
337         CLKDEV_DEV_ID("i2c-sh_mobile.1",        &mstp_clks[MSTP323]),
338 };
339
340 void __init r8a7740_clock_init(u8 md_ck)
341 {
342         int k, ret = 0;
343
344         /* detect system clock parent */
345         if (md_ck & MD_CK1)
346                 system_clk.parent = &extal1_div2_clk;
347         else
348                 system_clk.parent = &extal1_clk;
349
350         /* detect RCLK parent */
351         switch (md_ck & (MD_CK2 | MD_CK1)) {
352         case MD_CK2 | MD_CK1:
353                 r_clk.parent = &extal1_div2048_clk;
354                 break;
355         case MD_CK2:
356                 r_clk.parent = &extal1_div1024_clk;
357                 break;
358         case MD_CK1:
359         default:
360                 r_clk.parent = &extalr_clk;
361                 break;
362         }
363
364         for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++)
365                 ret = clk_register(main_clks[k]);
366
367         if (!ret)
368                 ret = sh_clk_div4_register(div4_clks, DIV4_NR, &div4_table);
369
370         if (!ret)
371                 ret = sh_clk_div6_register(div6_clks, DIV6_NR);
372
373         if (!ret)
374                 ret = sh_clk_mstp32_register(mstp_clks, MSTP_NR);
375
376         clkdev_add_table(lookups, ARRAY_SIZE(lookups));
377
378         if (!ret)
379                 clk_init();
380         else
381                 panic("failed to setup r8a7740 clocks\n");
382 }