aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-shmobile/board-ap4evb.c
diff options
context:
space:
mode:
authorJiri Kosina <jkosina@suse.cz>2010-12-22 12:57:02 -0500
committerJiri Kosina <jkosina@suse.cz>2010-12-22 12:57:02 -0500
commit4b7bd364700d9ac8372eff48832062b936d0793b (patch)
tree0dbf78c95456a0b02d07fcd473281f04a87e266d /arch/arm/mach-shmobile/board-ap4evb.c
parentc0d8768af260e2cbb4bf659ae6094a262c86b085 (diff)
parent90a8a73c06cc32b609a880d48449d7083327e11a (diff)
Merge branch 'master' into for-next
Conflicts: MAINTAINERS arch/arm/mach-omap2/pm24xx.c drivers/scsi/bfa/bfa_fcpim.c Needed to update to apply fixes for which the old branch was too outdated.
Diffstat (limited to 'arch/arm/mach-shmobile/board-ap4evb.c')
-rw-r--r--arch/arm/mach-shmobile/board-ap4evb.c167
1 files changed, 146 insertions, 21 deletions
diff --git a/arch/arm/mach-shmobile/board-ap4evb.c b/arch/arm/mach-shmobile/board-ap4evb.c
index 46ca4d4abf91..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,12 +567,143 @@ 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}
587
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)
638{
639 struct clk *fsib_clk;
640 struct clk *fdiv_clk = &sh7372_fsidivb_clk;
641 long fsib_rate = 0;
642 long fdiv_rate = 0;
643 int ackmd_bpfmd;
644 int ret;
645
646 switch (rate) {
647 case 44100:
648 fsib_rate = rate * 256;
649 ackmd_bpfmd = SH_FSI_ACKMD_256 | SH_FSI_BPFMD_64;
650 break;
651 case 48000:
652 fsib_rate = 85428000; /* around 48kHz x 256 x 7 */
653 fdiv_rate = rate * 256;
654 ackmd_bpfmd = SH_FSI_ACKMD_256 | SH_FSI_BPFMD_64;
655 break;
656 default:
657 pr_err("unsupported rate in FSI2 port B\n");
658 return -EINVAL;
659 }
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);
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);
691
692 return ret;
693}
694
568static struct sh_fsi_platform_info fsi_info = { 695static struct sh_fsi_platform_info fsi_info = {
569 .porta_flags = SH_FSI_BRS_INV | 696 .porta_flags = SH_FSI_BRS_INV |
570 SH_FSI_OUT_SLAVE_MODE | 697 SH_FSI_OUT_SLAVE_MODE |
571 SH_FSI_IN_SLAVE_MODE | 698 SH_FSI_IN_SLAVE_MODE |
572 SH_FSI_OFMT(PCM) | 699 SH_FSI_OFMT(PCM) |
573 SH_FSI_IFMT(PCM), 700 SH_FSI_IFMT(PCM),
701
702 .portb_flags = SH_FSI_BRS_INV |
703 SH_FSI_BRM_INV |
704 SH_FSI_LRS_INV |
705 SH_FSI_OFMT(SPDIF),
706 .set_rate = fsi_set_rate,
574}; 707};
575 708
576static struct resource fsi_resources[] = { 709static struct resource fsi_resources[] = {
@@ -634,6 +767,7 @@ static struct platform_device lcdc1_device = {
634static struct sh_mobile_hdmi_info hdmi_info = { 767static struct sh_mobile_hdmi_info hdmi_info = {
635 .lcd_chan = &sh_mobile_lcdc1_info.ch[0], 768 .lcd_chan = &sh_mobile_lcdc1_info.ch[0],
636 .lcd_dev = &lcdc1_device.dev, 769 .lcd_dev = &lcdc1_device.dev,
770 .flags = HDMI_SND_SRC_SPDIF,
637}; 771};
638 772
639static struct resource hdmi_resources[] = { 773static struct resource hdmi_resources[] = {
@@ -835,6 +969,11 @@ static int __init hdmi_init_pm_clock(void)
835 goto out; 969 goto out;
836 } 970 }
837 971
972 ret = clk_enable(&sh7372_pllc2_clk);
973 if (ret < 0) {
974 pr_err("Cannot enable pllc2 clock\n");
975 goto out;
976 }
838 pr_debug("PLLC2 set frequency %lu\n", rate); 977 pr_debug("PLLC2 set frequency %lu\n", rate);
839 978
840 ret = clk_set_parent(hdmi_ick, &sh7372_pllc2_clk); 979 ret = clk_set_parent(hdmi_ick, &sh7372_pllc2_clk);
@@ -851,23 +990,11 @@ out:
851 990
852device_initcall(hdmi_init_pm_clock); 991device_initcall(hdmi_init_pm_clock);
853 992
854#define FSIACK_DUMMY_RATE 48000
855static int __init fsi_init_pm_clock(void) 993static int __init fsi_init_pm_clock(void)
856{ 994{
857 struct clk *fsia_ick; 995 struct clk *fsia_ick;
858 int ret; 996 int ret;
859 997
860 /*
861 * FSIACK is connected to AK4642,
862 * and the rate is depend on playing sound rate.
863 * So, set dummy rate (= 48k) here
864 */
865 ret = clk_set_rate(&sh7372_fsiack_clk, FSIACK_DUMMY_RATE);
866 if (ret < 0) {
867 pr_err("Cannot set FSIACK dummy rate: %d\n", ret);
868 return ret;
869 }
870
871 fsia_ick = clk_get(&fsi_device.dev, "icka"); 998 fsia_ick = clk_get(&fsi_device.dev, "icka");
872 if (IS_ERR(fsia_ick)) { 999 if (IS_ERR(fsia_ick)) {
873 ret = PTR_ERR(fsia_ick); 1000 ret = PTR_ERR(fsia_ick);
@@ -876,16 +1003,9 @@ static int __init fsi_init_pm_clock(void)
876 } 1003 }
877 1004
878 ret = clk_set_parent(fsia_ick, &sh7372_fsiack_clk); 1005 ret = clk_set_parent(fsia_ick, &sh7372_fsiack_clk);
879 if (ret < 0) {
880 pr_err("Cannot set FSI-A parent: %d\n", ret);
881 goto out;
882 }
883
884 ret = clk_set_rate(fsia_ick, FSIACK_DUMMY_RATE);
885 if (ret < 0) 1006 if (ret < 0)
886 pr_err("Cannot set FSI-A rate: %d\n", ret); 1007 pr_err("Cannot set FSI-A parent: %d\n", ret);
887 1008
888out:
889 clk_put(fsia_ick); 1009 clk_put(fsia_ick);
890 1010
891 return ret; 1011 return ret;
@@ -992,6 +1112,7 @@ static void __init ap4evb_map_io(void)
992 1112
993#define GPIO_PORT9CR 0xE6051009 1113#define GPIO_PORT9CR 0xE6051009
994#define GPIO_PORT10CR 0xE605100A 1114#define GPIO_PORT10CR 0xE605100A
1115#define USCCR1 0xE6058144
995static void __init ap4evb_init(void) 1116static void __init ap4evb_init(void)
996{ 1117{
997 u32 srcr4; 1118 u32 srcr4;
@@ -1062,7 +1183,7 @@ static void __init ap4evb_init(void)
1062 /* setup USB phy */ 1183 /* setup USB phy */
1063 __raw_writew(0x8a0a, 0xE6058130); /* USBCR2 */ 1184 __raw_writew(0x8a0a, 0xE6058130); /* USBCR2 */
1064 1185
1065 /* enable FSI2 */ 1186 /* enable FSI2 port A (ak4643) */
1066 gpio_request(GPIO_FN_FSIAIBT, NULL); 1187 gpio_request(GPIO_FN_FSIAIBT, NULL);
1067 gpio_request(GPIO_FN_FSIAILR, NULL); 1188 gpio_request(GPIO_FN_FSIAILR, NULL);
1068 gpio_request(GPIO_FN_FSIAISLD, NULL); 1189 gpio_request(GPIO_FN_FSIAISLD, NULL);
@@ -1079,6 +1200,10 @@ static void __init ap4evb_init(void)
1079 gpio_request(GPIO_PORT41, NULL); 1200 gpio_request(GPIO_PORT41, NULL);
1080 gpio_direction_input(GPIO_PORT41); 1201 gpio_direction_input(GPIO_PORT41);
1081 1202
1203 /* setup FSI2 port B (HDMI) */
1204 gpio_request(GPIO_FN_FSIBCK, NULL);
1205 __raw_writew(__raw_readw(USCCR1) & ~(1 << 6), USCCR1); /* use SPDIF */
1206
1082 /* set SPU2 clock to 119.6 MHz */ 1207 /* set SPU2 clock to 119.6 MHz */
1083 clk = clk_get(NULL, "spu_clk"); 1208 clk = clk_get(NULL, "spu_clk");
1084 if (!IS_ERR(clk)) { 1209 if (!IS_ERR(clk)) {