From patchwork Wed Nov 24 14:10:35 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Manjunath Hadli X-Patchwork-Id: 353191 Received: from arroyo.ext.ti.com (arroyo.ext.ti.com [192.94.94.40]) by demeter1.kernel.org (8.14.4/8.14.3) with ESMTP id oAOEF1t6005593 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Wed, 24 Nov 2010 14:15:27 GMT Received: from dlep35.itg.ti.com ([157.170.170.118]) by arroyo.ext.ti.com (8.13.7/8.13.7) with ESMTP id oAOEBpIi027509 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Wed, 24 Nov 2010 08:12:16 -0600 Received: from linux.omap.com (localhost [127.0.0.1]) by dlep35.itg.ti.com (8.13.7/8.13.7) with ESMTP id oAOEBoEY017273; Wed, 24 Nov 2010 08:11:50 -0600 (CST) Received: from linux.omap.com (localhost [127.0.0.1]) by linux.omap.com (Postfix) with ESMTP id 7139A80657; Wed, 24 Nov 2010 08:11:32 -0600 (CST) X-Original-To: davinci-linux-open-source@linux.davincidsp.com Delivered-To: davinci-linux-open-source@linux.davincidsp.com Received: from dbdp31.itg.ti.com (dbdp31.itg.ti.com [172.24.170.98]) by linux.omap.com (Postfix) with ESMTP id 3DFF5806EF for ; Wed, 24 Nov 2010 08:10:39 -0600 (CST) Received: from psplinux051.india.ti.com (localhost [127.0.0.1]) by dbdp31.itg.ti.com (8.13.8/8.13.8) with ESMTP id oAOEAZgf028804; Wed, 24 Nov 2010 19:40:35 +0530 (IST) Received: from psplinux051.india.ti.com (localhost [127.0.0.1]) by psplinux051.india.ti.com (8.13.1/8.13.1) with ESMTP id oAOEAZkh010644; Wed, 24 Nov 2010 19:40:35 +0530 Received: (from x0144960@localhost) by psplinux051.india.ti.com (8.13.1/8.13.1/Submit) id oAOEAZ8l010641; Wed, 24 Nov 2010 19:40:35 +0530 From: Manjunath Hadli To: LMML Subject: [PATCH v2 5/6] davinci vpbe: platform specific additions Date: Wed, 24 Nov 2010 19:40:35 +0530 Message-Id: <1290607835-10612-1-git-send-email-manjunath.hadli@ti.com> X-Mailer: git-send-email 1.6.2.4 Cc: dlos , Mauro Carvalho Chehab X-BeenThere: davinci-linux-open-source@linux.davincidsp.com X-Mailman-Version: 2.1.12 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: davinci-linux-open-source-bounces@linux.davincidsp.com Errors-To: davinci-linux-open-source-bounces@linux.davincidsp.com X-Greylist: Sender succeeded STARTTLS authentication, not delayed by milter-greylist-4.2.3 (demeter1.kernel.org [140.211.167.41]); Wed, 24 Nov 2010 14:15:27 +0000 (UTC) diff --git a/arch/arm/mach-davinci/board-dm644x-evm.c b/arch/arm/mach-davinci/board-dm644x-evm.c index 34c8b41..1ca1456 100644 --- a/arch/arm/mach-davinci/board-dm644x-evm.c +++ b/arch/arm/mach-davinci/board-dm644x-evm.c @@ -166,18 +166,6 @@ static struct platform_device davinci_evm_nandflash_device = { .resource = davinci_evm_nandflash_resource, }; -static u64 davinci_fb_dma_mask = DMA_BIT_MASK(32); - -static struct platform_device davinci_fb_device = { - .name = "davincifb", - .id = -1, - .dev = { - .dma_mask = &davinci_fb_dma_mask, - .coherent_dma_mask = DMA_BIT_MASK(32), - }, - .num_resources = 0, -}; - static struct tvp514x_platform_data tvp5146_pdata = { .clk_polarity = 0, .hs_polarity = 1, @@ -606,8 +594,73 @@ 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 standards timings */ +static struct vpbe_enc_mode_info vbpe_enc_std_timings[] = { + {"ntsc", VPBE_ENC_STD, {V4L2_STD_525_60}, 1, 720, 480, + {11, 10}, {30000, 1001}, 0x79, 0, 0x10, 0, 0, 0, 0}, + {"pal", VPBE_ENC_STD, {V4L2_STD_625_50}, 1, 720, 576, + {54, 59}, {25, 1}, 0x7E, 0, 0x16, 0, 0, 0, 0}, +}; + +/* venc dv preset timings */ +static struct vpbe_enc_mode_info vbpe_enc_preset_timings[] = { + {"480p59_94", VPBE_ENC_DV_PRESET, {V4L2_DV_480P59_94}, 0, 720, 480, + {1, 1}, {5994, 100}, 0x80, 0, 0x20, 0, 0, 0, 0}, + {"576p50", VPBE_ENC_DV_PRESET, {V4L2_DV_576P50}, 0, 720, 576, + {1, 1}, {50, 1}, 0x7E, 0, 0x30, 0, 0, 0, 0}, +}; + +/* + * The outputs available from VPBE + ecnoders. Keep the + * the order same as that of encoders. First that 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. Application uses index of the array to set an output. + */ +static struct vpbe_output dm644x_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(vbpe_enc_std_timings), + .modes = vbpe_enc_std_timings, + .if_params = V4L2_MBUS_FMT_FIXED, + }, + { + .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(vbpe_enc_preset_timings), + .modes = vbpe_enc_preset_timings, + .if_params = V4L2_MBUS_FMT_FIXED, + }, +}; + +static struct vpbe_display_config vpbe_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(dm644x_vpbe_outputs), + .outputs = dm644x_vpbe_outputs, +}; static struct platform_device *davinci_evm_devices[] __initdata = { - &davinci_fb_device, &rtc_dev, }; @@ -620,6 +673,8 @@ davinci_evm_map_io(void) { /* setup input configuration for VPFE input devices */ dm644x_set_vpfe_config(&vpfe_cfg); + /* setup configuration for vpbe devices */ + dm644x_set_vpbe_display_config(&vpbe_display_cfg); dm644x_init(); } diff --git a/arch/arm/mach-davinci/dm644x.c b/arch/arm/mach-davinci/dm644x.c index 5e5b0a7..bad5b89 100644 --- a/arch/arm/mach-davinci/dm644x.c +++ b/arch/arm/mach-davinci/dm644x.c @@ -640,6 +640,216 @@ void dm644x_set_vpfe_config(struct vpfe_config *cfg) vpfe_capture_dev.dev.platform_data = cfg; } +static struct resource dm644x_osd_resources[] = { + { + .start = 0x01C72600, + .end = 0x01C72600 + 0x200, + .flags = IORESOURCE_MEM, + }, +}; + +static u64 dm644x_osd_dma_mask = DMA_BIT_MASK(32); + +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_osd_dma_mask, + .coherent_dma_mask = DMA_BIT_MASK(32), + .platform_data = (void *)DM644X_VPBE, + }, +}; + +static struct resource dm644x_venc_resources[] = { + /* venc registers io space */ + { + .start = 0x01C72400, + .end = 0x01C72400 + 0x180, + .flags = IORESOURCE_MEM, + }, +}; + +static u64 dm644x_venc_dma_mask = DMA_BIT_MASK(32); + +static int dm644x_vpbe_setup_pinmux(enum v4l2_mbus_pixelcode if_type, + int field) +{ + int ret = 0; + + switch (if_type) { + case V4L2_MBUS_FMT_SGRBG8_1X8: + /* This was VPBE_DIGITAL_IF_PRGB.Replace the enum accordingly + * when the right one gets into open source */ + davinci_cfg_reg(DM644X_GPIO46_47); + davinci_cfg_reg(DM644X_GPIO0); + davinci_cfg_reg(DM644X_RGB666); + davinci_cfg_reg(DM644X_LOEEN); + davinci_cfg_reg(DM644X_GPIO3); + break; + case V4L2_MBUS_FMT_YUYV10_1X20: + /* This was VPBE_DIGITAL_IF_YCC16.Replace the enum accordingly + * when the right one gets into open source */ + if (field) + davinci_cfg_reg(DM644X_LFLDEN); + else + davinci_cfg_reg(DM644X_GPIO3); + davinci_cfg_reg(DM644X_LOEEN); + break; + default: + ret = -EINVAL; + } + + return ret; +} + +#define VPSS_CLKCTL 0x01C40044 +#define VENC_VMOD 0x01C72400 +#define VENC_YCCTL 0x01C72438 +static void __iomem *vpss_clkctl_reg; +static void __iomem *venc_vmod_reg; +static void __iomem *venc_ycctl_reg; + +/* TBD. Check what VENC_CLOCK_SEL settings for HDTV and EDTV */ +static int dm644x_venc_setup_clock(enum vpbe_enc_timings_type type, __u64 mode) +{ + int ret = 0; + + if (NULL == vpss_clkctl_reg) + return -EINVAL; + if (type == VPBE_ENC_STD) { + __raw_writel(0x18, vpss_clkctl_reg); + } else if (type == VPBE_ENC_DV_PRESET) { + switch ((unsigned int)mode) { + case V4L2_DV_480P59_94: + case V4L2_DV_576P50: + __raw_writel(0x19, vpss_clkctl_reg); + 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 + */ + __raw_writel(0xa, vpss_clkctl_reg); + break; + default: + ret = -EINVAL; + break; + } + } else + ret = -EINVAL; + + return ret; +} + + +static inline u32 dm644x_reg_modify(void *reg, u32 val, u32 mask) +{ + u32 new_val = (__raw_readl(reg) & ~mask) | (val & mask); + __raw_writel(new_val, reg); + return new_val; +} + +static int dm644x_set_if_config(enum v4l2_mbus_pixelcode pixcode) +{ + unsigned int val = 0; + int ret = 0; + + switch (pixcode) { + case V4L2_MBUS_FMT_FIXED: + /* Analog out.do nothing */ + break; + case V4L2_MBUS_FMT_YUYV8_2X8: + /* BT656 */ + val = (1<<12); + /*set VDMD in VMOD */ + dm644x_reg_modify(venc_vmod_reg, val, (7 << 12)); + /* Set YCCTL */ + dm644x_reg_modify(venc_ycctl_reg, 1, 1); + break; + case V4L2_MBUS_FMT_YUYV10_1X20: + /* This was VPBE_DIGITAL_IF_YCC16.BT656.Replace the enum accordingly + * when the right one gets into open source */ + val = 0 << 12; + dm644x_reg_modify(venc_vmod_reg, val, (7 << 12)); + dm644x_reg_modify(venc_ycctl_reg, 1, 1); + break; + case V4L2_MBUS_FMT_SGRBG8_1X8: + /* This was VPBE_DIGITAL_IF_PRGB/SRGB.Replace the enum accordingly + * when the right one gets into open source */ + val = 2 << 12; + dm644x_reg_modify(venc_vmod_reg, val, (7 << 12)); + break; + default: + ret = -EINVAL; + break; + } + return ret; +} + +static u64 vpbe_display_dma_mask = DMA_BIT_MASK(32); + +static struct resource dm644x_v4l2_disp_resources[] = { + { + .start = IRQ_VENCINT, + .end = IRQ_VENCINT, + .flags = IORESOURCE_IRQ, + }, + { + .start = 0x01C72400, + .end = 0x01C72400 + 0x180, + .flags = IORESOURCE_MEM, + }, + +}; +static struct platform_device vpbe_v4l2_display = { + .name = "vpbe-v4l2", + .id = -1, + .num_resources = ARRAY_SIZE(dm644x_v4l2_disp_resources), + .resource = dm644x_v4l2_disp_resources, + .dev = { + .dma_mask = &vpbe_display_dma_mask, + .coherent_dma_mask = DMA_BIT_MASK(32), + }, +}; +struct venc_platform_data dm644x_venc_pdata = { + .venc_type = DM644X_VPBE, + .setup_pinmux = dm644x_vpbe_setup_pinmux, + .setup_clock = dm644x_venc_setup_clock, + .setup_if_config = dm644x_set_if_config, +}; + +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_venc_dma_mask, + .coherent_dma_mask = DMA_BIT_MASK(32), + .platform_data = (void *)&dm644x_venc_pdata, + }, +}; + +static u64 dm644x_vpbe_dma_mask = DMA_BIT_MASK(32); + +static struct platform_device dm644x_vpbe_dev = { + .name = "vpbe_controller", + .id = -1, + .dev = { + .dma_mask = &dm644x_vpbe_dma_mask, + .coherent_dma_mask = DMA_BIT_MASK(32), + }, +}; + +void dm644x_set_vpbe_display_config(struct vpbe_display_config *cfg) +{ + dm644x_vpbe_dev.dev.platform_data = cfg; +} + /*----------------------------------------------------------------------*/ static struct map_desc dm644x_io_desc[] = { @@ -767,20 +977,36 @@ void __init dm644x_init(void) davinci_common_init(&davinci_soc_info_dm644x); } +static struct platform_device *dm644x_video_devices[] __initdata = { + &dm644x_vpss_device, + &dm644x_ccdc_dev, + &vpfe_capture_dev, + &dm644x_osd_dev, + &dm644x_venc_dev, + &dm644x_vpbe_dev, + &vpbe_v4l2_display, +}; + +static int __init dm644x_init_video(void) +{ + /* 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); + vpss_clkctl_reg = ioremap_nocache(VPSS_CLKCTL, 4); + platform_add_devices(dm644x_video_devices, + ARRAY_SIZE(dm644x_video_devices)); + return 0; +} + static int __init dm644x_init_devices(void) { if (!cpu_is_davinci_dm644x()) return 0; /* 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_edma_device); platform_device_register(&dm644x_emac_device); - platform_device_register(&dm644x_vpss_device); - platform_device_register(&dm644x_ccdc_dev); - platform_device_register(&vpfe_capture_dev); - + dm644x_init_video(); return 0; } postcore_initcall(dm644x_init_devices); diff --git a/arch/arm/mach-davinci/include/mach/dm644x.h b/arch/arm/mach-davinci/include/mach/dm644x.h index 6fca568..bf7adcd 100644 --- a/arch/arm/mach-davinci/include/mach/dm644x.h +++ b/arch/arm/mach-davinci/include/mach/dm644x.h @@ -26,6 +26,9 @@ #include #include #include +#include +#include +#include #define DM644X_EMAC_BASE (0x01C80000) #define DM644X_EMAC_CNTRL_OFFSET (0x0000) @@ -43,5 +46,6 @@ void __init dm644x_init(void); void __init dm644x_init_asp(struct snd_platform_data *pdata); void dm644x_set_vpfe_config(struct vpfe_config *cfg); +void dm644x_set_vpbe_display_config(struct vpbe_display_config *cfg); #endif /* __ASM_ARCH_DM644X_H */