aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-shmobile/board-mackerel.c
diff options
context:
space:
mode:
authorKuninori Morimoto <kuninori.morimoto.gx@renesas.com>2011-01-05 21:44:09 -0500
committerPaul Mundt <lethal@linux-sh.org>2011-01-05 22:17:12 -0500
commit12c4309b78854ba117ea38a9178018591abd16ab (patch)
tree0a69e8583e2b77c2f8067515a35d6adaa3612a41 /arch/arm/mach-shmobile/board-mackerel.c
parent73674648e9bf3b0a75000b7e97edaac255cd73f7 (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.c141
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 */
338static 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
349static 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
362static 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
373static struct sh_mobile_hdmi_info hdmi_info = {
374 .lcd_chan = &hdmi_lcdc_info.ch[0],
375 .lcd_dev = &hdmi_lcdc_device.dev,
376};
377
378static 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
392static 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
402static 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
451out:
452 if (!IS_ERR(hdmi_ick))
453 clk_put(hdmi_ick);
454 return ret;
455}
456device_initcall(hdmi_init_pm_clock);
457
335/* USB1 (Host) */ 458/* USB1 (Host) */
336static void usb1_host_port_power(int port, int power) 459static 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
796static void __init mackerel_init(void) 922static 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
954static struct sys_timer mackerel_timer = { 1095static struct sys_timer mackerel_timer = {