diff options
| -rw-r--r-- | arch/arm/mach-shmobile/board-ap4evb.c | 154 |
1 files changed, 152 insertions, 2 deletions
diff --git a/arch/arm/mach-shmobile/board-ap4evb.c b/arch/arm/mach-shmobile/board-ap4evb.c index 968601201fb5..024f8f4c2a33 100644 --- a/arch/arm/mach-shmobile/board-ap4evb.c +++ b/arch/arm/mach-shmobile/board-ap4evb.c | |||
| @@ -44,6 +44,7 @@ | |||
| 44 | 44 | ||
| 45 | #include <sound/sh_fsi.h> | 45 | #include <sound/sh_fsi.h> |
| 46 | 46 | ||
| 47 | #include <video/sh_mobile_hdmi.h> | ||
| 47 | #include <video/sh_mobile_lcdc.h> | 48 | #include <video/sh_mobile_lcdc.h> |
| 48 | #include <video/sh_mipi_dsi.h> | 49 | #include <video/sh_mipi_dsi.h> |
| 49 | 50 | ||
| @@ -565,17 +566,152 @@ static struct platform_device fsi_device = { | |||
| 565 | }, | 566 | }, |
| 566 | }; | 567 | }; |
| 567 | 568 | ||
| 569 | static struct sh_mobile_lcdc_info sh_mobile_lcdc1_info = { | ||
| 570 | .clock_source = LCDC_CLK_EXTERNAL, | ||
| 571 | .ch[0] = { | ||
| 572 | .chan = LCDC_CHAN_MAINLCD, | ||
| 573 | .bpp = 16, | ||
| 574 | .interface_type = RGB24, | ||
| 575 | .clock_divider = 1, | ||
| 576 | .flags = LCDC_FLAGS_DWPOL, | ||
| 577 | .lcd_cfg = { | ||
| 578 | .name = "HDMI", | ||
| 579 | /* So far only 720p is supported */ | ||
| 580 | .xres = 1280, | ||
| 581 | .yres = 720, | ||
| 582 | /* | ||
| 583 | * If left and right margins are not multiples of 8, | ||
| 584 | * LDHAJR will be adjusted accordingly by the LCDC | ||
| 585 | * driver. Until we start using EDID, these values | ||
| 586 | * might have to be adjusted for different monitors. | ||
| 587 | */ | ||
| 588 | .left_margin = 200, | ||
| 589 | .right_margin = 88, | ||
| 590 | .hsync_len = 48, | ||
| 591 | .upper_margin = 20, | ||
| 592 | .lower_margin = 5, | ||
| 593 | .vsync_len = 5, | ||
| 594 | .pixclock = 13468, | ||
| 595 | .sync = FB_SYNC_VERT_HIGH_ACT | FB_SYNC_HOR_HIGH_ACT, | ||
| 596 | }, | ||
| 597 | } | ||
| 598 | }; | ||
| 599 | |||
| 600 | static struct resource lcdc1_resources[] = { | ||
| 601 | [0] = { | ||
| 602 | .name = "LCDC1", | ||
| 603 | .start = 0xfe944000, | ||
| 604 | .end = 0xfe947fff, | ||
| 605 | .flags = IORESOURCE_MEM, | ||
| 606 | }, | ||
| 607 | [1] = { | ||
| 608 | .start = intcs_evt2irq(0x17a0), | ||
| 609 | .flags = IORESOURCE_IRQ, | ||
| 610 | }, | ||
| 611 | }; | ||
| 612 | |||
| 613 | static struct platform_device lcdc1_device = { | ||
| 614 | .name = "sh_mobile_lcdc_fb", | ||
| 615 | .num_resources = ARRAY_SIZE(lcdc1_resources), | ||
| 616 | .resource = lcdc1_resources, | ||
| 617 | .id = 1, | ||
| 618 | .dev = { | ||
| 619 | .platform_data = &sh_mobile_lcdc1_info, | ||
| 620 | .coherent_dma_mask = ~0, | ||
| 621 | }, | ||
| 622 | }; | ||
| 623 | |||
| 624 | static struct sh_mobile_hdmi_info hdmi_info = { | ||
| 625 | .lcd_chan = &sh_mobile_lcdc1_info.ch[0], | ||
| 626 | .lcd_dev = &lcdc1_device.dev, | ||
| 627 | }; | ||
| 628 | |||
| 629 | static struct resource hdmi_resources[] = { | ||
| 630 | [0] = { | ||
| 631 | .name = "HDMI", | ||
| 632 | .start = 0xe6be0000, | ||
| 633 | .end = 0xe6be00ff, | ||
| 634 | .flags = IORESOURCE_MEM, | ||
| 635 | }, | ||
| 636 | [1] = { | ||
| 637 | /* There's also an HDMI interrupt on INTCS @ 0x18e0 */ | ||
| 638 | .start = evt2irq(0x17e0), | ||
| 639 | .flags = IORESOURCE_IRQ, | ||
| 640 | }, | ||
| 641 | }; | ||
| 642 | |||
| 643 | static struct platform_device hdmi_device = { | ||
| 644 | .name = "sh-mobile-hdmi", | ||
| 645 | .num_resources = ARRAY_SIZE(hdmi_resources), | ||
| 646 | .resource = hdmi_resources, | ||
| 647 | .id = -1, | ||
| 648 | .dev = { | ||
| 649 | .platform_data = &hdmi_info, | ||
| 650 | }, | ||
| 651 | }; | ||
| 652 | |||
| 568 | static struct platform_device *ap4evb_devices[] __initdata = { | 653 | static struct platform_device *ap4evb_devices[] __initdata = { |
| 569 | &nor_flash_device, | 654 | &nor_flash_device, |
| 570 | &smc911x_device, | 655 | &smc911x_device, |
| 571 | &sdhi0_device, | 656 | &sdhi0_device, |
| 572 | &sdhi1_device, | 657 | &sdhi1_device, |
| 573 | &usb1_host_device, | 658 | &usb1_host_device, |
| 574 | &lcdc_device, | ||
| 575 | &fsi_device, | 659 | &fsi_device, |
| 576 | &sh_mmcif_device | 660 | &sh_mmcif_device |
| 661 | &lcdc1_device, | ||
| 662 | &lcdc_device, | ||
| 663 | &hdmi_device, | ||
| 577 | }; | 664 | }; |
| 578 | 665 | ||
| 666 | static int __init hdmi_init_pm_clock(void) | ||
| 667 | { | ||
| 668 | struct clk *hdmi_ick = clk_get(&hdmi_device.dev, "ick"); | ||
| 669 | int ret; | ||
| 670 | long rate; | ||
| 671 | |||
| 672 | if (IS_ERR(hdmi_ick)) { | ||
| 673 | ret = PTR_ERR(hdmi_ick); | ||
| 674 | pr_err("Cannot get HDMI ICK: %d\n", ret); | ||
| 675 | goto out; | ||
| 676 | } | ||
| 677 | |||
| 678 | ret = clk_set_parent(&pllc2_clk, &dv_clki_div2_clk); | ||
| 679 | if (ret < 0) { | ||
| 680 | pr_err("Cannot set PLLC2 parent: %d, %d users\n", ret, pllc2_clk.usecount); | ||
| 681 | goto out; | ||
| 682 | } | ||
| 683 | |||
| 684 | pr_debug("PLLC2 initial frequency %lu\n", clk_get_rate(&pllc2_clk)); | ||
| 685 | |||
| 686 | rate = clk_round_rate(&pllc2_clk, 594000000); | ||
| 687 | if (rate < 0) { | ||
| 688 | pr_err("Cannot get suitable rate: %ld\n", rate); | ||
| 689 | ret = rate; | ||
| 690 | goto out; | ||
| 691 | } | ||
| 692 | |||
| 693 | ret = clk_set_rate(&pllc2_clk, rate); | ||
| 694 | if (ret < 0) { | ||
| 695 | pr_err("Cannot set rate %ld: %d\n", rate, ret); | ||
| 696 | goto out; | ||
| 697 | } | ||
| 698 | |||
| 699 | pr_debug("PLLC2 set frequency %lu\n", rate); | ||
| 700 | |||
| 701 | ret = clk_set_parent(hdmi_ick, &pllc2_clk); | ||
| 702 | if (ret < 0) { | ||
| 703 | pr_err("Cannot set HDMI parent: %d\n", ret); | ||
| 704 | goto out; | ||
| 705 | } | ||
| 706 | |||
| 707 | out: | ||
| 708 | if (!IS_ERR(hdmi_ick)) | ||
| 709 | clk_put(hdmi_ick); | ||
| 710 | return ret; | ||
| 711 | } | ||
| 712 | |||
| 713 | device_initcall(hdmi_init_pm_clock); | ||
| 714 | |||
| 579 | /* | 715 | /* |
| 580 | * FIXME !! | 716 | * FIXME !! |
| 581 | * | 717 | * |
| @@ -689,9 +825,9 @@ static void __init ap4evb_map_io(void) | |||
| 689 | 825 | ||
| 690 | #define GPIO_PORT9CR 0xE6051009 | 826 | #define GPIO_PORT9CR 0xE6051009 |
| 691 | #define GPIO_PORT10CR 0xE605100A | 827 | #define GPIO_PORT10CR 0xE605100A |
| 692 | |||
| 693 | static void __init ap4evb_init(void) | 828 | static void __init ap4evb_init(void) |
| 694 | { | 829 | { |
| 830 | u32 srcr4; | ||
| 695 | struct clk *clk; | 831 | struct clk *clk; |
| 696 | 832 | ||
| 697 | sh7372_pinmux_init(); | 833 | sh7372_pinmux_init(); |
| @@ -915,6 +1051,17 @@ static void __init ap4evb_init(void) | |||
| 915 | 1051 | ||
| 916 | sh7372_add_standard_devices(); | 1052 | sh7372_add_standard_devices(); |
| 917 | 1053 | ||
| 1054 | /* HDMI */ | ||
| 1055 | gpio_request(GPIO_FN_HDMI_HPD, NULL); | ||
| 1056 | gpio_request(GPIO_FN_HDMI_CEC, NULL); | ||
| 1057 | |||
| 1058 | /* Reset HDMI, must be held at least one EXTALR (32768Hz) period */ | ||
| 1059 | #define SRCR4 0xe61580bc | ||
| 1060 | srcr4 = __raw_readl(SRCR4); | ||
| 1061 | __raw_writel(srcr4 | (1 << 13), SRCR4); | ||
| 1062 | udelay(50); | ||
| 1063 | __raw_writel(srcr4 & ~(1 << 13), SRCR4); | ||
| 1064 | |||
| 918 | platform_add_devices(ap4evb_devices, ARRAY_SIZE(ap4evb_devices)); | 1065 | platform_add_devices(ap4evb_devices, ARRAY_SIZE(ap4evb_devices)); |
| 919 | } | 1066 | } |
| 920 | 1067 | ||
| @@ -922,6 +1069,9 @@ static void __init ap4evb_timer_init(void) | |||
| 922 | { | 1069 | { |
| 923 | sh7372_clock_init(); | 1070 | sh7372_clock_init(); |
| 924 | shmobile_timer.init(); | 1071 | shmobile_timer.init(); |
| 1072 | |||
| 1073 | /* External clock source */ | ||
| 1074 | clk_set_rate(&dv_clki_clk, 27000000); | ||
| 925 | } | 1075 | } |
| 926 | 1076 | ||
| 927 | static struct sys_timer ap4evb_timer = { | 1077 | static struct sys_timer ap4evb_timer = { |
