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.c253
1 files changed, 194 insertions, 59 deletions
diff --git a/arch/arm/mach-shmobile/board-ap4evb.c b/arch/arm/mach-shmobile/board-ap4evb.c
index 46ca4d4abf91..3cf0951caa2d 100644
--- a/arch/arm/mach-shmobile/board-ap4evb.c
+++ b/arch/arm/mach-shmobile/board-ap4evb.c
@@ -61,6 +61,7 @@
61#include <asm/mach/arch.h> 61#include <asm/mach/arch.h>
62#include <asm/mach/map.h> 62#include <asm/mach/map.h>
63#include <asm/mach/time.h> 63#include <asm/mach/time.h>
64#include <asm/setup.h>
64 65
65/* 66/*
66 * Address Interface BusWidth note 67 * Address Interface BusWidth note
@@ -163,11 +164,13 @@ static struct mtd_partition nor_flash_partitions[] = {
163 .name = "loader", 164 .name = "loader",
164 .offset = 0x00000000, 165 .offset = 0x00000000,
165 .size = 512 * 1024, 166 .size = 512 * 1024,
167 .mask_flags = MTD_WRITEABLE,
166 }, 168 },
167 { 169 {
168 .name = "bootenv", 170 .name = "bootenv",
169 .offset = MTDPART_OFS_APPEND, 171 .offset = MTDPART_OFS_APPEND,
170 .size = 512 * 1024, 172 .size = 512 * 1024,
173 .mask_flags = MTD_WRITEABLE,
171 }, 174 },
172 { 175 {
173 .name = "kernel_ro", 176 .name = "kernel_ro",
@@ -244,10 +247,7 @@ static struct platform_device smc911x_device = {
244 */ 247 */
245static int slot_cn7_get_cd(struct platform_device *pdev) 248static int slot_cn7_get_cd(struct platform_device *pdev)
246{ 249{
247 if (gpio_is_valid(GPIO_PORT41)) 250 return !gpio_get_value(GPIO_PORT41);
248 return !gpio_get_value(GPIO_PORT41);
249 else
250 return -ENXIO;
251} 251}
252 252
253/* SH_MMCIF */ 253/* SH_MMCIF */
@@ -270,6 +270,15 @@ static struct resource sh_mmcif_resources[] = {
270 }, 270 },
271}; 271};
272 272
273static struct sh_mmcif_dma sh_mmcif_dma = {
274 .chan_priv_rx = {
275 .slave_id = SHDMA_SLAVE_MMCIF_RX,
276 },
277 .chan_priv_tx = {
278 .slave_id = SHDMA_SLAVE_MMCIF_TX,
279 },
280};
281
273static struct sh_mmcif_plat_data sh_mmcif_plat = { 282static struct sh_mmcif_plat_data sh_mmcif_plat = {
274 .sup_pclk = 0, 283 .sup_pclk = 0,
275 .ocr = MMC_VDD_165_195 | MMC_VDD_32_33 | MMC_VDD_33_34, 284 .ocr = MMC_VDD_165_195 | MMC_VDD_32_33 | MMC_VDD_33_34,
@@ -277,6 +286,7 @@ static struct sh_mmcif_plat_data sh_mmcif_plat = {
277 MMC_CAP_8_BIT_DATA | 286 MMC_CAP_8_BIT_DATA |
278 MMC_CAP_NEEDS_POLL, 287 MMC_CAP_NEEDS_POLL,
279 .get_cd = slot_cn7_get_cd, 288 .get_cd = slot_cn7_get_cd,
289 .dma = &sh_mmcif_dma,
280}; 290};
281 291
282static struct platform_device sh_mmcif_device = { 292static struct platform_device sh_mmcif_device = {
@@ -295,6 +305,7 @@ static struct platform_device sh_mmcif_device = {
295static struct sh_mobile_sdhi_info sdhi0_info = { 305static struct sh_mobile_sdhi_info sdhi0_info = {
296 .dma_slave_tx = SHDMA_SLAVE_SDHI0_TX, 306 .dma_slave_tx = SHDMA_SLAVE_SDHI0_TX,
297 .dma_slave_rx = SHDMA_SLAVE_SDHI0_RX, 307 .dma_slave_rx = SHDMA_SLAVE_SDHI0_RX,
308 .tmio_caps = MMC_CAP_SDIO_IRQ,
298}; 309};
299 310
300static struct resource sdhi0_resources[] = { 311static struct resource sdhi0_resources[] = {
@@ -326,7 +337,7 @@ static struct sh_mobile_sdhi_info sdhi1_info = {
326 .dma_slave_rx = SHDMA_SLAVE_SDHI1_RX, 337 .dma_slave_rx = SHDMA_SLAVE_SDHI1_RX,
327 .tmio_ocr_mask = MMC_VDD_165_195, 338 .tmio_ocr_mask = MMC_VDD_165_195,
328 .tmio_flags = TMIO_MMC_WRPROTECT_DISABLE, 339 .tmio_flags = TMIO_MMC_WRPROTECT_DISABLE,
329 .tmio_caps = MMC_CAP_NEEDS_POLL, 340 .tmio_caps = MMC_CAP_NEEDS_POLL | MMC_CAP_SDIO_IRQ,
330 .get_cd = slot_cn7_get_cd, 341 .get_cd = slot_cn7_get_cd,
331}; 342};
332 343
@@ -499,7 +510,12 @@ static struct platform_device keysc_device = {
499static struct resource mipidsi0_resources[] = { 510static struct resource mipidsi0_resources[] = {
500 [0] = { 511 [0] = {
501 .start = 0xffc60000, 512 .start = 0xffc60000,
502 .end = 0xffc68fff, 513 .end = 0xffc63073,
514 .flags = IORESOURCE_MEM,
515 },
516 [1] = {
517 .start = 0xffc68000,
518 .end = 0xffc680ef,
503 .flags = IORESOURCE_MEM, 519 .flags = IORESOURCE_MEM,
504 }, 520 },
505}; 521};
@@ -507,6 +523,7 @@ static struct resource mipidsi0_resources[] = {
507static struct sh_mipi_dsi_info mipidsi0_info = { 523static struct sh_mipi_dsi_info mipidsi0_info = {
508 .data_format = MIPI_RGB888, 524 .data_format = MIPI_RGB888,
509 .lcd_chan = &lcdc_info.ch[0], 525 .lcd_chan = &lcdc_info.ch[0],
526 .vsynw_offset = 17,
510}; 527};
511 528
512static struct platform_device mipidsi0_device = { 529static struct platform_device mipidsi0_device = {
@@ -519,58 +536,154 @@ static struct platform_device mipidsi0_device = {
519 }, 536 },
520}; 537};
521 538
522/* This function will disappear when we switch to (runtime) PM */ 539static struct platform_device *qhd_devices[] __initdata = {
523static int __init ap4evb_init_display_clk(void) 540 &mipidsi0_device,
541 &keysc_device,
542};
543#endif /* CONFIG_AP4EVB_QHD */
544
545/* FSI */
546#define IRQ_FSI evt2irq(0x1840)
547static int __fsi_set_rate(struct clk *clk, long rate, int enable)
524{ 548{
525 struct clk *lcdc_clk; 549 int ret = 0;
526 struct clk *dsitx_clk;
527 int ret;
528 550
529 lcdc_clk = clk_get(&lcdc_device.dev, "sh_mobile_lcdc_fb.0"); 551 if (rate <= 0)
530 if (IS_ERR(lcdc_clk)) 552 return ret;
531 return PTR_ERR(lcdc_clk);
532 553
533 dsitx_clk = clk_get(&mipidsi0_device.dev, "sh-mipi-dsi.0"); 554 if (enable) {
534 if (IS_ERR(dsitx_clk)) { 555 ret = clk_set_rate(clk, rate);
535 ret = PTR_ERR(dsitx_clk); 556 if (0 == ret)
536 goto eclkdsitxget; 557 ret = clk_enable(clk);
558 } else {
559 clk_disable(clk);
537 } 560 }
538 561
539 ret = clk_enable(lcdc_clk); 562 return ret;
540 if (ret < 0) 563}
541 goto eclklcdcon; 564
565static int __fsi_set_round_rate(struct clk *clk, long rate, int enable)
566{
567 return __fsi_set_rate(clk, clk_round_rate(clk, rate), enable);
568}
542 569
543 ret = clk_enable(dsitx_clk); 570static int fsi_ak4642_set_rate(struct device *dev, int rate, int enable)
571{
572 struct clk *fsia_ick;
573 struct clk *fsiack;
574 int ret = -EIO;
575
576 fsia_ick = clk_get(dev, "icka");
577 if (IS_ERR(fsia_ick))
578 return PTR_ERR(fsia_ick);
579
580 /*
581 * FSIACK is connected to AK4642,
582 * and use external clock pin from it.
583 * it is parent of fsia_ick now.
584 */
585 fsiack = clk_get_parent(fsia_ick);
586 if (!fsiack)
587 goto fsia_ick_out;
588
589 /*
590 * we get 1/1 divided clock by setting same rate to fsiack and fsia_ick
591 *
592 ** FIXME **
593 * Because the freq_table of external clk (fsiack) are all 0,
594 * the return value of clk_round_rate became 0.
595 * So, it use __fsi_set_rate here.
596 */
597 ret = __fsi_set_rate(fsiack, rate, enable);
544 if (ret < 0) 598 if (ret < 0)
545 goto eclkdsitxon; 599 goto fsiack_out;
600
601 ret = __fsi_set_round_rate(fsia_ick, rate, enable);
602 if ((ret < 0) && enable)
603 __fsi_set_round_rate(fsiack, rate, 0); /* disable FSI ACK */
604
605fsiack_out:
606 clk_put(fsiack);
607
608fsia_ick_out:
609 clk_put(fsia_ick);
546 610
547 return 0; 611 return 0;
612}
613
614static int fsi_hdmi_set_rate(struct device *dev, int rate, int enable)
615{
616 struct clk *fsib_clk;
617 struct clk *fdiv_clk = &sh7372_fsidivb_clk;
618 long fsib_rate = 0;
619 long fdiv_rate = 0;
620 int ackmd_bpfmd;
621 int ret;
622
623 switch (rate) {
624 case 44100:
625 fsib_rate = rate * 256;
626 ackmd_bpfmd = SH_FSI_ACKMD_256 | SH_FSI_BPFMD_64;
627 break;
628 case 48000:
629 fsib_rate = 85428000; /* around 48kHz x 256 x 7 */
630 fdiv_rate = rate * 256;
631 ackmd_bpfmd = SH_FSI_ACKMD_256 | SH_FSI_BPFMD_64;
632 break;
633 default:
634 pr_err("unsupported rate in FSI2 port B\n");
635 return -EINVAL;
636 }
637
638 /* FSI B setting */
639 fsib_clk = clk_get(dev, "ickb");
640 if (IS_ERR(fsib_clk))
641 return -EIO;
642
643 ret = __fsi_set_round_rate(fsib_clk, fsib_rate, enable);
644 if (ret < 0)
645 goto fsi_set_rate_end;
548 646
549eclkdsitxon: 647 /* FSI DIV setting */
550 clk_disable(lcdc_clk); 648 ret = __fsi_set_round_rate(fdiv_clk, fdiv_rate, enable);
551eclklcdcon: 649 if (ret < 0) {
552 clk_put(dsitx_clk); 650 /* disable FSI B */
553eclkdsitxget: 651 if (enable)
554 clk_put(lcdc_clk); 652 __fsi_set_round_rate(fsib_clk, fsib_rate, 0);
653 goto fsi_set_rate_end;
654 }
555 655
656 ret = ackmd_bpfmd;
657
658fsi_set_rate_end:
659 clk_put(fsib_clk);
556 return ret; 660 return ret;
557} 661}
558device_initcall(ap4evb_init_display_clk);
559 662
560static struct platform_device *qhd_devices[] __initdata = { 663static int fsi_set_rate(struct device *dev, int is_porta, int rate, int enable)
561 &mipidsi0_device, 664{
562 &keysc_device, 665 int ret;
563}; 666
564#endif /* CONFIG_AP4EVB_QHD */ 667 if (is_porta)
668 ret = fsi_ak4642_set_rate(dev, rate, enable);
669 else
670 ret = fsi_hdmi_set_rate(dev, rate, enable);
671
672 return ret;
673}
565 674
566/* FSI */
567#define IRQ_FSI evt2irq(0x1840)
568static struct sh_fsi_platform_info fsi_info = { 675static struct sh_fsi_platform_info fsi_info = {
569 .porta_flags = SH_FSI_BRS_INV | 676 .porta_flags = SH_FSI_BRS_INV |
570 SH_FSI_OUT_SLAVE_MODE | 677 SH_FSI_OUT_SLAVE_MODE |
571 SH_FSI_IN_SLAVE_MODE | 678 SH_FSI_IN_SLAVE_MODE |
572 SH_FSI_OFMT(PCM) | 679 SH_FSI_OFMT(PCM) |
573 SH_FSI_IFMT(PCM), 680 SH_FSI_IFMT(PCM),
681
682 .portb_flags = SH_FSI_BRS_INV |
683 SH_FSI_BRM_INV |
684 SH_FSI_LRS_INV |
685 SH_FSI_OFMT(SPDIF),
686 .set_rate = fsi_set_rate,
574}; 687};
575 688
576static struct resource fsi_resources[] = { 689static struct resource fsi_resources[] = {
@@ -596,6 +709,10 @@ static struct platform_device fsi_device = {
596 }, 709 },
597}; 710};
598 711
712static struct platform_device fsi_ak4643_device = {
713 .name = "sh_fsi2_a_ak4643",
714};
715
599static struct sh_mobile_lcdc_info sh_mobile_lcdc1_info = { 716static struct sh_mobile_lcdc_info sh_mobile_lcdc1_info = {
600 .clock_source = LCDC_CLK_EXTERNAL, 717 .clock_source = LCDC_CLK_EXTERNAL,
601 .ch[0] = { 718 .ch[0] = {
@@ -631,9 +748,15 @@ static struct platform_device lcdc1_device = {
631 }, 748 },
632}; 749};
633 750
751static long ap4evb_clk_optimize(unsigned long target, unsigned long *best_freq,
752 unsigned long *parent_freq);
753
754
634static struct sh_mobile_hdmi_info hdmi_info = { 755static struct sh_mobile_hdmi_info hdmi_info = {
635 .lcd_chan = &sh_mobile_lcdc1_info.ch[0], 756 .lcd_chan = &sh_mobile_lcdc1_info.ch[0],
636 .lcd_dev = &lcdc1_device.dev, 757 .lcd_dev = &lcdc1_device.dev,
758 .flags = HDMI_SND_SRC_SPDIF,
759 .clk_optimize_parent = ap4evb_clk_optimize,
637}; 760};
638 761
639static struct resource hdmi_resources[] = { 762static struct resource hdmi_resources[] = {
@@ -660,6 +783,25 @@ static struct platform_device hdmi_device = {
660 }, 783 },
661}; 784};
662 785
786static long ap4evb_clk_optimize(unsigned long target, unsigned long *best_freq,
787 unsigned long *parent_freq)
788{
789 struct clk *hdmi_ick = clk_get(&hdmi_device.dev, "ick");
790 long error;
791
792 if (IS_ERR(hdmi_ick)) {
793 int ret = PTR_ERR(hdmi_ick);
794 pr_err("Cannot get HDMI ICK: %d\n", ret);
795 return ret;
796 }
797
798 error = clk_round_parent(hdmi_ick, target, best_freq, parent_freq, 1, 64);
799
800 clk_put(hdmi_ick);
801
802 return error;
803}
804
663static struct gpio_led ap4evb_leds[] = { 805static struct gpio_led ap4evb_leds[] = {
664 { 806 {
665 .name = "led4", 807 .name = "led4",
@@ -793,6 +935,7 @@ static struct platform_device *ap4evb_devices[] __initdata = {
793 &sdhi1_device, 935 &sdhi1_device,
794 &usb1_host_device, 936 &usb1_host_device,
795 &fsi_device, 937 &fsi_device,
938 &fsi_ak4643_device,
796 &sh_mmcif_device, 939 &sh_mmcif_device,
797 &lcdc1_device, 940 &lcdc1_device,
798 &lcdc_device, 941 &lcdc_device,
@@ -835,6 +978,11 @@ static int __init hdmi_init_pm_clock(void)
835 goto out; 978 goto out;
836 } 979 }
837 980
981 ret = clk_enable(&sh7372_pllc2_clk);
982 if (ret < 0) {
983 pr_err("Cannot enable pllc2 clock\n");
984 goto out;
985 }
838 pr_debug("PLLC2 set frequency %lu\n", rate); 986 pr_debug("PLLC2 set frequency %lu\n", rate);
839 987
840 ret = clk_set_parent(hdmi_ick, &sh7372_pllc2_clk); 988 ret = clk_set_parent(hdmi_ick, &sh7372_pllc2_clk);
@@ -851,23 +999,11 @@ out:
851 999
852device_initcall(hdmi_init_pm_clock); 1000device_initcall(hdmi_init_pm_clock);
853 1001
854#define FSIACK_DUMMY_RATE 48000
855static int __init fsi_init_pm_clock(void) 1002static int __init fsi_init_pm_clock(void)
856{ 1003{
857 struct clk *fsia_ick; 1004 struct clk *fsia_ick;
858 int ret; 1005 int ret;
859 1006
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"); 1007 fsia_ick = clk_get(&fsi_device.dev, "icka");
872 if (IS_ERR(fsia_ick)) { 1008 if (IS_ERR(fsia_ick)) {
873 ret = PTR_ERR(fsia_ick); 1009 ret = PTR_ERR(fsia_ick);
@@ -876,16 +1012,9 @@ static int __init fsi_init_pm_clock(void)
876 } 1012 }
877 1013
878 ret = clk_set_parent(fsia_ick, &sh7372_fsiack_clk); 1014 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) 1015 if (ret < 0)
886 pr_err("Cannot set FSI-A rate: %d\n", ret); 1016 pr_err("Cannot set FSI-A parent: %d\n", ret);
887 1017
888out:
889 clk_put(fsia_ick); 1018 clk_put(fsia_ick);
890 1019
891 return ret; 1020 return ret;
@@ -992,6 +1121,7 @@ static void __init ap4evb_map_io(void)
992 1121
993#define GPIO_PORT9CR 0xE6051009 1122#define GPIO_PORT9CR 0xE6051009
994#define GPIO_PORT10CR 0xE605100A 1123#define GPIO_PORT10CR 0xE605100A
1124#define USCCR1 0xE6058144
995static void __init ap4evb_init(void) 1125static void __init ap4evb_init(void)
996{ 1126{
997 u32 srcr4; 1127 u32 srcr4;
@@ -1060,9 +1190,9 @@ static void __init ap4evb_init(void)
1060 gpio_request(GPIO_FN_OVCN2_1, NULL); 1190 gpio_request(GPIO_FN_OVCN2_1, NULL);
1061 1191
1062 /* setup USB phy */ 1192 /* setup USB phy */
1063 __raw_writew(0x8a0a, 0xE6058130); /* USBCR2 */ 1193 __raw_writew(0x8a0a, 0xE6058130); /* USBCR4 */
1064 1194
1065 /* enable FSI2 */ 1195 /* enable FSI2 port A (ak4643) */
1066 gpio_request(GPIO_FN_FSIAIBT, NULL); 1196 gpio_request(GPIO_FN_FSIAIBT, NULL);
1067 gpio_request(GPIO_FN_FSIAILR, NULL); 1197 gpio_request(GPIO_FN_FSIAILR, NULL);
1068 gpio_request(GPIO_FN_FSIAISLD, NULL); 1198 gpio_request(GPIO_FN_FSIAISLD, NULL);
@@ -1079,6 +1209,10 @@ static void __init ap4evb_init(void)
1079 gpio_request(GPIO_PORT41, NULL); 1209 gpio_request(GPIO_PORT41, NULL);
1080 gpio_direction_input(GPIO_PORT41); 1210 gpio_direction_input(GPIO_PORT41);
1081 1211
1212 /* setup FSI2 port B (HDMI) */
1213 gpio_request(GPIO_FN_FSIBCK, NULL);
1214 __raw_writew(__raw_readw(USCCR1) & ~(1 << 6), USCCR1); /* use SPDIF */
1215
1082 /* set SPU2 clock to 119.6 MHz */ 1216 /* set SPU2 clock to 119.6 MHz */
1083 clk = clk_get(NULL, "spu_clk"); 1217 clk = clk_get(NULL, "spu_clk");
1084 if (!IS_ERR(clk)) { 1218 if (!IS_ERR(clk)) {
@@ -1230,6 +1364,7 @@ static struct sys_timer ap4evb_timer = {
1230MACHINE_START(AP4EVB, "ap4evb") 1364MACHINE_START(AP4EVB, "ap4evb")
1231 .map_io = ap4evb_map_io, 1365 .map_io = ap4evb_map_io,
1232 .init_irq = sh7372_init_irq, 1366 .init_irq = sh7372_init_irq,
1367 .handle_irq = shmobile_handle_irq_intc,
1233 .init_machine = ap4evb_init, 1368 .init_machine = ap4evb_init,
1234 .timer = &ap4evb_timer, 1369 .timer = &ap4evb_timer,
1235MACHINE_END 1370MACHINE_END