From af946f269973cda86d7263ac9f2dad659773545c Mon Sep 17 00:00:00 2001 From: Manjunath Hadli Date: Thu, 23 Feb 2012 15:17:45 +0530 Subject: ARM: davinci: dm644x: add support for v4l2 video display Add functions to register various video devices like venc, osd, vpbe and the v4l2 display driver for dm644x. Change dm644x_init_video() to make room for display related configuration. Register the vpfe or vpbe devices only if valid display configuration is provided to make sure boards without video support dont erroneously register video devices. Signed-off-by: Manjunath Hadli Signed-off-by: Sekhar Nori --- arch/arm/mach-davinci/board-dm644x-evm.c | 2 +- arch/arm/mach-davinci/davinci.h | 8 +- arch/arm/mach-davinci/dm644x.c | 166 ++++++++++++++++++++++++++++--- 3 files changed, 161 insertions(+), 15 deletions(-) (limited to 'arch/arm/mach-davinci') diff --git a/arch/arm/mach-davinci/board-dm644x-evm.c b/arch/arm/mach-davinci/board-dm644x-evm.c index b89bebe01c0..a61aa8d0a2b 100644 --- a/arch/arm/mach-davinci/board-dm644x-evm.c +++ b/arch/arm/mach-davinci/board-dm644x-evm.c @@ -696,7 +696,7 @@ static __init void davinci_evm_init(void) evm_init_i2c(); davinci_setup_mmc(0, &dm6446evm_mmc_config); - dm644x_init_video(&dm644xevm_capture_cfg); + dm644x_init_video(&dm644xevm_capture_cfg, NULL); davinci_serial_init(&uart_config); dm644x_init_asp(&dm644x_evm_snd_data); diff --git a/arch/arm/mach-davinci/davinci.h b/arch/arm/mach-davinci/davinci.h index 9d708034b57..3e519dad5bb 100644 --- a/arch/arm/mach-davinci/davinci.h +++ b/arch/arm/mach-davinci/davinci.h @@ -29,9 +29,15 @@ #include #include +#include +#include +#include +#include +#include #define DAVINCI_SYSTEM_MODULE_BASE 0x01c40000 #define SYSMOD_VIDCLKCTL 0x38 +#define SYSMOD_VPSS_CLKCTL 0x44 #define SYSMOD_VDD3P3VPWDN 0x48 #define SYSMOD_VSCLKDIS 0x6c #define SYSMOD_PUPDCTL1 0x7c @@ -83,7 +89,7 @@ void dm365_set_vpfe_config(struct vpfe_config *cfg); /* DM644x function declarations */ void __init dm644x_init(void); void __init dm644x_init_asp(struct snd_platform_data *pdata); -int __init dm644x_init_video(struct vpfe_config *); +int __init dm644x_init_video(struct vpfe_config *, struct vpbe_config *); /* DM646x function declarations */ void __init dm646x_init(void); diff --git a/arch/arm/mach-davinci/dm644x.c b/arch/arm/mach-davinci/dm644x.c index 23e81cafba8..c8b866657fc 100644 --- a/arch/arm/mach-davinci/dm644x.c +++ b/arch/arm/mach-davinci/dm644x.c @@ -627,7 +627,7 @@ static struct resource dm644x_vpfe_resources[] = { }, }; -static u64 vpfe_capture_dma_mask = DMA_BIT_MASK(32); +static u64 dm644x_video_dma_mask = DMA_BIT_MASK(32); static struct resource dm644x_ccdc_resource[] = { /* CCDC Base address */ { @@ -643,7 +643,7 @@ static struct platform_device dm644x_ccdc_dev = { .num_resources = ARRAY_SIZE(dm644x_ccdc_resource), .resource = dm644x_ccdc_resource, .dev = { - .dma_mask = &vpfe_capture_dma_mask, + .dma_mask = &dm644x_video_dma_mask, .coherent_dma_mask = DMA_BIT_MASK(32), }, }; @@ -654,7 +654,134 @@ static struct platform_device dm644x_vpfe_dev = { .num_resources = ARRAY_SIZE(dm644x_vpfe_resources), .resource = dm644x_vpfe_resources, .dev = { - .dma_mask = &vpfe_capture_dma_mask, + .dma_mask = &dm644x_video_dma_mask, + .coherent_dma_mask = DMA_BIT_MASK(32), + }, +}; + +#define DM644X_OSD_BASE 0x01c72600 + +static struct resource dm644x_osd_resources[] = { + { + .start = DM644X_OSD_BASE, + .end = DM644X_OSD_BASE + 0x1ff, + .flags = IORESOURCE_MEM, + }, +}; + +static struct osd_platform_data dm644x_osd_data = { + .vpbe_type = VPBE_VERSION_1, +}; + +static struct platform_device dm644x_osd_dev = { + .name = VPBE_OSD_SUBDEV_NAME, + .id = -1, + .num_resources = ARRAY_SIZE(dm644x_osd_resources), + .resource = dm644x_osd_resources, + .dev = { + .dma_mask = &dm644x_video_dma_mask, + .coherent_dma_mask = DMA_BIT_MASK(32), + .platform_data = &dm644x_osd_data, + }, +}; + +#define DM644X_VENC_BASE 0x01c72400 + +static struct resource dm644x_venc_resources[] = { + { + .start = DM644X_VENC_BASE, + .end = DM644X_VENC_BASE + 0x17f, + .flags = IORESOURCE_MEM, + }, +}; + +#define DM644X_VPSS_MUXSEL_PLL2_MODE BIT(0) +#define DM644X_VPSS_MUXSEL_VPBECLK_MODE BIT(1) +#define DM644X_VPSS_VENCLKEN BIT(3) +#define DM644X_VPSS_DACCLKEN BIT(4) + +static int dm644x_venc_setup_clock(enum vpbe_enc_timings_type type, + unsigned int mode) +{ + int ret = 0; + u32 v = DM644X_VPSS_VENCLKEN; + + switch (type) { + case VPBE_ENC_STD: + v |= DM644X_VPSS_DACCLKEN; + writel(v, DAVINCI_SYSMOD_VIRT(SYSMOD_VPSS_CLKCTL)); + break; + case VPBE_ENC_DV_PRESET: + switch (mode) { + case V4L2_DV_480P59_94: + case V4L2_DV_576P50: + v |= DM644X_VPSS_MUXSEL_PLL2_MODE | + DM644X_VPSS_DACCLKEN; + writel(v, DAVINCI_SYSMOD_VIRT(SYSMOD_VPSS_CLKCTL)); + break; + case V4L2_DV_720P60: + case V4L2_DV_1080I60: + case V4L2_DV_1080P30: + /* + * For HD, use external clock source since + * HD requires higher clock rate + */ + v |= DM644X_VPSS_MUXSEL_VPBECLK_MODE; + writel(v, DAVINCI_SYSMOD_VIRT(SYSMOD_VPSS_CLKCTL)); + break; + default: + ret = -EINVAL; + break; + } + break; + default: + ret = -EINVAL; + } + + return ret; +} + +static struct resource dm644x_v4l2_disp_resources[] = { + { + .start = IRQ_VENCINT, + .end = IRQ_VENCINT, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device dm644x_vpbe_display = { + .name = "vpbe-v4l2", + .id = -1, + .num_resources = ARRAY_SIZE(dm644x_v4l2_disp_resources), + .resource = dm644x_v4l2_disp_resources, + .dev = { + .dma_mask = &dm644x_video_dma_mask, + .coherent_dma_mask = DMA_BIT_MASK(32), + }, +}; + +static struct venc_platform_data dm644x_venc_pdata = { + .venc_type = VPBE_VERSION_1, + .setup_clock = dm644x_venc_setup_clock, +}; + +static struct platform_device dm644x_venc_dev = { + .name = VPBE_VENC_SUBDEV_NAME, + .id = -1, + .num_resources = ARRAY_SIZE(dm644x_venc_resources), + .resource = dm644x_venc_resources, + .dev = { + .dma_mask = &dm644x_video_dma_mask, + .coherent_dma_mask = DMA_BIT_MASK(32), + .platform_data = &dm644x_venc_pdata, + }, +}; + +static struct platform_device dm644x_vpbe_dev = { + .name = "vpbe_controller", + .id = -1, + .dev = { + .dma_mask = &dm644x_video_dma_mask, .coherent_dma_mask = DMA_BIT_MASK(32), }, }; @@ -786,17 +913,30 @@ void __init dm644x_init(void) davinci_map_sysmod(); } -int __init dm644x_init_video(struct vpfe_config *vpfe_cfg) +int __init dm644x_init_video(struct vpfe_config *vpfe_cfg, + struct vpbe_config *vpbe_cfg) { - dm644x_vpfe_dev.dev.platform_data = vpfe_cfg; - - /* Add ccdc clock aliases */ - clk_add_alias("master", dm644x_ccdc_dev.name, "vpss_master", NULL); - clk_add_alias("slave", dm644x_ccdc_dev.name, "vpss_slave", NULL); - - platform_device_register(&dm644x_vpss_device); - platform_device_register(&dm644x_ccdc_dev); - platform_device_register(&dm644x_vpfe_dev); + if (vpfe_cfg || vpbe_cfg) + platform_device_register(&dm644x_vpss_device); + + if (vpfe_cfg) { + dm644x_vpfe_dev.dev.platform_data = vpfe_cfg; + platform_device_register(&dm644x_ccdc_dev); + platform_device_register(&dm644x_vpfe_dev); + /* Add ccdc clock aliases */ + clk_add_alias("master", dm644x_ccdc_dev.name, + "vpss_master", NULL); + clk_add_alias("slave", dm644x_ccdc_dev.name, + "vpss_slave", NULL); + } + + if (vpbe_cfg) { + dm644x_vpbe_dev.dev.platform_data = vpbe_cfg; + platform_device_register(&dm644x_osd_dev); + platform_device_register(&dm644x_venc_dev); + platform_device_register(&dm644x_vpbe_dev); + platform_device_register(&dm644x_vpbe_display); + } return 0; } -- cgit v1.2.3-70-g09d2 From d5be5f549c9d619fe3e16160c453a72f718284de Mon Sep 17 00:00:00 2001 From: Manjunath Hadli Date: Thu, 23 Feb 2012 15:17:46 +0530 Subject: ARM: davinci: dm644x evm: add support for VPBE display This patch adds support for V4L2 video display to DM6446 EVM. Support for SD and ED modes is provided, along with composite and component outputs. Signed-off-by: Manjunath Hadli Signed-off-by: Sekhar Nori --- arch/arm/mach-davinci/board-dm644x-evm.c | 109 ++++++++++++++++++++++++++++++- 1 file changed, 108 insertions(+), 1 deletion(-) (limited to 'arch/arm/mach-davinci') diff --git a/arch/arm/mach-davinci/board-dm644x-evm.c b/arch/arm/mach-davinci/board-dm644x-evm.c index a61aa8d0a2b..385423558f1 100644 --- a/arch/arm/mach-davinci/board-dm644x-evm.c +++ b/arch/arm/mach-davinci/board-dm644x-evm.c @@ -613,6 +613,113 @@ static void __init evm_init_i2c(void) i2c_register_board_info(1, i2c_info, ARRAY_SIZE(i2c_info)); } +#define VENC_STD_ALL (V4L2_STD_NTSC | V4L2_STD_PAL) + +/* venc standard timings */ +static struct vpbe_enc_mode_info dm644xevm_enc_std_timing[] = { + { + .name = "ntsc", + .timings_type = VPBE_ENC_STD, + .timings = {V4L2_STD_525_60}, + .interlaced = 1, + .xres = 720, + .yres = 480, + .aspect = {11, 10}, + .fps = {30000, 1001}, + .left_margin = 0x79, + .upper_margin = 0x10, + }, + { + .name = "pal", + .timings_type = VPBE_ENC_STD, + .timings = {V4L2_STD_625_50}, + .interlaced = 1, + .xres = 720, + .yres = 576, + .aspect = {54, 59}, + .fps = {25, 1}, + .left_margin = 0x7e, + .upper_margin = 0x16, + }, +}; + +/* venc dv preset timings */ +static struct vpbe_enc_mode_info dm644xevm_enc_preset_timing[] = { + { + .name = "480p59_94", + .timings_type = VPBE_ENC_DV_PRESET, + .timings = {V4L2_DV_480P59_94}, + .interlaced = 0, + .xres = 720, + .yres = 480, + .aspect = {1, 1}, + .fps = {5994, 100}, + .left_margin = 0x80, + .upper_margin = 0x20, + }, + { + .name = "576p50", + .timings_type = VPBE_ENC_DV_PRESET, + .timings = {V4L2_DV_576P50}, + .interlaced = 0, + .xres = 720, + .yres = 576, + .aspect = {1, 1}, + .fps = {50, 1}, + .left_margin = 0x7e, + .upper_margin = 0x30, + }, +}; + +/* + * The outputs available from VPBE + encoders. Keep the order same + * as that of encoders. First those from venc followed by that from + * encoders. Index in the output refers to index on a particular encoder. + * Driver uses this index to pass it to encoder when it supports more + * than one output. Userspace applications use index of the array to + * set an output. + */ +static struct vpbe_output dm644xevm_vpbe_outputs[] = { + { + .output = { + .index = 0, + .name = "Composite", + .type = V4L2_OUTPUT_TYPE_ANALOG, + .std = VENC_STD_ALL, + .capabilities = V4L2_OUT_CAP_STD, + }, + .subdev_name = VPBE_VENC_SUBDEV_NAME, + .default_mode = "ntsc", + .num_modes = ARRAY_SIZE(dm644xevm_enc_std_timing), + .modes = dm644xevm_enc_std_timing, + }, + { + .output = { + .index = 1, + .name = "Component", + .type = V4L2_OUTPUT_TYPE_ANALOG, + .capabilities = V4L2_OUT_CAP_PRESETS, + }, + .subdev_name = VPBE_VENC_SUBDEV_NAME, + .default_mode = "480p59_94", + .num_modes = ARRAY_SIZE(dm644xevm_enc_preset_timing), + .modes = dm644xevm_enc_preset_timing, + }, +}; + +static struct vpbe_config dm644xevm_display_cfg = { + .module_name = "dm644x-vpbe-display", + .i2c_adapter_id = 1, + .osd = { + .module_name = VPBE_OSD_SUBDEV_NAME, + }, + .venc = { + .module_name = VPBE_VENC_SUBDEV_NAME, + }, + .num_outputs = ARRAY_SIZE(dm644xevm_vpbe_outputs), + .outputs = dm644xevm_vpbe_outputs, +}; + static struct platform_device *davinci_evm_devices[] __initdata = { &davinci_fb_device, &rtc_dev, @@ -696,7 +803,7 @@ static __init void davinci_evm_init(void) evm_init_i2c(); davinci_setup_mmc(0, &dm6446evm_mmc_config); - dm644x_init_video(&dm644xevm_capture_cfg, NULL); + dm644x_init_video(&dm644xevm_capture_cfg, &dm644xevm_display_cfg); davinci_serial_init(&uart_config); dm644x_init_asp(&dm644x_evm_snd_data); -- cgit v1.2.3-70-g09d2