diff options
author | Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> | 2010-10-15 01:15:05 -0400 |
---|---|---|
committer | Paul Mundt <lethal@linux-sh.org> | 2010-10-15 05:58:41 -0400 |
commit | 69ce8aa4925a54de192cf64e99abd294586c1984 (patch) | |
tree | da14c4a51e4000f50b10508a580b993b7917d032 /arch | |
parent | 685e4080c62b4b5c6f67c7b088e416e98d06f7e6 (diff) |
ARM: mach-shmobile: clock-sh7372: FSI parent select support
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm/mach-shmobile/board-ap4evb.c | 70 | ||||
-rw-r--r-- | arch/arm/mach-shmobile/clock-sh7372.c | 45 | ||||
-rw-r--r-- | arch/arm/mach-shmobile/include/mach/sh7372.h | 2 |
3 files changed, 80 insertions, 37 deletions
diff --git a/arch/arm/mach-shmobile/board-ap4evb.c b/arch/arm/mach-shmobile/board-ap4evb.c index f879eb3c3427..1e7beee79086 100644 --- a/arch/arm/mach-shmobile/board-ap4evb.c +++ b/arch/arm/mach-shmobile/board-ap4evb.c | |||
@@ -546,27 +546,6 @@ static struct platform_device *qhd_devices[] __initdata = { | |||
546 | 546 | ||
547 | /* FSI */ | 547 | /* FSI */ |
548 | #define IRQ_FSI evt2irq(0x1840) | 548 | #define IRQ_FSI evt2irq(0x1840) |
549 | #define FSIACKCR 0xE6150018 | ||
550 | static void fsiackcr_init(struct clk *clk) | ||
551 | { | ||
552 | u32 status = __raw_readl(clk->enable_reg); | ||
553 | |||
554 | /* use external clock */ | ||
555 | status &= ~0x000000ff; | ||
556 | status |= 0x00000080; | ||
557 | __raw_writel(status, clk->enable_reg); | ||
558 | } | ||
559 | |||
560 | static struct clk_ops fsiackcr_clk_ops = { | ||
561 | .init = fsiackcr_init, | ||
562 | }; | ||
563 | |||
564 | static struct clk fsiackcr_clk = { | ||
565 | .ops = &fsiackcr_clk_ops, | ||
566 | .enable_reg = (void __iomem *)FSIACKCR, | ||
567 | .rate = 0, /* unknown */ | ||
568 | }; | ||
569 | |||
570 | static struct sh_fsi_platform_info fsi_info = { | 549 | static struct sh_fsi_platform_info fsi_info = { |
571 | .porta_flags = SH_FSI_BRS_INV | | 550 | .porta_flags = SH_FSI_BRS_INV | |
572 | SH_FSI_OUT_SLAVE_MODE | | 551 | SH_FSI_OUT_SLAVE_MODE | |
@@ -817,6 +796,47 @@ out: | |||
817 | 796 | ||
818 | device_initcall(hdmi_init_pm_clock); | 797 | device_initcall(hdmi_init_pm_clock); |
819 | 798 | ||
799 | #define FSIACK_DUMMY_RATE 48000 | ||
800 | static int __init fsi_init_pm_clock(void) | ||
801 | { | ||
802 | struct clk *fsia_ick; | ||
803 | int ret; | ||
804 | |||
805 | /* | ||
806 | * FSIACK is connected to AK4642, | ||
807 | * and the rate is depend on playing sound rate. | ||
808 | * So, set dummy rate (= 48k) here | ||
809 | */ | ||
810 | ret = clk_set_rate(&sh7372_fsiack_clk, FSIACK_DUMMY_RATE); | ||
811 | if (ret < 0) { | ||
812 | pr_err("Cannot set FSIACK dummy rate: %d\n", ret); | ||
813 | return ret; | ||
814 | } | ||
815 | |||
816 | fsia_ick = clk_get(&fsi_device.dev, "icka"); | ||
817 | if (IS_ERR(fsia_ick)) { | ||
818 | ret = PTR_ERR(fsia_ick); | ||
819 | pr_err("Cannot get FSI ICK: %d\n", ret); | ||
820 | return ret; | ||
821 | } | ||
822 | |||
823 | ret = clk_set_parent(fsia_ick, &sh7372_fsiack_clk); | ||
824 | if (ret < 0) { | ||
825 | pr_err("Cannot set FSI-A parent: %d\n", ret); | ||
826 | goto out; | ||
827 | } | ||
828 | |||
829 | ret = clk_set_rate(fsia_ick, FSIACK_DUMMY_RATE); | ||
830 | if (ret < 0) | ||
831 | pr_err("Cannot set FSI-A rate: %d\n", ret); | ||
832 | |||
833 | out: | ||
834 | clk_put(fsia_ick); | ||
835 | |||
836 | return ret; | ||
837 | } | ||
838 | device_initcall(fsi_init_pm_clock); | ||
839 | |||
820 | /* | 840 | /* |
821 | * FIXME !! | 841 | * FIXME !! |
822 | * | 842 | * |
@@ -1007,14 +1027,6 @@ static void __init ap4evb_init(void) | |||
1007 | clk_put(clk); | 1027 | clk_put(clk); |
1008 | } | 1028 | } |
1009 | 1029 | ||
1010 | /* change parent of FSI A */ | ||
1011 | clk = clk_get(NULL, "fsia_clk"); | ||
1012 | if (!IS_ERR(clk)) { | ||
1013 | clk_register(&fsiackcr_clk); | ||
1014 | clk_set_parent(clk, &fsiackcr_clk); | ||
1015 | clk_put(clk); | ||
1016 | } | ||
1017 | |||
1018 | /* | 1030 | /* |
1019 | * set irq priority, to avoid sound chopping | 1031 | * set irq priority, to avoid sound chopping |
1020 | * when NFS rootfs is used | 1032 | * when NFS rootfs is used |
diff --git a/arch/arm/mach-shmobile/clock-sh7372.c b/arch/arm/mach-shmobile/clock-sh7372.c index 50c3971d3dcb..4557084a2f0f 100644 --- a/arch/arm/mach-shmobile/clock-sh7372.c +++ b/arch/arm/mach-shmobile/clock-sh7372.c | |||
@@ -292,6 +292,13 @@ struct clk sh7372_pllc2_clk = { | |||
292 | .parent_num = ARRAY_SIZE(pllc2_parent), | 292 | .parent_num = ARRAY_SIZE(pllc2_parent), |
293 | }; | 293 | }; |
294 | 294 | ||
295 | /* External input clock (pin name: FSIACK/FSIBCK ) */ | ||
296 | struct clk sh7372_fsiack_clk = { | ||
297 | }; | ||
298 | |||
299 | struct clk sh7372_fsibck_clk = { | ||
300 | }; | ||
301 | |||
295 | static struct clk *main_clks[] = { | 302 | static struct clk *main_clks[] = { |
296 | &sh7372_dv_clki_clk, | 303 | &sh7372_dv_clki_clk, |
297 | &r_clk, | 304 | &r_clk, |
@@ -305,6 +312,8 @@ static struct clk *main_clks[] = { | |||
305 | &pllc1_clk, | 312 | &pllc1_clk, |
306 | &pllc1_div2_clk, | 313 | &pllc1_div2_clk, |
307 | &sh7372_pllc2_clk, | 314 | &sh7372_pllc2_clk, |
315 | &sh7372_fsiack_clk, | ||
316 | &sh7372_fsibck_clk, | ||
308 | }; | 317 | }; |
309 | 318 | ||
310 | static void div4_kick(struct clk *clk) | 319 | static void div4_kick(struct clk *clk) |
@@ -357,7 +366,7 @@ static struct clk div4_clks[DIV4_NR] = { | |||
357 | }; | 366 | }; |
358 | 367 | ||
359 | enum { DIV6_VCK1, DIV6_VCK2, DIV6_VCK3, DIV6_FMSI, DIV6_FMSO, | 368 | enum { DIV6_VCK1, DIV6_VCK2, DIV6_VCK3, DIV6_FMSI, DIV6_FMSO, |
360 | DIV6_FSIA, DIV6_FSIB, DIV6_SUB, DIV6_SPU, | 369 | DIV6_SUB, DIV6_SPU, |
361 | DIV6_VOU, DIV6_DSIT, DIV6_DSI0P, DIV6_DSI1P, | 370 | DIV6_VOU, DIV6_DSIT, DIV6_DSI0P, DIV6_DSI1P, |
362 | DIV6_NR }; | 371 | DIV6_NR }; |
363 | 372 | ||
@@ -367,8 +376,6 @@ static struct clk div6_clks[DIV6_NR] = { | |||
367 | [DIV6_VCK3] = SH_CLK_DIV6(&pllc1_div2_clk, VCLKCR3, 0), | 376 | [DIV6_VCK3] = SH_CLK_DIV6(&pllc1_div2_clk, VCLKCR3, 0), |
368 | [DIV6_FMSI] = SH_CLK_DIV6(&pllc1_div2_clk, FMSICKCR, 0), | 377 | [DIV6_FMSI] = SH_CLK_DIV6(&pllc1_div2_clk, FMSICKCR, 0), |
369 | [DIV6_FMSO] = SH_CLK_DIV6(&pllc1_div2_clk, FMSOCKCR, 0), | 378 | [DIV6_FMSO] = SH_CLK_DIV6(&pllc1_div2_clk, FMSOCKCR, 0), |
370 | [DIV6_FSIA] = SH_CLK_DIV6(&pllc1_div2_clk, FSIACKCR, 0), | ||
371 | [DIV6_FSIB] = SH_CLK_DIV6(&pllc1_div2_clk, FSIBCKCR, 0), | ||
372 | [DIV6_SUB] = SH_CLK_DIV6(&sh7372_extal2_clk, SUBCKCR, 0), | 379 | [DIV6_SUB] = SH_CLK_DIV6(&sh7372_extal2_clk, SUBCKCR, 0), |
373 | [DIV6_SPU] = SH_CLK_DIV6(&pllc1_div2_clk, SPUCKCR, 0), | 380 | [DIV6_SPU] = SH_CLK_DIV6(&pllc1_div2_clk, SPUCKCR, 0), |
374 | [DIV6_VOU] = SH_CLK_DIV6(&pllc1_div2_clk, VOUCKCR, 0), | 381 | [DIV6_VOU] = SH_CLK_DIV6(&pllc1_div2_clk, VOUCKCR, 0), |
@@ -377,7 +384,7 @@ static struct clk div6_clks[DIV6_NR] = { | |||
377 | [DIV6_DSI1P] = SH_CLK_DIV6(&pllc1_div2_clk, DSI1PCKCR, 0), | 384 | [DIV6_DSI1P] = SH_CLK_DIV6(&pllc1_div2_clk, DSI1PCKCR, 0), |
378 | }; | 385 | }; |
379 | 386 | ||
380 | enum { DIV6_HDMI, DIV6_REPARENT_NR }; | 387 | enum { DIV6_HDMI, DIV6_FSIA, DIV6_FSIB, DIV6_REPARENT_NR }; |
381 | 388 | ||
382 | /* Indices are important - they are the actual src selecting values */ | 389 | /* Indices are important - they are the actual src selecting values */ |
383 | static struct clk *hdmi_parent[] = { | 390 | static struct clk *hdmi_parent[] = { |
@@ -387,9 +394,27 @@ static struct clk *hdmi_parent[] = { | |||
387 | [3] = NULL, /* pllc2_div4 not implemented yet */ | 394 | [3] = NULL, /* pllc2_div4 not implemented yet */ |
388 | }; | 395 | }; |
389 | 396 | ||
397 | static struct clk *fsiackcr_parent[] = { | ||
398 | [0] = &pllc1_div2_clk, | ||
399 | [1] = &sh7372_pllc2_clk, | ||
400 | [2] = &sh7372_fsiack_clk, /* external input for FSI A */ | ||
401 | [3] = NULL, /* setting prohibited */ | ||
402 | }; | ||
403 | |||
404 | static struct clk *fsibckcr_parent[] = { | ||
405 | [0] = &pllc1_div2_clk, | ||
406 | [1] = &sh7372_pllc2_clk, | ||
407 | [2] = &sh7372_fsibck_clk, /* external input for FSI B */ | ||
408 | [3] = NULL, /* setting prohibited */ | ||
409 | }; | ||
410 | |||
390 | static struct clk div6_reparent_clks[DIV6_REPARENT_NR] = { | 411 | static struct clk div6_reparent_clks[DIV6_REPARENT_NR] = { |
391 | [DIV6_HDMI] = SH_CLK_DIV6_EXT(&pllc1_div2_clk, HDMICKCR, 0, | 412 | [DIV6_HDMI] = SH_CLK_DIV6_EXT(&pllc1_div2_clk, HDMICKCR, 0, |
392 | hdmi_parent, ARRAY_SIZE(hdmi_parent), 6, 2), | 413 | hdmi_parent, ARRAY_SIZE(hdmi_parent), 6, 2), |
414 | [DIV6_FSIA] = SH_CLK_DIV6_EXT(&pllc1_div2_clk, FSIACKCR, 0, | ||
415 | fsiackcr_parent, ARRAY_SIZE(fsiackcr_parent), 6, 2), | ||
416 | [DIV6_FSIB] = SH_CLK_DIV6_EXT(&pllc1_div2_clk, FSIBCKCR, 0, | ||
417 | fsibckcr_parent, ARRAY_SIZE(fsibckcr_parent), 6, 2), | ||
393 | }; | 418 | }; |
394 | 419 | ||
395 | enum { MSTP001, | 420 | enum { MSTP001, |
@@ -429,7 +454,7 @@ static struct clk mstp_clks[MSTP_NR] = { | |||
429 | [MSTP201] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 1, 0), /* SCIFA3 */ | 454 | [MSTP201] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 1, 0), /* SCIFA3 */ |
430 | [MSTP200] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 0, 0), /* SCIFA4 */ | 455 | [MSTP200] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 0, 0), /* SCIFA4 */ |
431 | [MSTP329] = MSTP(&r_clk, SMSTPCR3, 29, 0), /* CMT10 */ | 456 | [MSTP329] = MSTP(&r_clk, SMSTPCR3, 29, 0), /* CMT10 */ |
432 | [MSTP328] = MSTP(&div6_clks[DIV6_SPU], SMSTPCR3, 28, 0), /* FSIA */ | 457 | [MSTP328] = MSTP(&div6_clks[DIV6_SPU], SMSTPCR3, 28, 0), /* FSI2 */ |
433 | [MSTP323] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 23, 0), /* IIC1 */ | 458 | [MSTP323] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 23, 0), /* IIC1 */ |
434 | [MSTP322] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 22, 0), /* USB0 */ | 459 | [MSTP322] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 22, 0), /* USB0 */ |
435 | [MSTP314] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 14, 0), /* SDHI0 */ | 460 | [MSTP314] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 14, 0), /* SDHI0 */ |
@@ -445,6 +470,7 @@ static struct clk mstp_clks[MSTP_NR] = { | |||
445 | 470 | ||
446 | #define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk } | 471 | #define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk } |
447 | #define CLKDEV_DEV_ID(_id, _clk) { .dev_id = _id, .clk = _clk } | 472 | #define CLKDEV_DEV_ID(_id, _clk) { .dev_id = _id, .clk = _clk } |
473 | #define CLKDEV_ICK_ID(_cid, _did, _clk) { .con_id = _cid, .dev_id = _did, .clk = _clk } | ||
448 | 474 | ||
449 | static struct clk_lookup lookups[] = { | 475 | static struct clk_lookup lookups[] = { |
450 | /* main clocks */ | 476 | /* main clocks */ |
@@ -483,8 +509,8 @@ static struct clk_lookup lookups[] = { | |||
483 | CLKDEV_CON_ID("vck3_clk", &div6_clks[DIV6_VCK3]), | 509 | CLKDEV_CON_ID("vck3_clk", &div6_clks[DIV6_VCK3]), |
484 | CLKDEV_CON_ID("fmsi_clk", &div6_clks[DIV6_FMSI]), | 510 | CLKDEV_CON_ID("fmsi_clk", &div6_clks[DIV6_FMSI]), |
485 | CLKDEV_CON_ID("fmso_clk", &div6_clks[DIV6_FMSO]), | 511 | CLKDEV_CON_ID("fmso_clk", &div6_clks[DIV6_FMSO]), |
486 | CLKDEV_CON_ID("fsia_clk", &div6_clks[DIV6_FSIA]), | 512 | CLKDEV_CON_ID("fsia_clk", &div6_reparent_clks[DIV6_FSIA]), |
487 | CLKDEV_CON_ID("fsib_clk", &div6_clks[DIV6_FSIB]), | 513 | CLKDEV_CON_ID("fsib_clk", &div6_reparent_clks[DIV6_FSIB]), |
488 | CLKDEV_CON_ID("sub_clk", &div6_clks[DIV6_SUB]), | 514 | CLKDEV_CON_ID("sub_clk", &div6_clks[DIV6_SUB]), |
489 | CLKDEV_CON_ID("spu_clk", &div6_clks[DIV6_SPU]), | 515 | CLKDEV_CON_ID("spu_clk", &div6_clks[DIV6_SPU]), |
490 | CLKDEV_CON_ID("vou_clk", &div6_clks[DIV6_VOU]), | 516 | CLKDEV_CON_ID("vou_clk", &div6_clks[DIV6_VOU]), |
@@ -531,7 +557,10 @@ static struct clk_lookup lookups[] = { | |||
531 | CLKDEV_DEV_ID("r8a66597_hcd.1", &mstp_clks[MSTP406]), /* USB1 */ | 557 | CLKDEV_DEV_ID("r8a66597_hcd.1", &mstp_clks[MSTP406]), /* USB1 */ |
532 | CLKDEV_DEV_ID("r8a66597_udc.1", &mstp_clks[MSTP406]), /* USB1 */ | 558 | CLKDEV_DEV_ID("r8a66597_udc.1", &mstp_clks[MSTP406]), /* USB1 */ |
533 | CLKDEV_DEV_ID("sh_keysc.0", &mstp_clks[MSTP403]), /* KEYSC */ | 559 | CLKDEV_DEV_ID("sh_keysc.0", &mstp_clks[MSTP403]), /* KEYSC */ |
534 | {.con_id = "ick", .dev_id = "sh-mobile-hdmi", .clk = &div6_reparent_clks[DIV6_HDMI]}, | 560 | |
561 | CLKDEV_ICK_ID("ick", "sh-mobile-hdmi", &div6_reparent_clks[DIV6_HDMI]), | ||
562 | CLKDEV_ICK_ID("icka", "sh_fsi2", &div6_reparent_clks[DIV6_FSIA]), | ||
563 | CLKDEV_ICK_ID("ickb", "sh_fsi2", &div6_reparent_clks[DIV6_FSIB]), | ||
535 | }; | 564 | }; |
536 | 565 | ||
537 | void __init sh7372_clock_init(void) | 566 | void __init sh7372_clock_init(void) |
diff --git a/arch/arm/mach-shmobile/include/mach/sh7372.h b/arch/arm/mach-shmobile/include/mach/sh7372.h index 9838fcf03083..147775a94bce 100644 --- a/arch/arm/mach-shmobile/include/mach/sh7372.h +++ b/arch/arm/mach-shmobile/include/mach/sh7372.h | |||
@@ -462,5 +462,7 @@ extern struct clk sh7372_extal2_clk; | |||
462 | extern struct clk sh7372_dv_clki_clk; | 462 | extern struct clk sh7372_dv_clki_clk; |
463 | extern struct clk sh7372_dv_clki_div2_clk; | 463 | extern struct clk sh7372_dv_clki_div2_clk; |
464 | extern struct clk sh7372_pllc2_clk; | 464 | extern struct clk sh7372_pllc2_clk; |
465 | extern struct clk sh7372_fsiack_clk; | ||
466 | extern struct clk sh7372_fsibck_clk; | ||
465 | 467 | ||
466 | #endif /* __ASM_SH7372_H__ */ | 468 | #endif /* __ASM_SH7372_H__ */ |