diff options
Diffstat (limited to 'arch/arm/mach-shmobile/clock-r8a7740.c')
-rw-r--r-- | arch/arm/mach-shmobile/clock-r8a7740.c | 150 |
1 files changed, 147 insertions, 3 deletions
diff --git a/arch/arm/mach-shmobile/clock-r8a7740.c b/arch/arm/mach-shmobile/clock-r8a7740.c index 26eea5f21054..ad5fccc7b5e7 100644 --- a/arch/arm/mach-shmobile/clock-r8a7740.c +++ b/arch/arm/mach-shmobile/clock-r8a7740.c | |||
@@ -43,7 +43,10 @@ | |||
43 | /* CPG registers */ | 43 | /* CPG registers */ |
44 | #define FRQCRA 0xe6150000 | 44 | #define FRQCRA 0xe6150000 |
45 | #define FRQCRB 0xe6150004 | 45 | #define FRQCRB 0xe6150004 |
46 | #define VCLKCR1 0xE6150008 | ||
47 | #define VCLKCR2 0xE615000c | ||
46 | #define FRQCRC 0xe61500e0 | 48 | #define FRQCRC 0xe61500e0 |
49 | #define FSIACKCR 0xe6150018 | ||
47 | #define PLLC01CR 0xe6150028 | 50 | #define PLLC01CR 0xe6150028 |
48 | 51 | ||
49 | #define SUBCKCR 0xe6150080 | 52 | #define SUBCKCR 0xe6150080 |
@@ -54,6 +57,8 @@ | |||
54 | #define MSTPSR2 0xe6150040 | 57 | #define MSTPSR2 0xe6150040 |
55 | #define MSTPSR3 0xe6150048 | 58 | #define MSTPSR3 0xe6150048 |
56 | #define MSTPSR4 0xe615004c | 59 | #define MSTPSR4 0xe615004c |
60 | #define FSIBCKCR 0xe6150090 | ||
61 | #define HDMICKCR 0xe6150094 | ||
57 | #define SMSTPCR0 0xe6150130 | 62 | #define SMSTPCR0 0xe6150130 |
58 | #define SMSTPCR1 0xe6150134 | 63 | #define SMSTPCR1 0xe6150134 |
59 | #define SMSTPCR2 0xe6150138 | 64 | #define SMSTPCR2 0xe6150138 |
@@ -271,6 +276,13 @@ static struct clk usb24_clk = { | |||
271 | .parent = &usb24s_clk, | 276 | .parent = &usb24s_clk, |
272 | }; | 277 | }; |
273 | 278 | ||
279 | /* External FSIACK/FSIBCK clock */ | ||
280 | static struct clk fsiack_clk = { | ||
281 | }; | ||
282 | |||
283 | static struct clk fsibck_clk = { | ||
284 | }; | ||
285 | |||
274 | struct clk *main_clks[] = { | 286 | struct clk *main_clks[] = { |
275 | &extalr_clk, | 287 | &extalr_clk, |
276 | &extal1_clk, | 288 | &extal1_clk, |
@@ -288,6 +300,8 @@ struct clk *main_clks[] = { | |||
288 | &pllc1_div2_clk, | 300 | &pllc1_div2_clk, |
289 | &usb24s_clk, | 301 | &usb24s_clk, |
290 | &usb24_clk, | 302 | &usb24_clk, |
303 | &fsiack_clk, | ||
304 | &fsibck_clk, | ||
291 | }; | 305 | }; |
292 | 306 | ||
293 | static void div4_kick(struct clk *clk) | 307 | static void div4_kick(struct clk *clk) |
@@ -313,6 +327,107 @@ static struct clk_div4_table div4_table = { | |||
313 | .kick = div4_kick, | 327 | .kick = div4_kick, |
314 | }; | 328 | }; |
315 | 329 | ||
330 | /* DIV6 reparent */ | ||
331 | enum { | ||
332 | DIV6_HDMI, | ||
333 | DIV6_VCLK1, DIV6_VCLK2, | ||
334 | DIV6_FSIA, DIV6_FSIB, | ||
335 | DIV6_REPARENT_NR, | ||
336 | }; | ||
337 | |||
338 | static struct clk *hdmi_parent[] = { | ||
339 | [0] = &pllc1_div2_clk, | ||
340 | [1] = &system_clk, | ||
341 | [2] = &dv_clk | ||
342 | }; | ||
343 | |||
344 | static struct clk *vclk_parents[8] = { | ||
345 | [0] = &pllc1_div2_clk, | ||
346 | [2] = &dv_clk, | ||
347 | [3] = &usb24s_clk, | ||
348 | [4] = &extal1_div2_clk, | ||
349 | [5] = &extalr_clk, | ||
350 | }; | ||
351 | |||
352 | static struct clk *fsia_parents[] = { | ||
353 | [0] = &pllc1_div2_clk, | ||
354 | [1] = &fsiack_clk, /* external clock */ | ||
355 | }; | ||
356 | |||
357 | static struct clk *fsib_parents[] = { | ||
358 | [0] = &pllc1_div2_clk, | ||
359 | [1] = &fsibck_clk, /* external clock */ | ||
360 | }; | ||
361 | |||
362 | static struct clk div6_reparent_clks[DIV6_REPARENT_NR] = { | ||
363 | [DIV6_HDMI] = SH_CLK_DIV6_EXT(HDMICKCR, 0, | ||
364 | hdmi_parent, ARRAY_SIZE(hdmi_parent), 6, 2), | ||
365 | [DIV6_VCLK1] = SH_CLK_DIV6_EXT(VCLKCR1, 0, | ||
366 | vclk_parents, ARRAY_SIZE(vclk_parents), 12, 3), | ||
367 | [DIV6_VCLK2] = SH_CLK_DIV6_EXT(VCLKCR2, 0, | ||
368 | vclk_parents, ARRAY_SIZE(vclk_parents), 12, 3), | ||
369 | [DIV6_FSIA] = SH_CLK_DIV6_EXT(FSIACKCR, 0, | ||
370 | fsia_parents, ARRAY_SIZE(fsia_parents), 6, 2), | ||
371 | [DIV6_FSIB] = SH_CLK_DIV6_EXT(FSIBCKCR, 0, | ||
372 | fsib_parents, ARRAY_SIZE(fsib_parents), 6, 2), | ||
373 | }; | ||
374 | |||
375 | /* HDMI1/2 clock */ | ||
376 | static unsigned long hdmi12_recalc(struct clk *clk) | ||
377 | { | ||
378 | u32 val = __raw_readl(HDMICKCR); | ||
379 | int shift = (int)clk->priv; | ||
380 | |||
381 | val >>= shift; | ||
382 | val &= 0x3; | ||
383 | |||
384 | return clk->parent->rate / (1 << val); | ||
385 | }; | ||
386 | |||
387 | static int hdmi12_set_rate(struct clk *clk, unsigned long rate) | ||
388 | { | ||
389 | u32 val, mask; | ||
390 | int i, shift; | ||
391 | |||
392 | for (i = 0; i < 3; i++) | ||
393 | if (rate == clk->parent->rate / (1 << i)) | ||
394 | goto find; | ||
395 | return -ENODEV; | ||
396 | |||
397 | find: | ||
398 | shift = (int)clk->priv; | ||
399 | |||
400 | val = __raw_readl(HDMICKCR); | ||
401 | mask = ~(0x3 << shift); | ||
402 | val = (val & mask) | i << shift; | ||
403 | __raw_writel(val, HDMICKCR); | ||
404 | |||
405 | return 0; | ||
406 | }; | ||
407 | |||
408 | static struct sh_clk_ops hdmi12_clk_ops = { | ||
409 | .recalc = hdmi12_recalc, | ||
410 | .set_rate = hdmi12_set_rate, | ||
411 | }; | ||
412 | |||
413 | static struct clk hdmi1_clk = { | ||
414 | .ops = &hdmi12_clk_ops, | ||
415 | .priv = (void *)9, | ||
416 | .parent = &div6_reparent_clks[DIV6_HDMI], /* late install */ | ||
417 | }; | ||
418 | |||
419 | static struct clk hdmi2_clk = { | ||
420 | .ops = &hdmi12_clk_ops, | ||
421 | .priv = (void *)11, | ||
422 | .parent = &div6_reparent_clks[DIV6_HDMI], /* late install */ | ||
423 | }; | ||
424 | |||
425 | static struct clk *late_main_clks[] = { | ||
426 | &hdmi1_clk, | ||
427 | &hdmi2_clk, | ||
428 | }; | ||
429 | |||
430 | /* MSTP */ | ||
316 | enum { | 431 | enum { |
317 | DIV4_I, DIV4_ZG, DIV4_B, DIV4_M1, DIV4_HP, | 432 | DIV4_I, DIV4_ZG, DIV4_B, DIV4_M1, DIV4_HP, |
318 | DIV4_HPP, DIV4_USBP, DIV4_S, DIV4_ZB, DIV4_M3, DIV4_CP, | 433 | DIV4_HPP, DIV4_USBP, DIV4_S, DIV4_ZB, DIV4_M3, DIV4_CP, |
@@ -343,11 +458,12 @@ static struct clk div6_clks[DIV6_NR] = { | |||
343 | }; | 458 | }; |
344 | 459 | ||
345 | enum { | 460 | enum { |
346 | MSTP125, | 461 | MSTP128, MSTP127, MSTP125, |
347 | MSTP116, MSTP111, MSTP100, MSTP117, | 462 | MSTP116, MSTP111, MSTP100, MSTP117, |
348 | 463 | ||
349 | MSTP230, | 464 | MSTP230, |
350 | MSTP222, | 465 | MSTP222, |
466 | MSTP218, MSTP217, MSTP216, MSTP214, | ||
351 | MSTP207, MSTP206, MSTP204, MSTP203, MSTP202, MSTP201, MSTP200, | 467 | MSTP207, MSTP206, MSTP204, MSTP203, MSTP202, MSTP201, MSTP200, |
352 | 468 | ||
353 | MSTP329, MSTP328, MSTP323, MSTP320, | 469 | MSTP329, MSTP328, MSTP323, MSTP320, |
@@ -360,6 +476,8 @@ enum { | |||
360 | }; | 476 | }; |
361 | 477 | ||
362 | static struct clk mstp_clks[MSTP_NR] = { | 478 | static struct clk mstp_clks[MSTP_NR] = { |
479 | [MSTP128] = SH_CLK_MSTP32(&div4_clks[DIV4_S], SMSTPCR1, 28, 0), /* CEU21 */ | ||
480 | [MSTP127] = SH_CLK_MSTP32(&div4_clks[DIV4_S], SMSTPCR1, 27, 0), /* CEU20 */ | ||
363 | [MSTP125] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR1, 25, 0), /* TMU0 */ | 481 | [MSTP125] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR1, 25, 0), /* TMU0 */ |
364 | [MSTP117] = SH_CLK_MSTP32(&div4_clks[DIV4_B], SMSTPCR1, 17, 0), /* LCDC1 */ | 482 | [MSTP117] = SH_CLK_MSTP32(&div4_clks[DIV4_B], SMSTPCR1, 17, 0), /* LCDC1 */ |
365 | [MSTP116] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR1, 16, 0), /* IIC0 */ | 483 | [MSTP116] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR1, 16, 0), /* IIC0 */ |
@@ -368,6 +486,10 @@ static struct clk mstp_clks[MSTP_NR] = { | |||
368 | 486 | ||
369 | [MSTP230] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR2, 30, 0), /* SCIFA6 */ | 487 | [MSTP230] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR2, 30, 0), /* SCIFA6 */ |
370 | [MSTP222] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR2, 22, 0), /* SCIFA7 */ | 488 | [MSTP222] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR2, 22, 0), /* SCIFA7 */ |
489 | [MSTP218] = SH_CLK_MSTP32(&div4_clks[DIV4_HP], SMSTPCR2, 18, 0), /* DMAC1 */ | ||
490 | [MSTP217] = SH_CLK_MSTP32(&div4_clks[DIV4_HP], SMSTPCR2, 17, 0), /* DMAC2 */ | ||
491 | [MSTP216] = SH_CLK_MSTP32(&div4_clks[DIV4_HP], SMSTPCR2, 16, 0), /* DMAC3 */ | ||
492 | [MSTP214] = SH_CLK_MSTP32(&div4_clks[DIV4_HP], SMSTPCR2, 14, 0), /* USBDMAC */ | ||
371 | [MSTP207] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR2, 7, 0), /* SCIFA5 */ | 493 | [MSTP207] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR2, 7, 0), /* SCIFA5 */ |
372 | [MSTP206] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR2, 6, 0), /* SCIFB */ | 494 | [MSTP206] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR2, 6, 0), /* SCIFB */ |
373 | [MSTP204] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR2, 4, 0), /* SCIFA0 */ | 495 | [MSTP204] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR2, 4, 0), /* SCIFA0 */ |
@@ -408,6 +530,12 @@ static struct clk_lookup lookups[] = { | |||
408 | CLKDEV_CON_ID("pllc1_clk", &pllc1_clk), | 530 | CLKDEV_CON_ID("pllc1_clk", &pllc1_clk), |
409 | CLKDEV_CON_ID("pllc1_div2_clk", &pllc1_div2_clk), | 531 | CLKDEV_CON_ID("pllc1_div2_clk", &pllc1_div2_clk), |
410 | CLKDEV_CON_ID("usb24s", &usb24s_clk), | 532 | CLKDEV_CON_ID("usb24s", &usb24s_clk), |
533 | CLKDEV_CON_ID("hdmi1", &hdmi1_clk), | ||
534 | CLKDEV_CON_ID("hdmi2", &hdmi2_clk), | ||
535 | CLKDEV_CON_ID("video1", &div6_reparent_clks[DIV6_VCLK1]), | ||
536 | CLKDEV_CON_ID("video2", &div6_reparent_clks[DIV6_VCLK2]), | ||
537 | CLKDEV_CON_ID("fsiack", &fsiack_clk), | ||
538 | CLKDEV_CON_ID("fsibck", &fsibck_clk), | ||
411 | 539 | ||
412 | /* DIV4 clocks */ | 540 | /* DIV4 clocks */ |
413 | CLKDEV_CON_ID("i_clk", &div4_clks[DIV4_I]), | 541 | CLKDEV_CON_ID("i_clk", &div4_clks[DIV4_I]), |
@@ -430,6 +558,8 @@ static struct clk_lookup lookups[] = { | |||
430 | CLKDEV_DEV_ID("i2c-sh_mobile.0", &mstp_clks[MSTP116]), | 558 | CLKDEV_DEV_ID("i2c-sh_mobile.0", &mstp_clks[MSTP116]), |
431 | CLKDEV_DEV_ID("sh_mobile_lcdc_fb.1", &mstp_clks[MSTP117]), | 559 | CLKDEV_DEV_ID("sh_mobile_lcdc_fb.1", &mstp_clks[MSTP117]), |
432 | CLKDEV_DEV_ID("sh_tmu.0", &mstp_clks[MSTP125]), | 560 | CLKDEV_DEV_ID("sh_tmu.0", &mstp_clks[MSTP125]), |
561 | CLKDEV_DEV_ID("sh_mobile_ceu.0", &mstp_clks[MSTP127]), | ||
562 | CLKDEV_DEV_ID("sh_mobile_ceu.1", &mstp_clks[MSTP128]), | ||
433 | 563 | ||
434 | CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP200]), | 564 | CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP200]), |
435 | CLKDEV_DEV_ID("sh-sci.3", &mstp_clks[MSTP201]), | 565 | CLKDEV_DEV_ID("sh-sci.3", &mstp_clks[MSTP201]), |
@@ -438,7 +568,10 @@ static struct clk_lookup lookups[] = { | |||
438 | CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[MSTP204]), | 568 | CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[MSTP204]), |
439 | CLKDEV_DEV_ID("sh-sci.8", &mstp_clks[MSTP206]), | 569 | CLKDEV_DEV_ID("sh-sci.8", &mstp_clks[MSTP206]), |
440 | CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[MSTP207]), | 570 | CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[MSTP207]), |
441 | 571 | CLKDEV_DEV_ID("sh-dma-engine.3", &mstp_clks[MSTP214]), | |
572 | CLKDEV_DEV_ID("sh-dma-engine.2", &mstp_clks[MSTP216]), | ||
573 | CLKDEV_DEV_ID("sh-dma-engine.1", &mstp_clks[MSTP217]), | ||
574 | CLKDEV_DEV_ID("sh-dma-engine.0", &mstp_clks[MSTP218]), | ||
442 | CLKDEV_DEV_ID("sh-sci.7", &mstp_clks[MSTP222]), | 575 | CLKDEV_DEV_ID("sh-sci.7", &mstp_clks[MSTP222]), |
443 | CLKDEV_DEV_ID("sh-sci.6", &mstp_clks[MSTP230]), | 576 | CLKDEV_DEV_ID("sh-sci.6", &mstp_clks[MSTP230]), |
444 | 577 | ||
@@ -459,6 +592,10 @@ static struct clk_lookup lookups[] = { | |||
459 | CLKDEV_ICK_ID("phy", "renesas_usbhs", &mstp_clks[MSTP406]), | 592 | CLKDEV_ICK_ID("phy", "renesas_usbhs", &mstp_clks[MSTP406]), |
460 | CLKDEV_ICK_ID("pci", "renesas_usbhs", &div4_clks[DIV4_USBP]), | 593 | CLKDEV_ICK_ID("pci", "renesas_usbhs", &div4_clks[DIV4_USBP]), |
461 | CLKDEV_ICK_ID("usb24", "renesas_usbhs", &usb24_clk), | 594 | CLKDEV_ICK_ID("usb24", "renesas_usbhs", &usb24_clk), |
595 | CLKDEV_ICK_ID("ick", "sh-mobile-hdmi", &div6_reparent_clks[DIV6_HDMI]), | ||
596 | |||
597 | CLKDEV_ICK_ID("icka", "sh_fsi2", &div6_reparent_clks[DIV6_FSIA]), | ||
598 | CLKDEV_ICK_ID("ickb", "sh_fsi2", &div6_reparent_clks[DIV6_FSIB]), | ||
462 | }; | 599 | }; |
463 | 600 | ||
464 | void __init r8a7740_clock_init(u8 md_ck) | 601 | void __init r8a7740_clock_init(u8 md_ck) |
@@ -495,7 +632,14 @@ void __init r8a7740_clock_init(u8 md_ck) | |||
495 | ret = sh_clk_div6_register(div6_clks, DIV6_NR); | 632 | ret = sh_clk_div6_register(div6_clks, DIV6_NR); |
496 | 633 | ||
497 | if (!ret) | 634 | if (!ret) |
498 | ret = sh_clk_mstp32_register(mstp_clks, MSTP_NR); | 635 | ret = sh_clk_div6_reparent_register(div6_reparent_clks, |
636 | DIV6_REPARENT_NR); | ||
637 | |||
638 | if (!ret) | ||
639 | ret = sh_clk_mstp_register(mstp_clks, MSTP_NR); | ||
640 | |||
641 | for (k = 0; !ret && (k < ARRAY_SIZE(late_main_clks)); k++) | ||
642 | ret = clk_register(late_main_clks[k]); | ||
499 | 643 | ||
500 | clkdev_add_table(lookups, ARRAY_SIZE(lookups)); | 644 | clkdev_add_table(lookups, ARRAY_SIZE(lookups)); |
501 | 645 | ||