diff options
author | Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> | 2011-01-05 21:44:09 -0500 |
---|---|---|
committer | Paul Mundt <lethal@linux-sh.org> | 2011-01-05 22:17:12 -0500 |
commit | 12c4309b78854ba117ea38a9178018591abd16ab (patch) | |
tree | 0a69e8583e2b77c2f8067515a35d6adaa3612a41 /arch/arm/mach-shmobile/board-mackerel.c | |
parent | 73674648e9bf3b0a75000b7e97edaac255cd73f7 (diff) |
ARM: mach-shmobile: mackerel: add HDMI video support
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'arch/arm/mach-shmobile/board-mackerel.c')
-rw-r--r-- | arch/arm/mach-shmobile/board-mackerel.c | 141 |
1 files changed, 141 insertions, 0 deletions
diff --git a/arch/arm/mach-shmobile/board-mackerel.c b/arch/arm/mach-shmobile/board-mackerel.c index 42f7c0d67b53..c7d378b57cfc 100644 --- a/arch/arm/mach-shmobile/board-mackerel.c +++ b/arch/arm/mach-shmobile/board-mackerel.c | |||
@@ -21,6 +21,7 @@ | |||
21 | * along with this program; if not, write to the Free Software | 21 | * along with this program; if not, write to the Free Software |
22 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | 22 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
23 | */ | 23 | */ |
24 | #include <linux/delay.h> | ||
24 | #include <linux/kernel.h> | 25 | #include <linux/kernel.h> |
25 | #include <linux/init.h> | 26 | #include <linux/init.h> |
26 | #include <linux/interrupt.h> | 27 | #include <linux/interrupt.h> |
@@ -43,6 +44,7 @@ | |||
43 | #include <linux/tca6416_keypad.h> | 44 | #include <linux/tca6416_keypad.h> |
44 | #include <linux/usb/r8a66597.h> | 45 | #include <linux/usb/r8a66597.h> |
45 | 46 | ||
47 | #include <video/sh_mobile_hdmi.h> | ||
46 | #include <video/sh_mobile_lcdc.h> | 48 | #include <video/sh_mobile_lcdc.h> |
47 | #include <media/sh_mobile_ceu.h> | 49 | #include <media/sh_mobile_ceu.h> |
48 | #include <media/soc_camera.h> | 50 | #include <media/soc_camera.h> |
@@ -332,6 +334,127 @@ static struct platform_device lcdc_device = { | |||
332 | }, | 334 | }, |
333 | }; | 335 | }; |
334 | 336 | ||
337 | /* HDMI */ | ||
338 | static struct sh_mobile_lcdc_info hdmi_lcdc_info = { | ||
339 | .clock_source = LCDC_CLK_EXTERNAL, | ||
340 | .ch[0] = { | ||
341 | .chan = LCDC_CHAN_MAINLCD, | ||
342 | .bpp = 16, | ||
343 | .interface_type = RGB24, | ||
344 | .clock_divider = 1, | ||
345 | .flags = LCDC_FLAGS_DWPOL, | ||
346 | } | ||
347 | }; | ||
348 | |||
349 | static struct resource hdmi_lcdc_resources[] = { | ||
350 | [0] = { | ||
351 | .name = "LCDC1", | ||
352 | .start = 0xfe944000, | ||
353 | .end = 0xfe947fff, | ||
354 | .flags = IORESOURCE_MEM, | ||
355 | }, | ||
356 | [1] = { | ||
357 | .start = intcs_evt2irq(0x1780), | ||
358 | .flags = IORESOURCE_IRQ, | ||
359 | }, | ||
360 | }; | ||
361 | |||
362 | static struct platform_device hdmi_lcdc_device = { | ||
363 | .name = "sh_mobile_lcdc_fb", | ||
364 | .num_resources = ARRAY_SIZE(hdmi_lcdc_resources), | ||
365 | .resource = hdmi_lcdc_resources, | ||
366 | .id = 1, | ||
367 | .dev = { | ||
368 | .platform_data = &hdmi_lcdc_info, | ||
369 | .coherent_dma_mask = ~0, | ||
370 | }, | ||
371 | }; | ||
372 | |||
373 | static struct sh_mobile_hdmi_info hdmi_info = { | ||
374 | .lcd_chan = &hdmi_lcdc_info.ch[0], | ||
375 | .lcd_dev = &hdmi_lcdc_device.dev, | ||
376 | }; | ||
377 | |||
378 | static struct resource hdmi_resources[] = { | ||
379 | [0] = { | ||
380 | .name = "HDMI", | ||
381 | .start = 0xe6be0000, | ||
382 | .end = 0xe6be00ff, | ||
383 | .flags = IORESOURCE_MEM, | ||
384 | }, | ||
385 | [1] = { | ||
386 | /* There's also an HDMI interrupt on INTCS @ 0x18e0 */ | ||
387 | .start = evt2irq(0x17e0), | ||
388 | .flags = IORESOURCE_IRQ, | ||
389 | }, | ||
390 | }; | ||
391 | |||
392 | static struct platform_device hdmi_device = { | ||
393 | .name = "sh-mobile-hdmi", | ||
394 | .num_resources = ARRAY_SIZE(hdmi_resources), | ||
395 | .resource = hdmi_resources, | ||
396 | .id = -1, | ||
397 | .dev = { | ||
398 | .platform_data = &hdmi_info, | ||
399 | }, | ||
400 | }; | ||
401 | |||
402 | static int __init hdmi_init_pm_clock(void) | ||
403 | { | ||
404 | struct clk *hdmi_ick = clk_get(&hdmi_device.dev, "ick"); | ||
405 | int ret; | ||
406 | long rate; | ||
407 | |||
408 | if (IS_ERR(hdmi_ick)) { | ||
409 | ret = PTR_ERR(hdmi_ick); | ||
410 | pr_err("Cannot get HDMI ICK: %d\n", ret); | ||
411 | goto out; | ||
412 | } | ||
413 | |||
414 | ret = clk_set_parent(&sh7372_pllc2_clk, &sh7372_dv_clki_div2_clk); | ||
415 | if (ret < 0) { | ||
416 | pr_err("Cannot set PLLC2 parent: %d, %d users\n", | ||
417 | ret, sh7372_pllc2_clk.usecount); | ||
418 | goto out; | ||
419 | } | ||
420 | |||
421 | pr_debug("PLLC2 initial frequency %lu\n", | ||
422 | clk_get_rate(&sh7372_pllc2_clk)); | ||
423 | |||
424 | rate = clk_round_rate(&sh7372_pllc2_clk, 594000000); | ||
425 | if (rate < 0) { | ||
426 | pr_err("Cannot get suitable rate: %ld\n", rate); | ||
427 | ret = rate; | ||
428 | goto out; | ||
429 | } | ||
430 | |||
431 | ret = clk_set_rate(&sh7372_pllc2_clk, rate); | ||
432 | if (ret < 0) { | ||
433 | pr_err("Cannot set rate %ld: %d\n", rate, ret); | ||
434 | goto out; | ||
435 | } | ||
436 | |||
437 | ret = clk_enable(&sh7372_pllc2_clk); | ||
438 | if (ret < 0) { | ||
439 | pr_err("Cannot enable pllc2 clock\n"); | ||
440 | goto out; | ||
441 | } | ||
442 | |||
443 | pr_debug("PLLC2 set frequency %lu\n", rate); | ||
444 | |||
445 | ret = clk_set_parent(hdmi_ick, &sh7372_pllc2_clk); | ||
446 | if (ret < 0) { | ||
447 | pr_err("Cannot set HDMI parent: %d\n", ret); | ||
448 | goto out; | ||
449 | } | ||
450 | |||
451 | out: | ||
452 | if (!IS_ERR(hdmi_ick)) | ||
453 | clk_put(hdmi_ick); | ||
454 | return ret; | ||
455 | } | ||
456 | device_initcall(hdmi_init_pm_clock); | ||
457 | |||
335 | /* USB1 (Host) */ | 458 | /* USB1 (Host) */ |
336 | static void usb1_host_port_power(int port, int power) | 459 | static void usb1_host_port_power(int port, int power) |
337 | { | 460 | { |
@@ -718,6 +841,8 @@ static struct platform_device *mackerel_devices[] __initdata = { | |||
718 | &sh_mmcif_device, | 841 | &sh_mmcif_device, |
719 | &ceu_device, | 842 | &ceu_device, |
720 | &mackerel_camera, | 843 | &mackerel_camera, |
844 | &hdmi_lcdc_device, | ||
845 | &hdmi_device, | ||
721 | }; | 846 | }; |
722 | 847 | ||
723 | /* Keypad Initialization */ | 848 | /* Keypad Initialization */ |
@@ -793,8 +918,11 @@ static void __init mackerel_map_io(void) | |||
793 | 918 | ||
794 | #define GPIO_PORT9CR 0xE6051009 | 919 | #define GPIO_PORT9CR 0xE6051009 |
795 | #define GPIO_PORT10CR 0xE605100A | 920 | #define GPIO_PORT10CR 0xE605100A |
921 | #define SRCR4 0xe61580bc | ||
796 | static void __init mackerel_init(void) | 922 | static void __init mackerel_init(void) |
797 | { | 923 | { |
924 | u32 srcr4; | ||
925 | |||
798 | sh7372_pinmux_init(); | 926 | sh7372_pinmux_init(); |
799 | 927 | ||
800 | /* enable SCIFA0 */ | 928 | /* enable SCIFA0 */ |
@@ -935,6 +1063,16 @@ static void __init mackerel_init(void) | |||
935 | gpio_request(GPIO_FN_VIO_D1, NULL); | 1063 | gpio_request(GPIO_FN_VIO_D1, NULL); |
936 | gpio_request(GPIO_FN_VIO_D0, NULL); | 1064 | gpio_request(GPIO_FN_VIO_D0, NULL); |
937 | 1065 | ||
1066 | /* HDMI */ | ||
1067 | gpio_request(GPIO_FN_HDMI_HPD, NULL); | ||
1068 | gpio_request(GPIO_FN_HDMI_CEC, NULL); | ||
1069 | |||
1070 | /* Reset HDMI, must be held at least one EXTALR (32768Hz) period */ | ||
1071 | srcr4 = __raw_readl(SRCR4); | ||
1072 | __raw_writel(srcr4 | (1 << 13), SRCR4); | ||
1073 | udelay(50); | ||
1074 | __raw_writel(srcr4 & ~(1 << 13), SRCR4); | ||
1075 | |||
938 | i2c_register_board_info(0, i2c0_devices, | 1076 | i2c_register_board_info(0, i2c0_devices, |
939 | ARRAY_SIZE(i2c0_devices)); | 1077 | ARRAY_SIZE(i2c0_devices)); |
940 | i2c_register_board_info(1, i2c1_devices, | 1078 | i2c_register_board_info(1, i2c1_devices, |
@@ -949,6 +1087,9 @@ static void __init mackerel_timer_init(void) | |||
949 | { | 1087 | { |
950 | sh7372_clock_init(); | 1088 | sh7372_clock_init(); |
951 | shmobile_timer.init(); | 1089 | shmobile_timer.init(); |
1090 | |||
1091 | /* External clock source */ | ||
1092 | clk_set_rate(&sh7372_dv_clki_clk, 27000000); | ||
952 | } | 1093 | } |
953 | 1094 | ||
954 | static struct sys_timer mackerel_timer = { | 1095 | static struct sys_timer mackerel_timer = { |