2 * R8A7740 processor support
4 * Copyright (C) 2011 Renesas Solutions Corp.
5 * Copyright (C) 2011 Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
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
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.
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
20 #include <linux/init.h>
21 #include <linux/kernel.h>
23 #include <linux/sh_clk.h>
24 #include <linux/clkdev.h>
25 #include <mach/common.h>
26 #include <mach/r8a7740.h>
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
44 #define FRQCRA 0xe6150000
45 #define FRQCRB 0xe6150004
46 #define FRQCRC 0xe61500e0
47 #define PLLC01CR 0xe6150028
49 #define SUBCKCR 0xe6150080
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
62 /* Fixed 32 KHz root clock from EXTALR pin */
63 static struct clk extalr_clk
= {
68 * 25MHz default rate for the EXTAL1 root input clock.
69 * If needed, reset this with clk_set_rate() from the platform code.
71 static struct clk extal1_clk
= {
76 * 48MHz default rate for the EXTAL2 root input clock.
77 * If needed, reset this with clk_set_rate() from the platform code.
79 static struct clk extal2_clk
= {
84 * 27MHz default rate for the DV_CLKI root input clock.
85 * If needed, reset this with clk_set_rate() from the platform code.
87 static struct clk dv_clk
= {
91 static unsigned long div_recalc(struct clk
*clk
)
93 return clk
->parent
->rate
/ (int)(clk
->priv
);
96 static struct clk_ops div_clk_ops
= {
101 static struct clk extal1_div2_clk
= {
104 .parent
= &extal1_clk
,
108 static struct clk extal1_div1024_clk
= {
110 .priv
= (void *)1024,
111 .parent
= &extal1_clk
,
114 /* extal1 / 2 / 1024 */
115 static struct clk extal1_div2048_clk
= {
117 .priv
= (void *)1024,
118 .parent
= &extal1_div2_clk
,
122 static struct clk extal2_div2_clk
= {
125 .parent
= &extal2_clk
,
128 static struct clk_ops followparent_clk_ops
= {
129 .recalc
= followparent_recalc
,
133 static struct clk system_clk
= {
134 .ops
= &followparent_clk_ops
,
137 static struct clk system_div2_clk
= {
140 .parent
= &system_clk
,
144 static struct clk r_clk
= {
145 .ops
= &followparent_clk_ops
,
149 static unsigned long pllc01_recalc(struct clk
*clk
)
151 unsigned long mult
= 1;
153 if (__raw_readl(PLLC01CR
) & (1 << 14))
154 mult
= ((__raw_readl(clk
->enable_reg
) >> 24) & 0x7f) + 1;
156 return clk
->parent
->rate
* mult
;
159 static struct clk_ops pllc01_clk_ops
= {
160 .recalc
= pllc01_recalc
,
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
,
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
,
178 static struct clk pllc1_div2_clk
= {
181 .parent
= &pllc1_clk
,
184 struct clk
*main_clks
[] = {
201 static void div4_kick(struct clk
*clk
)
205 /* set KICK bit in FRQCRB to update hardware setting */
206 value
= __raw_readl(FRQCRB
);
208 __raw_writel(value
, FRQCRB
);
211 static int divisors
[] = { 2, 3, 4, 6, 8, 12, 16, 18,
212 24, 32, 36, 48, 0, 72, 96, 0 };
214 static struct clk_div_mult_table div4_div_mult_table
= {
215 .divisors
= divisors
,
216 .nr_divisors
= ARRAY_SIZE(divisors
),
219 static struct clk_div4_table div4_table
= {
220 .div_mult_table
= &div4_div_mult_table
,
225 DIV4_I
, DIV4_ZG
, DIV4_B
, DIV4_M1
, DIV4_HP
,
226 DIV4_HPP
, DIV4_S
, DIV4_ZB
, DIV4_M3
, DIV4_CP
,
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),
248 static struct clk div6_clks
[DIV6_NR
] = {
249 [DIV6_SUB
] = SH_CLK_DIV6(&pllc1_div2_clk
, SUBCKCR
, 0),
254 MSTP116
, MSTP111
, MSTP100
, MSTP117
,
258 MSTP207
, MSTP206
, MSTP204
, MSTP203
, MSTP202
, MSTP201
, MSTP200
,
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 */
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 */
282 [MSTP329
] = SH_CLK_MSTP32(&r_clk
, SMSTPCR3
, 29, 0), /* CMT10 */
283 [MSTP323
] = SH_CLK_MSTP32(&div6_clks
[DIV6_SUB
], SMSTPCR3
, 23, 0), /* IIC1 */
286 static struct clk_lookup lookups
[] = {
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
),
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
]),
316 CLKDEV_CON_ID("sub_clk", &div6_clks
[DIV6_SUB
]),
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
]),
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
]),
333 CLKDEV_DEV_ID("sh-sci.7", &mstp_clks
[MSTP222
]),
334 CLKDEV_DEV_ID("sh-sci.6", &mstp_clks
[MSTP230
]),
336 CLKDEV_DEV_ID("sh_cmt.10", &mstp_clks
[MSTP329
]),
337 CLKDEV_DEV_ID("i2c-sh_mobile.1", &mstp_clks
[MSTP323
]),
340 void __init
r8a7740_clock_init(u8 md_ck
)
344 /* detect system clock parent */
346 system_clk
.parent
= &extal1_div2_clk
;
348 system_clk
.parent
= &extal1_clk
;
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
;
356 r_clk
.parent
= &extal1_div1024_clk
;
360 r_clk
.parent
= &extalr_clk
;
364 for (k
= 0; !ret
&& (k
< ARRAY_SIZE(main_clks
)); k
++)
365 ret
= clk_register(main_clks
[k
]);
368 ret
= sh_clk_div4_register(div4_clks
, DIV4_NR
, &div4_table
);
371 ret
= sh_clk_div6_register(div6_clks
, DIV6_NR
);
374 ret
= sh_clk_mstp32_register(mstp_clks
, MSTP_NR
);
376 clkdev_add_table(lookups
, ARRAY_SIZE(lookups
));
381 panic("failed to setup r8a7740 clocks\n");