aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-shmobile/board-ap4evb.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-shmobile/board-ap4evb.c')
-rw-r--r--arch/arm/mach-shmobile/board-ap4evb.c149
1 files changed, 115 insertions, 34 deletions
diff --git a/arch/arm/mach-shmobile/board-ap4evb.c b/arch/arm/mach-shmobile/board-ap4evb.c
index 32d9e2816e56..d440e5f456ad 100644
--- a/arch/arm/mach-shmobile/board-ap4evb.c
+++ b/arch/arm/mach-shmobile/board-ap4evb.c
@@ -163,11 +163,13 @@ static struct mtd_partition nor_flash_partitions[] = {
163 .name = "loader", 163 .name = "loader",
164 .offset = 0x00000000, 164 .offset = 0x00000000,
165 .size = 512 * 1024, 165 .size = 512 * 1024,
166 .mask_flags = MTD_WRITEABLE,
166 }, 167 },
167 { 168 {
168 .name = "bootenv", 169 .name = "bootenv",
169 .offset = MTDPART_OFS_APPEND, 170 .offset = MTDPART_OFS_APPEND,
170 .size = 512 * 1024, 171 .size = 512 * 1024,
172 .mask_flags = MTD_WRITEABLE,
171 }, 173 },
172 { 174 {
173 .name = "kernel_ro", 175 .name = "kernel_ro",
@@ -565,34 +567,127 @@ static struct platform_device *qhd_devices[] __initdata = {
565 567
566/* FSI */ 568/* FSI */
567#define IRQ_FSI evt2irq(0x1840) 569#define IRQ_FSI evt2irq(0x1840)
570static int __fsi_set_rate(struct clk *clk, long rate, int enable)
571{
572 int ret = 0;
573
574 if (rate <= 0)
575 return ret;
576
577 if (enable) {
578 ret = clk_set_rate(clk, rate);
579 if (0 == ret)
580 ret = clk_enable(clk);
581 } else {
582 clk_disable(clk);
583 }
584
585 return ret;
586}
568 587
569static int fsi_set_rate(int is_porta, int rate) 588static int __fsi_set_round_rate(struct clk *clk, long rate, int enable)
589{
590 return __fsi_set_rate(clk, clk_round_rate(clk, rate), enable);
591}
592
593static int fsi_ak4642_set_rate(struct device *dev, int rate, int enable)
594{
595 struct clk *fsia_ick;
596 struct clk *fsiack;
597 int ret = -EIO;
598
599 fsia_ick = clk_get(dev, "icka");
600 if (IS_ERR(fsia_ick))
601 return PTR_ERR(fsia_ick);
602
603 /*
604 * FSIACK is connected to AK4642,
605 * and use external clock pin from it.
606 * it is parent of fsia_ick now.
607 */
608 fsiack = clk_get_parent(fsia_ick);
609 if (!fsiack)
610 goto fsia_ick_out;
611
612 /*
613 * we get 1/1 divided clock by setting same rate to fsiack and fsia_ick
614 *
615 ** FIXME **
616 * Because the freq_table of external clk (fsiack) are all 0,
617 * the return value of clk_round_rate became 0.
618 * So, it use __fsi_set_rate here.
619 */
620 ret = __fsi_set_rate(fsiack, rate, enable);
621 if (ret < 0)
622 goto fsiack_out;
623
624 ret = __fsi_set_round_rate(fsia_ick, rate, enable);
625 if ((ret < 0) && enable)
626 __fsi_set_round_rate(fsiack, rate, 0); /* disable FSI ACK */
627
628fsiack_out:
629 clk_put(fsiack);
630
631fsia_ick_out:
632 clk_put(fsia_ick);
633
634 return 0;
635}
636
637static int fsi_hdmi_set_rate(struct device *dev, int rate, int enable)
570{ 638{
571 struct clk *fsib_clk; 639 struct clk *fsib_clk;
572 struct clk *fdiv_clk = &sh7372_fsidivb_clk; 640 struct clk *fdiv_clk = &sh7372_fsidivb_clk;
641 long fsib_rate = 0;
642 long fdiv_rate = 0;
643 int ackmd_bpfmd;
573 int ret; 644 int ret;
574 645
575 /* set_rate is not needed if port A */
576 if (is_porta)
577 return 0;
578
579 fsib_clk = clk_get(NULL, "fsib_clk");
580 if (IS_ERR(fsib_clk))
581 return -EINVAL;
582
583 switch (rate) { 646 switch (rate) {
647 case 44100:
648 fsib_rate = rate * 256;
649 ackmd_bpfmd = SH_FSI_ACKMD_256 | SH_FSI_BPFMD_64;
650 break;
584 case 48000: 651 case 48000:
585 clk_set_rate(fsib_clk, clk_round_rate(fsib_clk, 85428000)); 652 fsib_rate = 85428000; /* around 48kHz x 256 x 7 */
586 clk_set_rate(fdiv_clk, clk_round_rate(fdiv_clk, 12204000)); 653 fdiv_rate = rate * 256;
587 ret = SH_FSI_ACKMD_256 | SH_FSI_BPFMD_64; 654 ackmd_bpfmd = SH_FSI_ACKMD_256 | SH_FSI_BPFMD_64;
588 break; 655 break;
589 default: 656 default:
590 pr_err("unsupported rate in FSI2 port B\n"); 657 pr_err("unsupported rate in FSI2 port B\n");
591 ret = -EINVAL; 658 return -EINVAL;
592 break;
593 } 659 }
594 660
661 /* FSI B setting */
662 fsib_clk = clk_get(dev, "ickb");
663 if (IS_ERR(fsib_clk))
664 return -EIO;
665
666 ret = __fsi_set_round_rate(fsib_clk, fsib_rate, enable);
595 clk_put(fsib_clk); 667 clk_put(fsib_clk);
668 if (ret < 0)
669 return ret;
670
671 /* FSI DIV setting */
672 ret = __fsi_set_round_rate(fdiv_clk, fdiv_rate, enable);
673 if (ret < 0) {
674 /* disable FSI B */
675 if (enable)
676 __fsi_set_round_rate(fsib_clk, fsib_rate, 0);
677 return ret;
678 }
679
680 return ackmd_bpfmd;
681}
682
683static int fsi_set_rate(struct device *dev, int is_porta, int rate, int enable)
684{
685 int ret;
686
687 if (is_porta)
688 ret = fsi_ak4642_set_rate(dev, rate, enable);
689 else
690 ret = fsi_hdmi_set_rate(dev, rate, enable);
596 691
597 return ret; 692 return ret;
598} 693}
@@ -874,6 +969,11 @@ static int __init hdmi_init_pm_clock(void)
874 goto out; 969 goto out;
875 } 970 }
876 971
972 ret = clk_enable(&sh7372_pllc2_clk);
973 if (ret < 0) {
974 pr_err("Cannot enable pllc2 clock\n");
975 goto out;
976 }
877 pr_debug("PLLC2 set frequency %lu\n", rate); 977 pr_debug("PLLC2 set frequency %lu\n", rate);
878 978
879 ret = clk_set_parent(hdmi_ick, &sh7372_pllc2_clk); 979 ret = clk_set_parent(hdmi_ick, &sh7372_pllc2_clk);
@@ -890,23 +990,11 @@ out:
890 990
891device_initcall(hdmi_init_pm_clock); 991device_initcall(hdmi_init_pm_clock);
892 992
893#define FSIACK_DUMMY_RATE 48000
894static int __init fsi_init_pm_clock(void) 993static int __init fsi_init_pm_clock(void)
895{ 994{
896 struct clk *fsia_ick; 995 struct clk *fsia_ick;
897 int ret; 996 int ret;
898 997
899 /*
900 * FSIACK is connected to AK4642,
901 * and the rate is depend on playing sound rate.
902 * So, set dummy rate (= 48k) here
903 */
904 ret = clk_set_rate(&sh7372_fsiack_clk, FSIACK_DUMMY_RATE);
905 if (ret < 0) {
906 pr_err("Cannot set FSIACK dummy rate: %d\n", ret);
907 return ret;
908 }
909
910 fsia_ick = clk_get(&fsi_device.dev, "icka"); 998 fsia_ick = clk_get(&fsi_device.dev, "icka");
911 if (IS_ERR(fsia_ick)) { 999 if (IS_ERR(fsia_ick)) {
912 ret = PTR_ERR(fsia_ick); 1000 ret = PTR_ERR(fsia_ick);
@@ -915,16 +1003,9 @@ static int __init fsi_init_pm_clock(void)
915 } 1003 }
916 1004
917 ret = clk_set_parent(fsia_ick, &sh7372_fsiack_clk); 1005 ret = clk_set_parent(fsia_ick, &sh7372_fsiack_clk);
918 if (ret < 0) {
919 pr_err("Cannot set FSI-A parent: %d\n", ret);
920 goto out;
921 }
922
923 ret = clk_set_rate(fsia_ick, FSIACK_DUMMY_RATE);
924 if (ret < 0) 1006 if (ret < 0)
925 pr_err("Cannot set FSI-A rate: %d\n", ret); 1007 pr_err("Cannot set FSI-A parent: %d\n", ret);
926 1008
927out:
928 clk_put(fsia_ick); 1009 clk_put(fsia_ick);
929 1010
930 return ret; 1011 return ret;