diff options
author | Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> | 2013-04-05 00:22:41 -0400 |
---|---|---|
committer | Simon Horman <horms+renesas@verge.net.au> | 2013-06-07 01:24:46 -0400 |
commit | 9051e9125bf1088780c84deef6e16cf1c01f035c (patch) | |
tree | 9c343a6f706c8c4fe634cca32685b86ab22afd70 | |
parent | b89edf344696e7783312a370b6477beea90116f9 (diff) |
ARM: shmobile: r8a73a4: add div6 clocks
DIV6 clocks control each core clocks.
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
-rw-r--r-- | arch/arm/mach-shmobile/clock-r8a73a4.c | 182 |
1 files changed, 163 insertions, 19 deletions
diff --git a/arch/arm/mach-shmobile/clock-r8a73a4.c b/arch/arm/mach-shmobile/clock-r8a73a4.c index 147314ac6a14..f6227bb10aca 100644 --- a/arch/arm/mach-shmobile/clock-r8a73a4.c +++ b/arch/arm/mach-shmobile/clock-r8a73a4.c | |||
@@ -28,19 +28,34 @@ | |||
28 | #define CPG_BASE 0xe6150000 | 28 | #define CPG_BASE 0xe6150000 |
29 | #define CPG_LEN 0x270 | 29 | #define CPG_LEN 0x270 |
30 | 30 | ||
31 | #define MPCKCR 0xe6150080 | ||
32 | #define SMSTPCR2 0xe6150138 | 31 | #define SMSTPCR2 0xe6150138 |
33 | #define SMSTPCR5 0xe6150144 | 32 | #define SMSTPCR5 0xe6150144 |
34 | 33 | ||
35 | #define FRQCRA 0xE6150000 | 34 | #define FRQCRA 0xE6150000 |
36 | #define FRQCRB 0xE6150004 | 35 | #define FRQCRB 0xE6150004 |
37 | #define CKSCR 0xE61500C0 | 36 | #define VCLKCR1 0xE6150008 |
37 | #define VCLKCR2 0xE615000C | ||
38 | #define VCLKCR3 0xE615001C | ||
39 | #define VCLKCR4 0xE6150014 | ||
40 | #define VCLKCR5 0xE6150034 | ||
41 | #define ZBCKCR 0xE6150010 | ||
42 | #define SD0CKCR 0xE6150074 | ||
43 | #define SD1CKCR 0xE6150078 | ||
44 | #define SD2CKCR 0xE615007C | ||
45 | #define MMC0CKCR 0xE6150240 | ||
46 | #define MMC1CKCR 0xE6150244 | ||
47 | #define FSIACKCR 0xE6150018 | ||
48 | #define FSIBCKCR 0xE6150090 | ||
49 | #define MPCKCR 0xe6150080 | ||
50 | #define SPUVCKCR 0xE6150094 | ||
51 | #define HSICKCR 0xE615026C | ||
52 | #define M4CKCR 0xE6150098 | ||
38 | #define PLLECR 0xE61500D0 | 53 | #define PLLECR 0xE61500D0 |
39 | #define PLL1CR 0xE6150028 | 54 | #define PLL1CR 0xE6150028 |
40 | #define PLL2CR 0xE615002C | 55 | #define PLL2CR 0xE615002C |
41 | #define PLL2SCR 0xE61501F4 | 56 | #define PLL2SCR 0xE61501F4 |
42 | #define PLL2HCR 0xE61501E4 | 57 | #define PLL2HCR 0xE61501E4 |
43 | 58 | #define CKSCR 0xE61500C0 | |
44 | 59 | ||
45 | #define CPG_MAP(o) ((o - CPG_BASE) + cpg_mapping.base) | 60 | #define CPG_MAP(o) ((o - CPG_BASE) + cpg_mapping.base) |
46 | 61 | ||
@@ -81,6 +96,13 @@ SH_FIXED_RATIO_CLK(extal1_div2_clk, extal1_clk, div2); | |||
81 | SH_FIXED_RATIO_CLK(extal2_div2_clk, extal2_clk, div2); | 96 | SH_FIXED_RATIO_CLK(extal2_div2_clk, extal2_clk, div2); |
82 | SH_FIXED_RATIO_CLK(extal2_div4_clk, extal2_clk, div4); | 97 | SH_FIXED_RATIO_CLK(extal2_div4_clk, extal2_clk, div4); |
83 | 98 | ||
99 | /* External FSIACK/FSIBCK clock */ | ||
100 | static struct clk fsiack_clk = { | ||
101 | }; | ||
102 | |||
103 | static struct clk fsibck_clk = { | ||
104 | }; | ||
105 | |||
84 | /* | 106 | /* |
85 | * PLL clocks | 107 | * PLL clocks |
86 | */ | 108 | */ |
@@ -170,6 +192,8 @@ static struct clk *main_clks[] = { | |||
170 | &extal2_div4_clk, | 192 | &extal2_div4_clk, |
171 | &main_clk, | 193 | &main_clk, |
172 | &main_div2_clk, | 194 | &main_div2_clk, |
195 | &fsiack_clk, | ||
196 | &fsibck_clk, | ||
173 | &pll1_clk, | 197 | &pll1_clk, |
174 | &pll1_div2_clk, | 198 | &pll1_div2_clk, |
175 | &pll2_clk, | 199 | &pll2_clk, |
@@ -216,6 +240,111 @@ static struct clk div4_clks[DIV4_NR] = { | |||
216 | [DIV4_HP] = SH_CLK_DIV4(&pll1_clk, FRQCRB, 4, 0x0dff, 0), | 240 | [DIV4_HP] = SH_CLK_DIV4(&pll1_clk, FRQCRB, 4, 0x0dff, 0), |
217 | }; | 241 | }; |
218 | 242 | ||
243 | enum { | ||
244 | DIV6_ZB, | ||
245 | DIV6_SDHI0, DIV6_SDHI1, DIV6_SDHI2, | ||
246 | DIV6_MMC0, DIV6_MMC1, | ||
247 | DIV6_VCK1, DIV6_VCK2, DIV6_VCK3, DIV6_VCK4, DIV6_VCK5, | ||
248 | DIV6_FSIA, DIV6_FSIB, | ||
249 | DIV6_MP, DIV6_M4, DIV6_HSI, DIV6_SPUV, | ||
250 | DIV6_NR }; | ||
251 | |||
252 | static struct clk *div6_parents[8] = { | ||
253 | [0] = &pll1_div2_clk, | ||
254 | [1] = &pll2s_clk, | ||
255 | [3] = &extal2_clk, | ||
256 | [4] = &main_div2_clk, | ||
257 | [6] = &extalr_clk, | ||
258 | }; | ||
259 | |||
260 | static struct clk *fsia_parents[4] = { | ||
261 | [0] = &pll1_div2_clk, | ||
262 | [1] = &pll2s_clk, | ||
263 | [2] = &fsiack_clk, | ||
264 | }; | ||
265 | |||
266 | static struct clk *fsib_parents[4] = { | ||
267 | [0] = &pll1_div2_clk, | ||
268 | [1] = &pll2s_clk, | ||
269 | [2] = &fsibck_clk, | ||
270 | }; | ||
271 | |||
272 | static struct clk *mp_parents[4] = { | ||
273 | [0] = &pll1_div2_clk, | ||
274 | [1] = &pll2s_clk, | ||
275 | [2] = &extal2_clk, | ||
276 | [3] = &extal2_clk, | ||
277 | }; | ||
278 | |||
279 | static struct clk *m4_parents[2] = { | ||
280 | [0] = &pll2s_clk, | ||
281 | }; | ||
282 | |||
283 | static struct clk *hsi_parents[4] = { | ||
284 | [0] = &pll2h_clk, | ||
285 | [1] = &pll1_div2_clk, | ||
286 | [3] = &pll2s_clk, | ||
287 | }; | ||
288 | |||
289 | /*** FIXME *** | ||
290 | * SH_CLK_DIV6_EXT() macro doesn't care .mapping | ||
291 | * but, it is necessary on R-Car (= ioremap() base CPG) | ||
292 | * The difference between | ||
293 | * SH_CLK_DIV6_EXT() <--> SH_CLK_MAP_DIV6_EXT() | ||
294 | * is only .mapping | ||
295 | */ | ||
296 | #define SH_CLK_MAP_DIV6_EXT(_reg, _flags, _parents, \ | ||
297 | _num_parents, _src_shift, _src_width) \ | ||
298 | { \ | ||
299 | .enable_reg = (void __iomem *)_reg, \ | ||
300 | .enable_bit = 0, /* unused */ \ | ||
301 | .flags = _flags | CLK_MASK_DIV_ON_DISABLE, \ | ||
302 | .div_mask = SH_CLK_DIV6_MSK, \ | ||
303 | .parent_table = _parents, \ | ||
304 | .parent_num = _num_parents, \ | ||
305 | .src_shift = _src_shift, \ | ||
306 | .src_width = _src_width, \ | ||
307 | .mapping = &cpg_mapping, \ | ||
308 | } | ||
309 | |||
310 | static struct clk div6_clks[DIV6_NR] = { | ||
311 | [DIV6_ZB] = SH_CLK_MAP_DIV6_EXT(ZBCKCR, CLK_ENABLE_ON_INIT, | ||
312 | div6_parents, 2, 7, 1), | ||
313 | [DIV6_SDHI0] = SH_CLK_MAP_DIV6_EXT(SD0CKCR, 0, | ||
314 | div6_parents, 2, 6, 2), | ||
315 | [DIV6_SDHI1] = SH_CLK_MAP_DIV6_EXT(SD1CKCR, 0, | ||
316 | div6_parents, 2, 6, 2), | ||
317 | [DIV6_SDHI2] = SH_CLK_MAP_DIV6_EXT(SD2CKCR, 0, | ||
318 | div6_parents, 2, 6, 2), | ||
319 | [DIV6_MMC0] = SH_CLK_MAP_DIV6_EXT(MMC0CKCR, 0, | ||
320 | div6_parents, 2, 6, 2), | ||
321 | [DIV6_MMC1] = SH_CLK_MAP_DIV6_EXT(MMC1CKCR, 0, | ||
322 | div6_parents, 2, 6, 2), | ||
323 | [DIV6_VCK1] = SH_CLK_MAP_DIV6_EXT(VCLKCR1, 0, /* didn't care bit[6-7] */ | ||
324 | div6_parents, ARRAY_SIZE(div6_parents), 12, 3), | ||
325 | [DIV6_VCK2] = SH_CLK_MAP_DIV6_EXT(VCLKCR2, 0, /* didn't care bit[6-7] */ | ||
326 | div6_parents, ARRAY_SIZE(div6_parents), 12, 3), | ||
327 | [DIV6_VCK3] = SH_CLK_MAP_DIV6_EXT(VCLKCR3, 0, /* didn't care bit[6-7] */ | ||
328 | div6_parents, ARRAY_SIZE(div6_parents), 12, 3), | ||
329 | [DIV6_VCK4] = SH_CLK_MAP_DIV6_EXT(VCLKCR4, 0, /* didn't care bit[6-7] */ | ||
330 | div6_parents, ARRAY_SIZE(div6_parents), 12, 3), | ||
331 | [DIV6_VCK5] = SH_CLK_MAP_DIV6_EXT(VCLKCR5, 0, /* didn't care bit[6-7] */ | ||
332 | div6_parents, ARRAY_SIZE(div6_parents), 12, 3), | ||
333 | [DIV6_FSIA] = SH_CLK_MAP_DIV6_EXT(FSIACKCR, 0, | ||
334 | fsia_parents, ARRAY_SIZE(fsia_parents), 6, 2), | ||
335 | [DIV6_FSIB] = SH_CLK_MAP_DIV6_EXT(FSIBCKCR, 0, | ||
336 | fsib_parents, ARRAY_SIZE(fsib_parents), 6, 2), | ||
337 | [DIV6_MP] = SH_CLK_MAP_DIV6_EXT(MPCKCR, 0, /* it needs bit[9-11] control */ | ||
338 | mp_parents, ARRAY_SIZE(mp_parents), 6, 2), | ||
339 | /* pll2s will be selected always for M4 */ | ||
340 | [DIV6_M4] = SH_CLK_MAP_DIV6_EXT(M4CKCR, 0, /* it needs bit[9] control */ | ||
341 | m4_parents, ARRAY_SIZE(m4_parents), 6, 1), | ||
342 | [DIV6_HSI] = SH_CLK_MAP_DIV6_EXT(HSICKCR, 0, /* it needs bit[9] control */ | ||
343 | hsi_parents, ARRAY_SIZE(hsi_parents), 6, 2), | ||
344 | [DIV6_SPUV] = SH_CLK_MAP_DIV6_EXT(SPUVCKCR, 0, | ||
345 | mp_parents, ARRAY_SIZE(mp_parents), 6, 2), | ||
346 | }; | ||
347 | |||
219 | /* MSTP */ | 348 | /* MSTP */ |
220 | enum { | 349 | enum { |
221 | MSTP217, MSTP216, MSTP207, MSTP206, MSTP204, MSTP203, | 350 | MSTP217, MSTP216, MSTP207, MSTP206, MSTP204, MSTP203, |
@@ -224,12 +353,12 @@ enum { | |||
224 | }; | 353 | }; |
225 | 354 | ||
226 | static struct clk mstp_clks[MSTP_NR] = { | 355 | static struct clk mstp_clks[MSTP_NR] = { |
227 | [MSTP204] = SH_CLK_MSTP32(&extal2_clk, SMSTPCR2, 4, 0), /* SCIFA0 */ | 356 | [MSTP204] = SH_CLK_MSTP32(&div6_clks[DIV6_MP], SMSTPCR2, 4, 0), /* SCIFA0 */ |
228 | [MSTP203] = SH_CLK_MSTP32(&extal2_clk, SMSTPCR2, 3, 0), /* SCIFA1 */ | 357 | [MSTP203] = SH_CLK_MSTP32(&div6_clks[DIV6_MP], SMSTPCR2, 3, 0), /* SCIFA1 */ |
229 | [MSTP206] = SH_CLK_MSTP32(&extal2_clk, SMSTPCR2, 6, 0), /* SCIFB0 */ | 358 | [MSTP206] = SH_CLK_MSTP32(&div6_clks[DIV6_MP], SMSTPCR2, 6, 0), /* SCIFB0 */ |
230 | [MSTP207] = SH_CLK_MSTP32(&extal2_clk, SMSTPCR2, 7, 0), /* SCIFB1 */ | 359 | [MSTP207] = SH_CLK_MSTP32(&div6_clks[DIV6_MP], SMSTPCR2, 7, 0), /* SCIFB1 */ |
231 | [MSTP216] = SH_CLK_MSTP32(&extal2_clk, SMSTPCR2, 16, 0), /* SCIFB2 */ | 360 | [MSTP216] = SH_CLK_MSTP32(&div6_clks[DIV6_MP], SMSTPCR2, 16, 0), /* SCIFB2 */ |
232 | [MSTP217] = SH_CLK_MSTP32(&extal2_clk, SMSTPCR2, 17, 0), /* SCIFB3 */ | 361 | [MSTP217] = SH_CLK_MSTP32(&div6_clks[DIV6_MP], SMSTPCR2, 17, 0), /* SCIFB3 */ |
233 | [MSTP522] = SH_CLK_MSTP32(&extal2_clk, SMSTPCR5, 22, 0), /* Thermal */ | 362 | [MSTP522] = SH_CLK_MSTP32(&extal2_clk, SMSTPCR5, 22, 0), /* Thermal */ |
234 | }; | 363 | }; |
235 | 364 | ||
@@ -240,6 +369,8 @@ static struct clk_lookup lookups[] = { | |||
240 | CLKDEV_CON_ID("extal2", &extal2_clk), | 369 | CLKDEV_CON_ID("extal2", &extal2_clk), |
241 | CLKDEV_CON_ID("extal2_div2", &extal2_div2_clk), | 370 | CLKDEV_CON_ID("extal2_div2", &extal2_div2_clk), |
242 | CLKDEV_CON_ID("extal2_div4", &extal2_div4_clk), | 371 | CLKDEV_CON_ID("extal2_div4", &extal2_div4_clk), |
372 | CLKDEV_CON_ID("fsiack", &fsiack_clk), | ||
373 | CLKDEV_CON_ID("fsibck", &fsibck_clk), | ||
243 | 374 | ||
244 | /* pll clock */ | 375 | /* pll clock */ |
245 | CLKDEV_CON_ID("pll1", &pll1_clk), | 376 | CLKDEV_CON_ID("pll1", &pll1_clk), |
@@ -248,6 +379,25 @@ static struct clk_lookup lookups[] = { | |||
248 | CLKDEV_CON_ID("pll2s", &pll2s_clk), | 379 | CLKDEV_CON_ID("pll2s", &pll2s_clk), |
249 | CLKDEV_CON_ID("pll2h", &pll2h_clk), | 380 | CLKDEV_CON_ID("pll2h", &pll2h_clk), |
250 | 381 | ||
382 | /* DIV6 */ | ||
383 | CLKDEV_CON_ID("zb", &div6_clks[DIV6_ZB]), | ||
384 | CLKDEV_CON_ID("sdhi0", &div6_clks[DIV6_SDHI0]), | ||
385 | CLKDEV_CON_ID("sdhi1", &div6_clks[DIV6_SDHI1]), | ||
386 | CLKDEV_CON_ID("sdhi2", &div6_clks[DIV6_SDHI2]), | ||
387 | CLKDEV_CON_ID("mmc0", &div6_clks[DIV6_MMC0]), | ||
388 | CLKDEV_CON_ID("mmc1", &div6_clks[DIV6_MMC1]), | ||
389 | CLKDEV_CON_ID("vck1", &div6_clks[DIV6_VCK1]), | ||
390 | CLKDEV_CON_ID("vck2", &div6_clks[DIV6_VCK2]), | ||
391 | CLKDEV_CON_ID("vck3", &div6_clks[DIV6_VCK3]), | ||
392 | CLKDEV_CON_ID("vck4", &div6_clks[DIV6_VCK4]), | ||
393 | CLKDEV_CON_ID("vck5", &div6_clks[DIV6_VCK5]), | ||
394 | CLKDEV_CON_ID("fsia", &div6_clks[DIV6_FSIA]), | ||
395 | CLKDEV_CON_ID("fsib", &div6_clks[DIV6_FSIB]), | ||
396 | CLKDEV_CON_ID("mp", &div6_clks[DIV6_MP]), | ||
397 | CLKDEV_CON_ID("m4", &div6_clks[DIV6_M4]), | ||
398 | CLKDEV_CON_ID("hsi", &div6_clks[DIV6_HSI]), | ||
399 | CLKDEV_CON_ID("spuv", &div6_clks[DIV6_SPUV]), | ||
400 | |||
251 | /* MSTP */ | 401 | /* MSTP */ |
252 | CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[MSTP204]), | 402 | CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[MSTP204]), |
253 | CLKDEV_DEV_ID("sh-sci.1", &mstp_clks[MSTP203]), | 403 | CLKDEV_DEV_ID("sh-sci.1", &mstp_clks[MSTP203]), |
@@ -263,19 +413,10 @@ static struct clk_lookup lookups[] = { | |||
263 | 413 | ||
264 | void __init r8a73a4_clock_init(void) | 414 | void __init r8a73a4_clock_init(void) |
265 | { | 415 | { |
266 | void __iomem *cpg_base, *reg; | 416 | void __iomem *reg; |
267 | int k, ret = 0; | 417 | int k, ret = 0; |
268 | u32 ckscr; | 418 | u32 ckscr; |
269 | 419 | ||
270 | /* fix MPCLK to EXTAL2 for now. | ||
271 | * this is needed until more detailed clock topology is supported | ||
272 | */ | ||
273 | cpg_base = ioremap_nocache(CPG_BASE, CPG_LEN); | ||
274 | BUG_ON(!cpg_base); | ||
275 | reg = cpg_base + (MPCKCR - CPG_BASE); | ||
276 | iowrite32(ioread32(reg) | 1 << 7 | 0x0c, reg); /* set CKSEL */ | ||
277 | iounmap(cpg_base); | ||
278 | |||
279 | reg = ioremap_nocache(CKSCR, PAGE_SIZE); | 420 | reg = ioremap_nocache(CKSCR, PAGE_SIZE); |
280 | BUG_ON(!reg); | 421 | BUG_ON(!reg); |
281 | ckscr = ioread32(reg); | 422 | ckscr = ioread32(reg); |
@@ -303,6 +444,9 @@ void __init r8a73a4_clock_init(void) | |||
303 | ret = sh_clk_div4_register(div4_clks, DIV4_NR, &div4_table); | 444 | ret = sh_clk_div4_register(div4_clks, DIV4_NR, &div4_table); |
304 | 445 | ||
305 | if (!ret) | 446 | if (!ret) |
447 | ret = sh_clk_div6_reparent_register(div6_clks, DIV6_NR); | ||
448 | |||
449 | if (!ret) | ||
306 | ret = sh_clk_mstp_register(mstp_clks, MSTP_NR); | 450 | ret = sh_clk_mstp_register(mstp_clks, MSTP_NR); |
307 | 451 | ||
308 | clkdev_add_table(lookups, ARRAY_SIZE(lookups)); | 452 | clkdev_add_table(lookups, ARRAY_SIZE(lookups)); |