From nsekhar at ti.com Thu Sep 1 06:57:28 2011 From: nsekhar at ti.com (Nori, Sekhar) Date: Thu, 1 Sep 2011 17:27:28 +0530 Subject: [PATCH] arm: mach-davinci: use kzalloc() In-Reply-To: <1312629976.5589.128.camel@localhost.localdomain> References: <1312629976.5589.128.camel@localhost.localdomain> Message-ID: On Sat, Aug 06, 2011 at 16:56:13, Thomas Meyer wrote: > From: Thomas Meyer > > Use kzalloc rather than kmalloc followed by memset with 0 Queuing this for v3.2. While applying, I changed the subject to: "ARM: davinci: edma: use kzalloc()" to be more consistent with other patch headlines. Thanks, Sekhar From nsekhar at ti.com Thu Sep 1 06:59:08 2011 From: nsekhar at ti.com (Nori, Sekhar) Date: Thu, 1 Sep 2011 17:29:08 +0530 Subject: [PATCH v4] ARM: davinci: AM18x: Add wl1271/wlan support In-Reply-To: <1312444283-25581-1-git-send-email-ido@wizery.com> References: <1312444283-25581-1-git-send-email-ido@wizery.com> Message-ID: On Thu, Aug 04, 2011 at 13:21:23, Ido Yariv wrote: > The wl1271 daughter card for AM18x EVMs is a combo wireless connectivity > add-on card, based on the LS Research TiWi module with Texas > Instruments' wl1271 solution. > It is a 4-wire, 1.8V, embedded SDIO WLAN device with an external IRQ > line and is power-controlled by a GPIO-based fixed regulator. > > Add support for the WLAN capabilities of this expansion board. > > Signed-off-by: Ido Yariv Applied, thanks. Regards, Sekhar From nsekhar at ti.com Thu Sep 1 09:32:51 2011 From: nsekhar at ti.com (Nori, Sekhar) Date: Thu, 1 Sep 2011 20:02:51 +0530 Subject: [PATCH] [ARM] davinci: gpio: eliminate unused variable warnings In-Reply-To: <1313386893.25484.1.camel@phoenix> References: <1313386893.25484.1.camel@phoenix> Message-ID: Hi Axel, On Mon, Aug 15, 2011 at 11:11:33, Axel Lin wrote: > Since commit 5093aec872e5be7a55d8dd2b639e8a3818dc19db > "arm: davinci: Cleanup irq chip code", > the variable 'mask' and 'g' are not being used in gpio_irq_type. > > This patch eliminate below unused variable warnings: > > CC arch/arm/mach-davinci/gpio.o > arch/arm/mach-davinci/gpio.c: In function 'gpio_irq_type': > arch/arm/mach-davinci/gpio.c:234: warning: unused variable 'mask' > arch/arm/mach-davinci/gpio.c:233: warning: unused variable 'g' > > Signed-off-by: Axel Lin Thanks for the fix! There is a patch in linux-next committed by Russell which moves the DaVinci gpio driver to drivers/gpio/. Can you please redo this fix to apply on linux-next? Once Russell approves, it can go though his patch system so there are no conflicts. Thanks, Sekhar From robert.kariniemi at gmail.com Thu Sep 1 09:35:11 2011 From: robert.kariniemi at gmail.com (Robert Kariniemi) Date: Thu, 1 Sep 2011 09:35:11 -0500 Subject: Remove me Message-ID: -------------- next part -------------- An HTML attachment was scrubbed... URL: From axel.lin at gmail.com Thu Sep 1 09:48:08 2011 From: axel.lin at gmail.com (Axel Lin) Date: Thu, 01 Sep 2011 22:48:08 +0800 Subject: [PATCH] gpio: davinci: eliminate unused variable warnings Message-ID: <1314888488.11908.1.camel@phoenix> Since commit 5093aec872e5be7a55d8dd2b639e8a3818dc19db "arm: davinci: Cleanup irq chip code", the variable 'mask' and 'g' are not being used. This patch eliminates below unused variable warnings: CC drivers/gpio/gpio-davinci.o drivers/gpio/gpio-davinci.c: In function 'gpio_irq_type': drivers/gpio/gpio-davinci.c:234: warning: unused variable 'mask' drivers/gpio/gpio-davinci.c:233: warning: unused variable 'g' Signed-off-by: Axel Lin --- drivers/gpio/gpio-davinci.c | 3 --- 1 files changed, 0 insertions(+), 3 deletions(-) diff --git a/drivers/gpio/gpio-davinci.c b/drivers/gpio/gpio-davinci.c index a8066e8..df0d595 100644 --- a/drivers/gpio/gpio-davinci.c +++ b/drivers/gpio/gpio-davinci.c @@ -230,9 +230,6 @@ static void gpio_irq_enable(struct irq_data *d) static int gpio_irq_type(struct irq_data *d, unsigned trigger) { - struct davinci_gpio_regs __iomem *g = irq2regs(d->irq); - u32 mask = (u32) irq_data_get_irq_handler_data(d); - if (trigger & ~(IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING)) return -EINVAL; -- 1.7.4.1 From nsekhar at ti.com Thu Sep 1 11:24:41 2011 From: nsekhar at ti.com (Nori, Sekhar) Date: Thu, 1 Sep 2011 21:54:41 +0530 Subject: [PATCH] ARM: mach-davinci: Select PHYLIB for ARCH_DAVINCI_DM644x In-Reply-To: <1313903348.25059.3.camel@phoenix> References: <1313903348.25059.3.camel@phoenix> Message-ID: Hi Axel, On Sun, Aug 21, 2011 at 10:39:08, Axel Lin wrote: > We call phy_register_fixup_for_uid in davinci_evm_init, thus we need > select PHYLIB to fix below build error: (with "make davinci_all_defconfig") This shouldn't happen with davinci_all_defconfig as it selects PHYLIB (this doesn't undermine the need for a fix). > > LD .tmp_vmlinux1 > arch/arm/mach-davinci/built-in.o: In function `davinci_phy_fixup': > pm.c:(.text+0x35b8): undefined reference to `mdiobus_read' > pm.c:(.text+0x35d4): undefined reference to `mdiobus_write' > arch/arm/mach-davinci/built-in.o: In function `davinci_evm_init': > pm.c:(.init.text+0x237c): undefined reference to `phy_register_fixup_for_uid' > make: *** [.tmp_vmlinux1] Error 1 > > Signed-off-by: Axel Lin > --- > arch/arm/mach-davinci/Kconfig | 1 + > 1 files changed, 1 insertions(+), 0 deletions(-) > > diff --git a/arch/arm/mach-davinci/Kconfig b/arch/arm/mach-davinci/Kconfig > index c0deaca..029ec46b 100644 > --- a/arch/arm/mach-davinci/Kconfig > +++ b/arch/arm/mach-davinci/Kconfig > @@ -18,6 +18,7 @@ config ARCH_DAVINCI_DM644x > bool "DaVinci 644x based system" > select AINTC > select ARCH_DAVINCI_DMx > + select PHYLIB Selecting PHYLIB for the SoC isn't right because only the EVM is affected by this issue. Also, instead of selecting PHYLIB, a better fix would be to define the fixup function within #ifdef PHYLIB and have an empty fixup registration function in case PHYLIB is not defined (which should happen only when EMAC driver is not configured in which case a fixup is not required anyway). Thanks, Sekhar From m-karicheri2 at ti.com Thu Sep 1 12:48:35 2011 From: m-karicheri2 at ti.com (Murali Karicheri) Date: Thu, 1 Sep 2011 13:48:35 -0400 Subject: [PATCH v2 1/2] ARM: davinci - fix incorrect offsets and mask usage in psc code Message-ID: <1314899316-2708-1-git-send-email-m-karicheri2@ti.com> There are 5 LSB bits defined in PDSTAT and the code currently uses a mask of 1 bit to check the status. Also there is PDSTAT and PDCTL registers defined for ARM domain and DSP domain where as the code always read the ARM PDSTAT register and DSP PDCTL register. This patch fixes these issues. Reviewed-by: Sergei Shtylyov Signed-off-by: Murali Karicheri --- comments against previous version of the patch addressed:- - Moved the bug fix to a separate patch arch/arm/mach-davinci/include/mach/psc.h | 2 +- arch/arm/mach-davinci/psc.c | 19 ++++++++++--------- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/arch/arm/mach-davinci/include/mach/psc.h b/arch/arm/mach-davinci/include/mach/psc.h index 47fd0bc..63c4366 100644 --- a/arch/arm/mach-davinci/include/mach/psc.h +++ b/arch/arm/mach-davinci/include/mach/psc.h @@ -233,7 +233,7 @@ #define PTCMD 0x120 #define PTSTAT 0x128 #define PDSTAT 0x200 -#define PDCTL1 0x304 +#define PDCTL 0x300 #define MDSTAT 0x800 #define MDCTL 0xA00 diff --git a/arch/arm/mach-davinci/psc.c b/arch/arm/mach-davinci/psc.c index 1fb6bdf..f157d9c 100644 --- a/arch/arm/mach-davinci/psc.c +++ b/arch/arm/mach-davinci/psc.c @@ -52,7 +52,7 @@ int __init davinci_psc_is_clk_active(unsigned int ctlr, unsigned int id) void davinci_psc_config(unsigned int domain, unsigned int ctlr, unsigned int id, bool enable, u32 flags) { - u32 epcpr, ptcmd, ptstat, pdstat, pdctl1, mdstat, mdctl; + u32 epcpr, ptcmd, ptstat, pdstat, pdctl, mdstat, mdctl; void __iomem *psc_base; struct davinci_soc_info *soc_info = &davinci_soc_info; u32 next_state = PSC_STATE_ENABLE; @@ -79,11 +79,11 @@ void davinci_psc_config(unsigned int domain, unsigned int ctlr, mdctl |= MDCTL_FORCE; __raw_writel(mdctl, psc_base + MDCTL + 4 * id); - pdstat = __raw_readl(psc_base + PDSTAT); - if ((pdstat & 0x00000001) == 0) { - pdctl1 = __raw_readl(psc_base + PDCTL1); - pdctl1 |= 0x1; - __raw_writel(pdctl1, psc_base + PDCTL1); + pdstat = __raw_readl(psc_base + PDSTAT + 4 * domain); + if ((pdstat & 0x1F) == 0) { + pdctl = __raw_readl(psc_base + PDCTL + 4 * domain); + pdctl |= 0x1; + __raw_writel(pdctl, psc_base + PDCTL + 4 * domain); ptcmd = 1 << domain; __raw_writel(ptcmd, psc_base + PTCMD); @@ -92,9 +92,10 @@ void davinci_psc_config(unsigned int domain, unsigned int ctlr, epcpr = __raw_readl(psc_base + EPCPR); } while ((((epcpr >> domain) & 1) == 0)); - pdctl1 = __raw_readl(psc_base + PDCTL1); - pdctl1 |= 0x100; - __raw_writel(pdctl1, psc_base + PDCTL1); + pdctl = __raw_readl(psc_base + PDCTL + 4 * domain); + pdctl |= 0x100; + __raw_writel(pdctl, psc_base + PDCTL + 4 * domain); + } else { ptcmd = 1 << domain; __raw_writel(ptcmd, psc_base + PTCMD); -- 1.7.0.4 From m-karicheri2 at ti.com Thu Sep 1 12:48:36 2011 From: m-karicheri2 at ti.com (Murali Karicheri) Date: Thu, 1 Sep 2011 13:48:36 -0400 Subject: [PATCH v2 2/2] ARM: davinci: enhancement to support multiple power domains In-Reply-To: <1314899316-2708-1-git-send-email-m-karicheri2@ti.com> References: <1314899316-2708-1-git-send-email-m-karicheri2@ti.com> Message-ID: <1314899316-2708-2-git-send-email-m-karicheri2@ti.com> In one of the new SoC that we are working on, there are multiple power domains similar to that in C6670. Currently clock module assumes that there are only two power domains (ARM and DSP). This patch enhances the code to support more than two power domains and will allow porting of Linux on to the above SoC. Reviewed-by :Sergei Shtylyov Signed-off-by: Murali Karicheri --- comments against previous version addressed:- - Moved the bug fix in the psc code to a separate patch arch/arm/mach-davinci/clock.c | 13 +++---------- arch/arm/mach-davinci/clock.h | 10 +++++----- arch/arm/mach-davinci/dm644x.c | 4 ++-- arch/arm/mach-davinci/dm646x.c | 2 +- 4 files changed, 11 insertions(+), 18 deletions(-) diff --git a/arch/arm/mach-davinci/clock.c b/arch/arm/mach-davinci/clock.c index 0086113..008772e 100644 --- a/arch/arm/mach-davinci/clock.c +++ b/arch/arm/mach-davinci/clock.c @@ -31,19 +31,12 @@ static LIST_HEAD(clocks); static DEFINE_MUTEX(clocks_mutex); static DEFINE_SPINLOCK(clockfw_lock); -static unsigned psc_domain(struct clk *clk) -{ - return (clk->flags & PSC_DSP) - ? DAVINCI_GPSC_DSPDOMAIN - : DAVINCI_GPSC_ARMDOMAIN; -} - static void __clk_enable(struct clk *clk) { if (clk->parent) __clk_enable(clk->parent); if (clk->usecount++ == 0 && (clk->flags & CLK_PSC)) - davinci_psc_config(psc_domain(clk), clk->gpsc, clk->lpsc, + davinci_psc_config(clk->domain, clk->gpsc, clk->lpsc, true, clk->flags); } @@ -53,7 +46,7 @@ static void __clk_disable(struct clk *clk) return; if (--clk->usecount == 0 && !(clk->flags & CLK_PLL) && (clk->flags & CLK_PSC)) - davinci_psc_config(psc_domain(clk), clk->gpsc, clk->lpsc, + davinci_psc_config(clk->domain, clk->gpsc, clk->lpsc, false, clk->flags); if (clk->parent) __clk_disable(clk->parent); @@ -237,7 +230,7 @@ static int __init clk_disable_unused(void) pr_debug("Clocks: disable unused %s\n", ck->name); - davinci_psc_config(psc_domain(ck), ck->gpsc, ck->lpsc, + davinci_psc_config(ck->domain, ck->gpsc, ck->lpsc, false, ck->flags); } spin_unlock_irq(&clockfw_lock); diff --git a/arch/arm/mach-davinci/clock.h b/arch/arm/mach-davinci/clock.h index a705f36..46f0f1b 100644 --- a/arch/arm/mach-davinci/clock.h +++ b/arch/arm/mach-davinci/clock.h @@ -93,6 +93,7 @@ struct clk { u8 usecount; u8 lpsc; u8 gpsc; + u8 domain; u32 flags; struct clk *parent; struct list_head children; /* list of children */ @@ -107,11 +108,10 @@ struct clk { /* Clock flags: SoC-specific flags start at BIT(16) */ #define ALWAYS_ENABLED BIT(1) #define CLK_PSC BIT(2) -#define PSC_DSP BIT(3) /* PSC uses DSP domain, not ARM */ -#define CLK_PLL BIT(4) /* PLL-derived clock */ -#define PRE_PLL BIT(5) /* source is before PLL mult/div */ -#define PSC_SWRSTDISABLE BIT(6) /* Disable state is SwRstDisable */ -#define PSC_FORCE BIT(7) /* Force module state transtition */ +#define CLK_PLL BIT(3) /* PLL-derived clock */ +#define PRE_PLL BIT(4) /* source is before PLL mult/div */ +#define PSC_SWRSTDISABLE BIT(5) /* Disable state is SwRstDisable */ +#define PSC_FORCE BIT(6) /* Force module state transtition */ #define CLK(dev, con, ck) \ { \ diff --git a/arch/arm/mach-davinci/dm644x.c b/arch/arm/mach-davinci/dm644x.c index 555ff5b..f38c4bb 100644 --- a/arch/arm/mach-davinci/dm644x.c +++ b/arch/arm/mach-davinci/dm644x.c @@ -130,7 +130,7 @@ static struct clk dsp_clk = { .name = "dsp", .parent = &pll1_sysclk1, .lpsc = DAVINCI_LPSC_GEM, - .flags = PSC_DSP, + .domain = DAVINCI_GPSC_DSPDOMAIN, .usecount = 1, /* REVISIT how to disable? */ }; @@ -145,7 +145,7 @@ static struct clk vicp_clk = { .name = "vicp", .parent = &pll1_sysclk2, .lpsc = DAVINCI_LPSC_IMCOP, - .flags = PSC_DSP, + .domain = DAVINCI_GPSC_DSPDOMAIN, .usecount = 1, /* REVISIT how to disable? */ }; diff --git a/arch/arm/mach-davinci/dm646x.c b/arch/arm/mach-davinci/dm646x.c index 552031e..5bec8b6 100644 --- a/arch/arm/mach-davinci/dm646x.c +++ b/arch/arm/mach-davinci/dm646x.c @@ -160,7 +160,7 @@ static struct clk dsp_clk = { .name = "dsp", .parent = &pll1_sysclk1, .lpsc = DM646X_LPSC_C64X_CPU, - .flags = PSC_DSP, + .domain = DAVINCI_GPSC_DSPDOMAIN, .usecount = 1, /* REVISIT how to disable? */ }; -- 1.7.0.4 From sshtylyov at mvista.com Thu Sep 1 13:48:17 2011 From: sshtylyov at mvista.com (Sergei Shtylyov) Date: Thu, 01 Sep 2011 22:48:17 +0400 Subject: [PATCH v2 1/2] ARM: davinci - fix incorrect offsets and mask usage in psc code In-Reply-To: <1314899316-2708-1-git-send-email-m-karicheri2@ti.com> References: <1314899316-2708-1-git-send-email-m-karicheri2@ti.com> Message-ID: <4E5FD371.1020200@mvista.com> Hello. On 09/01/2011 09:48 PM, Murali Karicheri wrote: > There are 5 LSB bits defined in PDSTAT and the code currently uses > a mask of 1 bit to check the status. Also there is PDSTAT and PDCTL > registers defined for ARM domain and DSP domain where as the code > always read the ARM PDSTAT register and DSP PDCTL register. This patch > fixes these issues. > Reviewed-by: Sergei Shtylyov I haven't reviewed this patch yet. Maybe you mean "Suggested-by:"? > Signed-off-by: Murali Karicheri > --- > comments against previous version of the patch addressed:- Hm, I seem to have missed the previous version then... > - Moved the bug fix to a separate patch > arch/arm/mach-davinci/include/mach/psc.h | 2 +- > arch/arm/mach-davinci/psc.c | 19 ++++++++++--------- > 2 files changed, 11 insertions(+), 10 deletions(-) > > diff --git a/arch/arm/mach-davinci/include/mach/psc.h b/arch/arm/mach-davinci/include/mach/psc.h > index 47fd0bc..63c4366 100644 > --- a/arch/arm/mach-davinci/include/mach/psc.h > +++ b/arch/arm/mach-davinci/include/mach/psc.h > @@ -233,7 +233,7 @@ > #define PTCMD 0x120 > #define PTSTAT 0x128 > #define PDSTAT 0x200 > -#define PDCTL1 0x304 > +#define PDCTL 0x300 > #define MDSTAT 0x800 > #define MDCTL 0xA00 > > diff --git a/arch/arm/mach-davinci/psc.c b/arch/arm/mach-davinci/psc.c > index 1fb6bdf..f157d9c 100644 > --- a/arch/arm/mach-davinci/psc.c > +++ b/arch/arm/mach-davinci/psc.c > @@ -52,7 +52,7 @@ int __init davinci_psc_is_clk_active(unsigned int ctlr, unsigned int id) > void davinci_psc_config(unsigned int domain, unsigned int ctlr, > unsigned int id, bool enable, u32 flags) > { > - u32 epcpr, ptcmd, ptstat, pdstat, pdctl1, mdstat, mdctl; > + u32 epcpr, ptcmd, ptstat, pdstat, pdctl, mdstat, mdctl; > void __iomem *psc_base; > struct davinci_soc_info *soc_info =&davinci_soc_info; > u32 next_state = PSC_STATE_ENABLE; > @@ -79,11 +79,11 @@ void davinci_psc_config(unsigned int domain, unsigned int ctlr, > mdctl |= MDCTL_FORCE; > __raw_writel(mdctl, psc_base + MDCTL + 4 * id); > > - pdstat = __raw_readl(psc_base + PDSTAT); > - if ((pdstat& 0x00000001) == 0) { > - pdctl1 = __raw_readl(psc_base + PDCTL1); > - pdctl1 |= 0x1; > - __raw_writel(pdctl1, psc_base + PDCTL1); > + pdstat = __raw_readl(psc_base + PDSTAT + 4 * domain); > + if ((pdstat& 0x1F) == 0) { I suggest to make this mask a #define in , like we have MDSTAT_STATE_MASK there. > + pdctl = __raw_readl(psc_base + PDCTL + 4 * domain); > + pdctl |= 0x1; > + __raw_writel(pdctl, psc_base + PDCTL + 4 * domain); > > ptcmd = 1<< domain; > __raw_writel(ptcmd, psc_base + PTCMD); > @@ -92,9 +92,10 @@ void davinci_psc_config(unsigned int domain, unsigned int ctlr, > epcpr = __raw_readl(psc_base + EPCPR); > } while ((((epcpr>> domain)& 1) == 0)); Does this work for ARM domain, i.e. does it require an external power supply too? > - pdctl1 = __raw_readl(psc_base + PDCTL1); > - pdctl1 |= 0x100; > - __raw_writel(pdctl1, psc_base + PDCTL1); > + pdctl = __raw_readl(psc_base + PDCTL + 4 * domain); > + pdctl |= 0x100; > + __raw_writel(pdctl, psc_base + PDCTL + 4 * domain); > + > } else { > ptcmd = 1<< domain; > __raw_writel(ptcmd, psc_base + PTCMD); WBR, Sergei From axel.lin at gmail.com Thu Sep 1 18:40:12 2011 From: axel.lin at gmail.com (Axel Lin) Date: Fri, 2 Sep 2011 07:40:12 +0800 Subject: [PATCH] ARM: mach-davinci: Select PHYLIB for ARCH_DAVINCI_DM644x In-Reply-To: References: <1313903348.25059.3.camel@phoenix> Message-ID: 2011/9/2 Nori, Sekhar : > Hi Axel, > > On Sun, Aug 21, 2011 at 10:39:08, Axel Lin wrote: >> We call phy_register_fixup_for_uid in davinci_evm_init, thus we need >> select PHYLIB to fix below build error: (with "make davinci_all_defconfig") > > This shouldn't happen with davinci_all_defconfig as it > selects PHYLIB (this doesn't undermine the need for a fix). I remember that I got the build error with davinci_all_defconfig, but the build seems ok now with linux-next ( next-20110831 ). Regards, Axel From zanget at 163.com Thu Sep 1 20:46:55 2011 From: zanget at 163.com (zanget) Date: Thu, 1 Sep 2011 18:46:55 -0700 (PDT) Subject: DM365 uvc gadget In-Reply-To: References: Message-ID: <1314928015915-6752421.post@n2.nabble.com> the problem comes form the High-bandwidth ISO mode webcam with DM365. check it out: section 4.72 about USB. the source code about this part is now: musb_core.c?musb_core_init? if (reg & MUSB_CONFIGDATA_HBRXE) { strcat(aInfo, ", HB-ISO Rx"); musb->hb_iso_rx = true; } if (reg & MUSB_CONFIGDATA_HBTXE) { strcat(aInfo, ", HB-ISO Tx"); musb->hb_iso_tx = true; } musb_host.c, musb_urb_enqueue /* Bits 11 & 12 of wMaxPacketSize encode high bandwidth multiplier. * Some musb cores don't support high bandwidth ISO transfers; and * we don't (yet!) support high bandwidth interrupt transfers. */ qh->hb_mult = 1 + ((qh->maxpacket >> 11) & 0x03); if (qh->hb_mult > 1) { int ok = (qh->type == USB_ENDPOINT_XFER_ISOC); if (ok) ok = (usb_pipein(urb->pipe) && musb->hb_iso_rx) || (usb_pipeout(urb->pipe) && musb->hb_iso_tx); if (!ok) { ret = -EMSGSIZE; goto done; } qh->maxpacket &= 0x7ff; } -- View this message in context: http://davinci-linux-open-source.1494791.n2.nabble.com/DM365-uvc-gadget-tp5992168p6752421.html Sent from the davinci-linux-open-source mailing list archive at Nabble.com. From swamin at amazon.com Thu Sep 1 22:58:11 2011 From: swamin at amazon.com (Subbarathnam, Swaminathan) Date: Fri, 2 Sep 2011 09:28:11 +0530 Subject: DM365 uvc gadget In-Reply-To: <1314928015915-6752421.post@n2.nabble.com> References: <1314928015915-6752421.post@n2.nabble.com> Message-ID: <74DFAE2329015E4288E958E7E3D155378B758FA092@EX-MAIL-HYD1-1.ant.amazon.com> Zanget, DM365 usb controller does not support High Bandwidth ISO. Regards swami -----Original Message----- From: davinci-linux-open-source-bounces at linux.davincidsp.com [mailto:davinci-linux-open-source-bounces at linux.davincidsp.com] On Behalf Of zanget Sent: Friday, September 02, 2011 7:17 AM To: davinci-linux-open-source at linux.davincidsp.com Subject: Re: DM365 uvc gadget the problem comes form the High-bandwidth ISO mode webcam with DM365. check it out: section 4.72 about USB. the source code about this part is now: musb_core.c?musb_core_init? if (reg & MUSB_CONFIGDATA_HBRXE) { strcat(aInfo, ", HB-ISO Rx"); musb->hb_iso_rx = true; } if (reg & MUSB_CONFIGDATA_HBTXE) { strcat(aInfo, ", HB-ISO Tx"); musb->hb_iso_tx = true; } musb_host.c, musb_urb_enqueue /* Bits 11 & 12 of wMaxPacketSize encode high bandwidth multiplier. * Some musb cores don't support high bandwidth ISO transfers; and * we don't (yet!) support high bandwidth interrupt transfers. */ qh->hb_mult = 1 + ((qh->maxpacket >> 11) & 0x03); if (qh->hb_mult > 1) { int ok = (qh->type == USB_ENDPOINT_XFER_ISOC); if (ok) ok = (usb_pipein(urb->pipe) && musb->hb_iso_rx) || (usb_pipeout(urb->pipe) && musb->hb_iso_tx); if (!ok) { ret = -EMSGSIZE; goto done; } qh->maxpacket &= 0x7ff; } -- View this message in context: http://davinci-linux-open-source.1494791.n2.nabble.com/DM365-uvc-gadget-tp5992168p6752421.html Sent from the davinci-linux-open-source mailing list archive at Nabble.com. _______________________________________________ Davinci-linux-open-source mailing list Davinci-linux-open-source at linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source From snjw23 at gmail.com Thu Sep 1 15:47:49 2011 From: snjw23 at gmail.com (Sylwester Nawrocki) Date: Thu, 01 Sep 2011 22:47:49 +0200 Subject: [PATCH v2 1/8] davinci: vpfe: add dm3xx IPIPEIF hardware support module In-Reply-To: <1314630439-1122-2-git-send-email-manjunath.hadli@ti.com> References: <1314630439-1122-1-git-send-email-manjunath.hadli@ti.com> <1314630439-1122-2-git-send-email-manjunath.hadli@ti.com> Message-ID: <4E5FEF75.8060704@gmail.com> Hi Manjunath, A few comments below... On 08/29/2011 05:07 PM, Manjunath Hadli wrote: > add support for dm3xx IPIPEIF hardware setup. This is the > lowest software layer for the dm3x vpfe driver which directly > accesses hardware. Add support for features like default > pixel correction, dark frame substraction and hardware setup. > > Signed-off-by: Manjunath Hadli > Signed-off-by: Nagabhushana Netagunte > --- > drivers/media/video/davinci/dm3xx_ipipeif.c | 317 +++++++++++++++++++++++++++ > drivers/media/video/davinci/dm3xx_ipipeif.h | 258 ++++++++++++++++++++++ > include/linux/dm3xx_ipipeif.h | 64 ++++++ > 3 files changed, 639 insertions(+), 0 deletions(-) > create mode 100644 drivers/media/video/davinci/dm3xx_ipipeif.c > create mode 100644 drivers/media/video/davinci/dm3xx_ipipeif.h > create mode 100644 include/linux/dm3xx_ipipeif.h > > diff --git a/drivers/media/video/davinci/dm3xx_ipipeif.c b/drivers/media/video/davinci/dm3xx_ipipeif.c > new file mode 100644 > index 0000000..ebc8895 > --- /dev/null > +++ b/drivers/media/video/davinci/dm3xx_ipipeif.c > @@ -0,0 +1,317 @@ ... > + > +static void ipipeif_config_dpc(struct ipipeif_dpc *dpc) > +{ > + u32 val; > + > + /* Intialize val*/ > + val = 0; s/Intialize/Initialize ? But this comment doesn't seem much helpful and could probably be removed. Also it might be better to just do: u32 val = 0; > + > + if (dpc->en) { > + val = (dpc->en& 1)<< IPIPEIF_DPC2_EN_SHIFT; > + val |= dpc->thr& IPIPEIF_DPC2_THR_MASK; > + } > + > + regw_if(val, IPIPEIF_DPC2); > +} > + ... > + > +static int __devinit dm3xx_ipipeif_probe(struct platform_device *pdev) > +{ > + static resource_size_t res_len; > + struct resource *res; > + int status; > + > + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); > + if (!res) > + return -ENOENT; > + > + res_len = res->end - res->start + 1; resource_size(res) macro could be used here > + > + res = request_mem_region(res->start, res_len, res->name); > + if (!res) > + return -EBUSY; > + > + ipipeif_base_addr = ioremap_nocache(res->start, res_len); > + if (!ipipeif_base_addr) { > + status = -EBUSY; > + goto fail; > + } > + return 0; > + > +fail: > + release_mem_region(res->start, res_len); > + > + return status; > +} > + > +static int dm3xx_ipipeif_remove(struct platform_device *pdev) > +{ > + struct resource *res; > + > + iounmap(ipipeif_base_addr); > + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); > + if (res) > + release_mem_region(res->start, res->end - res->start + 1); release_mem_region(res->start, resource_size(res)); > + return 0; > +} > + > +static struct platform_driver dm3xx_ipipeif_driver = { > + .driver = { > + .name = "dm3xx_ipipeif", > + .owner = THIS_MODULE, > + }, > + .remove = __devexit_p(dm3xx_ipipeif_remove), > + .probe = dm3xx_ipipeif_probe, > +}; > + > +static int dm3xx_ipipeif_init(void) > +{ > + return platform_driver_register(&dm3xx_ipipeif_driver); > +} > + > +static void dm3xx_ipipeif_exit(void) > +{ > + platform_driver_unregister(&dm3xx_ipipeif_driver); > +} > + > +module_init(dm3xx_ipipeif_init); > +module_exit(dm3xx_ipipeif_exit); > + > +MODULE_LICENSE("GPL2"); > diff --git a/drivers/media/video/davinci/dm3xx_ipipeif.h b/drivers/media/video/davinci/dm3xx_ipipeif.h > new file mode 100644 > index 0000000..f3289f0 > --- /dev/null > +++ b/drivers/media/video/davinci/dm3xx_ipipeif.h > @@ -0,0 +1,258 @@ > +/* ... > + > +/* IPIPEIF Register Offsets from the base address */ > +#define IPIPEIF_ENABLE (0x00) > +#define IPIPEIF_CFG1 (0x04) > +#define IPIPEIF_PPLN (0x08) > +#define IPIPEIF_LPFR (0x0c) > +#define IPIPEIF_HNUM (0x10) > +#define IPIPEIF_VNUM (0x14) > +#define IPIPEIF_ADDRU (0x18) > +#define IPIPEIF_ADDRL (0x1c) > +#define IPIPEIF_ADOFS (0x20) > +#define IPIPEIF_RSZ (0x24) > +#define IPIPEIF_GAIN (0x28) > + > +/* Below registers are available only on IPIPE 5.1 */ > +#define IPIPEIF_DPCM (0x2c) > +#define IPIPEIF_CFG2 (0x30) > +#define IPIPEIF_INIRSZ (0x34) > +#define IPIPEIF_OCLIP (0x38) > +#define IPIPEIF_DTUDF (0x3c) > +#define IPIPEIF_CLKDIV (0x40) > +#define IPIPEIF_DPC1 (0x44) > +#define IPIPEIF_DPC2 (0x48) > +#define IPIPEIF_DFSGVL (0x4c) > +#define IPIPEIF_DFSGTH (0x50) > +#define IPIPEIF_RSZ3A (0x54) > +#define IPIPEIF_INIRSZ3A (0x58) > +#define IPIPEIF_RSZ_MIN (16) > +#define IPIPEIF_RSZ_MAX (112) > +#define IPIPEIF_RSZ_CONST (16) > +#define SETBIT(reg, bit) (reg = ((reg) | ((0x00000001)<<(bit)))) > +#define RESETBIT(reg, bit) (reg = ((reg)& (~(0x00000001<<(bit))))) > + > +#define IPIPEIF_ADOFS_LSB_MASK (0x1ff) > +#define IPIPEIF_ADOFS_LSB_SHIFT (5) > +#define IPIPEIF_ADOFS_MSB_MASK (0x200) > +#define IPIPEIF_ADDRU_MASK (0x7ff) > +#define IPIPEIF_ADDRL_SHIFT (5) > +#define IPIPEIF_ADDRL_MASK (0xffff) > +#define IPIPEIF_ADDRU_SHIFT (21) > +#define IPIPEIF_ADDRMSB_SHIFT (31) > +#define IPIPEIF_ADDRMSB_LEFT_SHIFT (10) > + > +/* CFG1 Masks and shifts */ > +#define ONESHOT_SHIFT (0) > +#define DECIM_SHIFT (1) > +#define INPSRC_SHIFT (2) > +#define CLKDIV_SHIFT (4) > +#define AVGFILT_SHIFT (7) > +#define PACK8IN_SHIFT (8) > +#define IALAW_SHIFT (9) > +#define CLKSEL_SHIFT (10) > +#define DATASFT_SHIFT (11) > +#define INPSRC1_SHIFT (14) > + > +/* DPC2 */ > +#define IPIPEIF_DPC2_EN_SHIFT (12) > +#define IPIPEIF_DPC2_THR_MASK (0xfff) > +/* Applicable for IPIPE 5.1 */ > +#define IPIPEIF_DF_GAIN_EN_SHIFT (10) > +#define IPIPEIF_DF_GAIN_MASK (0x3ff) > +#define IPIPEIF_DF_GAIN_THR_MASK (0xfff) > +/* DPCM */ > +#define IPIPEIF_DPCM_BITS_SHIFT (2) > +#define IPIPEIF_DPCM_PRED_SHIFT (1) > +/* CFG2 */ > +#define IPIPEIF_CFG2_HDPOL_SHIFT (1) > +#define IPIPEIF_CFG2_VDPOL_SHIFT (2) > +#define IPIPEIF_CFG2_YUV8_SHIFT (6) > +#define IPIPEIF_CFG2_YUV16_SHIFT (3) > +#define IPIPEIF_CFG2_YUV8P_SHIFT (7) > + > +/* INIRSZ */ > +#define IPIPEIF_INIRSZ_ALNSYNC_SHIFT (13) > +#define IPIPEIF_INIRSZ_MASK (0x1fff) Is there any good reason to use parentheses around the numbers ? -- Regards, Sylwester From snjw23 at gmail.com Thu Sep 1 16:23:08 2011 From: snjw23 at gmail.com (Sylwester Nawrocki) Date: Thu, 01 Sep 2011 23:23:08 +0200 Subject: [PATCH v2 4/8] davinci: vpfe: add support for CCDC hardware for dm365 In-Reply-To: <1314630439-1122-5-git-send-email-manjunath.hadli@ti.com> References: <1314630439-1122-1-git-send-email-manjunath.hadli@ti.com> <1314630439-1122-5-git-send-email-manjunath.hadli@ti.com> Message-ID: <4E5FF7BC.3040108@gmail.com> Hi Manjunath, few more comments below.. On 08/29/2011 05:07 PM, Manjunath Hadli wrote: > add support for ccdc on dm365 SoC. ccdc is responsible for > capturing video data- both raw bayer through sync seperate > signals and through BT656/1120 interfaces. This driver implements > the hardware functionality. Mainly- setting of hardware, validation > of parameters, and isr configuration. > > Signed-off-by: Manjunath Hadli > Signed-off-by: Nagabhushana Netagunte > --- > drivers/media/video/davinci/ccdc_types.h | 43 + > drivers/media/video/davinci/dm365_ccdc.c | 1519 +++++++++++++++++++++++++ > drivers/media/video/davinci/dm365_ccdc.h | 88 ++ > drivers/media/video/davinci/dm365_ccdc_regs.h | 309 +++++ > include/linux/dm365_ccdc.h | 664 +++++++++++ > 5 files changed, 2623 insertions(+), 0 deletions(-) > create mode 100644 drivers/media/video/davinci/ccdc_types.h > create mode 100644 drivers/media/video/davinci/dm365_ccdc.c > create mode 100644 drivers/media/video/davinci/dm365_ccdc.h > create mode 100644 drivers/media/video/davinci/dm365_ccdc_regs.h > create mode 100644 include/linux/dm365_ccdc.h ... > +#define CCDC_LINEAR_LUT0_ADDR 0x1c7c000 > +#define CCDC_LINEAR_LUT1_ADDR 0x1c7c400 > + > +/* Masks& Shifts below */ > +#define START_PX_HOR_MASK (0x7fff) > +#define NUM_PX_HOR_MASK (0x7fff) > +#define START_VER_ONE_MASK (0x7fff) > +#define START_VER_TWO_MASK (0x7fff) > +#define NUM_LINES_VER (0x7fff) > + > +/* gain - offset masks */ > +#define GAIN_INTEGER_MASK (0x7) > +#define GAIN_INTEGER_SHIFT (0x9) > +#define GAIN_DECIMAL_MASK (0x1ff) > +#define OFFSET_MASK (0xfff) > +#define GAIN_SDRAM_EN_SHIFT (12) > +#define GAIN_IPIPE_EN_SHIFT (13) > +#define GAIN_H3A_EN_SHIFT (14) > +#define OFST_SDRAM_EN_SHIFT (8) > +#define OFST_IPIPE_EN_SHIFT (9) > +#define OFST_H3A_EN_SHIFT (10) > +#define GAIN_OFFSET_EN_MASK (0x7700) > + > +/* Culling */ > +#define CULL_PAT_EVEN_LINE_SHIFT (8) > + > +/* CCDCFG register */ > +#define CCDC_YCINSWP_RAW (0x00<< 4) > +#define CCDC_YCINSWP_YCBCR (0x01<< 4) > +#define CCDC_CCDCFG_FIDMD_LATCH_VSYNC (0x00<< 6) > +#define CCDC_CCDCFG_WENLOG_AND (0x00<< 8) > +#define CCDC_CCDCFG_TRGSEL_WEN (0x00<< 9) > +#define CCDC_CCDCFG_EXTRG_DISABLE (0x00<< 10) > +#define CCDC_LATCH_ON_VSYNC_DISABLE (0x01<< 15) > +#define CCDC_LATCH_ON_VSYNC_ENABLE (0x00<< 15) > +#define CCDC_DATA_PACK_MASK (0x03) > +#define CCDC_DATA_PACK16 (0x0) > +#define CCDC_DATA_PACK12 (0x1) > +#define CCDC_DATA_PACK8 (0x2) > +#define CCDC_PIX_ORDER_SHIFT (11) > +#define CCDC_PIX_ORDER_MASK (0x01) > +#define CCDC_BW656_ENABLE (0x01<< 5) > + > +/* MODESET registers */ > +#define CCDC_VDHDOUT_INPUT (0x00<< 0) > +#define CCDC_INPUT_MASK (0x03) > +#define CCDC_INPUT_SHIFT (12) > +#define CCDC_RAW_INPUT_MODE (0x00) > +#define CCDC_FID_POL_MASK (0x01) > +#define CCDC_FID_POL_SHIFT (4) > +#define CCDC_HD_POL_MASK (0x01) > +#define CCDC_HD_POL_SHIFT (3) > +#define CCDC_VD_POL_MASK (0x01) > +#define CCDC_VD_POL_SHIFT (2) > +#define CCDC_DATAPOL_NORMAL (0x00) > +#define CCDC_DATAPOL_MASK (0x01) > +#define CCDC_DATAPOL_SHIFT (6) > +#define CCDC_EXWEN_DISABLE (0x00) > +#define CCDC_EXWEN_MASK (0x01) > +#define CCDC_EXWEN_SHIFT (5) > +#define CCDC_FRM_FMT_MASK (0x01) > +#define CCDC_FRM_FMT_SHIFT (7) > +#define CCDC_DATASFT_MASK (0x07) > +#define CCDC_DATASFT_SHIFT (8) > +#define CCDC_LPF_SHIFT (14) > +#define CCDC_LPF_MASK (0x1) > + > +/* GAMMAWD registers */ > +#define CCDC_ALAW_GAMA_WD_MASK (0xf) > +#define CCDC_ALAW_GAMA_WD_SHIFT (1) > +#define CCDC_ALAW_ENABLE (0x01) > +#define CCDC_GAMMAWD_CFA_MASK (0x01) > +#define CCDC_GAMMAWD_CFA_SHIFT (5) > + > +/* HSIZE registers */ > +#define CCDC_HSIZE_FLIP_MASK (0x01) > +#define CCDC_HSIZE_FLIP_SHIFT (12) > +#define CCDC_LINEOFST_MASK (0xfff) > + > +/* MISC registers */ > +#define CCDC_DPCM_EN_SHIFT (12) > +#define CCDC_DPCM_EN_MASK (1) > +#define CCDC_DPCM_PREDICTOR_SHIFT (13) > +#define CCDC_DPCM_PREDICTOR_MASK (1) > + > +/* Black clamp related */ > +#define CCDC_BC_DCOFFSET_MASK (0x1fff) > +#define CCDC_BC_MODE_COLOR_MASK (1) > +#define CCDC_BC_MODE_COLOR_SHIFT (4) > +#define CCDC_HORZ_BC_MODE_MASK (3) > +#define CCDC_HORZ_BC_MODE_SHIFT (1) > +#define CCDC_HORZ_BC_WIN_COUNT_MASK (0x1f) > +#define CCDC_HORZ_BC_WIN_SEL_SHIFT (5) > +#define CCDC_HORZ_BC_PIX_LIMIT_SHIFT (6) > +#define CCDC_HORZ_BC_WIN_H_SIZE_MASK (3) > +#define CCDC_HORZ_BC_WIN_H_SIZE_SHIFT (8) > +#define CCDC_HORZ_BC_WIN_V_SIZE_MASK (3) > +#define CCDC_HORZ_BC_WIN_V_SIZE_SHIFT (12) > +#define CCDC_HORZ_BC_WIN_START_H_MASK (0x1fff) > +#define CCDC_HORZ_BC_WIN_START_V_MASK (0x1fff) > +#define CCDC_VERT_BC_OB_H_SZ_MASK (7) > +#define CCDC_VERT_BC_RST_VAL_SEL_MASK (3) > +#define CCDC_VERT_BC_RST_VAL_SEL_SHIFT (4) > +#define CCDC_VERT_BC_LINE_AVE_COEF_SHIFT (8) > +#define CCDC_VERT_BC_OB_START_HORZ_MASK (0x1fff) > +#define CCDC_VERT_BC_OB_START_VERT_MASK (0x1fff) > +#define CCDC_VERT_BC_OB_VERT_SZ_MASK (0x1fff) > +#define CCDC_VERT_BC_RST_VAL_MASK (0xfff) > +#define CCDC_BC_VERT_START_SUB_V_MASK (0x1fff) > + > +/* VDFC registers */ > +#define CCDC_VDFC_EN_SHIFT (4) > +#define CCDC_VDFC_CORR_MOD_MASK (3) > +#define CCDC_VDFC_CORR_MOD_SHIFT (5) > +#define CCDC_VDFC_CORR_WHOLE_LN_SHIFT (7) > +#define CCDC_VDFC_LEVEL_SHFT_MASK (7) > +#define CCDC_VDFC_LEVEL_SHFT_SHIFT (8) > +#define CCDC_VDFC_SAT_LEVEL_MASK (0xfff) > +#define CCDC_VDFC_POS_MASK (0x1fff) > +#define CCDC_DFCMEMCTL_DFCMARST_SHIFT (2) > + > +/* CSC registers */ > +#define CCDC_CSC_COEF_INTEG_MASK (7) > +#define CCDC_CSC_COEF_DECIMAL_MASK (0x1f) > +#define CCDC_CSC_COEF_INTEG_SHIFT (5) > +#define CCDC_CSCM_MSB_SHIFT (8) > +#define CCDC_DF_CSC_SPH_MASK (0x1fff) > +#define CCDC_DF_CSC_LNH_MASK (0x1fff) > +#define CCDC_DF_CSC_SLV_MASK (0x1fff) > +#define CCDC_DF_CSC_LNV_MASK (0x1fff) > +#define CCDC_DF_NUMLINES (0x7fff) > +#define CCDC_DF_NUMPIX (0x1fff) > + > +/* Offsets for LSC/DFC/Gain */ > +#define CCDC_DATA_H_OFFSET_MASK (0x1fff) > +#define CCDC_DATA_V_OFFSET_MASK (0x1fff) > + > +/* Linearization */ > +#define CCDC_LIN_CORRSFT_MASK (7) > +#define CCDC_LIN_CORRSFT_SHIFT (4) > +#define CCDC_LIN_SCALE_FACT_INTEG_SHIFT (10) > +#define CCDC_LIN_SCALE_FACT_DECIMAL_MASK (0x3ff) > +#define CCDC_LIN_ENTRY_MASK (0x3ff) > + > +#define CCDC_DF_FMTRLEN_MASK (0x1fff) > +#define CCDC_DF_FMTHCNT_MASK (0x1fff) > + > +/* Pattern registers */ > +#define CCDC_PG_EN (1<< 3) > +#define CCDC_SEL_PG_SRC (3<< 4) > +#define CCDC_PG_VD_POL_SHIFT (0) > +#define CCDC_PG_HD_POL_SHIFT (1) > + > +/*masks and shifts*/ > +#define CCDC_SYNCEN_VDHDEN_MASK (1<< 0) > +#define CCDC_SYNCEN_WEN_MASK (1<< 1) > +#define CCDC_SYNCEN_WEN_SHIFT 1 > + > +#endif > diff --git a/include/linux/dm365_ccdc.h b/include/linux/dm365_ccdc.h > new file mode 100644 > index 0000000..4e50529 > --- /dev/null > +++ b/include/linux/dm365_ccdc.h > @@ -0,0 +1,664 @@ ... > +#define VPFE_CMD_S_CCDC_RAW_PARAMS _IOW('V', 1, \ > + struct ccdc_config_params_raw) > +#define VPFE_CMD_G_CCDC_RAW_PARAMS _IOR('V', 2, \ > + struct ccdc_config_params_raw) > +/** > + * ccdc float type S8Q8/U8Q8 > + */ > +struct ccdc_float_8 { > + /* 8 bit integer part */ > + unsigned char integer; > + /* 8 bit decimal part */ > + unsigned char decimal; > +}; Isn't it better to use explicit width type, like u8, u16, etc. ? Then we could just have: +struct ccdc_float_8 { + u8 integer; + u8 decimal; +}; > + > +/** > + * brief ccdc float type U16Q16/S16Q16 > + */ > +struct ccdc_float_16 { > + /* 16 bit integer part */ > + unsigned short integer; > + /* 16 bit decimal part */ > + unsigned short decimal; > +}; and +struct ccdc_float_16 { + u16 integer; + u16 decimal; +}; > + > +/* > + * ccdc image(target) window parameters > + */ > +struct ccdc_cropwin { > + /* horzontal offset of the top left corner in pixels */ > + unsigned int left; > + /* vertical offset of the top left corner in pixels */ > + unsigned int top; > + /* width in pixels of the rectangle */ > + unsigned int width; > + /* height in lines of the rectangle */ > + unsigned int height; > +}; How about using struct v4l2_rect instead ? ... > +/** > + * CCDC image data size > + */ > +enum ccdc_data_size { > + /* 8 bits */ > + CCDC_8_BITS, > + /* 9 bits */ > + CCDC_9_BITS, > + /* 10 bits */ > + CCDC_10_BITS, > + /* 11 bits */ > + CCDC_11_BITS, > + /* 12 bits */ > + CCDC_12_BITS, > + /* 13 bits */ > + CCDC_13_BITS, > + /* 14 bits */ > + CCDC_14_BITS, > + /* 15 bits */ > + CCDC_15_BITS, > + /* 16 bits */ > + CCDC_16_BITS > +}; > + > +/** > + * CCDC image data shift to right > + */ > +enum ccdc_datasft { > + /* No Shift */ > + CCDC_NO_SHIFT, > + /* 1 bit Shift */ > + CCDC_1BIT_SHIFT, > + /* 2 bit Shift */ > + CCDC_2BIT_SHIFT, > + /* 3 bit Shift */ > + CCDC_3BIT_SHIFT, > + /* 4 bit Shift */ > + CCDC_4BIT_SHIFT, > + /* 5 bit Shift */ > + CCDC_5BIT_SHIFT, > + /* 6 bit Shift */ > + CCDC_6BIT_SHIFT > +}; > + > +/** > + * MSB of image data connected to sensor port > + */ > +enum ccdc_data_msb { > + /* MSB b15 */ > + CCDC_BIT_MSB_15, > + /* MSB b14 */ > + CCDC_BIT_MSB_14, > + /* MSB b13 */ > + CCDC_BIT_MSB_13, > + /* MSB b12 */ > + CCDC_BIT_MSB_12, > + /* MSB b11 */ > + CCDC_BIT_MSB_11, > + /* MSB b10 */ > + CCDC_BIT_MSB_10, > + /* MSB b9 */ > + CCDC_BIT_MSB_9, > + /* MSB b8 */ > + CCDC_BIT_MSB_8, > + /* MSB b7 */ > + CCDC_BIT_MSB_7 Could you live without the comments in these 3 enum declarations ? They don't seem to add any information. -- Regards, Sylwester From Paul_Stuart at seektech.com Fri Sep 2 10:04:13 2011 From: Paul_Stuart at seektech.com (Paul Stuart) Date: Fri, 2 Sep 2011 08:04:13 -0700 Subject: DM365 with TVP5147M1 in bt656 10-bit mode? In-Reply-To: <74DFAE2329015E4288E958E7E3D155378B758FA092@EX-MAIL-HYD1-1.ant.amazon.com> References: <1314928015915-6752421.post@n2.nabble.com> <74DFAE2329015E4288E958E7E3D155378B758FA092@EX-MAIL-HYD1-1.ant.amazon.com> Message-ID: <7F1B6BBBDF05C649BBBA3C853F488A611B0177A1BC@Hawking.deepsea.com> Hi, We have a TVP5147M1 running in 10-bit BT656 with embedded syncs mode to our DM365, but getting "horrible video" (skewed color space, tons o' rolling noise). HW connection: Lines Y_0 - Y_7 from the TVP are running to CIN0-CIN7 on the DM365. Lines Y_8 and Y_9 from the TVP are running to YIN0 and YIN1 respectively on the DM365 SW setup: In our board config file, I specified if_type = VPFE_BT656_10BIT In the same file, the output route for the TVP5147 is set to OUTPUT_10BIT_422_EMBEDDED_SYNC In dm365_ccd.c: ccd_config_ycbcr for the case of VPFE_BT656_10BIT, I configure ccdcfg as follows: ccdcfg = ccdcfg | CCD_DATA_PACK8; In the same file I've changed the pix_fmt to CCDC_PIXFMT_YCBCR_16BIT, per the VPFE frontend user guide. TVP Setup: I've set it up to output 10-bit 656 with embedded syncs. We get interrupts, get "video", it just looks really bad. Am I missing something obvious in my setup? Has anyone had success with 10-bit BT.656 on the DM365? Thanks, Paul From m-karicheri2 at ti.com Fri Sep 2 15:02:04 2011 From: m-karicheri2 at ti.com (Karicheri, Muralidharan) Date: Fri, 2 Sep 2011 20:02:04 +0000 Subject: [PATCH v2 1/2] ARM: davinci - fix incorrect offsets and mask usage in psc code In-Reply-To: <4E5FD371.1020200@mvista.com> References: <1314899316-2708-1-git-send-email-m-karicheri2@ti.com> <4E5FD371.1020200@mvista.com> Message-ID: <3E54258959B69E4282D79E01AB1F32B701B2C9@DLEE12.ent.ti.com> >> >> > Reviewed-by: Sergei Shtylyov >> >> I haven't reviewed this patch yet. Maybe you mean "Suggested-by:"? You have reviewed v1 of the patch that has the fix and enhancement as a single patch. You had suggested To move the fix to a separate patch which I had accepted. Did you suggest without reviewing the code? :) Can I add you as "Reviewed-by" in the next version of the patch? >> >> > Signed-off-by: Murali Karicheri >> > --- >> > comments against previous version of the patch addressed:- >> >> Hm, I seem to have missed the previous version then... >> >> > - Moved the bug fix to a separate patch >> >> > arch/arm/mach-davinci/include/mach/psc.h | 2 +- >> > arch/arm/mach-davinci/psc.c | 19 ++++++++++--------- >> > 2 files changed, 11 insertions(+), 10 deletions(-) >> > >> > diff --git a/arch/arm/mach-davinci/include/mach/psc.h b/arch/arm/mach- >> davinci/include/mach/psc.h >> > index 47fd0bc..63c4366 100644 >> > --- a/arch/arm/mach-davinci/include/mach/psc.h >> > +++ b/arch/arm/mach-davinci/include/mach/psc.h >> > @@ -233,7 +233,7 @@ >> > #define PTCMD 0x120 >> > #define PTSTAT 0x128 >> > #define PDSTAT 0x200 >> > -#define PDCTL1 0x304 >> > +#define PDCTL 0x300 >> > #define MDSTAT 0x800 >> > #define MDCTL 0xA00 >> > >> > diff --git a/arch/arm/mach-davinci/psc.c b/arch/arm/mach-davinci/psc.c >> > index 1fb6bdf..f157d9c 100644 >> > --- a/arch/arm/mach-davinci/psc.c >> > +++ b/arch/arm/mach-davinci/psc.c >> > @@ -52,7 +52,7 @@ int __init davinci_psc_is_clk_active(unsigned int >> ctlr, unsigned int id) >> > void davinci_psc_config(unsigned int domain, unsigned int ctlr, >> > unsigned int id, bool enable, u32 flags) >> > { >> > - u32 epcpr, ptcmd, ptstat, pdstat, pdctl1, mdstat, mdctl; >> > + u32 epcpr, ptcmd, ptstat, pdstat, pdctl, mdstat, mdctl; >> > void __iomem *psc_base; >> > struct davinci_soc_info *soc_info =&davinci_soc_info; >> > u32 next_state = PSC_STATE_ENABLE; >> > @@ -79,11 +79,11 @@ void davinci_psc_config(unsigned int domain, >> unsigned int ctlr, >> > mdctl |= MDCTL_FORCE; >> > __raw_writel(mdctl, psc_base + MDCTL + 4 * id); >> > >> > - pdstat = __raw_readl(psc_base + PDSTAT); >> > - if ((pdstat& 0x00000001) == 0) { >> > - pdctl1 = __raw_readl(psc_base + PDCTL1); >> > - pdctl1 |= 0x1; >> > - __raw_writel(pdctl1, psc_base + PDCTL1); >> > + pdstat = __raw_readl(psc_base + PDSTAT + 4 * domain); >> > + if ((pdstat& 0x1F) == 0) { >> >> I suggest to make this mask a #define in , like we have >> MDSTAT_STATE_MASK there. Ok. I will do. >> >> > + pdctl = __raw_readl(psc_base + PDCTL + 4 * domain); >> > + pdctl |= 0x1; >> > + __raw_writel(pdctl, psc_base + PDCTL + 4 * domain); >> > >> > ptcmd = 1<< domain; >> > __raw_writel(ptcmd, psc_base + PTCMD); >> > @@ -92,9 +92,10 @@ void davinci_psc_config(unsigned int domain, unsigned >> int ctlr, >> > epcpr = __raw_readl(psc_base + EPCPR); >> > } while ((((epcpr>> domain)& 1) == 0)); >> >> Does this work for ARM domain, i.e. does it require an external power >> supply >> too? Not sure. Will someone actively using the DaVinci platforms answer this question? >> >> > - pdctl1 = __raw_readl(psc_base + PDCTL1); >> > - pdctl1 |= 0x100; >> > - __raw_writel(pdctl1, psc_base + PDCTL1); >> > + pdctl = __raw_readl(psc_base + PDCTL + 4 * domain); >> > + pdctl |= 0x100; >> > + __raw_writel(pdctl, psc_base + PDCTL + 4 * domain); >> > + >> > } else { >> > ptcmd = 1<< domain; >> > __raw_writel(ptcmd, psc_base + PTCMD); >> >> WBR, Sergei From sshtylyov at mvista.com Fri Sep 2 20:06:17 2011 From: sshtylyov at mvista.com (Sergei Shtylyov) Date: Sat, 03 Sep 2011 05:06:17 +0400 Subject: [PATCH v2 1/2] ARM: davinci - fix incorrect offsets and mask usage in psc code In-Reply-To: <3E54258959B69E4282D79E01AB1F32B701B2C9@DLEE12.ent.ti.com> References: <1314899316-2708-1-git-send-email-m-karicheri2@ti.com> <4E5FD371.1020200@mvista.com> <3E54258959B69E4282D79E01AB1F32B701B2C9@DLEE12.ent.ti.com> Message-ID: <4E617D89.80307@mvista.com> Hello. On 03-09-2011 0:02, Karicheri, Muralidharan wrote: >>>> Reviewed-by: Sergei Shtylyov >>> I haven't reviewed this patch yet. Maybe you mean "Suggested-by:"? > You have reviewed v1 of the patch that has the fix and enhancement as a single patch. You had suggested > To move the fix IIRC, I was only talking about the mask fix. But this patch seems OK. > to a separate patch which I had accepted. Did you suggest without reviewing the code? :) > Can I add you as "Reviewed-by" in the next version of the patch? Yes. >>>> Signed-off-by: Murali Karicheri [...] >>>> + pdctl = __raw_readl(psc_base + PDCTL + 4 * domain); >>>> + pdctl |= 0x1; >>>> + __raw_writel(pdctl, psc_base + PDCTL + 4 * domain); >>>> >>>> ptcmd = 1<< domain; >>>> __raw_writel(ptcmd, psc_base + PTCMD); >>>> @@ -92,9 +92,10 @@ void davinci_psc_config(unsigned int domain, unsigned >>> int ctlr, >>>> epcpr = __raw_readl(psc_base + EPCPR); >>>> } while ((((epcpr>> domain)& 1) == 0)); >>> Does this work for ARM domain, i.e. does it require an external power >>> supply too? > Not sure. Will someone actively using the DaVinci platforms answer this question? I may try to verify on my DM6446 if I'll find the time... >>> >>>> - pdctl1 = __raw_readl(psc_base + PDCTL1); >>>> - pdctl1 |= 0x100; >>>> - __raw_writel(pdctl1, psc_base + PDCTL1); >>>> + pdctl = __raw_readl(psc_base + PDCTL + 4 * domain); >>>> + pdctl |= 0x100; >>>> + __raw_writel(pdctl, psc_base + PDCTL + 4 * domain); >>>> + >>>> } else { >>>> ptcmd = 1<< domain; >>>> __raw_writel(ptcmd, psc_base + PTCMD); WBR, Sergei From albertbu at gmail.com Sun Sep 4 01:49:30 2011 From: albertbu at gmail.com (Albert Burbea) Date: Sun, 4 Sep 2011 09:49:30 +0300 Subject: DM365 with TVP5147M1 in bt656 10-bit mode? In-Reply-To: <7F1B6BBBDF05C649BBBA3C853F488A611B0177A1BC@Hawking.deepsea.com> References: <1314928015915-6752421.post@n2.nabble.com> <74DFAE2329015E4288E958E7E3D155378B758FA092@EX-MAIL-HYD1-1.ant.amazon.com> <7F1B6BBBDF05C649BBBA3C853F488A611B0177A1BC@Hawking.deepsea.com> Message-ID: Hi Paul, this seems wrong to me. I think you do NOT have to specify CCD_DATA_PACK8 - this is for 8 bit values - but leave this bit at zero - so you will get all your ten bits in a 16 bit memory address. Also, please recheck your connections. I am not sure they are correct. Look in the VPFE users' guide - there are many examples. Albert On Fri, Sep 2, 2011 at 6:04 PM, Paul Stuart wrote: > Hi, > We have a TVP5147M1 running in 10-bit BT656 with embedded syncs mode to our > DM365, but getting "horrible video" (skewed color space, tons o' rolling > noise). > > HW connection: > Lines Y_0 - Y_7 from the TVP are running to CIN0-CIN7 on the DM365. Lines > Y_8 and Y_9 from the TVP are running to YIN0 and YIN1 respectively on the > DM365 > > SW setup: > In our board config file, I specified if_type = VPFE_BT656_10BIT > > In the same file, the output route for the TVP5147 is set to > OUTPUT_10BIT_422_EMBEDDED_SYNC > > In dm365_ccd.c: ccd_config_ycbcr for the case of VPFE_BT656_10BIT, I > configure ccdcfg as follows: > ccdcfg = ccdcfg | CCD_DATA_PACK8; > > In the same file I've changed the pix_fmt to CCDC_PIXFMT_YCBCR_16BIT, per > the VPFE frontend user guide. > > > TVP Setup: > I've set it up to output 10-bit 656 with embedded syncs. > > > > We get interrupts, get "video", it just looks really bad. Am I missing > something obvious in my setup? Has anyone had success with 10-bit BT.656 on > the DM365? > > Thanks, > Paul > _______________________________________________ > Davinci-linux-open-source mailing list > Davinci-linux-open-source at linux.davincidsp.com > http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source > -- Albert Burbea Harishonim 8 Ramat Gan 52502, Israel Tel/Fax + 972-3-7526016 Mobile: +972-52-3541842 -------------- next part -------------- An HTML attachment was scrubbed... URL: From sshtylyov at mvista.com Tue Sep 6 08:50:20 2011 From: sshtylyov at mvista.com (Sergei Shtylyov) Date: Tue, 06 Sep 2011 17:50:20 +0400 Subject: [PATCH] DaVinci: correct MDSTAT_STATE_MASK In-Reply-To: References: <201107081924.57577.sshtylyov@ru.mvista.com> Message-ID: <4E66251C.2020804@mvista.com> Hello. On 07/27/2011 08:18 PM, Nori, Sekhar wrote: >> MDSTAT.STATE occupies bits 0..5 according to all available documentation, so fix >> the #define MDSTAT_STATE_MASK at last. Using the wrong value seems to have been >> harmless though... >> This was noticed by me back in 2009 but I didn't follow up with the patch back >> then... :-/ >> Signed-off-by: Sergei Shtylyov > I applied this with two changes. > Changed the headline to "ARM: davinci: correct MDSTAT_STATE_MASK" > to get the standardization requested by Arnd. > Also dropped the second paragraph of the commit text since it > doesn't really belong to the permanent history ;) You have queued it for 3.2, right? > Thanks, > Sekhar WBR, Sergei From sshtylyov at mvista.com Tue Sep 6 09:17:55 2011 From: sshtylyov at mvista.com (Sergei Shtylyov) Date: Tue, 06 Sep 2011 18:17:55 +0400 Subject: [PATCH v2 1/2] ARM: davinci - fix incorrect offsets and mask usage in psc code In-Reply-To: <4E617D89.80307@mvista.com> References: <1314899316-2708-1-git-send-email-m-karicheri2@ti.com> <4E5FD371.1020200@mvista.com> <3E54258959B69E4282D79E01AB1F32B701B2C9@DLEE12.ent.ti.com> <4E617D89.80307@mvista.com> Message-ID: <4E662B93.7080701@mvista.com> Hello. On 09/03/2011 05:06 AM, Sergei Shtylyov wrote: >>>>> Signed-off-by: Murali Karicheri > [...] >>>>> + pdctl = __raw_readl(psc_base + PDCTL + 4 * domain); >>>>> + pdctl |= 0x1; >>>>> + __raw_writel(pdctl, psc_base + PDCTL + 4 * domain); >>>>> >>>>> ptcmd = 1<< domain; >>>>> __raw_writel(ptcmd, psc_base + PTCMD); >>>>> @@ -92,9 +92,10 @@ void davinci_psc_config(unsigned int domain, unsigned >>>> int ctlr, >>>>> epcpr = __raw_readl(psc_base + EPCPR); >>>>> } while ((((epcpr>> domain)& 1) == 0)); >>>> Does this work for ARM domain, i.e. does it require an external power >>>> supply too? >> Not sure. Will someone actively using the DaVinci platforms answer this question? > I may try to verify on my DM6446 if I'll find the time... Hmm, DA8x0 documentation doesn't even mention the EPCPR register, so I'm not sure how this loop is supposed to work on those chips... unless this path is never actually executed -- which I'm trying to check now... WBR, Sergei From sshtylyov at mvista.com Tue Sep 6 09:36:26 2011 From: sshtylyov at mvista.com (Sergei Shtylyov) Date: Tue, 06 Sep 2011 18:36:26 +0400 Subject: [PATCH v2 1/2] ARM: davinci - fix incorrect offsets and mask usage in psc code In-Reply-To: <4E662B93.7080701@mvista.com> References: <1314899316-2708-1-git-send-email-m-karicheri2@ti.com> <4E5FD371.1020200@mvista.com> <3E54258959B69E4282D79E01AB1F32B701B2C9@DLEE12.ent.ti.com> <4E617D89.80307@mvista.com> <4E662B93.7080701@mvista.com> Message-ID: <4E662FEA.7090908@mvista.com> Hello. On 09/06/2011 06:17 PM, Sergei Shtylyov wrote: >>>>>> Signed-off-by: Murali Karicheri >> [...] >>>>>> + pdctl = __raw_readl(psc_base + PDCTL + 4 * domain); >>>>>> + pdctl |= 0x1; >>>>>> + __raw_writel(pdctl, psc_base + PDCTL + 4 * domain); >>>>>> >>>>>> ptcmd = 1<< domain; >>>>>> __raw_writel(ptcmd, psc_base + PTCMD); >>>>>> @@ -92,9 +92,10 @@ void davinci_psc_config(unsigned int domain, unsigned >>>>> int ctlr, >>>>>> epcpr = __raw_readl(psc_base + EPCPR); >>>>>> } while ((((epcpr>> domain)& 1) == 0)); >>>>> Does this work for ARM domain, i.e. does it require an external power >>>>> supply too? >>> Not sure. Will someone actively using the DaVinci platforms answer this >>> question? >> I may try to verify on my DM6446 if I'll find the time... > Hmm, DA8x0 documentation doesn't even mention the EPCPR register, so I'm not > sure how this loop is supposed to work on those chips... unless this path is > never actually executed -- which I'm trying to check now... Have verified that the patch was never being executed indeed. If I make it executed, the board happily locks up. So looks like this code has even more issues... WBR, Sergei From nsekhar at ti.com Tue Sep 6 12:40:09 2011 From: nsekhar at ti.com (Nori, Sekhar) Date: Tue, 6 Sep 2011 23:10:09 +0530 Subject: [PATCH] DaVinci: correct MDSTAT_STATE_MASK In-Reply-To: <4E66251C.2020804@mvista.com> References: <201107081924.57577.sshtylyov@ru.mvista.com> <4E66251C.2020804@mvista.com> Message-ID: Hi Sergei, On Tue, Sep 06, 2011 at 19:20:20, Sergei Shtylyov wrote: > Hello. > > On 07/27/2011 08:18 PM, Nori, Sekhar wrote: > > >> MDSTAT.STATE occupies bits 0..5 according to all available documentation, so fix > >> the #define MDSTAT_STATE_MASK at last. Using the wrong value seems to have been > >> harmless though... > > >> This was noticed by me back in 2009 but I didn't follow up with the patch back > >> then... :-/ > > >> Signed-off-by: Sergei Shtylyov > > > I applied this with two changes. > > > Changed the headline to "ARM: davinci: correct MDSTAT_STATE_MASK" > > to get the standardization requested by Arnd. > > > Also dropped the second paragraph of the commit text since it > > doesn't really belong to the permanent history ;) > > You have queued it for 3.2, right? No, actually planning to send for v3.1. Have been delayed a bit due to my recent travel. Thanks, Sekhar From nsekhar at ti.com Wed Sep 7 07:13:24 2011 From: nsekhar at ti.com (Nori, Sekhar) Date: Wed, 7 Sep 2011 17:43:24 +0530 Subject: [GIT PULL] DaVinci fixes for v3.1-rc6 Message-ID: Hi Arnd, Can you please pull the following fixes for v3.1-rc6? These are not regression fixes in the strict sense since none of the bugs were actually introduced in v3.1 and have been around for a while. But I hope we don't have to wait till v3.2 for these. Thanks, Sekhar The following changes since commit ddf28352b80c86754a6424e3a61e8bdf9213b3c7: Linus Torvalds (1): Linux 3.1-rc5 are available in the git repository at: git://gitorious.org/linux-davinci/linux-davinci.git fixes Linus Walleij (1): ARM: davinci: fix cache flush build error Rajashekhara, Sudhakar (1): ARM: davinci: da850 EVM: read mac address from SPI flash Sergei Shtylyov (1): ARM: davinci: correct MDSTAT_STATE_MASK arch/arm/mach-davinci/board-da850-evm.c | 28 ++++++++++++++++++++++++++++ arch/arm/mach-davinci/include/mach/psc.h | 2 +- arch/arm/mach-davinci/sleep.S | 6 +++++- 3 files changed, 34 insertions(+), 2 deletions(-) From sshtylyov at mvista.com Wed Sep 7 09:45:07 2011 From: sshtylyov at mvista.com (Sergei Shtylyov) Date: Wed, 07 Sep 2011 18:45:07 +0400 Subject: [PATCH v2 1/2] ARM: davinci - fix incorrect offsets and mask usage in psc code In-Reply-To: <4E662FEA.7090908@mvista.com> References: <1314899316-2708-1-git-send-email-m-karicheri2@ti.com> <4E5FD371.1020200@mvista.com> <3E54258959B69E4282D79E01AB1F32B701B2C9@DLEE12.ent.ti.com> <4E617D89.80307@mvista.com> <4E662B93.7080701@mvista.com> <4E662FEA.7090908@mvista.com> Message-ID: <4E678373.8020705@mvista.com> Hello. On 09-06-2011 06:36 PM, Sergei Shtylyov wrote: >>>>>>> Signed-off-by: Murali Karicheri >>> [...] >>>>>>> + pdctl = __raw_readl(psc_base + PDCTL + 4 * domain); >>>>>>> + pdctl |= 0x1; >>>>>>> + __raw_writel(pdctl, psc_base + PDCTL + 4 * domain); >>>>>>> >>>>>>> ptcmd = 1<< domain; >>>>>>> __raw_writel(ptcmd, psc_base + PTCMD); >>>>>>> @@ -92,9 +92,10 @@ void davinci_psc_config(unsigned int domain, unsigned >>>>>> int ctlr, >>>>>>> epcpr = __raw_readl(psc_base + EPCPR); >>>>>>> } while ((((epcpr>> domain)& 1) == 0)); >>>>>> Does this work for ARM domain, i.e. does it require an external power >>>>>> supply too? >>>> Not sure. Will someone actively using the DaVinci platforms answer this >>>> question? >>> I may try to verify on my DM6446 if I'll find the time... >> Hmm, DA8x0 documentation doesn't even mention the EPCPR register, so I'm not >> sure how this loop is supposed to work on those chips... unless this path is >> never actually executed -- which I'm trying to check now... > Have verified that the patch was never being executed indeed. If I make it > executed, the board happily locks up. So looks like this code has even more > issues... Seeing the same on DM6446 BUT the test is wrong -- of course, I just can't power down domain 0 and then power it up to see if the domain 0's bit gets set in the EPCPR register. :-) Well, given that domain 0 is always enabled, my above question doesn't make much sense anyway, so your patch is fine with me. :-) WBR, Sergei From sshtylyov at mvista.com Wed Sep 7 09:52:17 2011 From: sshtylyov at mvista.com (Sergei Shtylyov) Date: Wed, 07 Sep 2011 18:52:17 +0400 Subject: [PATCH v2 1/2] ARM: davinci - fix incorrect offsets and mask usage in psc code In-Reply-To: <1314899316-2708-1-git-send-email-m-karicheri2@ti.com> References: <1314899316-2708-1-git-send-email-m-karicheri2@ti.com> Message-ID: <4E678521.4010408@mvista.com> Hello. On 09/01/2011 09:48 PM, Murali Karicheri wrote: > There are 5 LSB bits defined in PDSTAT and the code currently uses > a mask of 1 bit to check the status. Also there is PDSTAT and PDCTL > registers defined for ARM domain and DSP domain where as the code > always read the ARM PDSTAT register and DSP PDCTL register. This patch Domain 0 PDSTAT and domain 1 PDCTL, to be precise. At least on DA8xx, these domains are called differently than on real DaVincis. > fixes these issues. The real issue seems that domain 1 was never properly powered up (unless domain 1 had been also powered up by the bootloader), because the PDSTAT0 check always indicated that the domain 0 had been already powered up, so we were falling thru to the 'else' alternative. > Reviewed-by: Sergei Shtylyov > Signed-off-by: Murali Karicheri WBR, Sergei From sshtylyov at mvista.com Wed Sep 7 09:54:56 2011 From: sshtylyov at mvista.com (Sergei Shtylyov) Date: Wed, 07 Sep 2011 18:54:56 +0400 Subject: [PATCH v2 1/2] ARM: davinci - fix incorrect offsets and mask usage in psc code In-Reply-To: <4E5FD371.1020200@mvista.com> References: <1314899316-2708-1-git-send-email-m-karicheri2@ti.com> <4E5FD371.1020200@mvista.com> Message-ID: <4E6785C0.7010709@mvista.com> Hello. On 09/01/2011 10:48 PM, Sergei Shtylyov wrote: >> There are 5 LSB bits defined in PDSTAT and the code currently uses >> a mask of 1 bit to check the status. Also there is PDSTAT and PDCTL >> registers defined for ARM domain and DSP domain where as the code >> always read the ARM PDSTAT register and DSP PDCTL register. This patch >> fixes these issues. >> Reviewed-by: Sergei Shtylyov >> Signed-off-by: Murali Karicheri >> arch/arm/mach-davinci/include/mach/psc.h | 2 +- >> arch/arm/mach-davinci/psc.c | 19 ++++++++++--------- >> 2 files changed, 11 insertions(+), 10 deletions(-) >> >> diff --git a/arch/arm/mach-davinci/psc.c b/arch/arm/mach-davinci/psc.c >> index 1fb6bdf..f157d9c 100644 >> --- a/arch/arm/mach-davinci/psc.c >> +++ b/arch/arm/mach-davinci/psc.c [...] >> @@ -92,9 +92,10 @@ void davinci_psc_config(unsigned int domain, unsigned int >> ctlr, >> epcpr = __raw_readl(psc_base + EPCPR); >> } while ((((epcpr>> domain)& 1) == 0)); > Does this work for ARM domain, i.e. does it require an external power supply too? >> - pdctl1 = __raw_readl(psc_base + PDCTL1); >> - pdctl1 |= 0x100; >> - __raw_writel(pdctl1, psc_base + PDCTL1); >> + pdctl = __raw_readl(psc_base + PDCTL + 4 * domain); >> + pdctl |= 0x100; >> + __raw_writel(pdctl, psc_base + PDCTL + 4 * domain); >> + Didn't notice before: this extra empty line is not needed here. WBR, Sergei From Paul_Stuart at seektech.com Wed Sep 7 10:02:25 2011 From: Paul_Stuart at seektech.com (Paul Stuart) Date: Wed, 7 Sep 2011 08:02:25 -0700 Subject: DM365 with TVP5147M1 in bt656 10-bit mode? In-Reply-To: References: <1314928015915-6752421.post@n2.nabble.com><74DFAE2329015E4288E958E7E3D155378B758FA092@EX-MAIL-HYD1-1.ant.amazon.com><7F1B6BBBDF05C649BBBA3C853F488A611B0177A1BC@Hawking.deepsea.com> Message-ID: <7F1B6BBBDF05C649BBBA3C853F488A611B017C6213@Hawking.deepsea.com> Regarding PACK8 - I'm perplexed what the data format *should* look like for captured BT.656. In the VPFE, they have plenty of examples for 8-bit mode, but nary a one for 10-bit. For example, the VPFE user guide specifies the following for "BT.656 Mode Data Format in SDRAM" | Pixel3 (Y1) | Pixel2 (Cr0) | Pixel1 (Y0) | Pixel0 (Cb0) | Where each of these is 8 bits. In 10-bit mode, is each pixel stored as 16 bits with the 10-bits in the lower half? ________________________________ From: Albert Burbea [mailto:albertbu at gmail.com] Sent: Saturday, September 03, 2011 11:50 PM To: Paul Stuart Cc: davinci-linux-open-source at linux.davincidsp.com Subject: Re: DM365 with TVP5147M1 in bt656 10-bit mode? Hi Paul, this seems wrong to me. I think you do NOT have to specify CCD_DATA_PACK8 - this is for 8 bit values - but leave this bit at zero - so you will get all your ten bits in a 16 bit memory address. Also, please recheck your connections. I am not sure they are correct. Look in the VPFE users' guide - there are many examples. Albert On Fri, Sep 2, 2011 at 6:04 PM, Paul Stuart > wrote: Hi, We have a TVP5147M1 running in 10-bit BT656 with embedded syncs mode to our DM365, but getting "horrible video" (skewed color space, tons o' rolling noise). HW connection: Lines Y_0 - Y_7 from the TVP are running to CIN0-CIN7 on the DM365. Lines Y_8 and Y_9 from the TVP are running to YIN0 and YIN1 respectively on the DM365 SW setup: In our board config file, I specified if_type = VPFE_BT656_10BIT In the same file, the output route for the TVP5147 is set to OUTPUT_10BIT_422_EMBEDDED_SYNC In dm365_ccd.c: ccd_config_ycbcr for the case of VPFE_BT656_10BIT, I configure ccdcfg as follows: ccdcfg = ccdcfg | CCD_DATA_PACK8; In the same file I've changed the pix_fmt to CCDC_PIXFMT_YCBCR_16BIT, per the VPFE frontend user guide. TVP Setup: I've set it up to output 10-bit 656 with embedded syncs. We get interrupts, get "video", it just looks really bad. Am I missing something obvious in my setup? Has anyone had success with 10-bit BT.656 on the DM365? Thanks, Paul _______________________________________________ Davinci-linux-open-source mailing list Davinci-linux-open-source at linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source -- Albert Burbea Harishonim 8 Ramat Gan 52502, Israel Tel/Fax + 972-3-7526016 Mobile: +972-52-3541842 -------------- next part -------------- An HTML attachment was scrubbed... URL: From m-karicheri2 at ti.com Wed Sep 7 10:32:45 2011 From: m-karicheri2 at ti.com (Karicheri, Muralidharan) Date: Wed, 7 Sep 2011 15:32:45 +0000 Subject: [PATCH v2 1/2] ARM: davinci - fix incorrect offsets and mask usage in psc code In-Reply-To: <4E6785C0.7010709@mvista.com> References: <1314899316-2708-1-git-send-email-m-karicheri2@ti.com> <4E5FD371.1020200@mvista.com> <4E6785C0.7010709@mvista.com> Message-ID: <3E54258959B69E4282D79E01AB1F32B701B8A7@DLEE12.ent.ti.com> Sergei, Thanks for all your investigation work and comments. I will take care of your recent comments against v2 in v3. Looks like the mask is being corrected by a different Patch (ARM: davinci: correct MDSTAT_STATE_MASK) and I can remove the same from my patch. Sekhar, Do you have a branch I can use to create my patch as it is dependent on "ARM: davinci: correct MDSTAT_STATE_MASK" ? Murali Karicheri Software Design Engineer email: m-karicheri2 at ti.com >> -----Original Message----- >> From: Sergei Shtylyov [mailto:sshtylyov at mvista.com] >> Sent: Wednesday, September 07, 2011 10:55 AM >> To: Karicheri, Muralidharan >> Cc: davinci-linux-open-source at linux.davincidsp.com; Nori, Sekhar; Hilman, >> Kevin >> Subject: Re: [PATCH v2 1/2] ARM: davinci - fix incorrect offsets and mask >> usage in psc code >> >> Hello. >> >> On 09/01/2011 10:48 PM, Sergei Shtylyov wrote: >> >> >> There are 5 LSB bits defined in PDSTAT and the code currently uses >> >> a mask of 1 bit to check the status. Also there is PDSTAT and PDCTL >> >> registers defined for ARM domain and DSP domain where as the code >> >> always read the ARM PDSTAT register and DSP PDCTL register. This patch >> >> fixes these issues. >> >> >> Reviewed-by: Sergei Shtylyov >> >> >> Signed-off-by: Murali Karicheri >> >> >> arch/arm/mach-davinci/include/mach/psc.h | 2 +- >> >> arch/arm/mach-davinci/psc.c | 19 ++++++++++--------- >> >> 2 files changed, 11 insertions(+), 10 deletions(-) >> >> >> >> diff --git a/arch/arm/mach-davinci/psc.c b/arch/arm/mach-davinci/psc.c >> >> index 1fb6bdf..f157d9c 100644 >> >> --- a/arch/arm/mach-davinci/psc.c >> >> +++ b/arch/arm/mach-davinci/psc.c >> [...] >> >> @@ -92,9 +92,10 @@ void davinci_psc_config(unsigned int domain, >> unsigned int >> >> ctlr, >> >> epcpr = __raw_readl(psc_base + EPCPR); >> >> } while ((((epcpr>> domain)& 1) == 0)); >> >> > Does this work for ARM domain, i.e. does it require an external power >> supply too? >> >> >> - pdctl1 = __raw_readl(psc_base + PDCTL1); >> >> - pdctl1 |= 0x100; >> >> - __raw_writel(pdctl1, psc_base + PDCTL1); >> >> + pdctl = __raw_readl(psc_base + PDCTL + 4 * domain); >> >> + pdctl |= 0x100; >> >> + __raw_writel(pdctl, psc_base + PDCTL + 4 * domain); >> >> + >> >> Didn't notice before: this extra empty line is not needed here. >> >> WBR, Sergei From m-karicheri2 at ti.com Wed Sep 7 10:43:19 2011 From: m-karicheri2 at ti.com (Karicheri, Muralidharan) Date: Wed, 7 Sep 2011 15:43:19 +0000 Subject: [GIT PULL] DaVinci fixes for v3.1-rc6 In-Reply-To: References: Message-ID: <3E54258959B69E4282D79E01AB1F32B701B8C9@DLEE12.ent.ti.com> Sekhar We ran into the build error when we started using linux-davinci tree for V7 architecture. So this fix for the following to be re-worked to include V7 as well. >> Linus Walleij (1): >> ARM: davinci: fix cache flush build error Murali Karicheri Software Design Engineer email: m-karicheri2 at ti.com Phone: (301) 407 9583 >> -----Original Message----- >> From: davinci-linux-open-source-bounces at linux.davincidsp.com >> [mailto:davinci-linux-open-source-bounces at linux.davincidsp.com] On Behalf >> Of Nori, Sekhar >> Sent: Wednesday, September 07, 2011 8:13 AM >> To: Arnd Bergmann >> Cc: davinci-linux-open-source at linux.davincidsp.com; linux-arm- >> kernel at lists.infradead.org >> Subject: [GIT PULL] DaVinci fixes for v3.1-rc6 >> >> Hi Arnd, >> >> Can you please pull the following fixes for v3.1-rc6? >> >> These are not regression fixes in the strict sense since >> none of the bugs were actually introduced in v3.1 and have >> been around for a while. But I hope we don't have to wait >> till v3.2 for these. >> >> Thanks, >> Sekhar >> >> The following changes since commit >> ddf28352b80c86754a6424e3a61e8bdf9213b3c7: >> Linus Torvalds (1): >> Linux 3.1-rc5 >> >> are available in the git repository at: >> >> git://gitorious.org/linux-davinci/linux-davinci.git fixes >> >> Linus Walleij (1): >> ARM: davinci: fix cache flush build error >> >> Rajashekhara, Sudhakar (1): >> ARM: davinci: da850 EVM: read mac address from SPI flash >> >> Sergei Shtylyov (1): >> ARM: davinci: correct MDSTAT_STATE_MASK >> >> arch/arm/mach-davinci/board-da850-evm.c | 28 >> ++++++++++++++++++++++++++++ >> arch/arm/mach-davinci/include/mach/psc.h | 2 +- >> arch/arm/mach-davinci/sleep.S | 6 +++++- >> 3 files changed, 34 insertions(+), 2 deletions(-) >> _______________________________________________ >> Davinci-linux-open-source mailing list >> Davinci-linux-open-source at linux.davincidsp.com >> http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source From m-karicheri2 at ti.com Wed Sep 7 10:44:31 2011 From: m-karicheri2 at ti.com (Karicheri, Muralidharan) Date: Wed, 7 Sep 2011 15:44:31 +0000 Subject: [PATCH v2 1/2] ARM: davinci - fix incorrect offsets and mask usage in psc code In-Reply-To: <3E54258959B69E4282D79E01AB1F32B701B8A7@DLEE12.ent.ti.com> References: <1314899316-2708-1-git-send-email-m-karicheri2@ti.com> <4E5FD371.1020200@mvista.com> <4E6785C0.7010709@mvista.com> <3E54258959B69E4282D79E01AB1F32B701B8A7@DLEE12.ent.ti.com> Message-ID: <3E54258959B69E4282D79E01AB1F32B701B8DB@DLEE12.ent.ti.com> Sekhar, Ignore my email, I can use linux-davinci tree to get the patch that I mentioned. Murali Karicheri Software Design Engineer email: m-karicheri2 at ti.com Phone: (301) 407 9583 >> -----Original Message----- >> From: davinci-linux-open-source-bounces at linux.davincidsp.com >> [mailto:davinci-linux-open-source-bounces at linux.davincidsp.com] On Behalf >> Of Karicheri, Muralidharan >> Sent: Wednesday, September 07, 2011 11:33 AM >> To: Sergei Shtylyov; Nori, Sekhar >> Cc: davinci-linux-open-source at linux.davincidsp.com >> Subject: RE: [PATCH v2 1/2] ARM: davinci - fix incorrect offsets and mask >> usage in psc code >> >> Sergei, >> >> Thanks for all your investigation work and comments. I will take care of >> your recent comments against v2 in v3. Looks like the mask is being >> corrected by a different Patch (ARM: davinci: correct MDSTAT_STATE_MASK) >> and I can remove the same from my patch. >> >> >> Sekhar, >> >> Do you have a branch I can use to create my patch as it is dependent on >> "ARM: davinci: correct MDSTAT_STATE_MASK" ? >> >> Murali Karicheri >> Software Design Engineer >> email: m-karicheri2 at ti.com >> >> >> >> -----Original Message----- >> >> From: Sergei Shtylyov [mailto:sshtylyov at mvista.com] >> >> Sent: Wednesday, September 07, 2011 10:55 AM >> >> To: Karicheri, Muralidharan >> >> Cc: davinci-linux-open-source at linux.davincidsp.com; Nori, Sekhar; >> Hilman, >> >> Kevin >> >> Subject: Re: [PATCH v2 1/2] ARM: davinci - fix incorrect offsets and >> mask >> >> usage in psc code >> >> >> >> Hello. >> >> >> >> On 09/01/2011 10:48 PM, Sergei Shtylyov wrote: >> >> >> >> >> There are 5 LSB bits defined in PDSTAT and the code currently uses >> >> >> a mask of 1 bit to check the status. Also there is PDSTAT and PDCTL >> >> >> registers defined for ARM domain and DSP domain where as the code >> >> >> always read the ARM PDSTAT register and DSP PDCTL register. This >> patch >> >> >> fixes these issues. >> >> >> >> >> Reviewed-by: Sergei Shtylyov >> >> >> >> >> Signed-off-by: Murali Karicheri >> >> >> >> >> arch/arm/mach-davinci/include/mach/psc.h | 2 +- >> >> >> arch/arm/mach-davinci/psc.c | 19 ++++++++++--------- >> >> >> 2 files changed, 11 insertions(+), 10 deletions(-) >> >> >> >> >> >> diff --git a/arch/arm/mach-davinci/psc.c b/arch/arm/mach- >> davinci/psc.c >> >> >> index 1fb6bdf..f157d9c 100644 >> >> >> --- a/arch/arm/mach-davinci/psc.c >> >> >> +++ b/arch/arm/mach-davinci/psc.c >> >> [...] >> >> >> @@ -92,9 +92,10 @@ void davinci_psc_config(unsigned int domain, >> >> unsigned int >> >> >> ctlr, >> >> >> epcpr = __raw_readl(psc_base + EPCPR); >> >> >> } while ((((epcpr>> domain)& 1) == 0)); >> >> >> >> > Does this work for ARM domain, i.e. does it require an external power >> >> supply too? >> >> >> >> >> - pdctl1 = __raw_readl(psc_base + PDCTL1); >> >> >> - pdctl1 |= 0x100; >> >> >> - __raw_writel(pdctl1, psc_base + PDCTL1); >> >> >> + pdctl = __raw_readl(psc_base + PDCTL + 4 * domain); >> >> >> + pdctl |= 0x100; >> >> >> + __raw_writel(pdctl, psc_base + PDCTL + 4 * domain); >> >> >> + >> >> >> >> Didn't notice before: this extra empty line is not needed here. >> >> >> >> WBR, Sergei >> _______________________________________________ >> Davinci-linux-open-source mailing list >> Davinci-linux-open-source at linux.davincidsp.com >> http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source From sshtylyov at mvista.com Wed Sep 7 13:18:24 2011 From: sshtylyov at mvista.com (Sergei Shtylyov) Date: Wed, 07 Sep 2011 22:18:24 +0400 Subject: [PATCH v2 1/2] ARM: davinci - fix incorrect offsets and mask usage in psc code In-Reply-To: <3E54258959B69E4282D79E01AB1F32B701B8A7@DLEE12.ent.ti.com> References: <1314899316-2708-1-git-send-email-m-karicheri2@ti.com> <4E5FD371.1020200@mvista.com> <4E6785C0.7010709@mvista.com> <3E54258959B69E4282D79E01AB1F32B701B8A7@DLEE12.ent.ti.com> Message-ID: <4E67B570.80100@mvista.com> On 09/07/2011 07:32 PM, Karicheri, Muralidharan wrote: > Sergei, > Thanks for all your investigation work and comments. I will take care of your recent comments against v2 in v3. Looks like the mask is being corrected by a different Patch (ARM: davinci: correct MDSTAT_STATE_MASK) and I can remove the same from my patch. This is a different register, MDSTAT vs PDSTAT in our case... WBR, Sergei From m-karicheri2 at ti.com Wed Sep 7 17:06:37 2011 From: m-karicheri2 at ti.com (Karicheri, Muralidharan) Date: Wed, 7 Sep 2011 22:06:37 +0000 Subject: [PATCH v2 1/2] ARM: davinci - fix incorrect offsets and mask usage in psc code In-Reply-To: <4E67B570.80100@mvista.com> References: <1314899316-2708-1-git-send-email-m-karicheri2@ti.com> <4E5FD371.1020200@mvista.com> <4E6785C0.7010709@mvista.com> <3E54258959B69E4282D79E01AB1F32B701B8A7@DLEE12.ent.ti.com> <4E67B570.80100@mvista.com> Message-ID: <3E54258959B69E4282D79E01AB1F32B701BA81@DLEE12.ent.ti.com> Ok. Murali Karicheri Software Design Engineer email: m-karicheri2 at ti.com Phone: (301) 407 9583 >> -----Original Message----- >> From: Sergei Shtylyov [mailto:sshtylyov at mvista.com] >> Sent: Wednesday, September 07, 2011 2:18 PM >> To: Karicheri, Muralidharan >> Cc: Nori, Sekhar; davinci-linux-open-source at linux.davincidsp.com; Hilman, >> Kevin >> Subject: Re: [PATCH v2 1/2] ARM: davinci - fix incorrect offsets and mask >> usage in psc code >> >> On 09/07/2011 07:32 PM, Karicheri, Muralidharan wrote: >> > Sergei, >> >> > Thanks for all your investigation work and comments. I will take care of >> your recent comments against v2 in v3. Looks like the mask is being >> corrected by a different Patch (ARM: davinci: correct MDSTAT_STATE_MASK) >> and I can remove the same from my patch. >> >> This is a different register, MDSTAT vs PDSTAT in our case... >> >> WBR, Sergei From nsekhar at ti.com Thu Sep 8 02:04:35 2011 From: nsekhar at ti.com (Nori, Sekhar) Date: Thu, 8 Sep 2011 12:34:35 +0530 Subject: [GIT PULL] DaVinci fixes for v3.1-rc6 In-Reply-To: <3E54258959B69E4282D79E01AB1F32B701B8C9@DLEE12.ent.ti.com> References: <3E54258959B69E4282D79E01AB1F32B701B8C9@DLEE12.ent.ti.com> Message-ID: Hi Murali, On Wed, Sep 07, 2011 at 21:13:19, Karicheri, Muralidharan wrote: > Sekhar > > We ran into the build error when we started using linux-davinci tree for V7 architecture. So this fix for the following to be re-worked to include V7 as well. > Since we don't support v7 in DaVinci currently, I don't want to hold a build break fix in anticipation of a new feature that will come in later. Thanks, Sekhar From nsekhar at ti.com Thu Sep 8 07:27:49 2011 From: nsekhar at ti.com (Nori, Sekhar) Date: Thu, 8 Sep 2011 17:57:49 +0530 Subject: [PATCH v2 1/2] ARM: davinci - fix incorrect offsets and mask usage in psc code In-Reply-To: <3E54258959B69E4282D79E01AB1F32B701B8A7@DLEE12.ent.ti.com> References: <1314899316-2708-1-git-send-email-m-karicheri2@ti.com> <4E5FD371.1020200@mvista.com> <4E6785C0.7010709@mvista.com> <3E54258959B69E4282D79E01AB1F32B701B8A7@DLEE12.ent.ti.com> Message-ID: Hi Murali, On Wed, Sep 07, 2011 at 21:02:45, Karicheri, Muralidharan wrote: > Sergei, > > Thanks for all your investigation work and comments. I will take care of > your recent comments against v2 in v3. Also, can you please ensure linux-arm-kernel at lists.infradead.org is CCed on future submissions. LAK is a subscribers only list, so if you are not already subscribed, please subscribe before posting. Thanks, Sekhar From m-karicheri2 at ti.com Thu Sep 8 08:17:38 2011 From: m-karicheri2 at ti.com (Karicheri, Muralidharan) Date: Thu, 8 Sep 2011 13:17:38 +0000 Subject: [GIT PULL] DaVinci fixes for v3.1-rc6 In-Reply-To: References: <3E54258959B69E4282D79E01AB1F32B701B8C9@DLEE12.ent.ti.com> Message-ID: <3E54258959B69E4282D79E01AB1F32B701BBFE@DLEE12.ent.ti.com> Sekhar, Ok. Murali Karicheri Software Design Engineer email: m-karicheri2 at ti.com Phone: (301) 407 9583 >> -----Original Message----- >> From: Nori, Sekhar >> Sent: Thursday, September 08, 2011 3:05 AM >> To: Karicheri, Muralidharan; Arnd Bergmann >> Cc: davinci-linux-open-source at linux.davincidsp.com; linux-arm- >> kernel at lists.infradead.org; Chemparathy, Cyril >> Subject: RE: [GIT PULL] DaVinci fixes for v3.1-rc6 >> >> Hi Murali, >> >> On Wed, Sep 07, 2011 at 21:13:19, Karicheri, Muralidharan wrote: >> > Sekhar >> > >> > We ran into the build error when we started using linux-davinci tree for >> V7 architecture. So this fix for the following to be re-worked to include >> V7 as well. >> > >> >> Since we don't support v7 in DaVinci currently, I don't >> want to hold a build break fix in anticipation of a new >> feature that will come in later. >> >> Thanks, >> Sekhar From sshtylyov at mvista.com Thu Sep 8 13:57:50 2011 From: sshtylyov at mvista.com (Sergei Shtylyov) Date: Thu, 08 Sep 2011 22:57:50 +0400 Subject: [PATCH v2 1/2] ARM: davinci - fix incorrect offsets and mask usage in psc code In-Reply-To: References: <1314899316-2708-1-git-send-email-m-karicheri2@ti.com> <4E5FD371.1020200@mvista.com> <4E6785C0.7010709@mvista.com> <3E54258959B69E4282D79E01AB1F32B701B8A7@DLEE12.ent.ti.com> Message-ID: <4E69102E.5000406@mvista.com> Hello. On 09/08/2011 04:27 PM, Nori, Sekhar wrote: >> Sergei, >> Thanks for all your investigation work and comments. I will take care of >> your recent comments against v2 in v3. > Also, can you please ensure linux-arm-kernel at lists.infradead.org is > CCed on future submissions. LAK is a subscribers only list, so if you > are not already subscribed, please subscribe before posting. It's just moderated for non-subscribers, according to MAINTAINERS. > Thanks, > Sekhar WBR, Sergei From manjunath.hadli at ti.com Fri Sep 9 08:20:39 2011 From: manjunath.hadli at ti.com (Hadli, Manjunath) Date: Fri, 9 Sep 2011 18:50:39 +0530 Subject: [PATCH v2 1/8] davinci: vpfe: add dm3xx IPIPEIF hardware support module In-Reply-To: <4E5FEF75.8060704@gmail.com> References: <1314630439-1122-1-git-send-email-manjunath.hadli@ti.com> <1314630439-1122-2-git-send-email-manjunath.hadli@ti.com> <4E5FEF75.8060704@gmail.com> Message-ID: Hi Sylwester, Thank you for your comments. My responses inline. Thanks and Regards, -Manju On Fri, Sep 02, 2011 at 02:17:49, Sylwester Nawrocki wrote: > Hi Manjunath, > > A few comments below... > > On 08/29/2011 05:07 PM, Manjunath Hadli wrote: > > add support for dm3xx IPIPEIF hardware setup. This is the lowest > > software layer for the dm3x vpfe driver which directly accesses > > hardware. Add support for features like default pixel correction, dark > > frame substraction and hardware setup. > > > > Signed-off-by: Manjunath Hadli > > Signed-off-by: Nagabhushana Netagunte > > --- > > drivers/media/video/davinci/dm3xx_ipipeif.c | 317 +++++++++++++++++++++++++++ > > drivers/media/video/davinci/dm3xx_ipipeif.h | 258 ++++++++++++++++++++++ > > include/linux/dm3xx_ipipeif.h | 64 ++++++ > > 3 files changed, 639 insertions(+), 0 deletions(-) > > create mode 100644 drivers/media/video/davinci/dm3xx_ipipeif.c > > create mode 100644 drivers/media/video/davinci/dm3xx_ipipeif.h > > create mode 100644 include/linux/dm3xx_ipipeif.h > > > > diff --git a/drivers/media/video/davinci/dm3xx_ipipeif.c > > b/drivers/media/video/davinci/dm3xx_ipipeif.c > > new file mode 100644 > > index 0000000..ebc8895 > > --- /dev/null > > +++ b/drivers/media/video/davinci/dm3xx_ipipeif.c > > @@ -0,0 +1,317 @@ > ... > > + > > +static void ipipeif_config_dpc(struct ipipeif_dpc *dpc) { > > + u32 val; > > + > > + /* Intialize val*/ > > + val = 0; > > s/Intialize/Initialize ? But this comment doesn't seem much helpful and could probably be removed. Also it might be better to just do: > > u32 val = 0; Done. > > > + > > + if (dpc->en) { > > + val = (dpc->en& 1)<< IPIPEIF_DPC2_EN_SHIFT; > > + val |= dpc->thr& IPIPEIF_DPC2_THR_MASK; > > + } > > + > > + regw_if(val, IPIPEIF_DPC2); > > +} > > + > ... > > + > > +static int __devinit dm3xx_ipipeif_probe(struct platform_device > > +*pdev) { > > + static resource_size_t res_len; > > + struct resource *res; > > + int status; > > + > > + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); > > + if (!res) > > + return -ENOENT; > > + > > + res_len = res->end - res->start + 1; > > resource_size(res) macro could be used here Done. > > > + > > + res = request_mem_region(res->start, res_len, res->name); > > + if (!res) > > + return -EBUSY; > > + > > + ipipeif_base_addr = ioremap_nocache(res->start, res_len); > > + if (!ipipeif_base_addr) { > > + status = -EBUSY; > > + goto fail; > > + } > > + return 0; > > + > > +fail: > > + release_mem_region(res->start, res_len); > > + > > + return status; > > +} > > + > > +static int dm3xx_ipipeif_remove(struct platform_device *pdev) { > > + struct resource *res; > > + > > + iounmap(ipipeif_base_addr); > > + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); > > + if (res) > > + release_mem_region(res->start, res->end - res->start + 1); > > release_mem_region(res->start, resource_size(res)); Done. > > > + return 0; > > +} > > + > > +static struct platform_driver dm3xx_ipipeif_driver = { > > + .driver = { > > + .name = "dm3xx_ipipeif", > > + .owner = THIS_MODULE, > > + }, > > + .remove = __devexit_p(dm3xx_ipipeif_remove), > > + .probe = dm3xx_ipipeif_probe, > > +}; > > + > > +static int dm3xx_ipipeif_init(void) > > +{ > > + return platform_driver_register(&dm3xx_ipipeif_driver); > > +} > > + > > +static void dm3xx_ipipeif_exit(void) > > +{ > > + platform_driver_unregister(&dm3xx_ipipeif_driver); > > +} > > + > > +module_init(dm3xx_ipipeif_init); > > +module_exit(dm3xx_ipipeif_exit); > > + > > +MODULE_LICENSE("GPL2"); > > diff --git a/drivers/media/video/davinci/dm3xx_ipipeif.h > > b/drivers/media/video/davinci/dm3xx_ipipeif.h > > new file mode 100644 > > index 0000000..f3289f0 > > --- /dev/null > > +++ b/drivers/media/video/davinci/dm3xx_ipipeif.h > > @@ -0,0 +1,258 @@ > > +/* > ... > > + > > +/* IPIPEIF Register Offsets from the base address */ > > +#define IPIPEIF_ENABLE (0x00) > > +#define IPIPEIF_CFG1 (0x04) > > +#define IPIPEIF_PPLN (0x08) > > +#define IPIPEIF_LPFR (0x0c) > > +#define IPIPEIF_HNUM (0x10) > > +#define IPIPEIF_VNUM (0x14) > > +#define IPIPEIF_ADDRU (0x18) > > +#define IPIPEIF_ADDRL (0x1c) > > +#define IPIPEIF_ADOFS (0x20) > > +#define IPIPEIF_RSZ (0x24) > > +#define IPIPEIF_GAIN (0x28) > > + > > +/* Below registers are available only on IPIPE 5.1 */ > > +#define IPIPEIF_DPCM (0x2c) > > +#define IPIPEIF_CFG2 (0x30) > > +#define IPIPEIF_INIRSZ (0x34) > > +#define IPIPEIF_OCLIP (0x38) > > +#define IPIPEIF_DTUDF (0x3c) > > +#define IPIPEIF_CLKDIV (0x40) > > +#define IPIPEIF_DPC1 (0x44) > > +#define IPIPEIF_DPC2 (0x48) > > +#define IPIPEIF_DFSGVL (0x4c) > > +#define IPIPEIF_DFSGTH (0x50) > > +#define IPIPEIF_RSZ3A (0x54) > > +#define IPIPEIF_INIRSZ3A (0x58) > > +#define IPIPEIF_RSZ_MIN (16) > > +#define IPIPEIF_RSZ_MAX (112) > > +#define IPIPEIF_RSZ_CONST (16) > > +#define SETBIT(reg, bit) (reg = ((reg) | ((0x00000001)<<(bit)))) > > +#define RESETBIT(reg, bit) (reg = ((reg)& (~(0x00000001<<(bit))))) > > + > > +#define IPIPEIF_ADOFS_LSB_MASK (0x1ff) > > +#define IPIPEIF_ADOFS_LSB_SHIFT (5) > > +#define IPIPEIF_ADOFS_MSB_MASK (0x200) > > +#define IPIPEIF_ADDRU_MASK (0x7ff) > > +#define IPIPEIF_ADDRL_SHIFT (5) > > +#define IPIPEIF_ADDRL_MASK (0xffff) > > +#define IPIPEIF_ADDRU_SHIFT (21) > > +#define IPIPEIF_ADDRMSB_SHIFT (31) > > +#define IPIPEIF_ADDRMSB_LEFT_SHIFT (10) > > + > > +/* CFG1 Masks and shifts */ > > +#define ONESHOT_SHIFT (0) > > +#define DECIM_SHIFT (1) > > +#define INPSRC_SHIFT (2) > > +#define CLKDIV_SHIFT (4) > > +#define AVGFILT_SHIFT (7) > > +#define PACK8IN_SHIFT (8) > > +#define IALAW_SHIFT (9) > > +#define CLKSEL_SHIFT (10) > > +#define DATASFT_SHIFT (11) > > +#define INPSRC1_SHIFT (14) > > + > > +/* DPC2 */ > > +#define IPIPEIF_DPC2_EN_SHIFT (12) > > +#define IPIPEIF_DPC2_THR_MASK (0xfff) > > +/* Applicable for IPIPE 5.1 */ > > +#define IPIPEIF_DF_GAIN_EN_SHIFT (10) > > +#define IPIPEIF_DF_GAIN_MASK (0x3ff) > > +#define IPIPEIF_DF_GAIN_THR_MASK (0xfff) > > +/* DPCM */ > > +#define IPIPEIF_DPCM_BITS_SHIFT (2) > > +#define IPIPEIF_DPCM_PRED_SHIFT (1) > > +/* CFG2 */ > > +#define IPIPEIF_CFG2_HDPOL_SHIFT (1) > > +#define IPIPEIF_CFG2_VDPOL_SHIFT (2) > > +#define IPIPEIF_CFG2_YUV8_SHIFT (6) > > +#define IPIPEIF_CFG2_YUV16_SHIFT (3) > > +#define IPIPEIF_CFG2_YUV8P_SHIFT (7) > > + > > +/* INIRSZ */ > > +#define IPIPEIF_INIRSZ_ALNSYNC_SHIFT (13) > > +#define IPIPEIF_INIRSZ_MASK (0x1fff) > > Is there any good reason to use parentheses around the numbers ? No. It was in the plan to remove them. Now it is taken care of. > > > -- > Regards, > Sylwester > From manjunath.hadli at ti.com Fri Sep 9 08:30:07 2011 From: manjunath.hadli at ti.com (Hadli, Manjunath) Date: Fri, 9 Sep 2011 19:00:07 +0530 Subject: [PATCH v2 4/8] davinci: vpfe: add support for CCDC hardware for dm365 In-Reply-To: <4E5FF7BC.3040108@gmail.com> References: <1314630439-1122-1-git-send-email-manjunath.hadli@ti.com> <1314630439-1122-5-git-send-email-manjunath.hadli@ti.com> <4E5FF7BC.3040108@gmail.com> Message-ID: Thank you for these comments too. My responses inlined. -Manju On Fri, Sep 02, 2011 at 02:53:08, Sylwester Nawrocki wrote: > Hi Manjunath, > > few more comments below.. > > On 08/29/2011 05:07 PM, Manjunath Hadli wrote: > > add support for ccdc on dm365 SoC. ccdc is responsible for capturing > > video data- both raw bayer through sync seperate signals and through > > BT656/1120 interfaces. This driver implements the hardware > > functionality. Mainly- setting of hardware, validation of parameters, > > and isr configuration. > > > > Signed-off-by: Manjunath Hadli > > Signed-off-by: Nagabhushana Netagunte > > --- > > drivers/media/video/davinci/ccdc_types.h | 43 + > > drivers/media/video/davinci/dm365_ccdc.c | 1519 +++++++++++++++++++++++++ > > drivers/media/video/davinci/dm365_ccdc.h | 88 ++ > > drivers/media/video/davinci/dm365_ccdc_regs.h | 309 +++++ > > include/linux/dm365_ccdc.h | 664 +++++++++++ > > 5 files changed, 2623 insertions(+), 0 deletions(-) > > create mode 100644 drivers/media/video/davinci/ccdc_types.h > > create mode 100644 drivers/media/video/davinci/dm365_ccdc.c > > create mode 100644 drivers/media/video/davinci/dm365_ccdc.h > > create mode 100644 drivers/media/video/davinci/dm365_ccdc_regs.h > > create mode 100644 include/linux/dm365_ccdc.h > ... > > +#define CCDC_LINEAR_LUT0_ADDR 0x1c7c000 > > +#define CCDC_LINEAR_LUT1_ADDR 0x1c7c400 > > + > > +/* Masks& Shifts below */ > > +#define START_PX_HOR_MASK (0x7fff) > > +#define NUM_PX_HOR_MASK (0x7fff) > > +#define START_VER_ONE_MASK (0x7fff) > > +#define START_VER_TWO_MASK (0x7fff) > > +#define NUM_LINES_VER (0x7fff) > > + > > +/* gain - offset masks */ > > +#define GAIN_INTEGER_MASK (0x7) > > +#define GAIN_INTEGER_SHIFT (0x9) > > +#define GAIN_DECIMAL_MASK (0x1ff) > > +#define OFFSET_MASK (0xfff) > > +#define GAIN_SDRAM_EN_SHIFT (12) > > +#define GAIN_IPIPE_EN_SHIFT (13) > > +#define GAIN_H3A_EN_SHIFT (14) > > +#define OFST_SDRAM_EN_SHIFT (8) > > +#define OFST_IPIPE_EN_SHIFT (9) > > +#define OFST_H3A_EN_SHIFT (10) > > +#define GAIN_OFFSET_EN_MASK (0x7700) > > + > > +/* Culling */ > > +#define CULL_PAT_EVEN_LINE_SHIFT (8) > > + > > +/* CCDCFG register */ > > +#define CCDC_YCINSWP_RAW (0x00<< 4) > > +#define CCDC_YCINSWP_YCBCR (0x01<< 4) > > +#define CCDC_CCDCFG_FIDMD_LATCH_VSYNC (0x00<< 6) > > +#define CCDC_CCDCFG_WENLOG_AND (0x00<< 8) > > +#define CCDC_CCDCFG_TRGSEL_WEN (0x00<< 9) > > +#define CCDC_CCDCFG_EXTRG_DISABLE (0x00<< 10) > > +#define CCDC_LATCH_ON_VSYNC_DISABLE (0x01<< 15) > > +#define CCDC_LATCH_ON_VSYNC_ENABLE (0x00<< 15) > > +#define CCDC_DATA_PACK_MASK (0x03) > > +#define CCDC_DATA_PACK16 (0x0) > > +#define CCDC_DATA_PACK12 (0x1) > > +#define CCDC_DATA_PACK8 (0x2) > > +#define CCDC_PIX_ORDER_SHIFT (11) > > +#define CCDC_PIX_ORDER_MASK (0x01) > > +#define CCDC_BW656_ENABLE (0x01<< 5) > > + > > +/* MODESET registers */ > > +#define CCDC_VDHDOUT_INPUT (0x00<< 0) > > +#define CCDC_INPUT_MASK (0x03) > > +#define CCDC_INPUT_SHIFT (12) > > +#define CCDC_RAW_INPUT_MODE (0x00) > > +#define CCDC_FID_POL_MASK (0x01) > > +#define CCDC_FID_POL_SHIFT (4) > > +#define CCDC_HD_POL_MASK (0x01) > > +#define CCDC_HD_POL_SHIFT (3) > > +#define CCDC_VD_POL_MASK (0x01) > > +#define CCDC_VD_POL_SHIFT (2) > > +#define CCDC_DATAPOL_NORMAL (0x00) > > +#define CCDC_DATAPOL_MASK (0x01) > > +#define CCDC_DATAPOL_SHIFT (6) > > +#define CCDC_EXWEN_DISABLE (0x00) > > +#define CCDC_EXWEN_MASK (0x01) > > +#define CCDC_EXWEN_SHIFT (5) > > +#define CCDC_FRM_FMT_MASK (0x01) > > +#define CCDC_FRM_FMT_SHIFT (7) > > +#define CCDC_DATASFT_MASK (0x07) > > +#define CCDC_DATASFT_SHIFT (8) > > +#define CCDC_LPF_SHIFT (14) > > +#define CCDC_LPF_MASK (0x1) > > + > > +/* GAMMAWD registers */ > > +#define CCDC_ALAW_GAMA_WD_MASK (0xf) > > +#define CCDC_ALAW_GAMA_WD_SHIFT (1) > > +#define CCDC_ALAW_ENABLE (0x01) > > +#define CCDC_GAMMAWD_CFA_MASK (0x01) > > +#define CCDC_GAMMAWD_CFA_SHIFT (5) > > + > > +/* HSIZE registers */ > > +#define CCDC_HSIZE_FLIP_MASK (0x01) > > +#define CCDC_HSIZE_FLIP_SHIFT (12) > > +#define CCDC_LINEOFST_MASK (0xfff) > > + > > +/* MISC registers */ > > +#define CCDC_DPCM_EN_SHIFT (12) > > +#define CCDC_DPCM_EN_MASK (1) > > +#define CCDC_DPCM_PREDICTOR_SHIFT (13) > > +#define CCDC_DPCM_PREDICTOR_MASK (1) > > + > > +/* Black clamp related */ > > +#define CCDC_BC_DCOFFSET_MASK (0x1fff) > > +#define CCDC_BC_MODE_COLOR_MASK (1) > > +#define CCDC_BC_MODE_COLOR_SHIFT (4) > > +#define CCDC_HORZ_BC_MODE_MASK (3) > > +#define CCDC_HORZ_BC_MODE_SHIFT (1) > > +#define CCDC_HORZ_BC_WIN_COUNT_MASK (0x1f) > > +#define CCDC_HORZ_BC_WIN_SEL_SHIFT (5) > > +#define CCDC_HORZ_BC_PIX_LIMIT_SHIFT (6) > > +#define CCDC_HORZ_BC_WIN_H_SIZE_MASK (3) > > +#define CCDC_HORZ_BC_WIN_H_SIZE_SHIFT (8) > > +#define CCDC_HORZ_BC_WIN_V_SIZE_MASK (3) > > +#define CCDC_HORZ_BC_WIN_V_SIZE_SHIFT (12) > > +#define CCDC_HORZ_BC_WIN_START_H_MASK (0x1fff) > > +#define CCDC_HORZ_BC_WIN_START_V_MASK (0x1fff) > > +#define CCDC_VERT_BC_OB_H_SZ_MASK (7) > > +#define CCDC_VERT_BC_RST_VAL_SEL_MASK (3) > > +#define CCDC_VERT_BC_RST_VAL_SEL_SHIFT (4) > > +#define CCDC_VERT_BC_LINE_AVE_COEF_SHIFT (8) > > +#define CCDC_VERT_BC_OB_START_HORZ_MASK (0x1fff) > > +#define CCDC_VERT_BC_OB_START_VERT_MASK (0x1fff) > > +#define CCDC_VERT_BC_OB_VERT_SZ_MASK (0x1fff) > > +#define CCDC_VERT_BC_RST_VAL_MASK (0xfff) > > +#define CCDC_BC_VERT_START_SUB_V_MASK (0x1fff) > > + > > +/* VDFC registers */ > > +#define CCDC_VDFC_EN_SHIFT (4) > > +#define CCDC_VDFC_CORR_MOD_MASK (3) > > +#define CCDC_VDFC_CORR_MOD_SHIFT (5) > > +#define CCDC_VDFC_CORR_WHOLE_LN_SHIFT (7) > > +#define CCDC_VDFC_LEVEL_SHFT_MASK (7) > > +#define CCDC_VDFC_LEVEL_SHFT_SHIFT (8) > > +#define CCDC_VDFC_SAT_LEVEL_MASK (0xfff) > > +#define CCDC_VDFC_POS_MASK (0x1fff) > > +#define CCDC_DFCMEMCTL_DFCMARST_SHIFT (2) > > + > > +/* CSC registers */ > > +#define CCDC_CSC_COEF_INTEG_MASK (7) > > +#define CCDC_CSC_COEF_DECIMAL_MASK (0x1f) > > +#define CCDC_CSC_COEF_INTEG_SHIFT (5) > > +#define CCDC_CSCM_MSB_SHIFT (8) > > +#define CCDC_DF_CSC_SPH_MASK (0x1fff) > > +#define CCDC_DF_CSC_LNH_MASK (0x1fff) > > +#define CCDC_DF_CSC_SLV_MASK (0x1fff) > > +#define CCDC_DF_CSC_LNV_MASK (0x1fff) > > +#define CCDC_DF_NUMLINES (0x7fff) > > +#define CCDC_DF_NUMPIX (0x1fff) > > + > > +/* Offsets for LSC/DFC/Gain */ > > +#define CCDC_DATA_H_OFFSET_MASK (0x1fff) > > +#define CCDC_DATA_V_OFFSET_MASK (0x1fff) > > + > > +/* Linearization */ > > +#define CCDC_LIN_CORRSFT_MASK (7) > > +#define CCDC_LIN_CORRSFT_SHIFT (4) > > +#define CCDC_LIN_SCALE_FACT_INTEG_SHIFT (10) > > +#define CCDC_LIN_SCALE_FACT_DECIMAL_MASK (0x3ff) > > +#define CCDC_LIN_ENTRY_MASK (0x3ff) > > + > > +#define CCDC_DF_FMTRLEN_MASK (0x1fff) > > +#define CCDC_DF_FMTHCNT_MASK (0x1fff) > > + > > +/* Pattern registers */ > > +#define CCDC_PG_EN (1<< 3) > > +#define CCDC_SEL_PG_SRC (3<< 4) > > +#define CCDC_PG_VD_POL_SHIFT (0) > > +#define CCDC_PG_HD_POL_SHIFT (1) > > + > > +/*masks and shifts*/ > > +#define CCDC_SYNCEN_VDHDEN_MASK (1<< 0) > > +#define CCDC_SYNCEN_WEN_MASK (1<< 1) > > +#define CCDC_SYNCEN_WEN_SHIFT 1 > > + > > +#endif > > diff --git a/include/linux/dm365_ccdc.h b/include/linux/dm365_ccdc.h > > new file mode 100644 index 0000000..4e50529 > > --- /dev/null > > +++ b/include/linux/dm365_ccdc.h > > @@ -0,0 +1,664 @@ > ... > > +#define VPFE_CMD_S_CCDC_RAW_PARAMS _IOW('V', 1, \ > > + struct ccdc_config_params_raw) > > +#define VPFE_CMD_G_CCDC_RAW_PARAMS _IOR('V', 2, \ > > + struct ccdc_config_params_raw) > > +/** > > + * ccdc float type S8Q8/U8Q8 > > + */ > > +struct ccdc_float_8 { > > + /* 8 bit integer part */ > > + unsigned char integer; > > + /* 8 bit decimal part */ > > + unsigned char decimal; > > +}; > > Isn't it better to use explicit width type, like u8, u16, etc. ? > Then we could just have: > > +struct ccdc_float_8 { > + u8 integer; > + u8 decimal; > +}; > This is an interface header which is also used by apps. So we have kept it as unsigned char. Any suggestions on that? > > > + > > +/** > > + * brief ccdc float type U16Q16/S16Q16 > > > + */ > > +struct ccdc_float_16 { > > + /* 16 bit integer part */ > > + unsigned short integer; > > + /* 16 bit decimal part */ > > + unsigned short decimal; > > +}; > > and > > +struct ccdc_float_16 { > + u16 integer; > + u16 decimal; > +}; > Ditto. > > + > > +/* > > + * ccdc image(target) window parameters */ struct ccdc_cropwin { > > + /* horzontal offset of the top left corner in pixels */ > > + unsigned int left; > > + /* vertical offset of the top left corner in pixels */ > > + unsigned int top; > > + /* width in pixels of the rectangle */ > > + unsigned int width; > > + /* height in lines of the rectangle */ > > + unsigned int height; > > +}; > > How about using struct v4l2_rect instead ? Done. > > ... > > +/** > > + * CCDC image data size > > + */ > > +enum ccdc_data_size { > > + /* 8 bits */ > > + CCDC_8_BITS, > > + /* 9 bits */ > > + CCDC_9_BITS, > > + /* 10 bits */ > > + CCDC_10_BITS, > > + /* 11 bits */ > > + CCDC_11_BITS, > > + /* 12 bits */ > > + CCDC_12_BITS, > > + /* 13 bits */ > > + CCDC_13_BITS, > > + /* 14 bits */ > > + CCDC_14_BITS, > > + /* 15 bits */ > > + CCDC_15_BITS, > > + /* 16 bits */ > > + CCDC_16_BITS > > +}; > > + > > +/** > > + * CCDC image data shift to right > > + */ > > +enum ccdc_datasft { > > + /* No Shift */ > > + CCDC_NO_SHIFT, > > + /* 1 bit Shift */ > > + CCDC_1BIT_SHIFT, > > + /* 2 bit Shift */ > > + CCDC_2BIT_SHIFT, > > + /* 3 bit Shift */ > > + CCDC_3BIT_SHIFT, > > + /* 4 bit Shift */ > > + CCDC_4BIT_SHIFT, > > + /* 5 bit Shift */ > > + CCDC_5BIT_SHIFT, > > + /* 6 bit Shift */ > > + CCDC_6BIT_SHIFT > > +}; > > + > > +/** > > + * MSB of image data connected to sensor port */ enum ccdc_data_msb > > +{ > > + /* MSB b15 */ > > + CCDC_BIT_MSB_15, > > + /* MSB b14 */ > > + CCDC_BIT_MSB_14, > > + /* MSB b13 */ > > + CCDC_BIT_MSB_13, > > + /* MSB b12 */ > > + CCDC_BIT_MSB_12, > > + /* MSB b11 */ > > + CCDC_BIT_MSB_11, > > + /* MSB b10 */ > > + CCDC_BIT_MSB_10, > > + /* MSB b9 */ > > + CCDC_BIT_MSB_9, > > + /* MSB b8 */ > > + CCDC_BIT_MSB_8, > > + /* MSB b7 */ > > + CCDC_BIT_MSB_7 > > Could you live without the comments in these 3 enum declarations ? > They don't seem to add any information. OK. > > > -- > Regards, > Sylwester > > From manjunath.hadli at ti.com Fri Sep 9 08:40:49 2011 From: manjunath.hadli at ti.com (Hadli, Manjunath) Date: Fri, 9 Sep 2011 19:10:49 +0530 Subject: [PATCH v2 0/8] RFC for Media Controller capture driver for DM365 In-Reply-To: <20110831213032.GT12368@valkosipuli.localdomain> References: <1314630439-1122-1-git-send-email-manjunath.hadli@ti.com> <20110831213032.GT12368@valkosipuli.localdomain> Message-ID: Hi Sakari, On Thu, Sep 01, 2011 at 03:00:32, Sakari Ailus wrote: > Hi Manju, > > Do you have the media device grap that would be typical for this hardware produced by media-ctl? That can be converted to postscript using dotfile. > > this would make it a little easier to understan this driver. Thanks. Sure. But can you be a little more elaborate on how you need this information? If you can tell me in little more detail about this that will help me make the information in a way that everyone can understand. Thanks and Regards, -Manju > > On Mon, Aug 29, 2011 at 08:37:11PM +0530, Manjunath Hadli wrote: > > changes from last patch set: > > 1. Made changes based on Sakari's feedback mainly: > > a. returned early to allow unindenting > > b. reformatting to shift the code to left where possible > > c. changed hex numbers to lower case > > d. corrected the defines according to module names. > > e. magic numbers removed. > > f. changed non-integer returning functions to void > > g. removed unwanted paranthses. > > h. fixed error codes. > > i. fixed some RESET_BIt code to what it was intended for. > > 2. reorganized the header files to move the kernel-only headers along > > with the c files and interface headers in the include folder. > > ... From sshtylyov at mvista.com Fri Sep 9 09:56:02 2011 From: sshtylyov at mvista.com (Sergei Shtylyov) Date: Fri, 09 Sep 2011 18:56:02 +0400 Subject: [PATCH v2 1/2] ARM: davinci - fix incorrect offsets and mask usage in psc code In-Reply-To: <4E662FEA.7090908@mvista.com> References: <1314899316-2708-1-git-send-email-m-karicheri2@ti.com> <4E5FD371.1020200@mvista.com> <3E54258959B69E4282D79E01AB1F32B701B2C9@DLEE12.ent.ti.com> <4E617D89.80307@mvista.com> <4E662B93.7080701@mvista.com> <4E662FEA.7090908@mvista.com> Message-ID: <4E6A2902.4000305@mvista.com> Hello. On 09/06/2011 06:36 PM, Sergei Shtylyov wrote: >>>>>>> Signed-off-by: Murali Karicheri >>> [...] >>>>>>> + pdctl = __raw_readl(psc_base + PDCTL + 4 * domain); >>>>>>> + pdctl |= 0x1; >>>>>>> + __raw_writel(pdctl, psc_base + PDCTL + 4 * domain); >>>>>>> >>>>>>> ptcmd = 1<< domain; >>>>>>> __raw_writel(ptcmd, psc_base + PTCMD); >>>>>>> @@ -92,9 +92,10 @@ void davinci_psc_config(unsigned int domain, unsigned >>>>>> int ctlr, >>>>>>> epcpr = __raw_readl(psc_base + EPCPR); >>>>>>> } while ((((epcpr>> domain)& 1) == 0)); >>>>>> Does this work for ARM domain, i.e. does it require an external power >>>>>> supply too? >>>> Not sure. Will someone actively using the DaVinci platforms answer this >>>> question? >>> I may try to verify on my DM6446 if I'll find the time... >> Hmm, DA8x0 documentation doesn't even mention the EPCPR register, so I'm not >> sure how this loop is supposed to work on those chips... unless this path is >> never actually executed -- which I'm trying to check now... > Have verified that the patch was never being executed indeed. If I make it s/patch/path/ > executed, the board happily locks up. I have experimented further and added code to power off domain 1 before powering it on in davinci_psc_config(). Strangely, it worked -- "OMAP-L137 Application Processor System Reference Guide" says that powering off domain 1 is not supported. The board still locks up while polling the EPCPR register -- which doesn't exist on DA8xx. > So looks like this code has even more issues... I think we should add a check for DA8xx before that loop; I'll look into it... WBR, Sergei From sshtylyov at mvista.com Fri Sep 9 10:04:14 2011 From: sshtylyov at mvista.com (Sergei Shtylyov) Date: Fri, 09 Sep 2011 19:04:14 +0400 Subject: [PATCH v2 1/2] ARM: davinci - fix incorrect offsets and mask usage in psc code In-Reply-To: <4E6A2902.4000305@mvista.com> References: <1314899316-2708-1-git-send-email-m-karicheri2@ti.com> <4E5FD371.1020200@mvista.com> <3E54258959B69E4282D79E01AB1F32B701B2C9@DLEE12.ent.ti.com> <4E617D89.80307@mvista.com> <4E662B93.7080701@mvista.com> <4E662FEA.7090908@mvista.com> <4E6A2902.4000305@mvista.com> Message-ID: <4E6A2AEE.6050001@mvista.com> Hello,. On 09/09/2011 06:56 PM, Sergei Shtylyov wrote: >>>>>>>> Signed-off-by: Murali Karicheri >>>> [...] >>>>>>>> + pdctl = __raw_readl(psc_base + PDCTL + 4 * domain); >>>>>>>> + pdctl |= 0x1; >>>>>>>> + __raw_writel(pdctl, psc_base + PDCTL + 4 * domain); >>>>>>>> >>>>>>>> ptcmd = 1<< domain; >>>>>>>> __raw_writel(ptcmd, psc_base + PTCMD); >>>>>>>> @@ -92,9 +92,10 @@ void davinci_psc_config(unsigned int domain, unsigned >>>>>>> int ctlr, >>>>>>>> epcpr = __raw_readl(psc_base + EPCPR); >>>>>>>> } while ((((epcpr>> domain)& 1) == 0)); >>>>>>> Does this work for ARM domain, i.e. does it require an external power >>>>>>> supply too? >>>>> Not sure. Will someone actively using the DaVinci platforms answer this >>>>> question? >>>> I may try to verify on my DM6446 if I'll find the time... >>> Hmm, DA8x0 documentation doesn't even mention the EPCPR register, so I'm not >>> sure how this loop is supposed to work on those chips... unless this path is >>> never actually executed -- which I'm trying to check now... >> Have verified that the patch was never being executed indeed. If I make it > s/patch/path/ >> executed, the board happily locks up. > I have experimented further and added code to power off domain 1 before powering > it on in davinci_psc_config(). Strangely, it worked -- "OMAP-L137 Application > Processor System Reference Guide" says that powering off domain 1 is not > supported. The board still locks up while polling the EPCPR register -- which > doesn't exist on DA8xx. BTW, I have tried the same on the DM6446 EVM board and there it locked up while polling the PTSTAT register after sent command to I power down the DSP domain. This seems to be in accordance with DM6446 datasheet which says that once powered on, DSP domain cannot be dynamically powered off. So I couldn't test the EPCPR polling loop on DM6446... WBR, Sergei From sakari.ailus at iki.fi Fri Sep 9 11:19:40 2011 From: sakari.ailus at iki.fi (Sakari Ailus) Date: Fri, 9 Sep 2011 19:19:40 +0300 Subject: [PATCH v2 0/8] RFC for Media Controller capture driver for DM365 In-Reply-To: References: <1314630439-1122-1-git-send-email-manjunath.hadli@ti.com> <20110831213032.GT12368@valkosipuli.localdomain> Message-ID: <20110909161940.GJ1724@valkosipuli.localdomain> On Fri, Sep 09, 2011 at 07:10:49PM +0530, Hadli, Manjunath wrote: > Hi Sakari, > > On Thu, Sep 01, 2011 at 03:00:32, Sakari Ailus wrote: > > Hi Manju, > > > > Do you have the media device grap that would be typical for this hardware produced by media-ctl? That can be converted to postscript using dotfile. > > > > this would make it a little easier to understan this driver. Thanks. > > Sure. But can you be a little more elaborate on how you need this > information? If you can tell me in little more detail about this that will > help me make the information in a way that everyone can understand. Preferrably in PostScript format so it's easy to visualise the layout of the hardware that the driver supports, as the OMAP 3 ISP example was. > Thanks and Regards, > -Manju > > > > > > On Mon, Aug 29, 2011 at 08:37:11PM +0530, Manjunath Hadli wrote: > > > changes from last patch set: > > > 1. Made changes based on Sakari's feedback mainly: > > > a. returned early to allow unindenting > > > b. reformatting to shift the code to left where possible > > > c. changed hex numbers to lower case > > > d. corrected the defines according to module names. > > > e. magic numbers removed. > > > f. changed non-integer returning functions to void > > > g. removed unwanted paranthses. > > > h. fixed error codes. > > > i. fixed some RESET_BIt code to what it was intended for. > > > 2. reorganized the header files to move the kernel-only headers along > > > with the c files and interface headers in the include folder. > > > > ... > > -- Sakari Ailus e-mail: sakari.ailus at iki.fi jabber/XMPP/Gmail: sailus at retiisi.org.uk From snjw23 at gmail.com Fri Sep 9 11:39:38 2011 From: snjw23 at gmail.com (Sylwester Nawrocki) Date: Fri, 09 Sep 2011 18:39:38 +0200 Subject: [PATCH v2 4/8] davinci: vpfe: add support for CCDC hardware for dm365 In-Reply-To: References: <1314630439-1122-1-git-send-email-manjunath.hadli@ti.com> <1314630439-1122-5-git-send-email-manjunath.hadli@ti.com> <4E5FF7BC.3040108@gmail.com> Message-ID: <4E6A414A.8070207@gmail.com> Hi Manju, On 09/09/2011 03:30 PM, Hadli, Manjunath wrote: > Thank you for these comments too. > > My responses inlined. > -Manju Thanks for addressing my comments. > > On Fri, Sep 02, 2011 at 02:53:08, Sylwester Nawrocki wrote: ... >>> +/** >>> + * ccdc float type S8Q8/U8Q8 >>> + */ >>> +struct ccdc_float_8 { >>> + /* 8 bit integer part */ >>> + unsigned char integer; >>> + /* 8 bit decimal part */ >>> + unsigned char decimal; >>> +}; >> >> Isn't it better to use explicit width type, like u8, u16, etc. ? >> Then we could just have: >> >> +struct ccdc_float_8 { >> + u8 integer; >> + u8 decimal; >> +}; >> > This is an interface header which is also used by apps. So we have > kept it as unsigned char. Any suggestions on that? OK, sorry, I haven't noticed that. Anyway, I think you could use the double underscore prefixed types (__[u,s][8,32,16]), from linux/types.h. They are widely used in in linux/videodev2.h for instance. -- Regards, Sylwester From BNiebuhr at efjohnson.com Fri Sep 9 13:53:09 2011 From: BNiebuhr at efjohnson.com (Brian Niebuhr) Date: Fri, 9 Sep 2011 13:53:09 -0500 Subject: L138/DA850 USB support in mainline? Message-ID: What is the current level of support for USB on L138/DA850 in the mainline kernel? A similar question was asked here: http://linux.davincidsp.com/pipermail/davinci-linux-open-source/2011-Jul y/023201.html but not really answered. I'm curious because TI's site at: http://processors.wiki.ti.com/index.php/DaVinci_GIT_Linux_Kernel seems to suggest that USB is still not there, but from reading forum posts it seems as if people are using USB on L138/DA850 with mainline kernels. We are currently using a TI release, but I would like to migrate to a mainline version. USB appears to be the only questionable feature at this point. Can anyone clarify what support might be missing before I take the time to make the jump, only to find out that it's not going to work anyway? I don't mind doing some work to glue pieces together, but if major functionality is missing, it would be nice to know beforehand. Thanks for the help! Brian ____________________ Brian Niebuhr Principal Design Engineer EF Johnson 3900 NW 12th St. Ste. 200 Lincoln, NE 68521 402-479-8434 From bengardiner at nanometrics.ca Fri Sep 9 16:06:05 2011 From: bengardiner at nanometrics.ca (Ben Gardiner) Date: Fri, 9 Sep 2011 17:06:05 -0400 Subject: [PATCH] ASoC: davinci-pcm: trivial: replace link with actual chan/link Message-ID: <1315602365-30105-1-git-send-email-bengardiner@nanometrics.ca> The ambiguously named variable 'link' is used as a temporary throughout davinci-pcm -- its presence makes grepping (and groking) the code difficult. Replace link with the value of link in almost all sites. The exception is a couple places where the last-assigned link/chan needs to be returned by a function -- in these cases, rename to last_link. Signed-off-by: Ben Gardiner --- sound/soc/davinci/davinci-pcm.c | 123 +++++++++++++++++++-------------------- 1 files changed, 59 insertions(+), 64 deletions(-) diff --git a/sound/soc/davinci/davinci-pcm.c b/sound/soc/davinci/davinci-pcm.c index a49e667..d5fe08c 100644 --- a/sound/soc/davinci/davinci-pcm.c +++ b/sound/soc/davinci/davinci-pcm.c @@ -180,7 +180,6 @@ static void davinci_pcm_enqueue_dma(struct snd_pcm_substream *substream) { struct davinci_runtime_data *prtd = substream->runtime->private_data; struct snd_pcm_runtime *runtime = substream->runtime; - int link = prtd->asp_link[0]; unsigned int period_size; unsigned int dma_offset; dma_addr_t dma_pos; @@ -198,7 +197,8 @@ static void davinci_pcm_enqueue_dma(struct snd_pcm_substream *substream) fifo_level = prtd->params->fifo_level; pr_debug("davinci_pcm: audio_set_dma_params_play channel = %d " - "dma_ptr = %x period_size=%x\n", link, dma_pos, period_size); + "dma_ptr = %x period_size=%x\n", prtd->asp_link[0], dma_pos, + period_size); data_type = prtd->params->data_type; count = period_size / data_type; @@ -222,17 +222,19 @@ static void davinci_pcm_enqueue_dma(struct snd_pcm_substream *substream) } acnt = prtd->params->acnt; - edma_set_src(link, src, INCR, W8BIT); - edma_set_dest(link, dst, INCR, W8BIT); + edma_set_src(prtd->asp_link[0], src, INCR, W8BIT); + edma_set_dest(prtd->asp_link[0], dst, INCR, W8BIT); - edma_set_src_index(link, src_bidx, src_cidx); - edma_set_dest_index(link, dst_bidx, dst_cidx); + edma_set_src_index(prtd->asp_link[0], src_bidx, src_cidx); + edma_set_dest_index(prtd->asp_link[0], dst_bidx, dst_cidx); if (!fifo_level) - edma_set_transfer_params(link, acnt, count, 1, 0, ASYNC); + edma_set_transfer_params(prtd->asp_link[0], acnt, count, 1, 0, + ASYNC); else - edma_set_transfer_params(link, acnt, fifo_level, count, - fifo_level, ABSYNC); + edma_set_transfer_params(prtd->asp_link[0], acnt, fifo_level, + count, fifo_level, + ABSYNC); } static void davinci_pcm_dma_irq(unsigned link, u16 ch_status, void *data) @@ -305,7 +307,6 @@ static int ping_pong_dma_setup(struct snd_pcm_substream *substream) unsigned int acnt = params->acnt; /* divide by 2 for ping/pong */ unsigned int ping_size = snd_pcm_lib_period_bytes(substream) >> 1; - int link = prtd->asp_link[1]; unsigned int fifo_level = prtd->params->fifo_level; unsigned int count; if ((data_type == 0) || (data_type > 4)) { @@ -316,28 +317,26 @@ static int ping_pong_dma_setup(struct snd_pcm_substream *substream) dma_addr_t asp_src_pong = iram_dma->addr + ping_size; ram_src_cidx = ping_size; ram_dst_cidx = -ping_size; - edma_set_src(link, asp_src_pong, INCR, W8BIT); + edma_set_src(prtd->asp_link[1], asp_src_pong, INCR, W8BIT); - link = prtd->asp_link[0]; - edma_set_src_index(link, data_type, data_type * fifo_level); - link = prtd->asp_link[1]; - edma_set_src_index(link, data_type, data_type * fifo_level); + edma_set_src_index(prtd->asp_link[0], data_type, + data_type * fifo_level); + edma_set_src_index(prtd->asp_link[1], data_type, + data_type * fifo_level); - link = prtd->ram_link; - edma_set_src(link, runtime->dma_addr, INCR, W32BIT); + edma_set_src(prtd->ram_link, runtime->dma_addr, INCR, W32BIT); } else { dma_addr_t asp_dst_pong = iram_dma->addr + ping_size; ram_src_cidx = -ping_size; ram_dst_cidx = ping_size; - edma_set_dest(link, asp_dst_pong, INCR, W8BIT); + edma_set_dest(prtd->asp_link[1], asp_dst_pong, INCR, W8BIT); - link = prtd->asp_link[0]; - edma_set_dest_index(link, data_type, data_type * fifo_level); - link = prtd->asp_link[1]; - edma_set_dest_index(link, data_type, data_type * fifo_level); + edma_set_dest_index(prtd->asp_link[0], data_type, + data_type * fifo_level); + edma_set_dest_index(prtd->asp_link[1], data_type, + data_type * fifo_level); - link = prtd->ram_link; - edma_set_dest(link, runtime->dma_addr, INCR, W32BIT); + edma_set_dest(prtd->ram_link, runtime->dma_addr, INCR, W32BIT); } if (!fifo_level) { @@ -354,10 +353,9 @@ static int ping_pong_dma_setup(struct snd_pcm_substream *substream) count, fifo_level, ABSYNC); } - link = prtd->ram_link; - edma_set_src_index(link, ping_size, ram_src_cidx); - edma_set_dest_index(link, ping_size, ram_dst_cidx); - edma_set_transfer_params(link, ping_size, 2, + edma_set_src_index(prtd->ram_link, ping_size, ram_src_cidx); + edma_set_dest_index(prtd->ram_link, ping_size, ram_dst_cidx); + edma_set_transfer_params(prtd->ram_link, ping_size, 2, runtime->periods, 2, ASYNC); /* init master params */ @@ -406,32 +404,32 @@ static int request_ping_pong(struct snd_pcm_substream *substream, { dma_addr_t asp_src_ping; dma_addr_t asp_dst_ping; - int link; + int ret; struct davinci_pcm_dma_params *params = prtd->params; /* Request ram master channel */ - link = prtd->ram_channel = edma_alloc_channel(EDMA_CHANNEL_ANY, + ret = prtd->ram_channel = edma_alloc_channel(EDMA_CHANNEL_ANY, davinci_pcm_dma_irq, substream, prtd->params->ram_chan_q); - if (link < 0) + if (ret < 0) goto exit1; /* Request ram link channel */ - link = prtd->ram_link = edma_alloc_slot( + ret = prtd->ram_link = edma_alloc_slot( EDMA_CTLR(prtd->ram_channel), EDMA_SLOT_ANY); - if (link < 0) + if (ret < 0) goto exit2; - link = prtd->asp_link[1] = edma_alloc_slot( + ret = prtd->asp_link[1] = edma_alloc_slot( EDMA_CTLR(prtd->asp_channel), EDMA_SLOT_ANY); - if (link < 0) + if (ret < 0) goto exit3; prtd->ram_link2 = -1; if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { - link = prtd->ram_link2 = edma_alloc_slot( + ret = prtd->ram_link2 = edma_alloc_slot( EDMA_CTLR(prtd->ram_channel), EDMA_SLOT_ANY); - if (link < 0) + if (ret < 0) goto exit4; } /* circle ping-pong buffers */ @@ -448,36 +446,33 @@ static int request_ping_pong(struct snd_pcm_substream *substream, asp_dst_ping = iram_dma->addr; } /* ping */ - link = prtd->asp_link[0]; - edma_set_src(link, asp_src_ping, INCR, W16BIT); - edma_set_dest(link, asp_dst_ping, INCR, W16BIT); - edma_set_src_index(link, 0, 0); - edma_set_dest_index(link, 0, 0); + edma_set_src(prtd->asp_link[0], asp_src_ping, INCR, W16BIT); + edma_set_dest(prtd->asp_link[0], asp_dst_ping, INCR, W16BIT); + edma_set_src_index(prtd->asp_link[0], 0, 0); + edma_set_dest_index(prtd->asp_link[0], 0, 0); - edma_read_slot(link, &prtd->asp_params); + edma_read_slot(prtd->asp_link[0], &prtd->asp_params); prtd->asp_params.opt &= ~(TCCMODE | EDMA_TCC(0x3f) | TCINTEN); prtd->asp_params.opt |= TCCHEN | EDMA_TCC(prtd->ram_channel & 0x3f); - edma_write_slot(link, &prtd->asp_params); + edma_write_slot(prtd->asp_link[0], &prtd->asp_params); /* pong */ - link = prtd->asp_link[1]; - edma_set_src(link, asp_src_ping, INCR, W16BIT); - edma_set_dest(link, asp_dst_ping, INCR, W16BIT); - edma_set_src_index(link, 0, 0); - edma_set_dest_index(link, 0, 0); + edma_set_src(prtd->asp_link[1], asp_src_ping, INCR, W16BIT); + edma_set_dest(prtd->asp_link[1], asp_dst_ping, INCR, W16BIT); + edma_set_src_index(prtd->asp_link[1], 0, 0); + edma_set_dest_index(prtd->asp_link[1], 0, 0); - edma_read_slot(link, &prtd->asp_params); + edma_read_slot(prtd->asp_link[1], &prtd->asp_params); prtd->asp_params.opt &= ~(TCCMODE | EDMA_TCC(0x3f)); /* interrupt after every pong completion */ prtd->asp_params.opt |= TCINTEN | TCCHEN | EDMA_TCC(prtd->ram_channel & 0x3f); - edma_write_slot(link, &prtd->asp_params); + edma_write_slot(prtd->asp_link[1], &prtd->asp_params); /* ram */ - link = prtd->ram_link; - edma_set_src(link, iram_dma->addr, INCR, W32BIT); - edma_set_dest(link, iram_dma->addr, INCR, W32BIT); + edma_set_src(prtd->ram_link, iram_dma->addr, INCR, W32BIT); + edma_set_dest(prtd->ram_link, iram_dma->addr, INCR, W32BIT); pr_debug("%s: audio dma channels/slots in use for ram:%u %u %u," "for asp:%u %u %u\n", __func__, prtd->ram_channel, prtd->ram_link, prtd->ram_link2, @@ -494,7 +489,7 @@ exit2: edma_free_channel(prtd->ram_channel); prtd->ram_channel = -1; exit1: - return link; + return ret; } static int davinci_pcm_dma_request(struct snd_pcm_substream *substream) @@ -502,22 +497,22 @@ static int davinci_pcm_dma_request(struct snd_pcm_substream *substream) struct snd_dma_buffer *iram_dma; struct davinci_runtime_data *prtd = substream->runtime->private_data; struct davinci_pcm_dma_params *params = prtd->params; - int link; + int ret; if (!params) return -ENODEV; /* Request asp master DMA channel */ - link = prtd->asp_channel = edma_alloc_channel(params->channel, + ret = prtd->asp_channel = edma_alloc_channel(params->channel, davinci_pcm_dma_irq, substream, prtd->params->asp_chan_q); - if (link < 0) + if (ret < 0) goto exit1; /* Request asp link channels */ - link = prtd->asp_link[0] = edma_alloc_slot( + ret = prtd->asp_link[0] = edma_alloc_slot( EDMA_CTLR(prtd->asp_channel), EDMA_SLOT_ANY); - if (link < 0) + if (ret < 0) goto exit2; iram_dma = (struct snd_dma_buffer *)substream->dma_buffer.private_data; @@ -537,17 +532,17 @@ static int davinci_pcm_dma_request(struct snd_pcm_substream *substream) * the buffer and its length (ccnt) ... use it as a template * so davinci_pcm_enqueue_dma() takes less time in IRQ. */ - edma_read_slot(link, &prtd->asp_params); + edma_read_slot(prtd->asp_link[0], &prtd->asp_params); prtd->asp_params.opt |= TCINTEN | EDMA_TCC(EDMA_CHAN_SLOT(prtd->asp_channel)); - prtd->asp_params.link_bcntrld = EDMA_CHAN_SLOT(link) << 5; - edma_write_slot(link, &prtd->asp_params); + prtd->asp_params.link_bcntrld = EDMA_CHAN_SLOT(prtd->asp_link[0]) << 5; + edma_write_slot(prtd->asp_link[0], &prtd->asp_params); return 0; exit2: edma_free_channel(prtd->asp_channel); prtd->asp_channel = -1; exit1: - return link; + return ret; } static int davinci_pcm_trigger(struct snd_pcm_substream *substream, int cmd) -- 1.7.4.1 From manjunath.hadli at ti.com Sat Sep 10 01:41:37 2011 From: manjunath.hadli at ti.com (Hadli, Manjunath) Date: Sat, 10 Sep 2011 12:11:37 +0530 Subject: [PATCH v2 0/8] RFC for Media Controller capture driver for DM365 In-Reply-To: <20110909161940.GJ1724@valkosipuli.localdomain> References: <1314630439-1122-1-git-send-email-manjunath.hadli@ti.com> <20110831213032.GT12368@valkosipuli.localdomain> <20110909161940.GJ1724@valkosipuli.localdomain> Message-ID: Hi Sakari, On Fri, Sep 09, 2011 at 21:49:40, Sakari Ailus wrote: > On Fri, Sep 09, 2011 at 07:10:49PM +0530, Hadli, Manjunath wrote: > > Hi Sakari, > > > > On Thu, Sep 01, 2011 at 03:00:32, Sakari Ailus wrote: > > > Hi Manju, > > > > > > Do you have the media device grap that would be typical for this hardware produced by media-ctl? That can be converted to postscript using dotfile. > > > > > > this would make it a little easier to understan this driver. Thanks. > > > > Sure. But can you be a little more elaborate on how you need this > > information? If you can tell me in little more detail about this that > > will help me make the information in a way that everyone can understand. > > Preferrably in PostScript format so it's easy to visualise the layout of the hardware that the driver supports, as the OMAP 3 ISP example was. Sure. I was more looking for an example of the same so it could help me put the data together in the way it has been done before. Can you send across if you have one? Many Thx, -Manju > > > Thanks and Regards, > > -Manju > > > > > > > > > > On Mon, Aug 29, 2011 at 08:37:11PM +0530, Manjunath Hadli wrote: > > > > changes from last patch set: > > > > 1. Made changes based on Sakari's feedback mainly: > > > > a. returned early to allow unindenting > > > > b. reformatting to shift the code to left where possible > > > > c. changed hex numbers to lower case > > > > d. corrected the defines according to module names. > > > > e. magic numbers removed. > > > > f. changed non-integer returning functions to void > > > > g. removed unwanted paranthses. > > > > h. fixed error codes. > > > > i. fixed some RESET_BIt code to what it was intended for. > > > > 2. reorganized the header files to move the kernel-only headers > > > > along with the c files and interface headers in the include folder. > > > > > > ... > > > > > > -- > Sakari Ailus > e-mail: sakari.ailus at iki.fi jabber/XMPP/Gmail: sailus at retiisi.org.uk > From gary at mlbassoc.com Sat Sep 10 08:06:27 2011 From: gary at mlbassoc.com (Gary Thomas) Date: Sat, 10 Sep 2011 07:06:27 -0600 Subject: L138/DA850 USB support in mainline? In-Reply-To: References: Message-ID: <4E6B60D3.1020908@mlbassoc.com> On 2011-09-09 12:53, Brian Niebuhr wrote: > What is the current level of support for USB on L138/DA850 in the > mainline kernel? A similar question was asked here: > > http://linux.davincidsp.com/pipermail/davinci-linux-open-source/2011-Jul > y/023201.html > > but not really answered. I'm curious because TI's site at: > > http://processors.wiki.ti.com/index.php/DaVinci_GIT_Linux_Kernel > > seems to suggest that USB is still not there, but from reading forum > posts it seems as if people are using USB on L138/DA850 with mainline > kernels. > > We are currently using a TI release, but I would like to migrate to a > mainline version. USB appears to be the only questionable feature at > this point. Can anyone clarify what support might be missing before I > take the time to make the jump, only to find out that it's not going to > work anyway? I don't mind doing some work to glue pieces together, but > if major functionality is missing, it would be nice to know beforehand. I was able to add USB-2.0 support for my board with just a few lines in my board support file. My board is not public, but if you contact me directly, I can show you what I did. -- ------------------------------------------------------------ Gary Thomas | Consulting for the MLB Associates | Embedded world ------------------------------------------------------------ From arnd at arndb.de Sat Sep 10 16:22:23 2011 From: arnd at arndb.de (Arnd Bergmann) Date: Sat, 10 Sep 2011 23:22:23 +0200 Subject: [GIT PULL] DaVinci fixes for v3.1-rc6 In-Reply-To: References: Message-ID: <201109102322.23671.arnd@arndb.de> On Wednesday 07 September 2011, Nori, Sekhar wrote: > Can you please pull the following fixes for v3.1-rc6? > > These are not regression fixes in the strict sense since > none of the bugs were actually introduced in v3.1 and have > been around for a while. But I hope we don't have to wait > till v3.2 for these. > Ok, pulled into the fixes branch for 3.2 now. I've finally decided to move the arm-soc tree to git.linaro.org while waiting for master.kernel.org to come back. Thanks, Arnd From sakari.ailus at iki.fi Mon Sep 12 06:59:25 2011 From: sakari.ailus at iki.fi (Sakari Ailus) Date: Mon, 12 Sep 2011 14:59:25 +0300 Subject: [PATCH v2 0/8] RFC for Media Controller capture driver for DM365 In-Reply-To: References: <1314630439-1122-1-git-send-email-manjunath.hadli@ti.com> <20110831213032.GT12368@valkosipuli.localdomain> <20110909161940.GJ1724@valkosipuli.localdomain> Message-ID: <20110912115925.GC1716@valkosipuli.localdomain> On Sat, Sep 10, 2011 at 12:11:37PM +0530, Hadli, Manjunath wrote: > Hi Sakari, > On Fri, Sep 09, 2011 at 21:49:40, Sakari Ailus wrote: > > On Fri, Sep 09, 2011 at 07:10:49PM +0530, Hadli, Manjunath wrote: > > > Hi Sakari, > > > > > > On Thu, Sep 01, 2011 at 03:00:32, Sakari Ailus wrote: > > > > Hi Manju, > > > > > > > > Do you have the media device grap that would be typical for this hardware produced by media-ctl? That can be converted to postscript using dotfile. > > > > > > > > this would make it a little easier to understan this driver. Thanks. > > > > > > Sure. But can you be a little more elaborate on how you need this > > > information? If you can tell me in little more detail about this that > > > will help me make the information in a way that everyone can understand. > > > > Preferrably in PostScript format so it's easy to visualise the layout of the hardware that the driver supports, as the OMAP 3 ISP example was. > Sure. > I was more looking for an example of the same so it could help me put the > data together in the way it has been done before. Can you send across if > you have one? Ah. I think I misunderstood you first. :-) On the device, run $ media-ctl --print-dot > graph.dot This will produce a graph of the media device in the dot format. This is then processed by program called dot: $ dot -o graph.ps -T ps < graph.dot dot is available at least in Debian in a package called graphviz. Cheers, -- Sakari Ailus e-mail: sakari.ailus at iki.fi jabber/XMPP/Gmail: sailus at retiisi.org.uk From nsekhar at ti.com Mon Sep 12 07:47:30 2011 From: nsekhar at ti.com (Nori, Sekhar) Date: Mon, 12 Sep 2011 18:17:30 +0530 Subject: [PATCH v2 1/2] ARM: davinci - fix incorrect offsets and mask usage in psc code In-Reply-To: <4E67B570.80100@mvista.com> References: <1314899316-2708-1-git-send-email-m-karicheri2@ti.com> <4E5FD371.1020200@mvista.com> <4E6785C0.7010709@mvista.com> <3E54258959B69E4282D79E01AB1F32B701B8A7@DLEE12.ent.ti.com> <4E67B570.80100@mvista.com> Message-ID: Hi Murali, On Wed, Sep 07, 2011 at 23:48:24, Sergei Shtylyov wrote: > On 09/07/2011 07:32 PM, Karicheri, Muralidharan wrote: > > Sergei, > > > Thanks for all your investigation work and comments. I will take care of your recent comments against v2 in v3. Looks like the mask is being corrected by a different Patch (ARM: davinci: correct MDSTAT_STATE_MASK) and I can remove the same from my patch. > > This is a different register, MDSTAT vs PDSTAT in our case... I also suggest moving the mask fix into another patch. Thanks, Sekhar From manjunath.hadli at ti.com Mon Sep 12 09:09:03 2011 From: manjunath.hadli at ti.com (Manjunath Hadli) Date: Mon, 12 Sep 2011 19:39:03 +0530 Subject: [RFC PATCH 0/4] davinci vpbe: enable DM365 v4l2 display driver Message-ID: <1315836547-20658-1-git-send-email-manjunath.hadli@ti.com> The patchset adds incremental changes necessary to enable dm365 v4l2 display driver, which includes vpbe display driver changes, osd specific changes and venc changes. The changes are incremental in nature,addind a few HD modes, and taking care of register level changes. The patch set does not include THS7303 amplifier driver which is planned to be sent seperately. Manjunath Hadli (4): davinci vpbe: remove unused macro. davinci vpbe: add dm365 VPBE display driver changes davinci vpbe: add dm365 and dm355 specific OSD changes davinci vpbe: add VENC block changes to enable dm365 and dm355 drivers/media/video/davinci/vpbe.c | 55 +++- drivers/media/video/davinci/vpbe_display.c | 1 - drivers/media/video/davinci/vpbe_osd.c | 474 +++++++++++++++++++++++++--- drivers/media/video/davinci/vpbe_venc.c | 205 +++++++++++-- include/media/davinci/vpbe.h | 16 + include/media/davinci/vpbe_venc.h | 4 + 6 files changed, 686 insertions(+), 69 deletions(-) From manjunath.hadli at ti.com Mon Sep 12 09:09:05 2011 From: manjunath.hadli at ti.com (Manjunath Hadli) Date: Mon, 12 Sep 2011 19:39:05 +0530 Subject: [RFC PATCH 2/4] davinci vpbe: add dm365 VPBE display driver changes In-Reply-To: <1315836547-20658-1-git-send-email-manjunath.hadli@ti.com> References: <1315836547-20658-1-git-send-email-manjunath.hadli@ti.com> Message-ID: <1315836547-20658-3-git-send-email-manjunath.hadli@ti.com> This patch implements the core additions to the display driver, mainly controlling the VENC and other encoders for dm365. This patch also includes addition of amplifier subdevice to the vpbe driver and interfacing with venc subdevice. Signed-off-by: Manjunath Hadli --- drivers/media/video/davinci/vpbe.c | 55 ++++++++++++++++++++++++++++++++++-- include/media/davinci/vpbe.h | 16 ++++++++++ 2 files changed, 68 insertions(+), 3 deletions(-) diff --git a/drivers/media/video/davinci/vpbe.c b/drivers/media/video/davinci/vpbe.c index d773d30..21a8645 100644 --- a/drivers/media/video/davinci/vpbe.c +++ b/drivers/media/video/davinci/vpbe.c @@ -141,11 +141,12 @@ static int vpbe_enum_outputs(struct vpbe_device *vpbe_dev, return 0; } -static int vpbe_get_mode_info(struct vpbe_device *vpbe_dev, char *mode) +static int vpbe_get_mode_info(struct vpbe_device *vpbe_dev, char *mode, + int output_index) { struct vpbe_config *cfg = vpbe_dev->cfg; struct vpbe_enc_mode_info var; - int curr_output = vpbe_dev->current_out_index; + int curr_output = output_index; int i; if (NULL == mode) @@ -245,6 +246,8 @@ static int vpbe_set_output(struct vpbe_device *vpbe_dev, int index) struct encoder_config_info *curr_enc_info = vpbe_current_encoder_info(vpbe_dev); struct vpbe_config *cfg = vpbe_dev->cfg; + struct venc_platform_data *venc_device = vpbe_dev->venc_device; + enum v4l2_mbus_pixelcode if_params; int enc_out_index; int sd_index; int ret = 0; @@ -274,6 +277,8 @@ static int vpbe_set_output(struct vpbe_device *vpbe_dev, int index) goto out; } + if_params = cfg->outputs[index].if_params; + venc_device->setup_if_config(if_params); if (ret) goto out; } @@ -293,7 +298,7 @@ static int vpbe_set_output(struct vpbe_device *vpbe_dev, int index) * encoder. */ ret = vpbe_get_mode_info(vpbe_dev, - cfg->outputs[index].default_mode); + cfg->outputs[index].default_mode, index); if (!ret) { struct osd_state *osd_device = vpbe_dev->osd_device; @@ -367,6 +372,11 @@ static int vpbe_s_dv_preset(struct vpbe_device *vpbe_dev, ret = v4l2_subdev_call(vpbe_dev->encoders[sd_index], video, s_dv_preset, dv_preset); + if (!ret && (vpbe_dev->amp != NULL)) { + /* Call amplifier subdevice */ + ret = v4l2_subdev_call(vpbe_dev->amp, video, + s_dv_preset, dv_preset); + } /* set the lcd controller output for the given mode */ if (!ret) { struct osd_state *osd_device = vpbe_dev->osd_device; @@ -566,6 +576,8 @@ static int platform_device_get(struct device *dev, void *data) if (strcmp("vpbe-osd", pdev->name) == 0) vpbe_dev->osd_device = platform_get_drvdata(pdev); + if (strcmp("vpbe-venc", pdev->name) == 0) + vpbe_dev->venc_device = dev_get_platdata(&pdev->dev); return 0; } @@ -584,6 +596,7 @@ static int platform_device_get(struct device *dev, void *data) static int vpbe_initialize(struct device *dev, struct vpbe_device *vpbe_dev) { struct encoder_config_info *enc_info; + struct amp_config_info *amp_info; struct v4l2_subdev **enc_subdev; struct osd_state *osd_device; struct i2c_adapter *i2c_adap; @@ -704,6 +717,39 @@ static int vpbe_initialize(struct device *dev, struct vpbe_device *vpbe_dev) v4l2_warn(&vpbe_dev->v4l2_dev, "non-i2c encoders" " currently not supported"); } + /* Add amplifier subdevice for dm365 */ + if ((strcmp(vpbe_dev->cfg->module_name, "dm365-vpbe-display") == 0) && + vpbe_dev->cfg->amp != NULL) { + vpbe_dev->amp = kmalloc(sizeof(struct v4l2_subdev *), + GFP_KERNEL); + if (vpbe_dev->amp == NULL) { + v4l2_err(&vpbe_dev->v4l2_dev, + "unable to allocate memory for sub device"); + ret = -ENOMEM; + goto vpbe_fail_v4l2_device; + } + amp_info = vpbe_dev->cfg->amp; + if (amp_info->is_i2c) { + vpbe_dev->amp = v4l2_i2c_new_subdev_board( + &vpbe_dev->v4l2_dev, i2c_adap, + &_info->board_info, NULL); + if (!vpbe_dev->amp) { + v4l2_err(&vpbe_dev->v4l2_dev, + "amplifier %s failed to register", + amp_info->module_name); + ret = -ENODEV; + goto vpbe_fail_amp_register; + } + v4l2_info(&vpbe_dev->v4l2_dev, + "v4l2 sub device %s registered\n", + amp_info->module_name); + } else { + vpbe_dev->amp = NULL; + v4l2_warn(&vpbe_dev->v4l2_dev, "non-i2c amplifiers" + " currently not supported"); + } + } else + vpbe_dev->amp = NULL; /* set the current encoder and output to that of venc by default */ vpbe_dev->current_sd_index = 0; @@ -731,6 +777,8 @@ static int vpbe_initialize(struct device *dev, struct vpbe_device *vpbe_dev) /* TBD handling of bootargs for default output and mode */ return 0; +vpbe_fail_amp_register: + kfree(vpbe_dev->amp); vpbe_fail_sd_register: kfree(vpbe_dev->encoders); vpbe_fail_v4l2_device: @@ -757,6 +805,7 @@ static void vpbe_deinitialize(struct device *dev, struct vpbe_device *vpbe_dev) if (strcmp(vpbe_dev->cfg->module_name, "dm644x-vpbe-display") != 0) clk_put(vpbe_dev->dac_clk); + kfree(vpbe_dev->amp); kfree(vpbe_dev->encoders); vpbe_dev->initialized = 0; /* disable vpss clocks */ diff --git a/include/media/davinci/vpbe.h b/include/media/davinci/vpbe.h index 8b11fb0..8bc1b3c 100644 --- a/include/media/davinci/vpbe.h +++ b/include/media/davinci/vpbe.h @@ -63,6 +63,7 @@ struct vpbe_output { * output basis. If per mode is needed, we may have to move this to * mode_info structure */ + enum v4l2_mbus_pixelcode if_params; }; /* encoder configuration info */ @@ -74,6 +75,15 @@ struct encoder_config_info { struct i2c_board_info board_info; }; +/*amplifier configuration info */ +struct amp_config_info { + char module_name[32]; + /* Is this an i2c device ? */ + unsigned int is_i2c:1; + /* i2c subdevice board info */ + struct i2c_board_info board_info; +}; + /* structure for defining vpbe display subsystem components */ struct vpbe_config { char module_name[32]; @@ -84,6 +94,8 @@ struct vpbe_config { /* external encoder information goes here */ int num_ext_encoders; struct encoder_config_info *ext_encoders; + /* amplifier information goes here */ + struct amp_config_info *amp; int num_outputs; /* Order is venc outputs followed by LCD and then external encoders */ struct vpbe_output *outputs; @@ -158,6 +170,8 @@ struct vpbe_device { struct v4l2_subdev **encoders; /* current encoder index */ int current_sd_index; + /* external amplifier v4l2 subdevice */ + struct v4l2_subdev *amp; struct mutex lock; /* device initialized */ int initialized; @@ -165,6 +179,8 @@ struct vpbe_device { struct clk *dac_clk; /* osd_device pointer */ struct osd_state *osd_device; + /* venc device pointer */ + struct venc_platform_data *venc_device; /* * fields below are accessed by users of vpbe_device. Not the * ones above -- 1.6.2.4 From manjunath.hadli at ti.com Mon Sep 12 09:09:07 2011 From: manjunath.hadli at ti.com (Manjunath Hadli) Date: Mon, 12 Sep 2011 19:39:07 +0530 Subject: [RFC PATCH 4/4] davinci vpbe: add VENC block changes to enable dm365 and dm355 In-Reply-To: <1315836547-20658-1-git-send-email-manjunath.hadli@ti.com> References: <1315836547-20658-1-git-send-email-manjunath.hadli@ti.com> Message-ID: <1315836547-20658-5-git-send-email-manjunath.hadli@ti.com> This patch implements necessary changes for enabling dm365 and dm355 hardware for vpbe. The patch contains additional HD mode support for dm365 (720p60, 1080i30) and appropriate register modifications based on version numbers. VPBE_VERSION_2 = dm365 specific VPBE_VERSION_3 = dm355 specific Signed-off-by: Manjunath Hadli --- drivers/media/video/davinci/vpbe_venc.c | 205 +++++++++++++++++++++++++++---- include/media/davinci/vpbe_venc.h | 4 + 2 files changed, 185 insertions(+), 24 deletions(-) diff --git a/drivers/media/video/davinci/vpbe_venc.c b/drivers/media/video/davinci/vpbe_venc.c index 03a3e5c..53c2994 100644 --- a/drivers/media/video/davinci/vpbe_venc.c +++ b/drivers/media/video/davinci/vpbe_venc.c @@ -99,6 +99,8 @@ static inline u32 vdaccfg_write(struct v4l2_subdev *sd, u32 val) return val; } +#define VDAC_COMPONENT 0x543 +#define VDAC_S_VIDEO 0x210 /* This function sets the dac of the VPBE for various outputs */ static int venc_set_dac(struct v4l2_subdev *sd, u32 out_index) @@ -109,11 +111,12 @@ static int venc_set_dac(struct v4l2_subdev *sd, u32 out_index) venc_write(sd, VENC_DACSEL, 0); break; case 1: - v4l2_dbg(debug, 1, sd, "Setting output to S-Video\n"); - venc_write(sd, VENC_DACSEL, 0x210); + v4l2_dbg(debug, 1, sd, "Setting output to Component\n"); + venc_write(sd, VENC_DACSEL, VDAC_COMPONENT); break; - case 2: - venc_write(sd, VENC_DACSEL, 0x543); + case 2: + v4l2_dbg(debug, 1, sd, "Setting output to S-video\n"); + venc_write(sd, VENC_DACSEL, VDAC_S_VIDEO); break; default: return -EINVAL; @@ -124,6 +127,8 @@ static int venc_set_dac(struct v4l2_subdev *sd, u32 out_index) static void venc_enabledigitaloutput(struct v4l2_subdev *sd, int benable) { + struct venc_state *venc = to_state(sd); + struct venc_platform_data *pdata = venc->pdata; v4l2_dbg(debug, 2, sd, "venc_enabledigitaloutput\n"); if (benable) { @@ -155,7 +160,8 @@ static void venc_enabledigitaloutput(struct v4l2_subdev *sd, int benable) /* Disable LCD output control (accepting default polarity) */ venc_write(sd, VENC_LCDOUT, 0); - venc_write(sd, VENC_CMPNT, 0x100); + if (pdata->venc_type != VPBE_VERSION_3) + venc_write(sd, VENC_CMPNT, 0x100); venc_write(sd, VENC_HSPLS, 0); venc_write(sd, VENC_HINT, 0); venc_write(sd, VENC_HSTART, 0); @@ -178,11 +184,14 @@ static void venc_enabledigitaloutput(struct v4l2_subdev *sd, int benable) } } +#define VDAC_CONFIG_SD_V3 0x0E21A6B6 +#define VDAC_CONFIG_SD_V2 0x081141CF /* * setting NTSC mode */ static int venc_set_ntsc(struct v4l2_subdev *sd) { + u32 val; struct venc_state *venc = to_state(sd); struct venc_platform_data *pdata = venc->pdata; @@ -195,12 +204,22 @@ static int venc_set_ntsc(struct v4l2_subdev *sd) venc_enabledigitaloutput(sd, 0); - /* to set VENC CLK DIV to 1 - final clock is 54 MHz */ - venc_modify(sd, VENC_VIDCTL, 0, 1 << 1); - /* Set REC656 Mode */ - venc_write(sd, VENC_YCCCTL, 0x1); - venc_modify(sd, VENC_VDPRO, 0, VENC_VDPRO_DAFRQ); - venc_modify(sd, VENC_VDPRO, 0, VENC_VDPRO_DAUPS); + if (pdata->venc_type == VPBE_VERSION_3) { + venc_write(sd, VENC_CLKCTL, 0x01); + venc_write(sd, VENC_VIDCTL, 0); + val = vdaccfg_write(sd, VDAC_CONFIG_SD_V3); + } else if (pdata->venc_type == VPBE_VERSION_2) { + venc_write(sd, VENC_CLKCTL, 0x01); + venc_write(sd, VENC_VIDCTL, 0); + vdaccfg_write(sd, VDAC_CONFIG_SD_V2); + } else { + /* to set VENC CLK DIV to 1 - final clock is 54 MHz */ + venc_modify(sd, VENC_VIDCTL, 0, 1 << 1); + /* Set REC656 Mode */ + venc_write(sd, VENC_YCCCTL, 0x1); + venc_modify(sd, VENC_VDPRO, 0, VENC_VDPRO_DAFRQ); + venc_modify(sd, VENC_VDPRO, 0, VENC_VDPRO_DAUPS); + } venc_write(sd, VENC_VMOD, 0); venc_modify(sd, VENC_VMOD, (1 << VENC_VMOD_VIE_SHIFT), @@ -220,6 +239,7 @@ static int venc_set_ntsc(struct v4l2_subdev *sd) static int venc_set_pal(struct v4l2_subdev *sd) { struct venc_state *venc = to_state(sd); + struct venc_platform_data *pdata = venc->pdata; v4l2_dbg(debug, 2, sd, "venc_set_pal\n"); @@ -230,10 +250,20 @@ static int venc_set_pal(struct v4l2_subdev *sd) venc_enabledigitaloutput(sd, 0); - /* to set VENC CLK DIV to 1 - final clock is 54 MHz */ - venc_modify(sd, VENC_VIDCTL, 0, 1 << 1); - /* Set REC656 Mode */ - venc_write(sd, VENC_YCCCTL, 0x1); + if (pdata->venc_type == VPBE_VERSION_3) { + venc_write(sd, VENC_CLKCTL, 0x1); + venc_write(sd, VENC_VIDCTL, 0); + vdaccfg_write(sd, VDAC_CONFIG_SD_V3); + } else if (pdata->venc_type == VPBE_VERSION_2) { + venc_write(sd, VENC_CLKCTL, 0x1); + venc_write(sd, VENC_VIDCTL, 0); + vdaccfg_write(sd, VDAC_CONFIG_SD_V2); + } else { + /* to set VENC CLK DIV to 1 - final clock is 54 MHz */ + venc_modify(sd, VENC_VIDCTL, 0, 1 << 1); + /* Set REC656 Mode */ + venc_write(sd, VENC_YCCCTL, 0x1); + } venc_modify(sd, VENC_SYNCCTL, 1 << VENC_SYNCCTL_OVD_SHIFT, VENC_SYNCCTL_OVD); @@ -252,6 +282,7 @@ static int venc_set_pal(struct v4l2_subdev *sd) return 0; } +#define VDAC_CONFIG_HD_V2 0x081141EF /* * venc_set_480p59_94 * @@ -263,6 +294,9 @@ static int venc_set_480p59_94(struct v4l2_subdev *sd) struct venc_platform_data *pdata = venc->pdata; v4l2_dbg(debug, 2, sd, "venc_set_480p59_94\n"); + if ((pdata->venc_type != VPBE_VERSION_1) && + (pdata->venc_type != VPBE_VERSION_2)) + return -EINVAL; /* Setup clock at VPSS & VENC for SD */ if (pdata->setup_clock(VPBE_ENC_DV_PRESET, V4L2_DV_480P59_94) < 0) @@ -270,12 +304,18 @@ static int venc_set_480p59_94(struct v4l2_subdev *sd) venc_enabledigitaloutput(sd, 0); + if (pdata->venc_type == VPBE_VERSION_2) + vdaccfg_write(sd, VDAC_CONFIG_HD_V2); venc_write(sd, VENC_OSDCLK0, 0); venc_write(sd, VENC_OSDCLK1, 1); - venc_modify(sd, VENC_VDPRO, VENC_VDPRO_DAFRQ, - VENC_VDPRO_DAFRQ); - venc_modify(sd, VENC_VDPRO, VENC_VDPRO_DAUPS, - VENC_VDPRO_DAUPS); + + if (pdata->venc_type == VPBE_VERSION_1) { + venc_modify(sd, VENC_VDPRO, VENC_VDPRO_DAFRQ, + VENC_VDPRO_DAFRQ); + venc_modify(sd, VENC_VDPRO, VENC_VDPRO_DAUPS, + VENC_VDPRO_DAUPS); + } + venc_write(sd, VENC_VMOD, 0); venc_modify(sd, VENC_VMOD, (1 << VENC_VMOD_VIE_SHIFT), VENC_VMOD_VIE); @@ -302,19 +342,27 @@ static int venc_set_576p50(struct v4l2_subdev *sd) v4l2_dbg(debug, 2, sd, "venc_set_576p50\n"); + if ((pdata->venc_type != VPBE_VERSION_1) && + (pdata->venc_type != VPBE_VERSION_2)) + return -EINVAL; /* Setup clock at VPSS & VENC for SD */ if (pdata->setup_clock(VPBE_ENC_DV_PRESET, V4L2_DV_576P50) < 0) return -EINVAL; venc_enabledigitaloutput(sd, 0); + if (pdata->venc_type == VPBE_VERSION_2) + vdaccfg_write(sd, VDAC_CONFIG_HD_V2); + venc_write(sd, VENC_OSDCLK0, 0); venc_write(sd, VENC_OSDCLK1, 1); - venc_modify(sd, VENC_VDPRO, VENC_VDPRO_DAFRQ, - VENC_VDPRO_DAFRQ); - venc_modify(sd, VENC_VDPRO, VENC_VDPRO_DAUPS, - VENC_VDPRO_DAUPS); + if (pdata->venc_type == VPBE_VERSION_1) { + venc_modify(sd, VENC_VDPRO, VENC_VDPRO_DAFRQ, + VENC_VDPRO_DAFRQ); + venc_modify(sd, VENC_VDPRO, VENC_VDPRO_DAUPS, + VENC_VDPRO_DAUPS); + } venc_write(sd, VENC_VMOD, 0); venc_modify(sd, VENC_VMOD, (1 << VENC_VMOD_VIE_SHIFT), @@ -330,6 +378,63 @@ static int venc_set_576p50(struct v4l2_subdev *sd) return 0; } +/* + * venc_set_720p60_internal - Setup 720p60 in venc for dm365 only + */ +static int venc_set_720p60_internal(struct v4l2_subdev *sd) +{ + struct venc_state *venc = to_state(sd); + struct venc_platform_data *pdata = venc->pdata; + + if (pdata->setup_clock(VPBE_ENC_DV_PRESET, V4L2_DV_720P60) < 0) + return -EINVAL; + + venc_enabledigitaloutput(sd, 0); + + venc_write(sd, VENC_OSDCLK0, 0); + venc_write(sd, VENC_OSDCLK1, 1); + + venc_write(sd, VENC_VMOD, 0); + /* DM365 component HD mode */ + venc_modify(sd, VENC_VMOD, (1 << VENC_VMOD_VIE_SHIFT), + VENC_VMOD_VIE); + venc_modify(sd, VENC_VMOD, VENC_VMOD_HDMD, VENC_VMOD_HDMD); + venc_modify(sd, VENC_VMOD, (HDTV_720P << VENC_VMOD_TVTYP_SHIFT), + VENC_VMOD_TVTYP); + venc_modify(sd, VENC_VMOD, VENC_VMOD_VENC, VENC_VMOD_VENC); + venc_write(sd, VENC_XHINTVL, 0); + return 0; +} + +/* + * venc_set_1080i30_internal - Setup 1080i30 in venc for dm365 only + */ +static int venc_set_1080i30_internal(struct v4l2_subdev *sd) +{ + struct venc_state *venc = to_state(sd); + struct venc_platform_data *pdata = venc->pdata; + + if (pdata->setup_clock(VPBE_ENC_DV_PRESET, V4L2_DV_1080P30) < 0) + return -EINVAL; + + venc_enabledigitaloutput(sd, 0); + + venc_write(sd, VENC_OSDCLK0, 0); + venc_write(sd, VENC_OSDCLK1, 1); + + + venc_write(sd, VENC_VMOD, 0); + /* DM365 component HD mode */ + venc_modify(sd, VENC_VMOD, (1 << VENC_VMOD_VIE_SHIFT), + VENC_VMOD_VIE); + venc_modify(sd, VENC_VMOD, VENC_VMOD_HDMD, VENC_VMOD_HDMD); + venc_modify(sd, VENC_VMOD, (HDTV_1080I << VENC_VMOD_TVTYP_SHIFT), + VENC_VMOD_TVTYP); + venc_modify(sd, VENC_VMOD, VENC_VMOD_VENC, VENC_VMOD_VENC); + venc_write(sd, VENC_XHINTVL, 0); + return 0; +} + static int venc_s_std_output(struct v4l2_subdev *sd, v4l2_std_id norm) { v4l2_dbg(debug, 1, sd, "venc_s_std_output\n"); @@ -345,13 +450,30 @@ static int venc_s_std_output(struct v4l2_subdev *sd, v4l2_std_id norm) static int venc_s_dv_preset(struct v4l2_subdev *sd, struct v4l2_dv_preset *dv_preset) { + struct venc_state *venc = to_state(sd); + int ret; + v4l2_dbg(debug, 1, sd, "venc_s_dv_preset\n"); if (dv_preset->preset == V4L2_DV_576P50) return venc_set_576p50(sd); else if (dv_preset->preset == V4L2_DV_480P59_94) return venc_set_480p59_94(sd); - + else if ((dv_preset->preset == V4L2_DV_720P60) && + (venc->pdata->venc_type == VPBE_VERSION_2)) { + /* TBD setup internal 720p mode here */ + ret = venc_set_720p60_internal(sd); + /* for DM365 VPBE, there is DAC inside */ + vdaccfg_write(sd, VDAC_CONFIG_HD_V2); + return ret; + } else if ((dv_preset->preset == V4L2_DV_1080I30) && + (venc->pdata->venc_type == VPBE_VERSION_2)) { + /* TBD setup internal 1080i mode here */ + ret = venc_set_1080i30_internal(sd); + /* for DM365 VPBE, there is DAC inside */ + vdaccfg_write(sd, VDAC_CONFIG_HD_V2); + return ret; + } return -EINVAL; } @@ -508,11 +630,41 @@ static int venc_probe(struct platform_device *pdev) goto release_venc_mem_region; } + if (venc->pdata->venc_type != VPBE_VERSION_1) { + res = platform_get_resource(pdev, IORESOURCE_MEM, 1); + if (!res) { + dev_err(venc->pdev, + "Unable to get VDAC_CONFIG address map\n"); + ret = -ENODEV; + goto unmap_venc_io; + } + + if (!request_mem_region(res->start, + resource_size(res), "venc")) { + dev_err(venc->pdev, + "Unable to reserve VDAC_CONFIG MMIO region\n"); + ret = -ENODEV; + goto unmap_venc_io; + } + + venc->vdaccfg_reg = ioremap_nocache(res->start, + resource_size(res)); + if (!venc->vdaccfg_reg) { + dev_err(venc->pdev, + "Unable to map VDAC_CONFIG IO space\n"); + ret = -ENODEV; + goto release_vdaccfg_mem_region; + } + } spin_lock_init(&venc->lock); platform_set_drvdata(pdev, venc); dev_notice(venc->pdev, "VENC sub device probe success\n"); return 0; +release_vdaccfg_mem_region: + release_mem_region(res->start, resource_size(res)); +unmap_venc_io: + iounmap(venc->venc_base); release_venc_mem_region: res = platform_get_resource(pdev, IORESOURCE_MEM, 0); release_mem_region(res->start, resource_size(res)); @@ -529,6 +681,11 @@ static int venc_remove(struct platform_device *pdev) res = platform_get_resource(pdev, IORESOURCE_MEM, 0); iounmap((void *)venc->venc_base); release_mem_region(res->start, resource_size(res)); + if (venc->pdata->venc_type != VPBE_VERSION_1) { + res = platform_get_resource(pdev, IORESOURCE_MEM, 1); + iounmap((void *)venc->vdaccfg_reg); + release_mem_region(res->start, resource_size(res)); + } kfree(venc); return 0; diff --git a/include/media/davinci/vpbe_venc.h b/include/media/davinci/vpbe_venc.h index 426c205..6b57334 100644 --- a/include/media/davinci/vpbe_venc.h +++ b/include/media/davinci/vpbe_venc.h @@ -29,10 +29,14 @@ struct venc_platform_data { enum vpbe_version venc_type; + int (*setup_pinmux)(enum v4l2_mbus_pixelcode if_type, + int field); int (*setup_clock)(enum vpbe_enc_timings_type type, unsigned int mode); + int (*setup_if_config)(enum v4l2_mbus_pixelcode pixcode); /* Number of LCD outputs supported */ int num_lcd_outputs; + struct vpbe_if_params *lcd_if_params; }; enum venc_ioctls { -- 1.6.2.4 From manjunath.hadli at ti.com Mon Sep 12 09:09:04 2011 From: manjunath.hadli at ti.com (Manjunath Hadli) Date: Mon, 12 Sep 2011 19:39:04 +0530 Subject: [RFC PATCH 1/4] davinci vpbe: remove unused macro. In-Reply-To: <1315836547-20658-1-git-send-email-manjunath.hadli@ti.com> References: <1315836547-20658-1-git-send-email-manjunath.hadli@ti.com> Message-ID: <1315836547-20658-2-git-send-email-manjunath.hadli@ti.com> remove VPBE_DISPLAY_SD_BUF_SIZE as it is no longer used. Signed-off-by: Manjunath Hadli --- drivers/media/video/davinci/vpbe_display.c | 1 - 1 files changed, 0 insertions(+), 1 deletions(-) diff --git a/drivers/media/video/davinci/vpbe_display.c b/drivers/media/video/davinci/vpbe_display.c index ae7add1..09a659e 100644 --- a/drivers/media/video/davinci/vpbe_display.c +++ b/drivers/media/video/davinci/vpbe_display.c @@ -43,7 +43,6 @@ static int debug; -#define VPBE_DISPLAY_SD_BUF_SIZE (720*576*2) #define VPBE_DEFAULT_NUM_BUFS 3 module_param(debug, int, 0644); -- 1.6.2.4 From manjunath.hadli at ti.com Mon Sep 12 09:09:06 2011 From: manjunath.hadli at ti.com (Manjunath Hadli) Date: Mon, 12 Sep 2011 19:39:06 +0530 Subject: [RFC PATCH 3/4] davinci vpbe: add dm365 and dm355 specific OSD changes In-Reply-To: <1315836547-20658-1-git-send-email-manjunath.hadli@ti.com> References: <1315836547-20658-1-git-send-email-manjunath.hadli@ti.com> Message-ID: <1315836547-20658-4-git-send-email-manjunath.hadli@ti.com> Add OSD block changes to enable dm365 and dm355 for vpbe driver. Changes are based on version number of OSD, which have incremental changes over 644x OSD hardware interms of few registers. VPBE_VERSION_2 = dm365 specific VPBE_VERSION_3 = dm355 specific Signed-off-by: Manjunath Hadli --- drivers/media/video/davinci/vpbe_osd.c | 474 +++++++++++++++++++++++++++++--- 1 files changed, 433 insertions(+), 41 deletions(-) diff --git a/drivers/media/video/davinci/vpbe_osd.c b/drivers/media/video/davinci/vpbe_osd.c index 5352884..cf472d3 100644 --- a/drivers/media/video/davinci/vpbe_osd.c +++ b/drivers/media/video/davinci/vpbe_osd.c @@ -248,11 +248,31 @@ static void _osd_set_rec601_attenuation(struct osd_state *sd, osd_modify(sd, OSD_OSDWIN0MD_ATN0E, enable ? OSD_OSDWIN0MD_ATN0E : 0, OSD_OSDWIN0MD); + if (sd->vpbe_type == VPBE_VERSION_1) { + osd_modify(sd, OSD_OSDWIN0MD_ATN0E, + enable ? OSD_OSDWIN0MD_ATN0E : 0, + OSD_OSDWIN0MD); + } else if ((sd->vpbe_type == VPBE_VERSION_3) || + (sd->vpbe_type == VPBE_VERSION_2)) { + osd_modify(sd, OSD_EXTMODE_ATNOSD0EN, + enable ? OSD_EXTMODE_ATNOSD0EN : 0, + OSD_EXTMODE); + } break; case OSDWIN_OSD1: osd_modify(sd, OSD_OSDWIN1MD_ATN1E, enable ? OSD_OSDWIN1MD_ATN1E : 0, OSD_OSDWIN1MD); + if (sd->vpbe_type == VPBE_VERSION_1) { + osd_modify(sd, OSD_OSDWIN1MD_ATN1E, + enable ? OSD_OSDWIN1MD_ATN1E : 0, + OSD_OSDWIN1MD); + } else if ((sd->vpbe_type == VPBE_VERSION_3) || + (sd->vpbe_type == VPBE_VERSION_2)) { + osd_modify(sd, OSD_EXTMODE_ATNOSD1EN, + enable ? OSD_EXTMODE_ATNOSD1EN : 0, + OSD_EXTMODE); + } break; } } @@ -273,15 +293,72 @@ static void _osd_set_blending_factor(struct osd_state *sd, } } +static void _osd_enable_rgb888_pixblend(struct osd_state *sd, + enum osd_win_layer osdwin) +{ + + osd_modify(sd, OSD_MISCCTL_BLDSEL, 0, OSD_MISCCTL); + switch (osdwin) { + case OSDWIN_OSD0: + osd_modify(sd, OSD_EXTMODE_OSD0BLDCHR, + OSD_EXTMODE_OSD0BLDCHR, OSD_EXTMODE); + break; + case OSDWIN_OSD1: + osd_modify(sd, OSD_EXTMODE_OSD1BLDCHR, + OSD_EXTMODE_OSD1BLDCHR, OSD_EXTMODE); + break; + } +} + static void _osd_enable_color_key(struct osd_state *sd, enum osd_win_layer osdwin, unsigned colorkey, enum osd_pix_format pixfmt) { switch (pixfmt) { + case PIXFMT_1BPP: + case PIXFMT_2BPP: + case PIXFMT_4BPP: + case PIXFMT_8BPP: + if (sd->vpbe_type == VPBE_VERSION_3) { + switch (osdwin) { + case OSDWIN_OSD0: + osd_modify(sd, OSD_TRANSPBMPIDX_BMP0, + colorkey << + OSD_TRANSPBMPIDX_BMP0_SHIFT, + OSD_TRANSPBMPIDX); + break; + case OSDWIN_OSD1: + osd_modify(sd, OSD_TRANSPBMPIDX_BMP1, + colorkey << + OSD_TRANSPBMPIDX_BMP1_SHIFT, + OSD_TRANSPBMPIDX); + break; + } + } + break; case PIXFMT_RGB565: - osd_write(sd, colorkey & OSD_TRANSPVAL_RGBTRANS, - OSD_TRANSPVAL); + if (sd->vpbe_type == VPBE_VERSION_1) { + osd_write(sd, colorkey & OSD_TRANSPVAL_RGBTRANS, + OSD_TRANSPVAL); + } else if (sd->vpbe_type == VPBE_VERSION_3) { + osd_write(sd, colorkey & OSD_TRANSPVALL_RGBL, + OSD_TRANSPVALL); + } + break; + case PIXFMT_YCbCrI: + case PIXFMT_YCrCbI: + if (sd->vpbe_type == VPBE_VERSION_3) + osd_modify(sd, OSD_TRANSPVALU_Y, colorkey, + OSD_TRANSPVALU); + break; + case PIXFMT_RGB888: + if (sd->vpbe_type == VPBE_VERSION_3) { + osd_write(sd, colorkey & OSD_TRANSPVALL_RGBL, + OSD_TRANSPVALL); + osd_modify(sd, OSD_TRANSPVALU_RGBU, colorkey >> 16, + OSD_TRANSPVALU); + } break; default: break; @@ -470,23 +547,187 @@ static int osd_enable_layer(struct osd_state *sd, enum osd_layer layer, return 0; } +#define OSD_SRC_ADDR_HIGH4 0x7800000 +#define OSD_SRC_ADDR_HIGH7 0x7F0000 +#define OSD_SRCADD_OFSET_SFT 23 +#define OSD_SRCADD_ADD_SFT 16 +#define OSD_WINADL_MASK 0xFFFF +#define OSD_WINOFST_MASK 0x1000 + static void _osd_start_layer(struct osd_state *sd, enum osd_layer layer, unsigned long fb_base_phys, unsigned long cbcr_ofst) { - switch (layer) { - case WIN_OSD0: - osd_write(sd, fb_base_phys & ~0x1F, OSD_OSDWIN0ADR); - break; - case WIN_VID0: - osd_write(sd, fb_base_phys & ~0x1F, OSD_VIDWIN0ADR); - break; - case WIN_OSD1: - osd_write(sd, fb_base_phys & ~0x1F, OSD_OSDWIN1ADR); - break; - case WIN_VID1: - osd_write(sd, fb_base_phys & ~0x1F, OSD_VIDWIN1ADR); - break; + + if (sd->vpbe_type == VPBE_VERSION_1) { + switch (layer) { + case WIN_OSD0: + osd_write(sd, fb_base_phys & ~0x1F, OSD_OSDWIN0ADR); + break; + case WIN_VID0: + osd_write(sd, fb_base_phys & ~0x1F, OSD_VIDWIN0ADR); + break; + case WIN_OSD1: + osd_write(sd, fb_base_phys & ~0x1F, OSD_OSDWIN1ADR); + break; + case WIN_VID1: + osd_write(sd, fb_base_phys & ~0x1F, OSD_VIDWIN1ADR); + break; + } + } else if (sd->vpbe_type == VPBE_VERSION_3) { + unsigned long fb_offset_32 = + (fb_base_phys - DAVINCI_DDR_BASE) >> 5; + + switch (layer) { + case WIN_OSD0: + osd_modify(sd, OSD_OSDWINADH_O0AH, + fb_offset_32 >> (OSD_SRCADD_ADD_SFT - + OSD_OSDWINADH_O0AH_SHIFT), + OSD_OSDWINADH); + osd_write(sd, fb_offset_32 & OSD_OSDWIN0ADL_O0AL, + OSD_OSDWIN0ADL); + break; + case WIN_VID0: + osd_modify(sd, OSD_VIDWINADH_V0AH, + fb_offset_32 >> (OSD_SRCADD_ADD_SFT - + OSD_VIDWINADH_V0AH_SHIFT), + OSD_VIDWINADH); + osd_write(sd, fb_offset_32 & OSD_VIDWIN0ADL_V0AL, + OSD_VIDWIN0ADL); + break; + case WIN_OSD1: + osd_modify(sd, OSD_OSDWINADH_O1AH, + fb_offset_32 >> (OSD_SRCADD_ADD_SFT - + OSD_OSDWINADH_O1AH_SHIFT), + OSD_OSDWINADH); + osd_write(sd, fb_offset_32 & OSD_OSDWIN1ADL_O1AL, + OSD_OSDWIN1ADL); + break; + case WIN_VID1: + osd_modify(sd, OSD_VIDWINADH_V1AH, + fb_offset_32 >> (OSD_SRCADD_ADD_SFT - + OSD_VIDWINADH_V1AH_SHIFT), + OSD_VIDWINADH); + osd_write(sd, fb_offset_32 & OSD_VIDWIN1ADL_V1AL, + OSD_VIDWIN1ADL); + break; + } + } else if (sd->vpbe_type == VPBE_VERSION_2) { + struct osd_window_state *win = &sd->win[layer]; + unsigned long fb_offset_32, cbcr_offset_32; + + fb_offset_32 = fb_base_phys - DAVINCI_DDR_BASE; + if (cbcr_ofst) + cbcr_offset_32 = cbcr_ofst; + else + cbcr_offset_32 = win->lconfig.line_length * + win->lconfig.ysize; + cbcr_offset_32 += fb_offset_32; + fb_offset_32 = fb_offset_32 >> 5; + cbcr_offset_32 = cbcr_offset_32 >> 5; + /* + * DM365: start address is 27-bit long address b26 - b23 are + * in offset register b12 - b9, and * bit 26 has to be '1' + */ + if (win->lconfig.pixfmt == PIXFMT_NV12) { + switch (layer) { + case WIN_VID0: + case WIN_VID1: + /* Y is in VID0 */ + osd_modify(sd, OSD_VIDWIN0OFST_V0AH, + ((fb_offset_32 & OSD_SRC_ADDR_HIGH4) >> + (OSD_SRCADD_OFSET_SFT - + OSD_WINOFST_AH_SHIFT)) | + OSD_WINOFST_MASK, OSD_VIDWIN0OFST); + osd_modify(sd, OSD_VIDWINADH_V0AH, + (fb_offset_32 & OSD_SRC_ADDR_HIGH7) >> + (OSD_SRCADD_ADD_SFT - + OSD_VIDWINADH_V0AH_SHIFT), + OSD_VIDWINADH); + osd_write(sd, fb_offset_32 & OSD_WINADL_MASK, + OSD_VIDWIN0ADL); + /* CbCr is in VID1 */ + osd_modify(sd, OSD_VIDWIN1OFST_V1AH, + ((cbcr_offset_32 & + OSD_SRC_ADDR_HIGH4) >> + (OSD_SRCADD_OFSET_SFT - + OSD_WINOFST_AH_SHIFT)) | + OSD_WINOFST_MASK, OSD_VIDWIN1OFST); + osd_modify(sd, OSD_VIDWINADH_V1AH, + (cbcr_offset_32 & + OSD_SRC_ADDR_HIGH7) >> + (OSD_SRCADD_ADD_SFT - + OSD_VIDWINADH_V1AH_SHIFT), + OSD_VIDWINADH); + osd_write(sd, cbcr_offset_32 & OSD_WINADL_MASK, + OSD_VIDWIN1ADL); + break; + default: + break; + } + } + + switch (layer) { + case WIN_OSD0: + osd_modify(sd, OSD_OSDWIN0OFST_O0AH, + ((fb_offset_32 & OSD_SRC_ADDR_HIGH4) >> + (OSD_SRCADD_OFSET_SFT - + OSD_WINOFST_AH_SHIFT)) | OSD_WINOFST_MASK, + OSD_OSDWIN0OFST); + osd_modify(sd, OSD_OSDWINADH_O0AH, + (fb_offset_32 & OSD_SRC_ADDR_HIGH7) >> + (OSD_SRCADD_ADD_SFT - + OSD_OSDWINADH_O0AH_SHIFT), OSD_OSDWINADH); + osd_write(sd, fb_offset_32 & OSD_WINADL_MASK, + OSD_OSDWIN0ADL); + break; + case WIN_VID0: + if (win->lconfig.pixfmt != PIXFMT_NV12) { + osd_modify(sd, OSD_VIDWIN0OFST_V0AH, + ((fb_offset_32 & OSD_SRC_ADDR_HIGH4) >> + (OSD_SRCADD_OFSET_SFT - + OSD_WINOFST_AH_SHIFT)) | + OSD_WINOFST_MASK, OSD_VIDWIN0OFST); + osd_modify(sd, OSD_VIDWINADH_V0AH, + (fb_offset_32 & OSD_SRC_ADDR_HIGH7) >> + (OSD_SRCADD_ADD_SFT - + OSD_VIDWINADH_V0AH_SHIFT), + OSD_VIDWINADH); + osd_write(sd, fb_offset_32 & OSD_WINADL_MASK, + OSD_VIDWIN0ADL); + } + break; + case WIN_OSD1: + osd_modify(sd, OSD_OSDWIN1OFST_O1AH, + ((fb_offset_32 & OSD_SRC_ADDR_HIGH4) >> + (OSD_SRCADD_OFSET_SFT - + OSD_WINOFST_AH_SHIFT)) | OSD_WINOFST_MASK, + OSD_OSDWIN1OFST); + osd_modify(sd, OSD_OSDWINADH_O1AH, + (fb_offset_32 & OSD_SRC_ADDR_HIGH7) >> + (OSD_SRCADD_ADD_SFT - + OSD_OSDWINADH_O1AH_SHIFT), + OSD_OSDWINADH); + osd_write(sd, fb_offset_32 & OSD_WINADL_MASK, + OSD_OSDWIN1ADL); + break; + case WIN_VID1: + if (win->lconfig.pixfmt != PIXFMT_NV12) { + osd_modify(sd, OSD_VIDWIN1OFST_V1AH, + ((fb_offset_32 & OSD_SRC_ADDR_HIGH4) >> + (OSD_SRCADD_OFSET_SFT - + OSD_WINOFST_AH_SHIFT)) | + OSD_WINOFST_MASK, OSD_VIDWIN1OFST); + osd_modify(sd, OSD_VIDWINADH_V1AH, + (fb_offset_32 & OSD_SRC_ADDR_HIGH7) >> + (OSD_SRCADD_ADD_SFT - + OSD_VIDWINADH_V1AH_SHIFT), + OSD_VIDWINADH); + osd_write(sd, fb_offset_32 & OSD_WINADL_MASK, + OSD_VIDWIN1ADL); + } + break; + } } } @@ -545,7 +786,7 @@ static int try_layer_config(struct osd_state *sd, enum osd_layer layer, { struct osd_state *osd = sd; struct osd_window_state *win = &osd->win[layer]; - int bad_config; + int bad_config = 0; /* verify that the pixel format is compatible with the layer */ switch (lconfig->pixfmt) { @@ -554,17 +795,25 @@ static int try_layer_config(struct osd_state *sd, enum osd_layer layer, case PIXFMT_4BPP: case PIXFMT_8BPP: case PIXFMT_RGB565: - bad_config = !is_osd_win(layer); + if (osd->vpbe_type == VPBE_VERSION_1) + bad_config = !is_vid_win(layer); break; case PIXFMT_YCbCrI: case PIXFMT_YCrCbI: bad_config = !is_vid_win(layer); break; case PIXFMT_RGB888: - bad_config = !is_vid_win(layer); + if (osd->vpbe_type == VPBE_VERSION_1) + bad_config = !is_vid_win(layer); + else if ((osd->vpbe_type == VPBE_VERSION_3) || + (osd->vpbe_type == VPBE_VERSION_2)) + bad_config = !is_osd_win(layer); break; case PIXFMT_NV12: - bad_config = 1; + if (osd->vpbe_type != VPBE_VERSION_2) + bad_config = 1; + else + bad_config = is_osd_win(layer); break; case PIXFMT_OSD_ATTR: bad_config = (layer != WIN_OSD1); @@ -584,7 +833,8 @@ static int try_layer_config(struct osd_state *sd, enum osd_layer layer, /* DM6446: */ /* only one OSD window at a time can use RGB pixel formats */ - if (is_osd_win(layer) && is_rgb_pixfmt(lconfig->pixfmt)) { + if ((osd->vpbe_type == VPBE_VERSION_1) && + is_osd_win(layer) && is_rgb_pixfmt(lconfig->pixfmt)) { enum osd_pix_format pixfmt; if (layer == WIN_OSD0) pixfmt = osd->win[WIN_OSD1].lconfig.pixfmt; @@ -602,7 +852,8 @@ static int try_layer_config(struct osd_state *sd, enum osd_layer layer, } /* DM6446: only one video window at a time can use RGB888 */ - if (is_vid_win(layer) && lconfig->pixfmt == PIXFMT_RGB888) { + if ((osd->vpbe_type == VPBE_VERSION_1) && is_vid_win(layer) && + lconfig->pixfmt == PIXFMT_RGB888) { enum osd_pix_format pixfmt; if (layer == WIN_VID0) @@ -652,7 +903,8 @@ static void _osd_disable_vid_rgb888(struct osd_state *sd) * The caller must ensure that neither video window is currently * configured for RGB888 pixel format. */ - osd_clear(sd, OSD_MISCCTL_RGBEN, OSD_MISCCTL); + if (sd->vpbe_type == VPBE_VERSION_1) + osd_clear(sd, OSD_MISCCTL_RGBEN, OSD_MISCCTL); } static void _osd_enable_vid_rgb888(struct osd_state *sd, @@ -665,13 +917,15 @@ static void _osd_enable_vid_rgb888(struct osd_state *sd, * currently configured for RGB888 pixel format, as this routine will * disable RGB888 pixel format for the other window. */ - if (layer == WIN_VID0) { - osd_modify(sd, OSD_MISCCTL_RGBEN | OSD_MISCCTL_RGBWIN, - OSD_MISCCTL_RGBEN, OSD_MISCCTL); - } else if (layer == WIN_VID1) { - osd_modify(sd, OSD_MISCCTL_RGBEN | OSD_MISCCTL_RGBWIN, - OSD_MISCCTL_RGBEN | OSD_MISCCTL_RGBWIN, - OSD_MISCCTL); + if (sd->vpbe_type == VPBE_VERSION_1) { + if (layer == WIN_VID0) { + osd_modify(sd, OSD_MISCCTL_RGBEN | OSD_MISCCTL_RGBWIN, + OSD_MISCCTL_RGBEN, OSD_MISCCTL); + } else if (layer == WIN_VID1) { + osd_modify(sd, OSD_MISCCTL_RGBEN | OSD_MISCCTL_RGBWIN, + OSD_MISCCTL_RGBEN | OSD_MISCCTL_RGBWIN, + OSD_MISCCTL); + } } } @@ -697,9 +951,30 @@ static void _osd_set_layer_config(struct osd_state *sd, enum osd_layer layer, switch (layer) { case WIN_OSD0: - winmd_mask |= OSD_OSDWIN0MD_RGB0E; - if (lconfig->pixfmt == PIXFMT_RGB565) - winmd |= OSD_OSDWIN0MD_RGB0E; + if (sd->vpbe_type == VPBE_VERSION_1) { + winmd_mask |= OSD_OSDWIN0MD_RGB0E; + if (lconfig->pixfmt == PIXFMT_RGB565) + winmd |= OSD_OSDWIN0MD_RGB0E; + } else if ((sd->vpbe_type == VPBE_VERSION_3) || + (sd->vpbe_type == VPBE_VERSION_2)) { + winmd_mask |= OSD_OSDWIN0MD_BMP0MD; + switch (lconfig->pixfmt) { + case PIXFMT_RGB565: + winmd |= (1 << + OSD_OSDWIN0MD_BMP0MD_SHIFT); + break; + case PIXFMT_RGB888: + winmd |= (2 << OSD_OSDWIN0MD_BMP0MD_SHIFT); + _osd_enable_rgb888_pixblend(sd, OSDWIN_OSD0); + break; + case PIXFMT_YCbCrI: + case PIXFMT_YCrCbI: + winmd |= (3 << OSD_OSDWIN0MD_BMP0MD_SHIFT); + break; + default: + break; + } + } winmd_mask |= OSD_OSDWIN0MD_BMW0 | OSD_OSDWIN0MD_OFF0; @@ -749,12 +1024,58 @@ static void _osd_set_layer_config(struct osd_state *sd, enum osd_layer layer, * For YUV420P format the register contents are * duplicated in both VID registers */ + if ((sd->vpbe_type == VPBE_VERSION_2) && + (lconfig->pixfmt == PIXFMT_NV12)) { + /* other window also */ + if (lconfig->interlaced) { + winmd_mask |= OSD_VIDWINMD_VFF1; + winmd |= OSD_VIDWINMD_VFF1; + osd_modify(sd, winmd_mask, winmd, + OSD_VIDWINMD); + } + + osd_modify(sd, OSD_MISCCTL_S420D, + OSD_MISCCTL_S420D, OSD_MISCCTL); + osd_write(sd, lconfig->line_length >> 5, + OSD_VIDWIN1OFST); + osd_write(sd, lconfig->xpos, OSD_VIDWIN1XP); + osd_write(sd, lconfig->xsize, OSD_VIDWIN1XL); + /* + * if NV21 pixfmt and line length not 32B + * aligned (e.g. NTSC), Need to set window + * X pixel size to be 32B aligned as well + */ + if (lconfig->xsize % 32) { + osd_write(sd, + ((lconfig->xsize + 31) & ~31), + OSD_VIDWIN1XL); + osd_write(sd, + ((lconfig->xsize + 31) & ~31), + OSD_VIDWIN0XL); + } + } else if ((sd->vpbe_type == VPBE_VERSION_2) && + (lconfig->pixfmt != PIXFMT_NV12)) + osd_modify(sd, OSD_MISCCTL_S420D, ~OSD_MISCCTL_S420D, + OSD_MISCCTL); + if (lconfig->interlaced) { osd_write(sd, lconfig->ypos >> 1, OSD_VIDWIN0YP); osd_write(sd, lconfig->ysize >> 1, OSD_VIDWIN0YL); + if ((sd->vpbe_type == VPBE_VERSION_2) && + lconfig->pixfmt == PIXFMT_NV12) { + osd_write(sd, lconfig->ypos >> 1, + OSD_VIDWIN1YP); + osd_write(sd, lconfig->ysize >> 1, + OSD_VIDWIN1YL); + } } else { osd_write(sd, lconfig->ypos, OSD_VIDWIN0YP); osd_write(sd, lconfig->ysize, OSD_VIDWIN0YL); + if ((sd->vpbe_type == VPBE_VERSION_2) && + lconfig->pixfmt == PIXFMT_NV12) { + osd_write(sd, lconfig->ypos, OSD_VIDWIN1YP); + osd_write(sd, lconfig->ysize, OSD_VIDWIN1YL); + } } break; case WIN_OSD1: @@ -764,14 +1085,43 @@ static void _osd_set_layer_config(struct osd_state *sd, enum osd_layer layer, * attribute mode to a normal mode. */ if (lconfig->pixfmt == PIXFMT_OSD_ATTR) { - winmd_mask |= - OSD_OSDWIN1MD_ATN1E | OSD_OSDWIN1MD_RGB1E | - OSD_OSDWIN1MD_CLUTS1 | - OSD_OSDWIN1MD_BLND1 | OSD_OSDWIN1MD_TE1; + if (sd->vpbe_type == VPBE_VERSION_1) { + winmd_mask |= OSD_OSDWIN1MD_ATN1E | + OSD_OSDWIN1MD_RGB1E | OSD_OSDWIN1MD_CLUTS1 | + OSD_OSDWIN1MD_BLND1 | OSD_OSDWIN1MD_TE1; + } else { + winmd_mask |= OSD_OSDWIN1MD_BMP1MD | + OSD_OSDWIN1MD_CLUTS1 | OSD_OSDWIN1MD_BLND1 | + OSD_OSDWIN1MD_TE1; + } } else { - winmd_mask |= OSD_OSDWIN1MD_RGB1E; - if (lconfig->pixfmt == PIXFMT_RGB565) - winmd |= OSD_OSDWIN1MD_RGB1E; + if (sd->vpbe_type == VPBE_VERSION_1) { + winmd_mask |= OSD_OSDWIN1MD_RGB1E; + if (lconfig->pixfmt == PIXFMT_RGB565) + winmd |= OSD_OSDWIN1MD_RGB1E; + } else if ((sd->vpbe_type == VPBE_VERSION_3) + || (sd->vpbe_type == VPBE_VERSION_2)) { + winmd_mask |= OSD_OSDWIN1MD_BMP1MD; + switch (lconfig->pixfmt) { + case PIXFMT_RGB565: + winmd |= + (1 << OSD_OSDWIN1MD_BMP1MD_SHIFT); + break; + case PIXFMT_RGB888: + winmd |= + (2 << OSD_OSDWIN1MD_BMP1MD_SHIFT); + _osd_enable_rgb888_pixblend(sd, + OSDWIN_OSD1); + break; + case PIXFMT_YCbCrI: + case PIXFMT_YCrCbI: + winmd |= + (3 << OSD_OSDWIN1MD_BMP1MD_SHIFT); + break; + default: + break; + } + } winmd_mask |= OSD_OSDWIN1MD_BMW1; switch (lconfig->pixfmt) { @@ -822,15 +1172,44 @@ static void _osd_set_layer_config(struct osd_state *sd, enum osd_layer layer, * For YUV420P format the register contents are * duplicated in both VID registers */ - osd_modify(sd, OSD_MISCCTL_S420D, ~OSD_MISCCTL_S420D, - OSD_MISCCTL); + if (sd->vpbe_type == VPBE_VERSION_2) { + if (lconfig->pixfmt == PIXFMT_NV12) { + /* other window also */ + if (lconfig->interlaced) { + winmd_mask |= OSD_VIDWINMD_VFF0; + winmd |= OSD_VIDWINMD_VFF0; + osd_modify(sd, winmd_mask, winmd, + OSD_VIDWINMD); + } + osd_modify(sd, OSD_MISCCTL_S420D, + OSD_MISCCTL_S420D, OSD_MISCCTL); + osd_write(sd, lconfig->line_length >> 5, + OSD_VIDWIN0OFST); + osd_write(sd, lconfig->xpos, OSD_VIDWIN0XP); + osd_write(sd, lconfig->xsize, OSD_VIDWIN0XL); + } else + osd_modify(sd, OSD_MISCCTL_S420D, + ~OSD_MISCCTL_S420D, OSD_MISCCTL); + } if (lconfig->interlaced) { osd_write(sd, lconfig->ypos >> 1, OSD_VIDWIN1YP); osd_write(sd, lconfig->ysize >> 1, OSD_VIDWIN1YL); + if ((sd->vpbe_type == VPBE_VERSION_2) && + lconfig->pixfmt == PIXFMT_NV12) { + osd_write(sd, lconfig->ypos >> 1, + OSD_VIDWIN0YP); + osd_write(sd, lconfig->ysize >> 1, + OSD_VIDWIN0YL); + } } else { osd_write(sd, lconfig->ypos, OSD_VIDWIN1YP); osd_write(sd, lconfig->ysize, OSD_VIDWIN1YL); + if ((sd->vpbe_type == VPBE_VERSION_2) && + lconfig->pixfmt == PIXFMT_NV12) { + osd_write(sd, lconfig->ypos, OSD_VIDWIN0YP); + osd_write(sd, lconfig->ysize, OSD_VIDWIN0YL); + } } break; } @@ -1089,6 +1468,11 @@ static void _osd_init(struct osd_state *sd) osd_write(sd, 0, OSD_OSDWIN1MD); osd_write(sd, 0, OSD_RECTCUR); osd_write(sd, 0, OSD_MISCCTL); + if (sd->vpbe_type == VPBE_VERSION_3) { + osd_write(sd, 0, OSD_VBNDRY); + osd_write(sd, 0, OSD_EXTMODE); + osd_write(sd, OSD_MISCCTL_DMANG, OSD_MISCCTL); + } } static void osd_set_left_margin(struct osd_state *sd, u32 val) @@ -1110,6 +1494,14 @@ static int osd_initialize(struct osd_state *osd) /* set default Cb/Cr order */ osd->yc_pixfmt = PIXFMT_YCbCrI; + if (osd->vpbe_type == VPBE_VERSION_3) { + /* + * ROM CLUT1 on the DM355 is similar (identical?) to ROM CLUT0 + * on the DM6446, so make ROM_CLUT1 the default on the DM355. + */ + osd->rom_clut = ROM_CLUT1; + } + _osd_set_field_inversion(osd, osd->field_inversion); _osd_set_rom_clut(osd, osd->rom_clut); -- 1.6.2.4 From manjunath.hadli at ti.com Mon Sep 12 09:18:16 2011 From: manjunath.hadli at ti.com (Hadli, Manjunath) Date: Mon, 12 Sep 2011 19:48:16 +0530 Subject: [PATCH v2 0/8] RFC for Media Controller capture driver for DM365 In-Reply-To: <20110912115925.GC1716@valkosipuli.localdomain> References: <1314630439-1122-1-git-send-email-manjunath.hadli@ti.com> <20110831213032.GT12368@valkosipuli.localdomain> <20110909161940.GJ1724@valkosipuli.localdomain> <20110912115925.GC1716@valkosipuli.localdomain> Message-ID: Thank you Sakari. -Manju On Mon, Sep 12, 2011 at 17:29:25, Sakari Ailus wrote: > On Sat, Sep 10, 2011 at 12:11:37PM +0530, Hadli, Manjunath wrote: > > Hi Sakari, > > On Fri, Sep 09, 2011 at 21:49:40, Sakari Ailus wrote: > > > On Fri, Sep 09, 2011 at 07:10:49PM +0530, Hadli, Manjunath wrote: > > > > Hi Sakari, > > > > > > > > On Thu, Sep 01, 2011 at 03:00:32, Sakari Ailus wrote: > > > > > Hi Manju, > > > > > > > > > > Do you have the media device grap that would be typical for this hardware produced by media-ctl? That can be converted to postscript using dotfile. > > > > > > > > > > this would make it a little easier to understan this driver. Thanks. > > > > > > > > Sure. But can you be a little more elaborate on how you need this > > > > information? If you can tell me in little more detail about this > > > > that will help me make the information in a way that everyone can understand. > > > > > > Preferrably in PostScript format so it's easy to visualise the layout of the hardware that the driver supports, as the OMAP 3 ISP example was. > > Sure. > > I was more looking for an example of the same so it could help me put > > the data together in the way it has been done before. Can you send > > across if you have one? > > Ah. I think I misunderstood you first. :-) > > On the device, run > > $ media-ctl --print-dot > graph.dot > > This will produce a graph of the media device in the dot format. This is then processed by program called dot: > > $ dot -o graph.ps -T ps < graph.dot > > dot is available at least in Debian in a package called graphviz. > > Cheers, > > -- > Sakari Ailus > e-mail: sakari.ailus at iki.fi jabber/XMPP/Gmail: sailus at retiisi.org.uk > From const at makelinux.com Tue Sep 13 04:50:10 2011 From: const at makelinux.com (Constantine Shulyupin) Date: Tue, 13 Sep 2011 12:50:10 +0300 Subject: video capture application Message-ID: Hi What application can I use to test video capture on dm365 with latest kernels located at git://arago-project.org/git/projects/linux-davinci.git and git://gitorious.org/linux-davinci/linux-davinci.git? ( DVSDK and other demo applications works only with older kernels from DVSDK) Thanks -- Constantine Shulyupin http://www.MakeLinux.com/ Embedded Linux Systems, Device Drivers, TI DaVinci From nagabhushana.netagunte at ti.com Tue Sep 13 05:27:04 2011 From: nagabhushana.netagunte at ti.com (Netagunte, Nagabhushana) Date: Tue, 13 Sep 2011 15:57:04 +0530 Subject: video capture application In-Reply-To: References: Message-ID: Constantine, If you are referring to media controller based branch 03.21.00.05, please refer to http://arago-project.org/git/projects/?p=examples-davinci.git;a=shortlog;h=refs/heads/03.21.00.03 for examples. Otherwise, if the branch you are referring to is r39, then, refer to http://arago-project.org/git/projects/?p=examples-davinci.git;a=shortlog;h=refs/heads/r38 for examples. Regards, Nag ________________________________________ From: Constantine Shulyupin [const at makelinux.com] Sent: Tuesday, September 13, 2011 3:20 PM To: Netagunte, Nagabhushana; davinci-linux-open-source at linux.davincidsp.com; Hadli, Manjunath Subject: video capture application Hi What application can I use to test video capture on dm365 with latest kernels located at git://arago-project.org/git/projects/linux-davinci.git and git://gitorious.org/linux-davinci/linux-davinci.git? ( DVSDK and other demo applications works only with older kernels from DVSDK) Thanks -- Constantine Shulyupin http://www.MakeLinux.com/ Embedded Linux Systems, Device Drivers, TI DaVinci From gary at mlbassoc.com Tue Sep 13 07:02:49 2011 From: gary at mlbassoc.com (Gary Thomas) Date: Tue, 13 Sep 2011 06:02:49 -0600 Subject: video capture application In-Reply-To: References: Message-ID: <4E6F4669.3050008@mlbassoc.com> On 2011-09-13 04:27, Netagunte, Nagabhushana wrote: > Constantine, > > If you are referring to media controller based branch 03.21.00.05, please refer to http://arago-project.org/git/projects/?p=examples-davinci.git;a=shortlog;h=refs/heads/03.21.00.03 for examples. > > Otherwise, if the branch you are referring to is r39, then, refer to http://arago-project.org/git/projects/?p=examples-davinci.git;a=shortlog;h=refs/heads/r38 for examples. > > Regards, > Nag > ________________________________________ > From: Constantine Shulyupin [const at makelinux.com] > Sent: Tuesday, September 13, 2011 3:20 PM > To: Netagunte, Nagabhushana; davinci-linux-open-source at linux.davincidsp.com; Hadli, Manjunath > Subject: video capture application > > Hi > > What application can I use to test video capture on dm365 with latest > kernels located at > git://arago-project.org/git/projects/linux-davinci.git and > git://gitorious.org/linux-davinci/linux-davinci.git? > ( DVSDK and other demo applications works only with older kernels from DVSDK) Which Linux source tree (git & branch) has the media controller support? I looked at the examples mentioned above and see ioctl functions being used with the TVP514x driver, but I can't find the driver that supports them, e.g. VIDIOC_S_INPUT?? Thanks -- ------------------------------------------------------------ Gary Thomas | Consulting for the MLB Associates | Embedded world ------------------------------------------------------------ From nagabhushana.netagunte at ti.com Tue Sep 13 07:05:15 2011 From: nagabhushana.netagunte at ti.com (Netagunte, Nagabhushana) Date: Tue, 13 Sep 2011 17:35:15 +0530 Subject: video capture application In-Reply-To: <4E6F4669.3050008@mlbassoc.com> References: , <4E6F4669.3050008@mlbassoc.com> Message-ID: Gary, Please refer to - http://arago-project.org/git/projects/?p=linux-davinci.git;a=blob;f=drivers/media/video/davinci/vpfe_video.c;h=9555c93c4bcf4d92b1296883a6333161068f85ca;hb=6ac7a3440bbd9fc30c175c205f0efd4b2fd8cde7 Branch name:- 03.21.00.05 Tree:- linux-davinci (http://arago-project.org/git/projects/?p=linux-davinci.git;a=summary) Regards, Nag ________________________________________ From: Gary Thomas [gary at mlbassoc.com] Sent: Tuesday, September 13, 2011 5:32 PM To: Netagunte, Nagabhushana Cc: Constantine Shulyupin; davinci-linux-open-source at linux.davincidsp.com; Hadli, Manjunath Subject: Re: video capture application On 2011-09-13 04:27, Netagunte, Nagabhushana wrote: > Constantine, > > If you are referring to media controller based branch 03.21.00.05, please refer to http://arago-project.org/git/projects/?p=examples-davinci.git;a=shortlog;h=refs/heads/03.21.00.03 for examples. > > Otherwise, if the branch you are referring to is r39, then, refer to http://arago-project.org/git/projects/?p=examples-davinci.git;a=shortlog;h=refs/heads/r38 for examples. > > Regards, > Nag > ________________________________________ > From: Constantine Shulyupin [const at makelinux.com] > Sent: Tuesday, September 13, 2011 3:20 PM > To: Netagunte, Nagabhushana; davinci-linux-open-source at linux.davincidsp.com; Hadli, Manjunath > Subject: video capture application > > Hi > > What application can I use to test video capture on dm365 with latest > kernels located at > git://arago-project.org/git/projects/linux-davinci.git and > git://gitorious.org/linux-davinci/linux-davinci.git? > ( DVSDK and other demo applications works only with older kernels from DVSDK) Which Linux source tree (git & branch) has the media controller support? I looked at the examples mentioned above and see ioctl functions being used with the TVP514x driver, but I can't find the driver that supports them, e.g. VIDIOC_S_INPUT?? Thanks -- ------------------------------------------------------------ Gary Thomas | Consulting for the MLB Associates | Embedded world ------------------------------------------------------------ From gary at mlbassoc.com Tue Sep 13 07:24:26 2011 From: gary at mlbassoc.com (Gary Thomas) Date: Tue, 13 Sep 2011 06:24:26 -0600 Subject: video capture application In-Reply-To: References: , <4E6F4669.3050008@mlbassoc.com> Message-ID: <4E6F4B7A.5030107@mlbassoc.com> On 2011-09-13 06:05, Netagunte, Nagabhushana wrote: > Gary, > Please refer to - > > http://arago-project.org/git/projects/?p=linux-davinci.git;a=blob;f=drivers/media/video/davinci/vpfe_video.c;h=9555c93c4bcf4d92b1296883a6333161068f85ca;hb=6ac7a3440bbd9fc30c175c205f0efd4b2fd8cde7 > > Branch name:- 03.21.00.05 > Tree:- linux-davinci (http://arago-project.org/git/projects/?p=linux-davinci.git;a=summary) Thanks. How does that relate to the TVP514x driver? Are they hooked together somehow? > ________________________________________ > From: Gary Thomas [gary at mlbassoc.com] > Sent: Tuesday, September 13, 2011 5:32 PM > To: Netagunte, Nagabhushana > Cc: Constantine Shulyupin; davinci-linux-open-source at linux.davincidsp.com; Hadli, Manjunath > Subject: Re: video capture application > > On 2011-09-13 04:27, Netagunte, Nagabhushana wrote: >> Constantine, >> >> If you are referring to media controller based branch 03.21.00.05, please refer to http://arago-project.org/git/projects/?p=examples-davinci.git;a=shortlog;h=refs/heads/03.21.00.03 for examples. >> >> Otherwise, if the branch you are referring to is r39, then, refer to http://arago-project.org/git/projects/?p=examples-davinci.git;a=shortlog;h=refs/heads/r38 for examples. >> >> Regards, >> Nag >> ________________________________________ >> From: Constantine Shulyupin [const at makelinux.com] >> Sent: Tuesday, September 13, 2011 3:20 PM >> To: Netagunte, Nagabhushana; davinci-linux-open-source at linux.davincidsp.com; Hadli, Manjunath >> Subject: video capture application >> >> Hi >> >> What application can I use to test video capture on dm365 with latest >> kernels located at >> git://arago-project.org/git/projects/linux-davinci.git and >> git://gitorious.org/linux-davinci/linux-davinci.git? >> ( DVSDK and other demo applications works only with older kernels from DVSDK) > > Which Linux source tree (git& branch) has the media controller support? > I looked at the examples mentioned above and see ioctl functions being used > with the TVP514x driver, but I can't find the driver that supports them, e.g. VIDIOC_S_INPUT?? > > Thanks > > -- > ------------------------------------------------------------ > Gary Thomas | Consulting for the > MLB Associates | Embedded world > ------------------------------------------------------------ -- ------------------------------------------------------------ Gary Thomas | Consulting for the MLB Associates | Embedded world ------------------------------------------------------------ From nagabhushana.netagunte at ti.com Tue Sep 13 07:53:45 2011 From: nagabhushana.netagunte at ti.com (Netagunte, Nagabhushana) Date: Tue, 13 Sep 2011 18:23:45 +0530 Subject: video capture application In-Reply-To: <4E6F4B7A.5030107@mlbassoc.com> References: , <4E6F4669.3050008@mlbassoc.com> , <4E6F4B7A.5030107@mlbassoc.com> Message-ID: Gary, s_routing is called from s_input of vpfe_video.c. Regards, Nag ________________________________________ From: Gary Thomas [gary at mlbassoc.com] Sent: Tuesday, September 13, 2011 5:54 PM To: Netagunte, Nagabhushana Cc: Constantine Shulyupin; davinci-linux-open-source at linux.davincidsp.com; Hadli, Manjunath Subject: Re: video capture application On 2011-09-13 06:05, Netagunte, Nagabhushana wrote: > Gary, > Please refer to - > > http://arago-project.org/git/projects/?p=linux-davinci.git;a=blob;f=drivers/media/video/davinci/vpfe_video.c;h=9555c93c4bcf4d92b1296883a6333161068f85ca;hb=6ac7a3440bbd9fc30c175c205f0efd4b2fd8cde7 > > Branch name:- 03.21.00.05 > Tree:- linux-davinci (http://arago-project.org/git/projects/?p=linux-davinci.git;a=summary) Thanks. How does that relate to the TVP514x driver? Are they hooked together somehow? > ________________________________________ > From: Gary Thomas [gary at mlbassoc.com] > Sent: Tuesday, September 13, 2011 5:32 PM > To: Netagunte, Nagabhushana > Cc: Constantine Shulyupin; davinci-linux-open-source at linux.davincidsp.com; Hadli, Manjunath > Subject: Re: video capture application > > On 2011-09-13 04:27, Netagunte, Nagabhushana wrote: >> Constantine, >> >> If you are referring to media controller based branch 03.21.00.05, please refer to http://arago-project.org/git/projects/?p=examples-davinci.git;a=shortlog;h=refs/heads/03.21.00.03 for examples. >> >> Otherwise, if the branch you are referring to is r39, then, refer to http://arago-project.org/git/projects/?p=examples-davinci.git;a=shortlog;h=refs/heads/r38 for examples. >> >> Regards, >> Nag >> ________________________________________ >> From: Constantine Shulyupin [const at makelinux.com] >> Sent: Tuesday, September 13, 2011 3:20 PM >> To: Netagunte, Nagabhushana; davinci-linux-open-source at linux.davincidsp.com; Hadli, Manjunath >> Subject: video capture application >> >> Hi >> >> What application can I use to test video capture on dm365 with latest >> kernels located at >> git://arago-project.org/git/projects/linux-davinci.git and >> git://gitorious.org/linux-davinci/linux-davinci.git? >> ( DVSDK and other demo applications works only with older kernels from DVSDK) > > Which Linux source tree (git& branch) has the media controller support? > I looked at the examples mentioned above and see ioctl functions being used > with the TVP514x driver, but I can't find the driver that supports them, e.g. VIDIOC_S_INPUT?? > > Thanks > > -- > ------------------------------------------------------------ > Gary Thomas | Consulting for the > MLB Associates | Embedded world > ------------------------------------------------------------ -- ------------------------------------------------------------ Gary Thomas | Consulting for the MLB Associates | Embedded world ------------------------------------------------------------ From nagabhushana.netagunte at ti.com Tue Sep 13 08:19:33 2011 From: nagabhushana.netagunte at ti.com (Netagunte, Nagabhushana) Date: Tue, 13 Sep 2011 18:49:33 +0530 Subject: DM365 with TVP5147M1 in bt656 10-bit mode? In-Reply-To: <7F1B6BBBDF05C649BBBA3C853F488A611B017C6213@Hawking.deepsea.com> References: <1314928015915-6752421.post@n2.nabble.com><74DFAE2329015E4288E958E7E3D155378B758FA092@EX-MAIL-HYD1-1.ant.amazon.com><7F1B6BBBDF05C649BBBA3C853F488A611B0177A1BC@Hawking.deepsea.com> , <7F1B6BBBDF05C649BBBA3C853F488A611B017C6213@Hawking.deepsea.com> Message-ID: Paul, "In 10-bit mode, is each pixel stored as 16 bits with the 10-bits in the lower half?" I believe you are right. You had mentioned that you are setting ccdccfg as "ccdcfg = ccdcfg | CCD_DATA_PACK8;". In addition to above setting you have to add "ccdcfg = CCDC_BW656_ENABLE" In indicating that it is 10 bit input. Refer this code - http://arago-project.org/git/projects/?p=linux-davinci.git;a=blob;f=drivers/media/video/davinci/dm365_ccdc.c;h=c06874fc73b5d93133cc8a06d24c7cc25ad31182;hb=3df7eda25fe6477a6005556fce821dbe86475c8d Also, how are you testing the captured data? Can you please share video files with us? Have you posted this query on Ti e2e forum? If not, it is a good idea to post so that query reaches big audience. Regards, Nag ________________________________________ From: davinci-linux-open-source-bounces at linux.davincidsp.com [davinci-linux-open-source-bounces at linux.davincidsp.com] On Behalf Of Paul Stuart [Paul_Stuart at seektech.com] Sent: Wednesday, September 07, 2011 8:32 PM To: Albert Burbea Cc: davinci-linux-open-source at linux.davincidsp.com Subject: RE: DM365 with TVP5147M1 in bt656 10-bit mode? Regarding PACK8 ? I?m perplexed what the data format *should* look like for captured BT.656. In the VPFE, they have plenty of examples for 8-bit mode, but nary a one for 10-bit. For example, the VPFE user guide specifies the following for ?BT.656 Mode Data Format in SDRAM? | Pixel3 (Y1) | Pixel2 (Cr0) | Pixel1 (Y0) | Pixel0 (Cb0) | Where each of these is 8 bits. In 10-bit mode, is each pixel stored as 16 bits with the 10-bits in the lower half? ________________________________ From: Albert Burbea [mailto:albertbu at gmail.com] Sent: Saturday, September 03, 2011 11:50 PM To: Paul Stuart Cc: davinci-linux-open-source at linux.davincidsp.com Subject: Re: DM365 with TVP5147M1 in bt656 10-bit mode? Hi Paul, this seems wrong to me. I think you do NOT have to specify CCD_DATA_PACK8 - this is for 8 bit values - but leave this bit at zero - so you will get all your ten bits in a 16 bit memory address. Also, please recheck your connections. I am not sure they are correct. Look in the VPFE users' guide - there are many examples. Albert On Fri, Sep 2, 2011 at 6:04 PM, Paul Stuart > wrote: Hi, We have a TVP5147M1 running in 10-bit BT656 with embedded syncs mode to our DM365, but getting "horrible video" (skewed color space, tons o' rolling noise). HW connection: Lines Y_0 - Y_7 from the TVP are running to CIN0-CIN7 on the DM365. Lines Y_8 and Y_9 from the TVP are running to YIN0 and YIN1 respectively on the DM365 SW setup: In our board config file, I specified if_type = VPFE_BT656_10BIT In the same file, the output route for the TVP5147 is set to OUTPUT_10BIT_422_EMBEDDED_SYNC In dm365_ccd.c: ccd_config_ycbcr for the case of VPFE_BT656_10BIT, I configure ccdcfg as follows: ccdcfg = ccdcfg | CCD_DATA_PACK8; In the same file I've changed the pix_fmt to CCDC_PIXFMT_YCBCR_16BIT, per the VPFE frontend user guide. TVP Setup: I've set it up to output 10-bit 656 with embedded syncs. We get interrupts, get "video", it just looks really bad. Am I missing something obvious in my setup? Has anyone had success with 10-bit BT.656 on the DM365? Thanks, Paul _______________________________________________ Davinci-linux-open-source mailing list Davinci-linux-open-source at linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source -- Albert Burbea Harishonim 8 Ramat Gan 52502, Israel Tel/Fax + 972-3-7526016 Mobile: +972-52-3541842 From paul_stuart at seektech.com Tue Sep 13 08:57:18 2011 From: paul_stuart at seektech.com (Paul Stuart) Date: Tue, 13 Sep 2011 06:57:18 -0700 Subject: DM365 with TVP5147M1 in bt656 10-bit mode? In-Reply-To: References: <1314928015915-6752421.post@n2.nabble.com><74DFAE2329015E4288E958E7E3D155378B758FA092@EX-MAIL-HYD1-1.ant.amazon.com><7F1B6BBBDF05C649BBBA3C853F488A611B0177A1BC@Hawking.deepsea.com> , <7F1B6BBBDF05C649BBBA3C853F488A611B017C6213@Hawking.deepsea.com> Message-ID: <4E6F613E.2010302@seektech.com> Nag, Thanks, I've learned a few things since the last posting. Turns out that my capture side is fine, it's the VPBE that won't play nice. When capturing 10-bit BT.656, each component for Y, Cb, Cr, is packed into 16 bits, vs 8 bits for 8-bit BT.656. So, now one needs 64 bits for every two pixels vs 32 bits for every two pixels. As far as I can tell, the VPBE will not display this format. Every mention of YUV422 format indicates it wants 16 bits per pixel. It simply can't display the captured format. I've also heard that the codecs won't accept the expanded color format. I'm perplexed why 10-bit BT.656 is even an option if nothing downstream can make use of it. Thanks, Paul Netagunte, Nagabhushana wrote: > Paul, > > "In 10-bit mode, is each pixel stored as 16 bits with the 10-bits in the lower half?" > > I believe you are right. > > You had mentioned that you are setting ccdccfg as "ccdcfg = ccdcfg | CCD_DATA_PACK8;". > > In addition to above setting you have to add "ccdcfg = CCDC_BW656_ENABLE" In indicating that it is 10 bit input. Refer this code - http://arago-project.org/git/projects/?p=linux-davinci.git;a=blob;f=drivers/media/video/davinci/dm365_ccdc.c;h=c06874fc73b5d93133cc8a06d24c7cc25ad31182;hb=3df7eda25fe6477a6005556fce821dbe86475c8d > > Also, how are you testing the captured data? Can you please share video files with us? > > Have you posted this query on Ti e2e forum? If not, it is a good idea to post so that query reaches big audience. > > Regards, > Nag > > ________________________________________ > From: davinci-linux-open-source-bounces at linux.davincidsp.com [davinci-linux-open-source-bounces at linux.davincidsp.com] On Behalf Of Paul Stuart [Paul_Stuart at seektech.com] > Sent: Wednesday, September 07, 2011 8:32 PM > To: Albert Burbea > Cc: davinci-linux-open-source at linux.davincidsp.com > Subject: RE: DM365 with TVP5147M1 in bt656 10-bit mode? > > Regarding PACK8 ? I?m perplexed what the data format *should* look like for captured BT.656. In the VPFE, they have plenty of examples for 8-bit mode, but nary a one for 10-bit. For example, the VPFE user guide specifies the following for ?BT.656 Mode Data Format in SDRAM? > | Pixel3 (Y1) | Pixel2 (Cr0) | Pixel1 (Y0) | Pixel0 (Cb0) | > Where each of these is 8 bits. > > In 10-bit mode, is each pixel stored as 16 bits with the 10-bits in the lower half? > > > > ________________________________ > From: Albert Burbea [mailto:albertbu at gmail.com] > Sent: Saturday, September 03, 2011 11:50 PM > To: Paul Stuart > Cc: davinci-linux-open-source at linux.davincidsp.com > Subject: Re: DM365 with TVP5147M1 in bt656 10-bit mode? > > Hi Paul, > this seems wrong to me. > I think you do NOT have to specify CCD_DATA_PACK8 - this is for 8 bit values - but leave this bit at zero - so you will get all your ten bits in a 16 bit memory address. > Also, please recheck your connections. I am not sure they are correct. Look in the VPFE users' guide - there are many examples. > Albert > On Fri, Sep 2, 2011 at 6:04 PM, Paul Stuart > wrote: > Hi, > We have a TVP5147M1 running in 10-bit BT656 with embedded syncs mode to our DM365, but getting "horrible video" (skewed color space, tons o' rolling noise). > > HW connection: > Lines Y_0 - Y_7 from the TVP are running to CIN0-CIN7 on the DM365. Lines Y_8 and Y_9 from the TVP are running to YIN0 and YIN1 respectively on the DM365 > > SW setup: > In our board config file, I specified if_type = VPFE_BT656_10BIT > > In the same file, the output route for the TVP5147 is set to OUTPUT_10BIT_422_EMBEDDED_SYNC > > In dm365_ccd.c: ccd_config_ycbcr for the case of VPFE_BT656_10BIT, I configure ccdcfg as follows: > ccdcfg = ccdcfg | CCD_DATA_PACK8; > > In the same file I've changed the pix_fmt to CCDC_PIXFMT_YCBCR_16BIT, per the VPFE frontend user guide. > > > TVP Setup: > I've set it up to output 10-bit 656 with embedded syncs. > > > > We get interrupts, get "video", it just looks really bad. Am I missing something obvious in my setup? Has anyone had success with 10-bit BT.656 on the DM365? > > Thanks, > Paul > _______________________________________________ > Davinci-linux-open-source mailing list > Davinci-linux-open-source at linux.davincidsp.com > http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source > > > > -- > Albert Burbea > Harishonim 8 > Ramat Gan 52502, Israel > Tel/Fax + 972-3-7526016 > Mobile: +972-52-3541842 > From m-karicheri2 at ti.com Tue Sep 13 09:52:08 2011 From: m-karicheri2 at ti.com (Karicheri, Muralidharan) Date: Tue, 13 Sep 2011 14:52:08 +0000 Subject: [PATCH v2 1/2] ARM: davinci - fix incorrect offsets and mask usage in psc code In-Reply-To: References: <1314899316-2708-1-git-send-email-m-karicheri2@ti.com> <4E5FD371.1020200@mvista.com> <4E6785C0.7010709@mvista.com> <3E54258959B69E4282D79E01AB1F32B701B8A7@DLEE12.ent.ti.com> <4E67B570.80100@mvista.com> Message-ID: <3E54258959B69E4282D79E01AB1F32B701C494@DLEE12.ent.ti.com> Sekhar, V2 of my patch already moved the mask change to a separate patch. I will be resending my v3 (hopefully final) this week after incorporating one comment from Sergei. Murali Karicheri Software Design Engineer email: m-karicheri2 at ti.com Phone: (301) 407 9583 >> -----Original Message----- >> From: Nori, Sekhar >> Sent: Monday, September 12, 2011 8:48 AM >> To: Karicheri, Muralidharan >> Cc: davinci-linux-open-source at linux.davincidsp.com; Hilman, Kevin; Sergei >> Shtylyov >> Subject: RE: [PATCH v2 1/2] ARM: davinci - fix incorrect offsets and mask >> usage in psc code >> >> Hi Murali, >> >> On Wed, Sep 07, 2011 at 23:48:24, Sergei Shtylyov wrote: >> > On 09/07/2011 07:32 PM, Karicheri, Muralidharan wrote: >> > > Sergei, >> > >> > > Thanks for all your investigation work and comments. I will take care >> of your recent comments against v2 in v3. Looks like the mask is being >> corrected by a different Patch (ARM: davinci: correct MDSTAT_STATE_MASK) >> and I can remove the same from my patch. >> > >> > This is a different register, MDSTAT vs PDSTAT in our case... >> >> I also suggest moving the mask fix into another patch. >> >> Thanks, >> Sekhar From lrg at ti.com Tue Sep 13 09:52:48 2011 From: lrg at ti.com (Liam Girdwood) Date: Tue, 13 Sep 2011 15:52:48 +0100 Subject: [PATCH] ASoC: davinci-pcm: trivial: replace link with actual chan/link In-Reply-To: <1315602365-30105-1-git-send-email-bengardiner@nanometrics.ca> References: <1315602365-30105-1-git-send-email-bengardiner@nanometrics.ca> Message-ID: <1315925568.5157.9.camel@odin> On Fri, 2011-09-09 at 17:06 -0400, Ben Gardiner wrote: > The ambiguously named variable 'link' is used as a temporary throughout > davinci-pcm -- its presence makes grepping (and groking) the code > difficult. > > Replace link with the value of link in almost all sites. The exception > is a couple places where the last-assigned link/chan needs to be > returned by a function -- in these cases, rename to last_link. > > Signed-off-by: Ben Gardiner Acked-by: Liam Girdwood > --- > sound/soc/davinci/davinci-pcm.c | 123 +++++++++++++++++++-------------------- > 1 files changed, 59 insertions(+), 64 deletions(-) > > diff --git a/sound/soc/davinci/davinci-pcm.c b/sound/soc/davinci/davinci-pcm.c > index a49e667..d5fe08c 100644 > --- a/sound/soc/davinci/davinci-pcm.c > +++ b/sound/soc/davinci/davinci-pcm.c > @@ -180,7 +180,6 @@ static void davinci_pcm_enqueue_dma(struct snd_pcm_substream *substream) > { > struct davinci_runtime_data *prtd = substream->runtime->private_data; > struct snd_pcm_runtime *runtime = substream->runtime; > - int link = prtd->asp_link[0]; > unsigned int period_size; > unsigned int dma_offset; > dma_addr_t dma_pos; > @@ -198,7 +197,8 @@ static void davinci_pcm_enqueue_dma(struct snd_pcm_substream *substream) > fifo_level = prtd->params->fifo_level; > > pr_debug("davinci_pcm: audio_set_dma_params_play channel = %d " > - "dma_ptr = %x period_size=%x\n", link, dma_pos, period_size); > + "dma_ptr = %x period_size=%x\n", prtd->asp_link[0], dma_pos, > + period_size); > > data_type = prtd->params->data_type; > count = period_size / data_type; > @@ -222,17 +222,19 @@ static void davinci_pcm_enqueue_dma(struct snd_pcm_substream *substream) > } > > acnt = prtd->params->acnt; > - edma_set_src(link, src, INCR, W8BIT); > - edma_set_dest(link, dst, INCR, W8BIT); > + edma_set_src(prtd->asp_link[0], src, INCR, W8BIT); > + edma_set_dest(prtd->asp_link[0], dst, INCR, W8BIT); > > - edma_set_src_index(link, src_bidx, src_cidx); > - edma_set_dest_index(link, dst_bidx, dst_cidx); > + edma_set_src_index(prtd->asp_link[0], src_bidx, src_cidx); > + edma_set_dest_index(prtd->asp_link[0], dst_bidx, dst_cidx); > > if (!fifo_level) > - edma_set_transfer_params(link, acnt, count, 1, 0, ASYNC); > + edma_set_transfer_params(prtd->asp_link[0], acnt, count, 1, 0, > + ASYNC); > else > - edma_set_transfer_params(link, acnt, fifo_level, count, > - fifo_level, ABSYNC); > + edma_set_transfer_params(prtd->asp_link[0], acnt, fifo_level, > + count, fifo_level, > + ABSYNC); > } > > static void davinci_pcm_dma_irq(unsigned link, u16 ch_status, void *data) > @@ -305,7 +307,6 @@ static int ping_pong_dma_setup(struct snd_pcm_substream *substream) > unsigned int acnt = params->acnt; > /* divide by 2 for ping/pong */ > unsigned int ping_size = snd_pcm_lib_period_bytes(substream) >> 1; > - int link = prtd->asp_link[1]; > unsigned int fifo_level = prtd->params->fifo_level; > unsigned int count; > if ((data_type == 0) || (data_type > 4)) { > @@ -316,28 +317,26 @@ static int ping_pong_dma_setup(struct snd_pcm_substream *substream) > dma_addr_t asp_src_pong = iram_dma->addr + ping_size; > ram_src_cidx = ping_size; > ram_dst_cidx = -ping_size; > - edma_set_src(link, asp_src_pong, INCR, W8BIT); > + edma_set_src(prtd->asp_link[1], asp_src_pong, INCR, W8BIT); > > - link = prtd->asp_link[0]; > - edma_set_src_index(link, data_type, data_type * fifo_level); > - link = prtd->asp_link[1]; > - edma_set_src_index(link, data_type, data_type * fifo_level); > + edma_set_src_index(prtd->asp_link[0], data_type, > + data_type * fifo_level); > + edma_set_src_index(prtd->asp_link[1], data_type, > + data_type * fifo_level); > > - link = prtd->ram_link; > - edma_set_src(link, runtime->dma_addr, INCR, W32BIT); > + edma_set_src(prtd->ram_link, runtime->dma_addr, INCR, W32BIT); > } else { > dma_addr_t asp_dst_pong = iram_dma->addr + ping_size; > ram_src_cidx = -ping_size; > ram_dst_cidx = ping_size; > - edma_set_dest(link, asp_dst_pong, INCR, W8BIT); > + edma_set_dest(prtd->asp_link[1], asp_dst_pong, INCR, W8BIT); > > - link = prtd->asp_link[0]; > - edma_set_dest_index(link, data_type, data_type * fifo_level); > - link = prtd->asp_link[1]; > - edma_set_dest_index(link, data_type, data_type * fifo_level); > + edma_set_dest_index(prtd->asp_link[0], data_type, > + data_type * fifo_level); > + edma_set_dest_index(prtd->asp_link[1], data_type, > + data_type * fifo_level); > > - link = prtd->ram_link; > - edma_set_dest(link, runtime->dma_addr, INCR, W32BIT); > + edma_set_dest(prtd->ram_link, runtime->dma_addr, INCR, W32BIT); > } > > if (!fifo_level) { > @@ -354,10 +353,9 @@ static int ping_pong_dma_setup(struct snd_pcm_substream *substream) > count, fifo_level, ABSYNC); > } > > - link = prtd->ram_link; > - edma_set_src_index(link, ping_size, ram_src_cidx); > - edma_set_dest_index(link, ping_size, ram_dst_cidx); > - edma_set_transfer_params(link, ping_size, 2, > + edma_set_src_index(prtd->ram_link, ping_size, ram_src_cidx); > + edma_set_dest_index(prtd->ram_link, ping_size, ram_dst_cidx); > + edma_set_transfer_params(prtd->ram_link, ping_size, 2, > runtime->periods, 2, ASYNC); > > /* init master params */ > @@ -406,32 +404,32 @@ static int request_ping_pong(struct snd_pcm_substream *substream, > { > dma_addr_t asp_src_ping; > dma_addr_t asp_dst_ping; > - int link; > + int ret; > struct davinci_pcm_dma_params *params = prtd->params; > > /* Request ram master channel */ > - link = prtd->ram_channel = edma_alloc_channel(EDMA_CHANNEL_ANY, > + ret = prtd->ram_channel = edma_alloc_channel(EDMA_CHANNEL_ANY, > davinci_pcm_dma_irq, substream, > prtd->params->ram_chan_q); > - if (link < 0) > + if (ret < 0) > goto exit1; > > /* Request ram link channel */ > - link = prtd->ram_link = edma_alloc_slot( > + ret = prtd->ram_link = edma_alloc_slot( > EDMA_CTLR(prtd->ram_channel), EDMA_SLOT_ANY); > - if (link < 0) > + if (ret < 0) > goto exit2; > > - link = prtd->asp_link[1] = edma_alloc_slot( > + ret = prtd->asp_link[1] = edma_alloc_slot( > EDMA_CTLR(prtd->asp_channel), EDMA_SLOT_ANY); > - if (link < 0) > + if (ret < 0) > goto exit3; > > prtd->ram_link2 = -1; > if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { > - link = prtd->ram_link2 = edma_alloc_slot( > + ret = prtd->ram_link2 = edma_alloc_slot( > EDMA_CTLR(prtd->ram_channel), EDMA_SLOT_ANY); > - if (link < 0) > + if (ret < 0) > goto exit4; > } > /* circle ping-pong buffers */ > @@ -448,36 +446,33 @@ static int request_ping_pong(struct snd_pcm_substream *substream, > asp_dst_ping = iram_dma->addr; > } > /* ping */ > - link = prtd->asp_link[0]; > - edma_set_src(link, asp_src_ping, INCR, W16BIT); > - edma_set_dest(link, asp_dst_ping, INCR, W16BIT); > - edma_set_src_index(link, 0, 0); > - edma_set_dest_index(link, 0, 0); > + edma_set_src(prtd->asp_link[0], asp_src_ping, INCR, W16BIT); > + edma_set_dest(prtd->asp_link[0], asp_dst_ping, INCR, W16BIT); > + edma_set_src_index(prtd->asp_link[0], 0, 0); > + edma_set_dest_index(prtd->asp_link[0], 0, 0); > > - edma_read_slot(link, &prtd->asp_params); > + edma_read_slot(prtd->asp_link[0], &prtd->asp_params); > prtd->asp_params.opt &= ~(TCCMODE | EDMA_TCC(0x3f) | TCINTEN); > prtd->asp_params.opt |= TCCHEN | > EDMA_TCC(prtd->ram_channel & 0x3f); > - edma_write_slot(link, &prtd->asp_params); > + edma_write_slot(prtd->asp_link[0], &prtd->asp_params); > > /* pong */ > - link = prtd->asp_link[1]; > - edma_set_src(link, asp_src_ping, INCR, W16BIT); > - edma_set_dest(link, asp_dst_ping, INCR, W16BIT); > - edma_set_src_index(link, 0, 0); > - edma_set_dest_index(link, 0, 0); > + edma_set_src(prtd->asp_link[1], asp_src_ping, INCR, W16BIT); > + edma_set_dest(prtd->asp_link[1], asp_dst_ping, INCR, W16BIT); > + edma_set_src_index(prtd->asp_link[1], 0, 0); > + edma_set_dest_index(prtd->asp_link[1], 0, 0); > > - edma_read_slot(link, &prtd->asp_params); > + edma_read_slot(prtd->asp_link[1], &prtd->asp_params); > prtd->asp_params.opt &= ~(TCCMODE | EDMA_TCC(0x3f)); > /* interrupt after every pong completion */ > prtd->asp_params.opt |= TCINTEN | TCCHEN | > EDMA_TCC(prtd->ram_channel & 0x3f); > - edma_write_slot(link, &prtd->asp_params); > + edma_write_slot(prtd->asp_link[1], &prtd->asp_params); > > /* ram */ > - link = prtd->ram_link; > - edma_set_src(link, iram_dma->addr, INCR, W32BIT); > - edma_set_dest(link, iram_dma->addr, INCR, W32BIT); > + edma_set_src(prtd->ram_link, iram_dma->addr, INCR, W32BIT); > + edma_set_dest(prtd->ram_link, iram_dma->addr, INCR, W32BIT); > pr_debug("%s: audio dma channels/slots in use for ram:%u %u %u," > "for asp:%u %u %u\n", __func__, > prtd->ram_channel, prtd->ram_link, prtd->ram_link2, > @@ -494,7 +489,7 @@ exit2: > edma_free_channel(prtd->ram_channel); > prtd->ram_channel = -1; > exit1: > - return link; > + return ret; > } > > static int davinci_pcm_dma_request(struct snd_pcm_substream *substream) > @@ -502,22 +497,22 @@ static int davinci_pcm_dma_request(struct snd_pcm_substream *substream) > struct snd_dma_buffer *iram_dma; > struct davinci_runtime_data *prtd = substream->runtime->private_data; > struct davinci_pcm_dma_params *params = prtd->params; > - int link; > + int ret; > > if (!params) > return -ENODEV; > > /* Request asp master DMA channel */ > - link = prtd->asp_channel = edma_alloc_channel(params->channel, > + ret = prtd->asp_channel = edma_alloc_channel(params->channel, > davinci_pcm_dma_irq, substream, > prtd->params->asp_chan_q); > - if (link < 0) > + if (ret < 0) > goto exit1; > > /* Request asp link channels */ > - link = prtd->asp_link[0] = edma_alloc_slot( > + ret = prtd->asp_link[0] = edma_alloc_slot( > EDMA_CTLR(prtd->asp_channel), EDMA_SLOT_ANY); > - if (link < 0) > + if (ret < 0) > goto exit2; > > iram_dma = (struct snd_dma_buffer *)substream->dma_buffer.private_data; > @@ -537,17 +532,17 @@ static int davinci_pcm_dma_request(struct snd_pcm_substream *substream) > * the buffer and its length (ccnt) ... use it as a template > * so davinci_pcm_enqueue_dma() takes less time in IRQ. > */ > - edma_read_slot(link, &prtd->asp_params); > + edma_read_slot(prtd->asp_link[0], &prtd->asp_params); > prtd->asp_params.opt |= TCINTEN | > EDMA_TCC(EDMA_CHAN_SLOT(prtd->asp_channel)); > - prtd->asp_params.link_bcntrld = EDMA_CHAN_SLOT(link) << 5; > - edma_write_slot(link, &prtd->asp_params); > + prtd->asp_params.link_bcntrld = EDMA_CHAN_SLOT(prtd->asp_link[0]) << 5; > + edma_write_slot(prtd->asp_link[0], &prtd->asp_params); > return 0; > exit2: > edma_free_channel(prtd->asp_channel); > prtd->asp_channel = -1; > exit1: > - return link; > + return ret; > } > > static int davinci_pcm_trigger(struct snd_pcm_substream *substream, int cmd) From m-karicheri2 at ti.com Tue Sep 13 09:58:25 2011 From: m-karicheri2 at ti.com (Karicheri, Muralidharan) Date: Tue, 13 Sep 2011 14:58:25 +0000 Subject: [PATCH v2 1/2] ARM: davinci - fix incorrect offsets and mask usage in psc code In-Reply-To: <4E6A2AEE.6050001@mvista.com> References: <1314899316-2708-1-git-send-email-m-karicheri2@ti.com> <4E5FD371.1020200@mvista.com> <3E54258959B69E4282D79E01AB1F32B701B2C9@DLEE12.ent.ti.com> <4E617D89.80307@mvista.com> <4E662B93.7080701@mvista.com> <4E662FEA.7090908@mvista.com> <4E6A2902.4000305@mvista.com> <4E6A2AEE.6050001@mvista.com> Message-ID: <3E54258959B69E4282D79E01AB1F32B701C4B4@DLEE12.ent.ti.com> Sergei, Looks like EPCPR register is not available on all platforms. It appears to be specific to the DM644x SoC. So doesn't it make sense to execute it only for DM644x. Any comments? Murali Karicheri Software Design Engineer email: m-karicheri2 at ti.com Phone: (301) 407 9583 >> -----Original Message----- >> From: Sergei Shtylyov [mailto:sshtylyov at mvista.com] >> Sent: Friday, September 09, 2011 11:04 AM >> To: Karicheri, Muralidharan >> Cc: davinci-linux-open-source at linux.davincidsp.com; Nori, Sekhar; Hilman, >> Kevin >> Subject: Re: [PATCH v2 1/2] ARM: davinci - fix incorrect offsets and mask >> usage in psc code >> >> Hello,. >> >> On 09/09/2011 06:56 PM, Sergei Shtylyov wrote: >> >> >>>>>>>> Signed-off-by: Murali Karicheri >> >>>> [...] >> >> >>>>>>>> + pdctl = __raw_readl(psc_base + PDCTL + 4 * domain); >> >>>>>>>> + pdctl |= 0x1; >> >>>>>>>> + __raw_writel(pdctl, psc_base + PDCTL + 4 * domain); >> >>>>>>>> >> >>>>>>>> ptcmd = 1<< domain; >> >>>>>>>> __raw_writel(ptcmd, psc_base + PTCMD); >> >>>>>>>> @@ -92,9 +92,10 @@ void davinci_psc_config(unsigned int domain, >> unsigned >> >>>>>>> int ctlr, >> >>>>>>>> epcpr = __raw_readl(psc_base + EPCPR); >> >>>>>>>> } while ((((epcpr>> domain)& 1) == 0)); >> >> >>>>>>> Does this work for ARM domain, i.e. does it require an external >> power >> >>>>>>> supply too? >> >> >>>>> Not sure. Will someone actively using the DaVinci platforms answer >> this >> >>>>> question? >> >> >>>> I may try to verify on my DM6446 if I'll find the time... >> >> >>> Hmm, DA8x0 documentation doesn't even mention the EPCPR register, so >> I'm not >> >>> sure how this loop is supposed to work on those chips... unless this >> path is >> >>> never actually executed -- which I'm trying to check now... >> >> >> Have verified that the patch was never being executed indeed. If I make >> it >> >> > s/patch/path/ >> >> >> executed, the board happily locks up. >> >> > I have experimented further and added code to power off domain 1 before >> powering >> > it on in davinci_psc_config(). Strangely, it worked -- "OMAP-L137 >> Application >> > Processor System Reference Guide" says that powering off domain 1 is not >> > supported. The board still locks up while polling the EPCPR register -- >> which >> > doesn't exist on DA8xx. >> >> BTW, I have tried the same on the DM6446 EVM board and there it locked >> up >> while polling the PTSTAT register after sent command to I power down the >> DSP >> domain. This seems to be in accordance with DM6446 datasheet which says >> that >> once powered on, DSP domain cannot be dynamically powered off. So I >> couldn't >> test the EPCPR polling loop on DM6446... >> >> WBR, Sergei From lrg at ti.com Tue Sep 13 11:16:18 2011 From: lrg at ti.com (Liam Girdwood) Date: Tue, 13 Sep 2011 17:16:18 +0100 Subject: [PATCH] ASoC: davinci-pcm: trivial: replace link with actual chan/link In-Reply-To: <1315602365-30105-1-git-send-email-bengardiner@nanometrics.ca> References: <1315602365-30105-1-git-send-email-bengardiner@nanometrics.ca> Message-ID: <1315930578.5157.17.camel@odin> On Fri, 2011-09-09 at 17:06 -0400, Ben Gardiner wrote: > The ambiguously named variable 'link' is used as a temporary throughout > davinci-pcm -- its presence makes grepping (and groking) the code > difficult. > > Replace link with the value of link in almost all sites. The exception > is a couple places where the last-assigned link/chan needs to be > returned by a function -- in these cases, rename to last_link. > > Signed-off-by: Ben Gardiner Acked-by: Liam Girdwood > --- > sound/soc/davinci/davinci-pcm.c | 123 +++++++++++++++++++-------------------- > 1 files changed, 59 insertions(+), 64 deletions(-) > > diff --git a/sound/soc/davinci/davinci-pcm.c b/sound/soc/davinci/davinci-pcm.c > index a49e667..d5fe08c 100644 > --- a/sound/soc/davinci/davinci-pcm.c > +++ b/sound/soc/davinci/davinci-pcm.c > @@ -180,7 +180,6 @@ static void davinci_pcm_enqueue_dma(struct snd_pcm_substream *substream) > { > struct davinci_runtime_data *prtd = substream->runtime->private_data; > struct snd_pcm_runtime *runtime = substream->runtime; > - int link = prtd->asp_link[0]; > unsigned int period_size; > unsigned int dma_offset; > dma_addr_t dma_pos; > @@ -198,7 +197,8 @@ static void davinci_pcm_enqueue_dma(struct snd_pcm_substream *substream) > fifo_level = prtd->params->fifo_level; > > pr_debug("davinci_pcm: audio_set_dma_params_play channel = %d " > - "dma_ptr = %x period_size=%x\n", link, dma_pos, period_size); > + "dma_ptr = %x period_size=%x\n", prtd->asp_link[0], dma_pos, > + period_size); > > data_type = prtd->params->data_type; > count = period_size / data_type; > @@ -222,17 +222,19 @@ static void davinci_pcm_enqueue_dma(struct snd_pcm_substream *substream) > } > > acnt = prtd->params->acnt; > - edma_set_src(link, src, INCR, W8BIT); > - edma_set_dest(link, dst, INCR, W8BIT); > + edma_set_src(prtd->asp_link[0], src, INCR, W8BIT); > + edma_set_dest(prtd->asp_link[0], dst, INCR, W8BIT); > > - edma_set_src_index(link, src_bidx, src_cidx); > - edma_set_dest_index(link, dst_bidx, dst_cidx); > + edma_set_src_index(prtd->asp_link[0], src_bidx, src_cidx); > + edma_set_dest_index(prtd->asp_link[0], dst_bidx, dst_cidx); > > if (!fifo_level) > - edma_set_transfer_params(link, acnt, count, 1, 0, ASYNC); > + edma_set_transfer_params(prtd->asp_link[0], acnt, count, 1, 0, > + ASYNC); > else > - edma_set_transfer_params(link, acnt, fifo_level, count, > - fifo_level, ABSYNC); > + edma_set_transfer_params(prtd->asp_link[0], acnt, fifo_level, > + count, fifo_level, > + ABSYNC); > } > > static void davinci_pcm_dma_irq(unsigned link, u16 ch_status, void *data) > @@ -305,7 +307,6 @@ static int ping_pong_dma_setup(struct snd_pcm_substream *substream) > unsigned int acnt = params->acnt; > /* divide by 2 for ping/pong */ > unsigned int ping_size = snd_pcm_lib_period_bytes(substream) >> 1; > - int link = prtd->asp_link[1]; > unsigned int fifo_level = prtd->params->fifo_level; > unsigned int count; > if ((data_type == 0) || (data_type > 4)) { > @@ -316,28 +317,26 @@ static int ping_pong_dma_setup(struct snd_pcm_substream *substream) > dma_addr_t asp_src_pong = iram_dma->addr + ping_size; > ram_src_cidx = ping_size; > ram_dst_cidx = -ping_size; > - edma_set_src(link, asp_src_pong, INCR, W8BIT); > + edma_set_src(prtd->asp_link[1], asp_src_pong, INCR, W8BIT); > > - link = prtd->asp_link[0]; > - edma_set_src_index(link, data_type, data_type * fifo_level); > - link = prtd->asp_link[1]; > - edma_set_src_index(link, data_type, data_type * fifo_level); > + edma_set_src_index(prtd->asp_link[0], data_type, > + data_type * fifo_level); > + edma_set_src_index(prtd->asp_link[1], data_type, > + data_type * fifo_level); > > - link = prtd->ram_link; > - edma_set_src(link, runtime->dma_addr, INCR, W32BIT); > + edma_set_src(prtd->ram_link, runtime->dma_addr, INCR, W32BIT); > } else { > dma_addr_t asp_dst_pong = iram_dma->addr + ping_size; > ram_src_cidx = -ping_size; > ram_dst_cidx = ping_size; > - edma_set_dest(link, asp_dst_pong, INCR, W8BIT); > + edma_set_dest(prtd->asp_link[1], asp_dst_pong, INCR, W8BIT); > > - link = prtd->asp_link[0]; > - edma_set_dest_index(link, data_type, data_type * fifo_level); > - link = prtd->asp_link[1]; > - edma_set_dest_index(link, data_type, data_type * fifo_level); > + edma_set_dest_index(prtd->asp_link[0], data_type, > + data_type * fifo_level); > + edma_set_dest_index(prtd->asp_link[1], data_type, > + data_type * fifo_level); > > - link = prtd->ram_link; > - edma_set_dest(link, runtime->dma_addr, INCR, W32BIT); > + edma_set_dest(prtd->ram_link, runtime->dma_addr, INCR, W32BIT); > } > > if (!fifo_level) { > @@ -354,10 +353,9 @@ static int ping_pong_dma_setup(struct snd_pcm_substream *substream) > count, fifo_level, ABSYNC); > } > > - link = prtd->ram_link; > - edma_set_src_index(link, ping_size, ram_src_cidx); > - edma_set_dest_index(link, ping_size, ram_dst_cidx); > - edma_set_transfer_params(link, ping_size, 2, > + edma_set_src_index(prtd->ram_link, ping_size, ram_src_cidx); > + edma_set_dest_index(prtd->ram_link, ping_size, ram_dst_cidx); > + edma_set_transfer_params(prtd->ram_link, ping_size, 2, > runtime->periods, 2, ASYNC); > > /* init master params */ > @@ -406,32 +404,32 @@ static int request_ping_pong(struct snd_pcm_substream *substream, > { > dma_addr_t asp_src_ping; > dma_addr_t asp_dst_ping; > - int link; > + int ret; > struct davinci_pcm_dma_params *params = prtd->params; > > /* Request ram master channel */ > - link = prtd->ram_channel = edma_alloc_channel(EDMA_CHANNEL_ANY, > + ret = prtd->ram_channel = edma_alloc_channel(EDMA_CHANNEL_ANY, > davinci_pcm_dma_irq, substream, > prtd->params->ram_chan_q); > - if (link < 0) > + if (ret < 0) > goto exit1; > > /* Request ram link channel */ > - link = prtd->ram_link = edma_alloc_slot( > + ret = prtd->ram_link = edma_alloc_slot( > EDMA_CTLR(prtd->ram_channel), EDMA_SLOT_ANY); > - if (link < 0) > + if (ret < 0) > goto exit2; > > - link = prtd->asp_link[1] = edma_alloc_slot( > + ret = prtd->asp_link[1] = edma_alloc_slot( > EDMA_CTLR(prtd->asp_channel), EDMA_SLOT_ANY); > - if (link < 0) > + if (ret < 0) > goto exit3; > > prtd->ram_link2 = -1; > if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { > - link = prtd->ram_link2 = edma_alloc_slot( > + ret = prtd->ram_link2 = edma_alloc_slot( > EDMA_CTLR(prtd->ram_channel), EDMA_SLOT_ANY); > - if (link < 0) > + if (ret < 0) > goto exit4; > } > /* circle ping-pong buffers */ > @@ -448,36 +446,33 @@ static int request_ping_pong(struct snd_pcm_substream *substream, > asp_dst_ping = iram_dma->addr; > } > /* ping */ > - link = prtd->asp_link[0]; > - edma_set_src(link, asp_src_ping, INCR, W16BIT); > - edma_set_dest(link, asp_dst_ping, INCR, W16BIT); > - edma_set_src_index(link, 0, 0); > - edma_set_dest_index(link, 0, 0); > + edma_set_src(prtd->asp_link[0], asp_src_ping, INCR, W16BIT); > + edma_set_dest(prtd->asp_link[0], asp_dst_ping, INCR, W16BIT); > + edma_set_src_index(prtd->asp_link[0], 0, 0); > + edma_set_dest_index(prtd->asp_link[0], 0, 0); > > - edma_read_slot(link, &prtd->asp_params); > + edma_read_slot(prtd->asp_link[0], &prtd->asp_params); > prtd->asp_params.opt &= ~(TCCMODE | EDMA_TCC(0x3f) | TCINTEN); > prtd->asp_params.opt |= TCCHEN | > EDMA_TCC(prtd->ram_channel & 0x3f); > - edma_write_slot(link, &prtd->asp_params); > + edma_write_slot(prtd->asp_link[0], &prtd->asp_params); > > /* pong */ > - link = prtd->asp_link[1]; > - edma_set_src(link, asp_src_ping, INCR, W16BIT); > - edma_set_dest(link, asp_dst_ping, INCR, W16BIT); > - edma_set_src_index(link, 0, 0); > - edma_set_dest_index(link, 0, 0); > + edma_set_src(prtd->asp_link[1], asp_src_ping, INCR, W16BIT); > + edma_set_dest(prtd->asp_link[1], asp_dst_ping, INCR, W16BIT); > + edma_set_src_index(prtd->asp_link[1], 0, 0); > + edma_set_dest_index(prtd->asp_link[1], 0, 0); > > - edma_read_slot(link, &prtd->asp_params); > + edma_read_slot(prtd->asp_link[1], &prtd->asp_params); > prtd->asp_params.opt &= ~(TCCMODE | EDMA_TCC(0x3f)); > /* interrupt after every pong completion */ > prtd->asp_params.opt |= TCINTEN | TCCHEN | > EDMA_TCC(prtd->ram_channel & 0x3f); > - edma_write_slot(link, &prtd->asp_params); > + edma_write_slot(prtd->asp_link[1], &prtd->asp_params); > > /* ram */ > - link = prtd->ram_link; > - edma_set_src(link, iram_dma->addr, INCR, W32BIT); > - edma_set_dest(link, iram_dma->addr, INCR, W32BIT); > + edma_set_src(prtd->ram_link, iram_dma->addr, INCR, W32BIT); > + edma_set_dest(prtd->ram_link, iram_dma->addr, INCR, W32BIT); > pr_debug("%s: audio dma channels/slots in use for ram:%u %u %u," > "for asp:%u %u %u\n", __func__, > prtd->ram_channel, prtd->ram_link, prtd->ram_link2, > @@ -494,7 +489,7 @@ exit2: > edma_free_channel(prtd->ram_channel); > prtd->ram_channel = -1; > exit1: > - return link; > + return ret; > } > > static int davinci_pcm_dma_request(struct snd_pcm_substream *substream) > @@ -502,22 +497,22 @@ static int davinci_pcm_dma_request(struct snd_pcm_substream *substream) > struct snd_dma_buffer *iram_dma; > struct davinci_runtime_data *prtd = substream->runtime->private_data; > struct davinci_pcm_dma_params *params = prtd->params; > - int link; > + int ret; > > if (!params) > return -ENODEV; > > /* Request asp master DMA channel */ > - link = prtd->asp_channel = edma_alloc_channel(params->channel, > + ret = prtd->asp_channel = edma_alloc_channel(params->channel, > davinci_pcm_dma_irq, substream, > prtd->params->asp_chan_q); > - if (link < 0) > + if (ret < 0) > goto exit1; > > /* Request asp link channels */ > - link = prtd->asp_link[0] = edma_alloc_slot( > + ret = prtd->asp_link[0] = edma_alloc_slot( > EDMA_CTLR(prtd->asp_channel), EDMA_SLOT_ANY); > - if (link < 0) > + if (ret < 0) > goto exit2; > > iram_dma = (struct snd_dma_buffer *)substream->dma_buffer.private_data; > @@ -537,17 +532,17 @@ static int davinci_pcm_dma_request(struct snd_pcm_substream *substream) > * the buffer and its length (ccnt) ... use it as a template > * so davinci_pcm_enqueue_dma() takes less time in IRQ. > */ > - edma_read_slot(link, &prtd->asp_params); > + edma_read_slot(prtd->asp_link[0], &prtd->asp_params); > prtd->asp_params.opt |= TCINTEN | > EDMA_TCC(EDMA_CHAN_SLOT(prtd->asp_channel)); > - prtd->asp_params.link_bcntrld = EDMA_CHAN_SLOT(link) << 5; > - edma_write_slot(link, &prtd->asp_params); > + prtd->asp_params.link_bcntrld = EDMA_CHAN_SLOT(prtd->asp_link[0]) << 5; > + edma_write_slot(prtd->asp_link[0], &prtd->asp_params); > return 0; > exit2: > edma_free_channel(prtd->asp_channel); > prtd->asp_channel = -1; > exit1: > - return link; > + return ret; > } > > static int davinci_pcm_trigger(struct snd_pcm_substream *substream, int cmd) From sshtylyov at mvista.com Wed Sep 14 05:16:43 2011 From: sshtylyov at mvista.com (Sergei Shtylyov) Date: Wed, 14 Sep 2011 14:16:43 +0400 Subject: [PATCH v2 1/2] ARM: davinci - fix incorrect offsets and mask usage in psc code In-Reply-To: <3E54258959B69E4282D79E01AB1F32B701C4B4@DLEE12.ent.ti.com> References: <1314899316-2708-1-git-send-email-m-karicheri2@ti.com> <4E5FD371.1020200@mvista.com> <3E54258959B69E4282D79E01AB1F32B701B2C9@DLEE12.ent.ti.com> <4E617D89.80307@mvista.com> <4E662B93.7080701@mvista.com> <4E662FEA.7090908@mvista.com> <4E6A2902.4000305@mvista.com> <4E6A2AEE.6050001@mvista.com> <3E54258959B69E4282D79E01AB1F32B701C4B4@DLEE12.ent.ti.com> Message-ID: <4E707F0B.1070400@mvista.com> Hello. On 13-09-2011 18:58, Karicheri, Muralidharan wrote: > Sergei, > Looks like EPCPR register is not available on all platforms. It appears to be specific to the DM644x SoC. I've looked thru the documentation, and it appears that the register also exists on DM35x. > So doesn't it make sense to execute it only for DM644x. Any comments? It does indeed. I was thinking about checking for DA8xx before but now I'm seeing that not all DMxxxx SoCs support this register either... > Murali Karicheri > Software Design Engineer > email: m-karicheri2 at ti.com > Phone: (301) 407 9583 WBR, Sergei From samarth_i at yahoo.com Thu Sep 8 23:40:17 2011 From: samarth_i at yahoo.com (Samarth) Date: Fri, 9 Sep 2011 04:40:17 +0000 (UTC) Subject: hardware setup for dm355 and IP addresses Message-ID: I am new to TI EVMs. I was trying to run a simple piece of code on the EVM but I couldn't boot the board. here's the error I get in U-boot - Looking up port of RPC 100003/2 on 127.0.0.1 RPC: sendmsg returned error 22 portmap: RPC call returned error 22 Root-NFS: Unable to get nfsd port number from server, using default Looking up port of RPC 100005/1 on 127.0.0.1 RPC: sendmsg returned error 22 portmap: RPC call returned error 22 Root-NFS: Unable to get mountd port number from server, using default RPC: sendmsg returned error 22 mount: RPC call returned error 22 Root-NFS: Server returned error -22 while mounting /home/samarth/workdir/filesys VFS: Unable to mount root fs via NFS, trying floppy. VFS: Cannot open root device "nfs" or unknown-block(2,0) Please append a correct "root=" boot option Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(2,0) <7>eth0: no IPv6 routers present I suspect I bungled up in the hardware setup and setting the bard and host IP address variables. Should I connect both my computer and the board to ethernet via separate cables or just interconnect them? How can I know the IP address of the EVM board? These are probably naive questions but any help would be greatly appreciated. From ohad at wizery.com Wed Sep 14 13:38:43 2011 From: ohad at wizery.com (Ohad Ben-Cohen) Date: Wed, 14 Sep 2011 21:38:43 +0300 Subject: [RFC 7/8] drivers: introduce rpmsg, a remote-processor messaging bus In-Reply-To: References: <1308640714-17961-1-git-send-email-ohad@wizery.com> <1308640714-17961-8-git-send-email-ohad@wizery.com> <87liwu8u3q.fsf@rustcorp.com.au> Message-ID: Hi Rusty, On Wed, Jun 22, 2011 at 1:46 PM, Ohad Ben-Cohen wrote: > On Wed, Jun 22, 2011 at 5:42 AM, Rusty Russell wrote: >> On Tue, 21 Jun 2011 10:18:33 +0300, Ohad Ben-Cohen wrote: >>> +#define VIRTIO_ID_RPMSG ? ? ? ? ? ? ?10 /* virtio remote processor messaging */ >> >> I think you want 6. ?Plan 9 jumped ahead to grab 9 :) > > 6 it is :) Looking at the virtio-spec, it seems that 6 is taken by 'ioMemory'. There's no indication for it in virtio_ids.h though, and the virtio-spec has no appendix for this id, so maybe it's available after all ? If it is available, I'll take it for rpmsg, and will also update virtio-spec appropriately. Otherwise, we'll settle on 7 ? :) Thanks, Ohad. From manjunath.hadli at ti.com Wed Sep 14 14:02:33 2011 From: manjunath.hadli at ti.com (Hadli, Manjunath) Date: Thu, 15 Sep 2011 00:32:33 +0530 Subject: [PATCH v2 0/8] RFC for Media Controller capture driver for DM365 In-Reply-To: <20110912115925.GC1716@valkosipuli.localdomain> References: <1314630439-1122-1-git-send-email-manjunath.hadli@ti.com> <20110831213032.GT12368@valkosipuli.localdomain> <20110909161940.GJ1724@valkosipuli.localdomain> <20110912115925.GC1716@valkosipuli.localdomain> Message-ID: Hello Sakari, I have attached two .ps files with the entity graph details in them, one with RAW input and the other with YCbCr. Hope this is what you were looking for? Thanks and Regards, -Manju On Mon, Sep 12, 2011 at 17:29:25, Sakari Ailus wrote: > On Sat, Sep 10, 2011 at 12:11:37PM +0530, Hadli, Manjunath wrote: > > Hi Sakari, > > On Fri, Sep 09, 2011 at 21:49:40, Sakari Ailus wrote: > > > On Fri, Sep 09, 2011 at 07:10:49PM +0530, Hadli, Manjunath wrote: > > > > Hi Sakari, > > > > > > > > On Thu, Sep 01, 2011 at 03:00:32, Sakari Ailus wrote: > > > > > Hi Manju, > > > > > > > > > > Do you have the media device grap that would be typical for this hardware produced by media-ctl? That can be converted to postscript using dotfile. > > > > > > > > > > this would make it a little easier to understan this driver. Thanks. > > > > > > > > Sure. But can you be a little more elaborate on how you need this > > > > information? If you can tell me in little more detail about this > > > > that will help me make the information in a way that everyone can understand. > > > > > > Preferrably in PostScript format so it's easy to visualise the layout of the hardware that the driver supports, as the OMAP 3 ISP example was. > > Sure. > > I was more looking for an example of the same so it could help me put > > the data together in the way it has been done before. Can you send > > across if you have one? > > Ah. I think I misunderstood you first. :-) > > On the device, run > > $ media-ctl --print-dot > graph.dot > > This will produce a graph of the media device in the dot format. This is then processed by program called dot: > > $ dot -o graph.ps -T ps < graph.dot > > dot is available at least in Debian in a package called graphviz. > > Cheers, > > -- > Sakari Ailus > e-mail: sakari.ailus at iki.fi jabber/XMPP/Gmail: sailus at retiisi.org.uk > -------------- next part -------------- A non-text attachment was scrubbed... Name: tvp.ps Type: application/postscript Size: 29137 bytes Desc: tvp.ps URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: capture.ps Type: application/postscript Size: 26101 bytes Desc: capture.ps URL: From rusty at rustcorp.com.au Wed Sep 14 19:12:05 2011 From: rusty at rustcorp.com.au (Rusty Russell) Date: Thu, 15 Sep 2011 09:42:05 +0930 Subject: [RFC 7/8] drivers: introduce rpmsg, a remote-processor messaging bus In-Reply-To: References: <1308640714-17961-1-git-send-email-ohad@wizery.com> <1308640714-17961-8-git-send-email-ohad@wizery.com> <87liwu8u3q.fsf@rustcorp.com.au> Message-ID: <87d3f2hdey.fsf@rustcorp.com.au> On Wed, 14 Sep 2011 21:38:43 +0300, Ohad Ben-Cohen wrote: > Hi Rusty, > > On Wed, Jun 22, 2011 at 1:46 PM, Ohad Ben-Cohen wrote: > > On Wed, Jun 22, 2011 at 5:42 AM, Rusty Russell wrote: > >> On Tue, 21 Jun 2011 10:18:33 +0300, Ohad Ben-Cohen wrote: > >>> +#define VIRTIO_ID_RPMSG ? ? ? ? ? ? ?10 /* virtio remote processor messaging */ > >> > >> I think you want 6. ?Plan 9 jumped ahead to grab 9 :) > > > > 6 it is :) > > Looking at the virtio-spec, it seems that 6 is taken by 'ioMemory'. > There's no indication for it in virtio_ids.h though, and the > virtio-spec has no appendix for this id, so maybe it's available after > all ? > > If it is available, I'll take it for rpmsg, and will also update > virtio-spec appropriately. Otherwise, we'll settle on 7 ? :) 7... numbers are cheap :) Cheers, Rusty. From Jon.Povey at racelogic.co.uk Wed Sep 14 23:30:31 2011 From: Jon.Povey at racelogic.co.uk (Jon Povey) Date: Thu, 15 Sep 2011 05:30:31 +0100 Subject: [PATCH v2 0/8] RFC for Media Controller capture driver for DM365 In-Reply-To: Message-ID: <70E876B0EA86DD4BAF101844BC814DFE0BD381130B@Cloud.RL.local> davinci-linux-open-source-bounces at linux.davincidsp.com wrote: > Hello Sakari, > I have attached two .ps files with the entity graph details > in them, one with RAW input and the other with YCbCr. > Hope this is what you were looking for? Just wanted to say thanks for these and the new input drivers you have been working on. I am trying to puzzle out drivers for a new design based on dm365 so this is all interesting stuff. -- Jon Povey jon.povey at racelogic.co.uk Racelogic is a limited company registered in England. Registered number 2743719 . Registered Office Unit 10, Swan Business Centre, Osier Way, Buckingham, Bucks, MK18 1TB . The information contained in this electronic mail transmission is intended by Racelogic Ltd for the use of the named individual or entity to which it is directed and may contain information that is confidential or privileged. If you have received this electronic mail transmission in error, please delete it from your system without copying or forwarding it, and notify the sender of the error by reply email so that the sender's address records can be corrected. The views expressed by the sender of this communication do not necessarily represent those of Racelogic Ltd. Please note that Racelogic reserves the right to monitor e-mail communications passing through its network From schen at mvista.com Thu Sep 15 08:21:16 2011 From: schen at mvista.com (Steve Chen) Date: Thu, 15 Sep 2011 08:21:16 -0500 Subject: hardware setup for dm355 and IP addresses In-Reply-To: References: Message-ID: On Thu, Sep 8, 2011 at 11:40 PM, Samarth wrote: > I am new to TI EVMs. I was trying to run a simple piece of code on the EVM > but I > couldn't boot the board. > > here's the error I get in U-boot - > > Looking up port of RPC 100003/2 on 127.0.0.1 > RPC: sendmsg returned error 22 > portmap: RPC call returned error 22 > Root-NFS: Unable to get nfsd port number from server, using default > Looking up port of RPC 100005/1 on 127.0.0.1 > RPC: sendmsg returned error 22 > portmap: RPC call returned error 22 > Root-NFS: Unable to get mountd port number from server, using default > RPC: sendmsg returned error 22 > mount: RPC call returned error 22 > Root-NFS: Server returned error -22 while mounting > /home/samarth/workdir/filesys > VFS: Unable to mount root fs via NFS, trying floppy. > VFS: Cannot open root device "nfs" or unknown-block(2,0) > Please append a correct "root=" boot option > Kernel panic - not syncing: VFS: Unable to mount root fs on > unknown-block(2,0) > <7>eth0: no IPv6 routers present > This message is in the last stages of Linux kernel boot process > I suspect I bungled up in the hardware setup and setting the bard and host > IP > address variables. > Agree, you can get pass the problem by 1. Change kernel command line to use flash for root filesystem. 2. Set up NFS server on your host and use NFS as root filesystem. > Should I connect both my computer and the board to ethernet via separate > cables > or just interconnect them? > You probably need a cross over Ethernet cable if you connect the board directly to your host unless your host has Gigabit Ethernet where RX/TX are detected and set automatically. > How can I know the IP address of the EVM board? > If everything is set up correctly, you should see the ip address on the serial output. Regards, Steve -------------- next part -------------- An HTML attachment was scrubbed... URL: From sshtylyov at ru.mvista.com Thu Sep 15 09:29:48 2011 From: sshtylyov at ru.mvista.com (Sergei Shtylyov) Date: Thu, 15 Sep 2011 18:29:48 +0400 Subject: [PATCH] DaVinci: only poll EPCPR on DM644x and DM355 Message-ID: <201109151829.49256.sshtylyov@ru.mvista.com> EPCPR register and PDCTL.EPCGOOD bit exist only on DaVinci DM644x and DM35x, so do not try to poll EPCPR and set PDCTL.EPCGOOD on the other SoCs -- it would lead to lock up if some power domain hasn't been powered up by this time (which hasn't happened yet on any board, it seems). Signed-off-by: Sergei Shtylyov --- The patch is against the recent DaVinci tree plus this patch: http://linux.davincidsp.com/pipermail/davinci-linux-open-source/2011-September/023308.html Index: linux-davinci/arch/arm/mach-davinci/psc.c =================================================================== --- linux-davinci.orig/arch/arm/mach-davinci/psc.c +++ linux-davinci/arch/arm/mach-davinci/psc.c @@ -88,14 +88,19 @@ void davinci_psc_config(unsigned int dom ptcmd = 1 << domain; __raw_writel(ptcmd, psc_base + PTCMD); - do { - epcpr = __raw_readl(psc_base + EPCPR); - } while ((((epcpr >> domain) & 1) == 0)); - - pdctl = __raw_readl(psc_base + PDCTL + 4 * domain); - pdctl |= 0x100; - __raw_writel(pdctl, psc_base + PDCTL + 4 * domain); - + /* + * EPCPR register and PDCTL.EPCGOOD bit exist only on DaVinci + * DM644x and DM35x... + */ + if (cpu_is_davinci_dm644x() || cpu_is_davinci_dm355()) { + do { + epcpr = __raw_readl(psc_base + EPCPR); + } while (((epcpr >> domain) & 1) == 0); + + pdctl = __raw_readl(psc_base + PDCTL + 4 * domain); + pdctl |= 0x100; + __raw_writel(pdctl, psc_base + PDCTL + 4 * domain); + } } else { ptcmd = 1 << domain; __raw_writel(ptcmd, psc_base + PTCMD); From ohad at wizery.com Thu Sep 15 09:56:22 2011 From: ohad at wizery.com (Ohad Ben-Cohen) Date: Thu, 15 Sep 2011 17:56:22 +0300 Subject: [RFC 7/8] drivers: introduce rpmsg, a remote-processor messaging bus In-Reply-To: <87d3f2hdey.fsf@rustcorp.com.au> References: <1308640714-17961-1-git-send-email-ohad@wizery.com> <1308640714-17961-8-git-send-email-ohad@wizery.com> <87liwu8u3q.fsf@rustcorp.com.au> <87d3f2hdey.fsf@rustcorp.com.au> Message-ID: On Thu, Sep 15, 2011 at 3:12 AM, Rusty Russell wrote: > 7... numbers are cheap :) 7 it is :) Thanks, Ohad. From damateem4 at gmail.com Thu Sep 15 10:58:23 2011 From: damateem4 at gmail.com (damateem) Date: Thu, 15 Sep 2011 11:58:23 -0400 Subject: DM355 capture image from MT9M112 Message-ID: <4E72209F.9000107@gmail.com> My kernel version is Arago/2.6.31+2.6.32-rc2-r52+gitr. I'm struggling to wrap my head around how to capture images from an MT9M112 image sensor. I found a driver in mt9m111.c that appears to include the camera driver written for the soc-camera framework, but what are the steps for using it? Before getting into the details of the problem, a general overview would help a bunch. 1.) Does this kernel version have support for the soc-camera framework on the DM355? 2.) Is there a document (other than soc-camera.txt) that describes the soc-camera framework at a high level? What files are involved and how do they fit together? Is this correct? User Application /|\ | \|/ vpfe_capture.c <---> soc_camera.c <---> mt9m111.c (User Application should point to soc_camera.c) Thanks, David From m-karicheri2 at ti.com Thu Sep 15 14:27:33 2011 From: m-karicheri2 at ti.com (Karicheri, Muralidharan) Date: Thu, 15 Sep 2011 19:27:33 +0000 Subject: [PATCH] DaVinci: only poll EPCPR on DM644x and DM355 In-Reply-To: <201109151829.49256.sshtylyov@ru.mvista.com> References: <201109151829.49256.sshtylyov@ru.mvista.com> Message-ID: <3E54258959B69E4282D79E01AB1F32B701D2A6@DLEE12.ent.ti.com> Sergei, Thanks for the patch. Looks good to me. Murali Karicheri Software Design Engineer email: m-karicheri2 at ti.com >> -----Original Message----- >> From: davinci-linux-open-source-bounces at linux.davincidsp.com >> [mailto:davinci-linux-open-source-bounces at linux.davincidsp.com] On Behalf >> Of Sergei Shtylyov >> Sent: Thursday, September 15, 2011 10:30 AM >> To: Hilman, Kevin; davinci-linux-open-source at linux.davincidsp.com; Nori, >> Sekhar >> Cc: linux-arm-kernel at lists.infradead.org >> Subject: [PATCH] DaVinci: only poll EPCPR on DM644x and DM355 >> >> EPCPR register and PDCTL.EPCGOOD bit exist only on DaVinci DM644x and >> DM35x, >> so do not try to poll EPCPR and set PDCTL.EPCGOOD on the other SoCs -- it >> would >> lead to lock up if some power domain hasn't been powered up by this time >> (which >> hasn't happened yet on any board, it seems). >> >> Signed-off-by: Sergei Shtylyov >> >> --- >> The patch is against the recent DaVinci tree plus this patch: >> >> http://linux.davincidsp.com/pipermail/davinci-linux-open-source/2011- >> September/023308.html >> >> Index: linux-davinci/arch/arm/mach-davinci/psc.c >> =================================================================== >> --- linux-davinci.orig/arch/arm/mach-davinci/psc.c >> +++ linux-davinci/arch/arm/mach-davinci/psc.c >> @@ -88,14 +88,19 @@ void davinci_psc_config(unsigned int dom >> ptcmd = 1 << domain; >> __raw_writel(ptcmd, psc_base + PTCMD); >> >> - do { >> - epcpr = __raw_readl(psc_base + EPCPR); >> - } while ((((epcpr >> domain) & 1) == 0)); >> - >> - pdctl = __raw_readl(psc_base + PDCTL + 4 * domain); >> - pdctl |= 0x100; >> - __raw_writel(pdctl, psc_base + PDCTL + 4 * domain); >> - >> + /* >> + * EPCPR register and PDCTL.EPCGOOD bit exist only on DaVinci >> + * DM644x and DM35x... >> + */ >> + if (cpu_is_davinci_dm644x() || cpu_is_davinci_dm355()) { >> + do { >> + epcpr = __raw_readl(psc_base + EPCPR); >> + } while (((epcpr >> domain) & 1) == 0); >> + >> + pdctl = __raw_readl(psc_base + PDCTL + 4 * domain); >> + pdctl |= 0x100; >> + __raw_writel(pdctl, psc_base + PDCTL + 4 * domain); >> + } >> } else { >> ptcmd = 1 << domain; >> __raw_writel(ptcmd, psc_base + PTCMD); >> _______________________________________________ >> Davinci-linux-open-source mailing list >> Davinci-linux-open-source at linux.davincidsp.com >> http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source From broonie at opensource.wolfsonmicro.com Fri Sep 16 04:13:02 2011 From: broonie at opensource.wolfsonmicro.com (Mark Brown) Date: Fri, 16 Sep 2011 10:13:02 +0100 Subject: [PATCH] ASoC: davinci-pcm: trivial: replace link with actual chan/link In-Reply-To: <1315602365-30105-1-git-send-email-bengardiner@nanometrics.ca> References: <1315602365-30105-1-git-send-email-bengardiner@nanometrics.ca> Message-ID: <20110916091302.GI22062@opensource.wolfsonmicro.com> On Fri, Sep 09, 2011 at 05:06:05PM -0400, Ben Gardiner wrote: > The ambiguously named variable 'link' is used as a temporary throughout > davinci-pcm -- its presence makes grepping (and groking) the code > difficult. Applied, thanks. From sakari.ailus at iki.fi Fri Sep 16 16:05:09 2011 From: sakari.ailus at iki.fi (Sakari Ailus) Date: Sat, 17 Sep 2011 00:05:09 +0300 Subject: [PATCH v2 0/8] RFC for Media Controller capture driver for DM365 In-Reply-To: References: <1314630439-1122-1-git-send-email-manjunath.hadli@ti.com> <20110831213032.GT12368@valkosipuli.localdomain> <20110909161940.GJ1724@valkosipuli.localdomain> <20110912115925.GC1716@valkosipuli.localdomain> Message-ID: <20110916210509.GK1845@valkosipuli.localdomain> On Thu, Sep 15, 2011 at 12:32:33AM +0530, Hadli, Manjunath wrote: > Hello Sakari, > I have attached two .ps files with the entity graph details in them, one with RAW input and the other with YCbCr. > Hope this is what you were looking for? Hi Manju, This was exactly what I was looking for. Thanks! -- Sakari Ailus e-mail: sakari.ailus at iki.fi jabber/XMPP/Gmail: sailus at retiisi.org.uk From nsekhar at ti.com Sat Sep 17 05:29:21 2011 From: nsekhar at ti.com (Nori, Sekhar) Date: Sat, 17 Sep 2011 15:59:21 +0530 Subject: [PATCH v2 0/8] RFC for Media Controller capture driver for DM365 In-Reply-To: <70E876B0EA86DD4BAF101844BC814DFE0BD381130B@Cloud.RL.local> References: <70E876B0EA86DD4BAF101844BC814DFE0BD381130B@Cloud.RL.local> Message-ID: Hi Jon, On Thu, Sep 15, 2011 at 10:00:31, Jon Povey wrote: > davinci-linux-open-source-bounces at linux.davincidsp.com wrote: > > Hello Sakari, > > I have attached two .ps files with the entity graph details > > in them, one with RAW input and the other with YCbCr. > > Hope this is what you were looking for? > > Just wanted to say thanks for these and the new input drivers you > have been working on. > I am trying to puzzle out drivers for a new design based on dm365 > so this is all interesting stuff. If you happen to test/review these drivers, please do send your Tested-by: or Reviewed-by:. It will definitely help accelerate acceptance. Thanks, Sekhar From nsekhar at ti.com Sat Sep 17 06:43:36 2011 From: nsekhar at ti.com (Nori, Sekhar) Date: Sat, 17 Sep 2011 17:13:36 +0530 Subject: [GIT PULL] davinci fixes for v3.2 merge window Message-ID: Hi Arnd, Please pull the following two fixes for the v3.2 merge window. They are not applicable to stable tree and hence the stable tag has not been added. Thanks, Sekhar The following changes since commit b6fd41e29dea9c6753b1843a77e50433e6123bcb: Linus Torvalds (1): Linux 3.1-rc6 are available in the git repository at: git://gitorious.org/linux-davinci/linux-davinci.git v3.2/fixes Ido Yariv (1): ARM: davinci: Explicitly set channel controllers' default queues Thomas Meyer (1): ARM: davinci: edma: use kzalloc() arch/arm/mach-davinci/devices-da8xx.c | 3 +++ arch/arm/mach-davinci/devices-tnetv107x.c | 1 + arch/arm/mach-davinci/dm355.c | 1 + arch/arm/mach-davinci/dm644x.c | 1 + arch/arm/mach-davinci/dm646x.c | 1 + arch/arm/mach-davinci/dma.c | 5 +---- 6 files changed, 8 insertions(+), 4 deletions(-) From nsekhar at ti.com Sat Sep 17 06:51:10 2011 From: nsekhar at ti.com (Nori, Sekhar) Date: Sat, 17 Sep 2011 17:21:10 +0530 Subject: [GIT PULL] davinci features for v3.2 merge windiow Message-ID: Hi Arnd, Please pull the following feature for v3.2 merge window. It adds TI WLAN support on AM18x board. Thanks, Sekhar The following changes since commit b6fd41e29dea9c6753b1843a77e50433e6123bcb: Linus Torvalds (1): Linux 3.1-rc6 are available in the git repository at: git://gitorious.org/linux-davinci/linux-davinci.git v3.2/features Ido Yariv (4): ARM: davinci: DA850: Add MMC/SD1 pinmux configuration ARM: davinci: DA850: Add GPIO pinmux configuration for wl1271 mmc: davinci: Add support for set_power callback ARM: davinci: AM18x: Add wl1271/wlan support arch/arm/mach-davinci/Kconfig | 10 +++ arch/arm/mach-davinci/board-da850-evm.c | 114 ++++++++++++++++++++++++++++++ arch/arm/mach-davinci/da850.c | 9 +++ arch/arm/mach-davinci/include/mach/mmc.h | 3 + arch/arm/mach-davinci/include/mach/mux.h | 10 +++ drivers/mmc/host/davinci_mmc.c | 13 ++++ 6 files changed, 159 insertions(+), 0 deletions(-) From mchehab at redhat.com Sun Sep 18 09:35:46 2011 From: mchehab at redhat.com (Mauro Carvalho Chehab) Date: Sun, 18 Sep 2011 11:35:46 -0300 Subject: [PATCH v2 0/8] RFC for Media Controller capture driver for DM365 In-Reply-To: <1314630439-1122-1-git-send-email-manjunath.hadli@ti.com> References: <1314630439-1122-1-git-send-email-manjunath.hadli@ti.com> Message-ID: <4E7601C2.9030900@redhat.com> Em 29-08-2011 12:07, Manjunath Hadli escreveu: > changes from last patch set: > 1. Made changes based on Sakari's feedback mainly: > a. returned early to allow unindenting > b. reformatting to shift the code to left where possible > c. changed hex numbers to lower case > d. corrected the defines according to module names. > e. magic numbers removed. > f. changed non-integer returning functions to void > g. removed unwanted paranthses. > h. fixed error codes. > i. fixed some RESET_BIt code to what it was intended for. > 2. reorganized the header files to move the kernel-only headers > along with the c files and interface headers in the include folder. Manju, Please be sure to send me a pull request when you think this driver is ready for merge. The first submission I'm noticing for this driver was back on 2009, and still today, nobody sent me a git pull request for it. Two years seems too much time to solve the pending issues and sending a pull request for me to merge it! > > Manjunath Hadli (6): > davinci: vpfe: add dm3xx IPIPEIF hardware support module > davinci: vpfe: add support for CCDC hardware for dm365 > davinci: vpfe: add ccdc driver with media controller interface > davinci: vpfe: add v4l2 video driver support > davinci: vpfe: v4l2 capture driver with media interface > davinci: vpfe: build infrastructure for dm365 > > Nagabhushana Netagunte (2): > davinci: vpfe: add IPIPE hardware layer support > davinci: vpfe: add IPIPE support for media controller driver > > drivers/media/video/davinci/Kconfig | 46 +- > drivers/media/video/davinci/Makefile | 17 +- > drivers/media/video/davinci/ccdc_hw_device.h | 10 +- > drivers/media/video/davinci/ccdc_types.h | 43 + > drivers/media/video/davinci/dm365_ccdc.c | 1519 ++++++++++ > drivers/media/video/davinci/dm365_ccdc.h | 88 + > drivers/media/video/davinci/dm365_ccdc_regs.h | 309 ++ > drivers/media/video/davinci/dm365_def_para.c | 486 +++ > drivers/media/video/davinci/dm365_def_para.h | 39 + > drivers/media/video/davinci/dm365_ipipe.c | 3966 +++++++++++++++++++++++++ > drivers/media/video/davinci/dm365_ipipe.h | 300 ++ > drivers/media/video/davinci/dm365_ipipe_hw.c | 949 ++++++ > drivers/media/video/davinci/dm365_ipipe_hw.h | 539 ++++ > drivers/media/video/davinci/dm3xx_ipipeif.c | 317 ++ > drivers/media/video/davinci/dm3xx_ipipeif.h | 258 ++ > drivers/media/video/davinci/imp_common.h | 85 + > drivers/media/video/davinci/imp_hw_if.h | 178 ++ > drivers/media/video/davinci/vpfe_capture.c | 793 +++++ > drivers/media/video/davinci/vpfe_capture.h | 104 + > drivers/media/video/davinci/vpfe_ccdc.c | 813 +++++ > drivers/media/video/davinci/vpfe_ccdc.h | 85 + > drivers/media/video/davinci/vpfe_video.c | 1712 +++++++++++ > drivers/media/video/davinci/vpfe_video.h | 142 + > include/linux/davinci_vpfe.h | 1223 ++++++++ > include/linux/dm365_ccdc.h | 664 +++++ > include/linux/dm3xx_ipipeif.h | 64 + > include/media/davinci/vpfe.h | 91 + > 27 files changed, 14829 insertions(+), 11 deletions(-) > create mode 100644 drivers/media/video/davinci/ccdc_types.h > create mode 100644 drivers/media/video/davinci/dm365_ccdc.c > create mode 100644 drivers/media/video/davinci/dm365_ccdc.h > create mode 100644 drivers/media/video/davinci/dm365_ccdc_regs.h > create mode 100644 drivers/media/video/davinci/dm365_def_para.c > create mode 100644 drivers/media/video/davinci/dm365_def_para.h > create mode 100644 drivers/media/video/davinci/dm365_ipipe.c > create mode 100644 drivers/media/video/davinci/dm365_ipipe.h > create mode 100644 drivers/media/video/davinci/dm365_ipipe_hw.c > create mode 100644 drivers/media/video/davinci/dm365_ipipe_hw.h > create mode 100644 drivers/media/video/davinci/dm3xx_ipipeif.c > create mode 100644 drivers/media/video/davinci/dm3xx_ipipeif.h > create mode 100644 drivers/media/video/davinci/imp_common.h > create mode 100644 drivers/media/video/davinci/imp_hw_if.h > create mode 100644 drivers/media/video/davinci/vpfe_capture.c > create mode 100644 drivers/media/video/davinci/vpfe_capture.h > create mode 100644 drivers/media/video/davinci/vpfe_ccdc.c > create mode 100644 drivers/media/video/davinci/vpfe_ccdc.h > create mode 100644 drivers/media/video/davinci/vpfe_video.c > create mode 100644 drivers/media/video/davinci/vpfe_video.h > create mode 100644 include/linux/davinci_vpfe.h > create mode 100644 include/linux/dm365_ccdc.h > create mode 100644 include/linux/dm3xx_ipipeif.h > create mode 100644 include/media/davinci/vpfe.h > > -- > To unsubscribe from this list: send the line "unsubscribe linux-media" in > the body of a message to majordomo at vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html From manjunath.hadli at ti.com Mon Sep 19 00:09:04 2011 From: manjunath.hadli at ti.com (Hadli, Manjunath) Date: Mon, 19 Sep 2011 10:39:04 +0530 Subject: [PATCH v2 0/8] RFC for Media Controller capture driver for DM365 In-Reply-To: <4E7601C2.9030900@redhat.com> References: <1314630439-1122-1-git-send-email-manjunath.hadli@ti.com> <4E7601C2.9030900@redhat.com> Message-ID: Mauro, Thank you for your note. The first RFC for this (VPFE MC) driver was sent only in August this year. The other driver being discussed before was VPBE (which did go through some grind but not 2 years) which you accepted. This series of patches is definitely not two years old (unless I am mistaken somewhere). Currently Sakari is taking active interest in reviewing the patches, but I would like to take the cue from your note to request others also to actively review these patches and help me get them accepted. Thanks and Regards, -Manju On Sun, Sep 18, 2011 at 20:05:46, Mauro Carvalho Chehab wrote: > Em 29-08-2011 12:07, Manjunath Hadli escreveu: > > changes from last patch set: > > 1. Made changes based on Sakari's feedback mainly: > > a. returned early to allow unindenting > > b. reformatting to shift the code to left where possible > > c. changed hex numbers to lower case > > d. corrected the defines according to module names. > > e. magic numbers removed. > > f. changed non-integer returning functions to void > > g. removed unwanted paranthses. > > h. fixed error codes. > > i. fixed some RESET_BIt code to what it was intended for. > > 2. reorganized the header files to move the kernel-only headers along > > with the c files and interface headers in the include folder. > > Manju, > > Please be sure to send me a pull request when you think this driver is ready for merge. The first submission I'm noticing for this driver was back on 2009, and still today, nobody sent me a git pull request for it. Two years seems too much time to solve the pending issues and sending a pull request for me to merge it! > > > > Manjunath Hadli (6): > > davinci: vpfe: add dm3xx IPIPEIF hardware support module > > davinci: vpfe: add support for CCDC hardware for dm365 > > davinci: vpfe: add ccdc driver with media controller interface > > davinci: vpfe: add v4l2 video driver support > > davinci: vpfe: v4l2 capture driver with media interface > > davinci: vpfe: build infrastructure for dm365 > > > > Nagabhushana Netagunte (2): > > davinci: vpfe: add IPIPE hardware layer support > > davinci: vpfe: add IPIPE support for media controller driver > > > > drivers/media/video/davinci/Kconfig | 46 +- > > drivers/media/video/davinci/Makefile | 17 +- > > drivers/media/video/davinci/ccdc_hw_device.h | 10 +- > > drivers/media/video/davinci/ccdc_types.h | 43 + > > drivers/media/video/davinci/dm365_ccdc.c | 1519 ++++++++++ > > drivers/media/video/davinci/dm365_ccdc.h | 88 + > > drivers/media/video/davinci/dm365_ccdc_regs.h | 309 ++ > > drivers/media/video/davinci/dm365_def_para.c | 486 +++ > > drivers/media/video/davinci/dm365_def_para.h | 39 + > > drivers/media/video/davinci/dm365_ipipe.c | 3966 +++++++++++++++++++++++++ > > drivers/media/video/davinci/dm365_ipipe.h | 300 ++ > > drivers/media/video/davinci/dm365_ipipe_hw.c | 949 ++++++ > > drivers/media/video/davinci/dm365_ipipe_hw.h | 539 ++++ > > drivers/media/video/davinci/dm3xx_ipipeif.c | 317 ++ > > drivers/media/video/davinci/dm3xx_ipipeif.h | 258 ++ > > drivers/media/video/davinci/imp_common.h | 85 + > > drivers/media/video/davinci/imp_hw_if.h | 178 ++ > > drivers/media/video/davinci/vpfe_capture.c | 793 +++++ > > drivers/media/video/davinci/vpfe_capture.h | 104 + > > drivers/media/video/davinci/vpfe_ccdc.c | 813 +++++ > > drivers/media/video/davinci/vpfe_ccdc.h | 85 + > > drivers/media/video/davinci/vpfe_video.c | 1712 +++++++++++ > > drivers/media/video/davinci/vpfe_video.h | 142 + > > include/linux/davinci_vpfe.h | 1223 ++++++++ > > include/linux/dm365_ccdc.h | 664 +++++ > > include/linux/dm3xx_ipipeif.h | 64 + > > include/media/davinci/vpfe.h | 91 + > > 27 files changed, 14829 insertions(+), 11 deletions(-) create mode > > 100644 drivers/media/video/davinci/ccdc_types.h > > create mode 100644 drivers/media/video/davinci/dm365_ccdc.c > > create mode 100644 drivers/media/video/davinci/dm365_ccdc.h > > create mode 100644 drivers/media/video/davinci/dm365_ccdc_regs.h > > create mode 100644 drivers/media/video/davinci/dm365_def_para.c > > create mode 100644 drivers/media/video/davinci/dm365_def_para.h > > create mode 100644 drivers/media/video/davinci/dm365_ipipe.c > > create mode 100644 drivers/media/video/davinci/dm365_ipipe.h > > create mode 100644 drivers/media/video/davinci/dm365_ipipe_hw.c > > create mode 100644 drivers/media/video/davinci/dm365_ipipe_hw.h > > create mode 100644 drivers/media/video/davinci/dm3xx_ipipeif.c > > create mode 100644 drivers/media/video/davinci/dm3xx_ipipeif.h > > create mode 100644 drivers/media/video/davinci/imp_common.h > > create mode 100644 drivers/media/video/davinci/imp_hw_if.h > > create mode 100644 drivers/media/video/davinci/vpfe_capture.c > > create mode 100644 drivers/media/video/davinci/vpfe_capture.h > > create mode 100644 drivers/media/video/davinci/vpfe_ccdc.c > > create mode 100644 drivers/media/video/davinci/vpfe_ccdc.h > > create mode 100644 drivers/media/video/davinci/vpfe_video.c > > create mode 100644 drivers/media/video/davinci/vpfe_video.h > > create mode 100644 include/linux/davinci_vpfe.h create mode 100644 > > include/linux/dm365_ccdc.h create mode 100644 > > include/linux/dm3xx_ipipeif.h create mode 100644 > > include/media/davinci/vpfe.h > > > > -- > > To unsubscribe from this list: send the line "unsubscribe linux-media" > > in the body of a message to majordomo at vger.kernel.org More majordomo > > info at http://vger.kernel.org/majordomo-info.html > > From manjunath.hadli at ti.com Mon Sep 19 00:35:25 2011 From: manjunath.hadli at ti.com (Manjunath Hadli) Date: Mon, 19 Sep 2011 11:05:25 +0530 Subject: [PATCH RESEND 0/4] davinci vpbe: enable DM365 v4l2 display driver Message-ID: <1316410529-14744-1-git-send-email-manjunath.hadli@ti.com> The patchset adds incremental changes necessary to enable dm365 v4l2 display driver, which includes vpbe display driver changes, osd specific changes and venc changes. The changes are incremental in nature,addind a few HD modes, and taking care of register level changes. The patch set does not include THS7303 amplifier driver which is planned to be sent seperately. Manjunath Hadli (4): davinci vpbe: remove unused macro. davinci vpbe: add dm365 VPBE display driver changes davinci vpbe: add dm365 and dm355 specific OSD changes davinci vpbe: add VENC block changes to enable dm365 and dm355 drivers/media/video/davinci/vpbe.c | 55 +++- drivers/media/video/davinci/vpbe_display.c | 1 - drivers/media/video/davinci/vpbe_osd.c | 474 +++++++++++++++++++++++++--- drivers/media/video/davinci/vpbe_venc.c | 205 +++++++++++-- include/media/davinci/vpbe.h | 16 + include/media/davinci/vpbe_venc.h | 4 + 6 files changed, 686 insertions(+), 69 deletions(-) From manjunath.hadli at ti.com Mon Sep 19 00:35:29 2011 From: manjunath.hadli at ti.com (Manjunath Hadli) Date: Mon, 19 Sep 2011 11:05:29 +0530 Subject: [PATCH RESEND 4/4] davinci vpbe: add VENC block changes to enable dm365 and dm355 In-Reply-To: <1316410529-14744-1-git-send-email-manjunath.hadli@ti.com> References: <1316410529-14744-1-git-send-email-manjunath.hadli@ti.com> Message-ID: <1316410529-14744-5-git-send-email-manjunath.hadli@ti.com> This patch implements necessary changes for enabling dm365 and dm355 hardware for vpbe. The patch contains additional HD mode support for dm365 (720p60, 1080i30) and appropriate register modifications based on version numbers. VPBE_VERSION_2 = dm365 specific VPBE_VERSION_3 = dm355 specific Signed-off-by: Manjunath Hadli --- drivers/media/video/davinci/vpbe_venc.c | 205 +++++++++++++++++++++++++++---- include/media/davinci/vpbe_venc.h | 4 + 2 files changed, 185 insertions(+), 24 deletions(-) diff --git a/drivers/media/video/davinci/vpbe_venc.c b/drivers/media/video/davinci/vpbe_venc.c index 03a3e5c..53c2994 100644 --- a/drivers/media/video/davinci/vpbe_venc.c +++ b/drivers/media/video/davinci/vpbe_venc.c @@ -99,6 +99,8 @@ static inline u32 vdaccfg_write(struct v4l2_subdev *sd, u32 val) return val; } +#define VDAC_COMPONENT 0x543 +#define VDAC_S_VIDEO 0x210 /* This function sets the dac of the VPBE for various outputs */ static int venc_set_dac(struct v4l2_subdev *sd, u32 out_index) @@ -109,11 +111,12 @@ static int venc_set_dac(struct v4l2_subdev *sd, u32 out_index) venc_write(sd, VENC_DACSEL, 0); break; case 1: - v4l2_dbg(debug, 1, sd, "Setting output to S-Video\n"); - venc_write(sd, VENC_DACSEL, 0x210); + v4l2_dbg(debug, 1, sd, "Setting output to Component\n"); + venc_write(sd, VENC_DACSEL, VDAC_COMPONENT); break; - case 2: - venc_write(sd, VENC_DACSEL, 0x543); + case 2: + v4l2_dbg(debug, 1, sd, "Setting output to S-video\n"); + venc_write(sd, VENC_DACSEL, VDAC_S_VIDEO); break; default: return -EINVAL; @@ -124,6 +127,8 @@ static int venc_set_dac(struct v4l2_subdev *sd, u32 out_index) static void venc_enabledigitaloutput(struct v4l2_subdev *sd, int benable) { + struct venc_state *venc = to_state(sd); + struct venc_platform_data *pdata = venc->pdata; v4l2_dbg(debug, 2, sd, "venc_enabledigitaloutput\n"); if (benable) { @@ -155,7 +160,8 @@ static void venc_enabledigitaloutput(struct v4l2_subdev *sd, int benable) /* Disable LCD output control (accepting default polarity) */ venc_write(sd, VENC_LCDOUT, 0); - venc_write(sd, VENC_CMPNT, 0x100); + if (pdata->venc_type != VPBE_VERSION_3) + venc_write(sd, VENC_CMPNT, 0x100); venc_write(sd, VENC_HSPLS, 0); venc_write(sd, VENC_HINT, 0); venc_write(sd, VENC_HSTART, 0); @@ -178,11 +184,14 @@ static void venc_enabledigitaloutput(struct v4l2_subdev *sd, int benable) } } +#define VDAC_CONFIG_SD_V3 0x0E21A6B6 +#define VDAC_CONFIG_SD_V2 0x081141CF /* * setting NTSC mode */ static int venc_set_ntsc(struct v4l2_subdev *sd) { + u32 val; struct venc_state *venc = to_state(sd); struct venc_platform_data *pdata = venc->pdata; @@ -195,12 +204,22 @@ static int venc_set_ntsc(struct v4l2_subdev *sd) venc_enabledigitaloutput(sd, 0); - /* to set VENC CLK DIV to 1 - final clock is 54 MHz */ - venc_modify(sd, VENC_VIDCTL, 0, 1 << 1); - /* Set REC656 Mode */ - venc_write(sd, VENC_YCCCTL, 0x1); - venc_modify(sd, VENC_VDPRO, 0, VENC_VDPRO_DAFRQ); - venc_modify(sd, VENC_VDPRO, 0, VENC_VDPRO_DAUPS); + if (pdata->venc_type == VPBE_VERSION_3) { + venc_write(sd, VENC_CLKCTL, 0x01); + venc_write(sd, VENC_VIDCTL, 0); + val = vdaccfg_write(sd, VDAC_CONFIG_SD_V3); + } else if (pdata->venc_type == VPBE_VERSION_2) { + venc_write(sd, VENC_CLKCTL, 0x01); + venc_write(sd, VENC_VIDCTL, 0); + vdaccfg_write(sd, VDAC_CONFIG_SD_V2); + } else { + /* to set VENC CLK DIV to 1 - final clock is 54 MHz */ + venc_modify(sd, VENC_VIDCTL, 0, 1 << 1); + /* Set REC656 Mode */ + venc_write(sd, VENC_YCCCTL, 0x1); + venc_modify(sd, VENC_VDPRO, 0, VENC_VDPRO_DAFRQ); + venc_modify(sd, VENC_VDPRO, 0, VENC_VDPRO_DAUPS); + } venc_write(sd, VENC_VMOD, 0); venc_modify(sd, VENC_VMOD, (1 << VENC_VMOD_VIE_SHIFT), @@ -220,6 +239,7 @@ static int venc_set_ntsc(struct v4l2_subdev *sd) static int venc_set_pal(struct v4l2_subdev *sd) { struct venc_state *venc = to_state(sd); + struct venc_platform_data *pdata = venc->pdata; v4l2_dbg(debug, 2, sd, "venc_set_pal\n"); @@ -230,10 +250,20 @@ static int venc_set_pal(struct v4l2_subdev *sd) venc_enabledigitaloutput(sd, 0); - /* to set VENC CLK DIV to 1 - final clock is 54 MHz */ - venc_modify(sd, VENC_VIDCTL, 0, 1 << 1); - /* Set REC656 Mode */ - venc_write(sd, VENC_YCCCTL, 0x1); + if (pdata->venc_type == VPBE_VERSION_3) { + venc_write(sd, VENC_CLKCTL, 0x1); + venc_write(sd, VENC_VIDCTL, 0); + vdaccfg_write(sd, VDAC_CONFIG_SD_V3); + } else if (pdata->venc_type == VPBE_VERSION_2) { + venc_write(sd, VENC_CLKCTL, 0x1); + venc_write(sd, VENC_VIDCTL, 0); + vdaccfg_write(sd, VDAC_CONFIG_SD_V2); + } else { + /* to set VENC CLK DIV to 1 - final clock is 54 MHz */ + venc_modify(sd, VENC_VIDCTL, 0, 1 << 1); + /* Set REC656 Mode */ + venc_write(sd, VENC_YCCCTL, 0x1); + } venc_modify(sd, VENC_SYNCCTL, 1 << VENC_SYNCCTL_OVD_SHIFT, VENC_SYNCCTL_OVD); @@ -252,6 +282,7 @@ static int venc_set_pal(struct v4l2_subdev *sd) return 0; } +#define VDAC_CONFIG_HD_V2 0x081141EF /* * venc_set_480p59_94 * @@ -263,6 +294,9 @@ static int venc_set_480p59_94(struct v4l2_subdev *sd) struct venc_platform_data *pdata = venc->pdata; v4l2_dbg(debug, 2, sd, "venc_set_480p59_94\n"); + if ((pdata->venc_type != VPBE_VERSION_1) && + (pdata->venc_type != VPBE_VERSION_2)) + return -EINVAL; /* Setup clock at VPSS & VENC for SD */ if (pdata->setup_clock(VPBE_ENC_DV_PRESET, V4L2_DV_480P59_94) < 0) @@ -270,12 +304,18 @@ static int venc_set_480p59_94(struct v4l2_subdev *sd) venc_enabledigitaloutput(sd, 0); + if (pdata->venc_type == VPBE_VERSION_2) + vdaccfg_write(sd, VDAC_CONFIG_HD_V2); venc_write(sd, VENC_OSDCLK0, 0); venc_write(sd, VENC_OSDCLK1, 1); - venc_modify(sd, VENC_VDPRO, VENC_VDPRO_DAFRQ, - VENC_VDPRO_DAFRQ); - venc_modify(sd, VENC_VDPRO, VENC_VDPRO_DAUPS, - VENC_VDPRO_DAUPS); + + if (pdata->venc_type == VPBE_VERSION_1) { + venc_modify(sd, VENC_VDPRO, VENC_VDPRO_DAFRQ, + VENC_VDPRO_DAFRQ); + venc_modify(sd, VENC_VDPRO, VENC_VDPRO_DAUPS, + VENC_VDPRO_DAUPS); + } + venc_write(sd, VENC_VMOD, 0); venc_modify(sd, VENC_VMOD, (1 << VENC_VMOD_VIE_SHIFT), VENC_VMOD_VIE); @@ -302,19 +342,27 @@ static int venc_set_576p50(struct v4l2_subdev *sd) v4l2_dbg(debug, 2, sd, "venc_set_576p50\n"); + if ((pdata->venc_type != VPBE_VERSION_1) && + (pdata->venc_type != VPBE_VERSION_2)) + return -EINVAL; /* Setup clock at VPSS & VENC for SD */ if (pdata->setup_clock(VPBE_ENC_DV_PRESET, V4L2_DV_576P50) < 0) return -EINVAL; venc_enabledigitaloutput(sd, 0); + if (pdata->venc_type == VPBE_VERSION_2) + vdaccfg_write(sd, VDAC_CONFIG_HD_V2); + venc_write(sd, VENC_OSDCLK0, 0); venc_write(sd, VENC_OSDCLK1, 1); - venc_modify(sd, VENC_VDPRO, VENC_VDPRO_DAFRQ, - VENC_VDPRO_DAFRQ); - venc_modify(sd, VENC_VDPRO, VENC_VDPRO_DAUPS, - VENC_VDPRO_DAUPS); + if (pdata->venc_type == VPBE_VERSION_1) { + venc_modify(sd, VENC_VDPRO, VENC_VDPRO_DAFRQ, + VENC_VDPRO_DAFRQ); + venc_modify(sd, VENC_VDPRO, VENC_VDPRO_DAUPS, + VENC_VDPRO_DAUPS); + } venc_write(sd, VENC_VMOD, 0); venc_modify(sd, VENC_VMOD, (1 << VENC_VMOD_VIE_SHIFT), @@ -330,6 +378,63 @@ static int venc_set_576p50(struct v4l2_subdev *sd) return 0; } +/* + * venc_set_720p60_internal - Setup 720p60 in venc for dm365 only + */ +static int venc_set_720p60_internal(struct v4l2_subdev *sd) +{ + struct venc_state *venc = to_state(sd); + struct venc_platform_data *pdata = venc->pdata; + + if (pdata->setup_clock(VPBE_ENC_DV_PRESET, V4L2_DV_720P60) < 0) + return -EINVAL; + + venc_enabledigitaloutput(sd, 0); + + venc_write(sd, VENC_OSDCLK0, 0); + venc_write(sd, VENC_OSDCLK1, 1); + + venc_write(sd, VENC_VMOD, 0); + /* DM365 component HD mode */ + venc_modify(sd, VENC_VMOD, (1 << VENC_VMOD_VIE_SHIFT), + VENC_VMOD_VIE); + venc_modify(sd, VENC_VMOD, VENC_VMOD_HDMD, VENC_VMOD_HDMD); + venc_modify(sd, VENC_VMOD, (HDTV_720P << VENC_VMOD_TVTYP_SHIFT), + VENC_VMOD_TVTYP); + venc_modify(sd, VENC_VMOD, VENC_VMOD_VENC, VENC_VMOD_VENC); + venc_write(sd, VENC_XHINTVL, 0); + return 0; +} + +/* + * venc_set_1080i30_internal - Setup 1080i30 in venc for dm365 only + */ +static int venc_set_1080i30_internal(struct v4l2_subdev *sd) +{ + struct venc_state *venc = to_state(sd); + struct venc_platform_data *pdata = venc->pdata; + + if (pdata->setup_clock(VPBE_ENC_DV_PRESET, V4L2_DV_1080P30) < 0) + return -EINVAL; + + venc_enabledigitaloutput(sd, 0); + + venc_write(sd, VENC_OSDCLK0, 0); + venc_write(sd, VENC_OSDCLK1, 1); + + + venc_write(sd, VENC_VMOD, 0); + /* DM365 component HD mode */ + venc_modify(sd, VENC_VMOD, (1 << VENC_VMOD_VIE_SHIFT), + VENC_VMOD_VIE); + venc_modify(sd, VENC_VMOD, VENC_VMOD_HDMD, VENC_VMOD_HDMD); + venc_modify(sd, VENC_VMOD, (HDTV_1080I << VENC_VMOD_TVTYP_SHIFT), + VENC_VMOD_TVTYP); + venc_modify(sd, VENC_VMOD, VENC_VMOD_VENC, VENC_VMOD_VENC); + venc_write(sd, VENC_XHINTVL, 0); + return 0; +} + static int venc_s_std_output(struct v4l2_subdev *sd, v4l2_std_id norm) { v4l2_dbg(debug, 1, sd, "venc_s_std_output\n"); @@ -345,13 +450,30 @@ static int venc_s_std_output(struct v4l2_subdev *sd, v4l2_std_id norm) static int venc_s_dv_preset(struct v4l2_subdev *sd, struct v4l2_dv_preset *dv_preset) { + struct venc_state *venc = to_state(sd); + int ret; + v4l2_dbg(debug, 1, sd, "venc_s_dv_preset\n"); if (dv_preset->preset == V4L2_DV_576P50) return venc_set_576p50(sd); else if (dv_preset->preset == V4L2_DV_480P59_94) return venc_set_480p59_94(sd); - + else if ((dv_preset->preset == V4L2_DV_720P60) && + (venc->pdata->venc_type == VPBE_VERSION_2)) { + /* TBD setup internal 720p mode here */ + ret = venc_set_720p60_internal(sd); + /* for DM365 VPBE, there is DAC inside */ + vdaccfg_write(sd, VDAC_CONFIG_HD_V2); + return ret; + } else if ((dv_preset->preset == V4L2_DV_1080I30) && + (venc->pdata->venc_type == VPBE_VERSION_2)) { + /* TBD setup internal 1080i mode here */ + ret = venc_set_1080i30_internal(sd); + /* for DM365 VPBE, there is DAC inside */ + vdaccfg_write(sd, VDAC_CONFIG_HD_V2); + return ret; + } return -EINVAL; } @@ -508,11 +630,41 @@ static int venc_probe(struct platform_device *pdev) goto release_venc_mem_region; } + if (venc->pdata->venc_type != VPBE_VERSION_1) { + res = platform_get_resource(pdev, IORESOURCE_MEM, 1); + if (!res) { + dev_err(venc->pdev, + "Unable to get VDAC_CONFIG address map\n"); + ret = -ENODEV; + goto unmap_venc_io; + } + + if (!request_mem_region(res->start, + resource_size(res), "venc")) { + dev_err(venc->pdev, + "Unable to reserve VDAC_CONFIG MMIO region\n"); + ret = -ENODEV; + goto unmap_venc_io; + } + + venc->vdaccfg_reg = ioremap_nocache(res->start, + resource_size(res)); + if (!venc->vdaccfg_reg) { + dev_err(venc->pdev, + "Unable to map VDAC_CONFIG IO space\n"); + ret = -ENODEV; + goto release_vdaccfg_mem_region; + } + } spin_lock_init(&venc->lock); platform_set_drvdata(pdev, venc); dev_notice(venc->pdev, "VENC sub device probe success\n"); return 0; +release_vdaccfg_mem_region: + release_mem_region(res->start, resource_size(res)); +unmap_venc_io: + iounmap(venc->venc_base); release_venc_mem_region: res = platform_get_resource(pdev, IORESOURCE_MEM, 0); release_mem_region(res->start, resource_size(res)); @@ -529,6 +681,11 @@ static int venc_remove(struct platform_device *pdev) res = platform_get_resource(pdev, IORESOURCE_MEM, 0); iounmap((void *)venc->venc_base); release_mem_region(res->start, resource_size(res)); + if (venc->pdata->venc_type != VPBE_VERSION_1) { + res = platform_get_resource(pdev, IORESOURCE_MEM, 1); + iounmap((void *)venc->vdaccfg_reg); + release_mem_region(res->start, resource_size(res)); + } kfree(venc); return 0; diff --git a/include/media/davinci/vpbe_venc.h b/include/media/davinci/vpbe_venc.h index 426c205..6b57334 100644 --- a/include/media/davinci/vpbe_venc.h +++ b/include/media/davinci/vpbe_venc.h @@ -29,10 +29,14 @@ struct venc_platform_data { enum vpbe_version venc_type; + int (*setup_pinmux)(enum v4l2_mbus_pixelcode if_type, + int field); int (*setup_clock)(enum vpbe_enc_timings_type type, unsigned int mode); + int (*setup_if_config)(enum v4l2_mbus_pixelcode pixcode); /* Number of LCD outputs supported */ int num_lcd_outputs; + struct vpbe_if_params *lcd_if_params; }; enum venc_ioctls { -- 1.6.2.4 From manjunath.hadli at ti.com Mon Sep 19 00:35:26 2011 From: manjunath.hadli at ti.com (Manjunath Hadli) Date: Mon, 19 Sep 2011 11:05:26 +0530 Subject: [PATCH RESEND 1/4] davinci vpbe: remove unused macro. In-Reply-To: <1316410529-14744-1-git-send-email-manjunath.hadli@ti.com> References: <1316410529-14744-1-git-send-email-manjunath.hadli@ti.com> Message-ID: <1316410529-14744-2-git-send-email-manjunath.hadli@ti.com> remove VPBE_DISPLAY_SD_BUF_SIZE as it is no longer used. Signed-off-by: Manjunath Hadli --- drivers/media/video/davinci/vpbe_display.c | 1 - 1 files changed, 0 insertions(+), 1 deletions(-) diff --git a/drivers/media/video/davinci/vpbe_display.c b/drivers/media/video/davinci/vpbe_display.c index ae7add1..09a659e 100644 --- a/drivers/media/video/davinci/vpbe_display.c +++ b/drivers/media/video/davinci/vpbe_display.c @@ -43,7 +43,6 @@ static int debug; -#define VPBE_DISPLAY_SD_BUF_SIZE (720*576*2) #define VPBE_DEFAULT_NUM_BUFS 3 module_param(debug, int, 0644); -- 1.6.2.4 From manjunath.hadli at ti.com Mon Sep 19 00:35:27 2011 From: manjunath.hadli at ti.com (Manjunath Hadli) Date: Mon, 19 Sep 2011 11:05:27 +0530 Subject: [PATCH RESEND 2/4] davinci vpbe: add dm365 VPBE display driver changes In-Reply-To: <1316410529-14744-1-git-send-email-manjunath.hadli@ti.com> References: <1316410529-14744-1-git-send-email-manjunath.hadli@ti.com> Message-ID: <1316410529-14744-3-git-send-email-manjunath.hadli@ti.com> This patch implements the core additions to the display driver, mainly controlling the VENC and other encoders for dm365. This patch also includes addition of amplifier subdevice to the vpbe driver and interfacing with venc subdevice. Signed-off-by: Manjunath Hadli --- drivers/media/video/davinci/vpbe.c | 55 ++++++++++++++++++++++++++++++++++-- include/media/davinci/vpbe.h | 16 ++++++++++ 2 files changed, 68 insertions(+), 3 deletions(-) diff --git a/drivers/media/video/davinci/vpbe.c b/drivers/media/video/davinci/vpbe.c index d773d30..21a8645 100644 --- a/drivers/media/video/davinci/vpbe.c +++ b/drivers/media/video/davinci/vpbe.c @@ -141,11 +141,12 @@ static int vpbe_enum_outputs(struct vpbe_device *vpbe_dev, return 0; } -static int vpbe_get_mode_info(struct vpbe_device *vpbe_dev, char *mode) +static int vpbe_get_mode_info(struct vpbe_device *vpbe_dev, char *mode, + int output_index) { struct vpbe_config *cfg = vpbe_dev->cfg; struct vpbe_enc_mode_info var; - int curr_output = vpbe_dev->current_out_index; + int curr_output = output_index; int i; if (NULL == mode) @@ -245,6 +246,8 @@ static int vpbe_set_output(struct vpbe_device *vpbe_dev, int index) struct encoder_config_info *curr_enc_info = vpbe_current_encoder_info(vpbe_dev); struct vpbe_config *cfg = vpbe_dev->cfg; + struct venc_platform_data *venc_device = vpbe_dev->venc_device; + enum v4l2_mbus_pixelcode if_params; int enc_out_index; int sd_index; int ret = 0; @@ -274,6 +277,8 @@ static int vpbe_set_output(struct vpbe_device *vpbe_dev, int index) goto out; } + if_params = cfg->outputs[index].if_params; + venc_device->setup_if_config(if_params); if (ret) goto out; } @@ -293,7 +298,7 @@ static int vpbe_set_output(struct vpbe_device *vpbe_dev, int index) * encoder. */ ret = vpbe_get_mode_info(vpbe_dev, - cfg->outputs[index].default_mode); + cfg->outputs[index].default_mode, index); if (!ret) { struct osd_state *osd_device = vpbe_dev->osd_device; @@ -367,6 +372,11 @@ static int vpbe_s_dv_preset(struct vpbe_device *vpbe_dev, ret = v4l2_subdev_call(vpbe_dev->encoders[sd_index], video, s_dv_preset, dv_preset); + if (!ret && (vpbe_dev->amp != NULL)) { + /* Call amplifier subdevice */ + ret = v4l2_subdev_call(vpbe_dev->amp, video, + s_dv_preset, dv_preset); + } /* set the lcd controller output for the given mode */ if (!ret) { struct osd_state *osd_device = vpbe_dev->osd_device; @@ -566,6 +576,8 @@ static int platform_device_get(struct device *dev, void *data) if (strcmp("vpbe-osd", pdev->name) == 0) vpbe_dev->osd_device = platform_get_drvdata(pdev); + if (strcmp("vpbe-venc", pdev->name) == 0) + vpbe_dev->venc_device = dev_get_platdata(&pdev->dev); return 0; } @@ -584,6 +596,7 @@ static int platform_device_get(struct device *dev, void *data) static int vpbe_initialize(struct device *dev, struct vpbe_device *vpbe_dev) { struct encoder_config_info *enc_info; + struct amp_config_info *amp_info; struct v4l2_subdev **enc_subdev; struct osd_state *osd_device; struct i2c_adapter *i2c_adap; @@ -704,6 +717,39 @@ static int vpbe_initialize(struct device *dev, struct vpbe_device *vpbe_dev) v4l2_warn(&vpbe_dev->v4l2_dev, "non-i2c encoders" " currently not supported"); } + /* Add amplifier subdevice for dm365 */ + if ((strcmp(vpbe_dev->cfg->module_name, "dm365-vpbe-display") == 0) && + vpbe_dev->cfg->amp != NULL) { + vpbe_dev->amp = kmalloc(sizeof(struct v4l2_subdev *), + GFP_KERNEL); + if (vpbe_dev->amp == NULL) { + v4l2_err(&vpbe_dev->v4l2_dev, + "unable to allocate memory for sub device"); + ret = -ENOMEM; + goto vpbe_fail_v4l2_device; + } + amp_info = vpbe_dev->cfg->amp; + if (amp_info->is_i2c) { + vpbe_dev->amp = v4l2_i2c_new_subdev_board( + &vpbe_dev->v4l2_dev, i2c_adap, + &_info->board_info, NULL); + if (!vpbe_dev->amp) { + v4l2_err(&vpbe_dev->v4l2_dev, + "amplifier %s failed to register", + amp_info->module_name); + ret = -ENODEV; + goto vpbe_fail_amp_register; + } + v4l2_info(&vpbe_dev->v4l2_dev, + "v4l2 sub device %s registered\n", + amp_info->module_name); + } else { + vpbe_dev->amp = NULL; + v4l2_warn(&vpbe_dev->v4l2_dev, "non-i2c amplifiers" + " currently not supported"); + } + } else + vpbe_dev->amp = NULL; /* set the current encoder and output to that of venc by default */ vpbe_dev->current_sd_index = 0; @@ -731,6 +777,8 @@ static int vpbe_initialize(struct device *dev, struct vpbe_device *vpbe_dev) /* TBD handling of bootargs for default output and mode */ return 0; +vpbe_fail_amp_register: + kfree(vpbe_dev->amp); vpbe_fail_sd_register: kfree(vpbe_dev->encoders); vpbe_fail_v4l2_device: @@ -757,6 +805,7 @@ static void vpbe_deinitialize(struct device *dev, struct vpbe_device *vpbe_dev) if (strcmp(vpbe_dev->cfg->module_name, "dm644x-vpbe-display") != 0) clk_put(vpbe_dev->dac_clk); + kfree(vpbe_dev->amp); kfree(vpbe_dev->encoders); vpbe_dev->initialized = 0; /* disable vpss clocks */ diff --git a/include/media/davinci/vpbe.h b/include/media/davinci/vpbe.h index 8b11fb0..8bc1b3c 100644 --- a/include/media/davinci/vpbe.h +++ b/include/media/davinci/vpbe.h @@ -63,6 +63,7 @@ struct vpbe_output { * output basis. If per mode is needed, we may have to move this to * mode_info structure */ + enum v4l2_mbus_pixelcode if_params; }; /* encoder configuration info */ @@ -74,6 +75,15 @@ struct encoder_config_info { struct i2c_board_info board_info; }; +/*amplifier configuration info */ +struct amp_config_info { + char module_name[32]; + /* Is this an i2c device ? */ + unsigned int is_i2c:1; + /* i2c subdevice board info */ + struct i2c_board_info board_info; +}; + /* structure for defining vpbe display subsystem components */ struct vpbe_config { char module_name[32]; @@ -84,6 +94,8 @@ struct vpbe_config { /* external encoder information goes here */ int num_ext_encoders; struct encoder_config_info *ext_encoders; + /* amplifier information goes here */ + struct amp_config_info *amp; int num_outputs; /* Order is venc outputs followed by LCD and then external encoders */ struct vpbe_output *outputs; @@ -158,6 +170,8 @@ struct vpbe_device { struct v4l2_subdev **encoders; /* current encoder index */ int current_sd_index; + /* external amplifier v4l2 subdevice */ + struct v4l2_subdev *amp; struct mutex lock; /* device initialized */ int initialized; @@ -165,6 +179,8 @@ struct vpbe_device { struct clk *dac_clk; /* osd_device pointer */ struct osd_state *osd_device; + /* venc device pointer */ + struct venc_platform_data *venc_device; /* * fields below are accessed by users of vpbe_device. Not the * ones above -- 1.6.2.4 From manjunath.hadli at ti.com Mon Sep 19 00:35:28 2011 From: manjunath.hadli at ti.com (Manjunath Hadli) Date: Mon, 19 Sep 2011 11:05:28 +0530 Subject: [PATCH RESEND 3/4] davinci vpbe: add dm365 and dm355 specific OSD changes In-Reply-To: <1316410529-14744-1-git-send-email-manjunath.hadli@ti.com> References: <1316410529-14744-1-git-send-email-manjunath.hadli@ti.com> Message-ID: <1316410529-14744-4-git-send-email-manjunath.hadli@ti.com> Add OSD block changes to enable dm365 and dm355 for vpbe driver. Changes are based on version number of OSD, which have incremental changes over 644x OSD hardware interms of few registers. VPBE_VERSION_2 = dm365 specific VPBE_VERSION_3 = dm355 specific Signed-off-by: Manjunath Hadli --- drivers/media/video/davinci/vpbe_osd.c | 474 +++++++++++++++++++++++++++++--- 1 files changed, 433 insertions(+), 41 deletions(-) diff --git a/drivers/media/video/davinci/vpbe_osd.c b/drivers/media/video/davinci/vpbe_osd.c index 5352884..cf472d3 100644 --- a/drivers/media/video/davinci/vpbe_osd.c +++ b/drivers/media/video/davinci/vpbe_osd.c @@ -248,11 +248,31 @@ static void _osd_set_rec601_attenuation(struct osd_state *sd, osd_modify(sd, OSD_OSDWIN0MD_ATN0E, enable ? OSD_OSDWIN0MD_ATN0E : 0, OSD_OSDWIN0MD); + if (sd->vpbe_type == VPBE_VERSION_1) { + osd_modify(sd, OSD_OSDWIN0MD_ATN0E, + enable ? OSD_OSDWIN0MD_ATN0E : 0, + OSD_OSDWIN0MD); + } else if ((sd->vpbe_type == VPBE_VERSION_3) || + (sd->vpbe_type == VPBE_VERSION_2)) { + osd_modify(sd, OSD_EXTMODE_ATNOSD0EN, + enable ? OSD_EXTMODE_ATNOSD0EN : 0, + OSD_EXTMODE); + } break; case OSDWIN_OSD1: osd_modify(sd, OSD_OSDWIN1MD_ATN1E, enable ? OSD_OSDWIN1MD_ATN1E : 0, OSD_OSDWIN1MD); + if (sd->vpbe_type == VPBE_VERSION_1) { + osd_modify(sd, OSD_OSDWIN1MD_ATN1E, + enable ? OSD_OSDWIN1MD_ATN1E : 0, + OSD_OSDWIN1MD); + } else if ((sd->vpbe_type == VPBE_VERSION_3) || + (sd->vpbe_type == VPBE_VERSION_2)) { + osd_modify(sd, OSD_EXTMODE_ATNOSD1EN, + enable ? OSD_EXTMODE_ATNOSD1EN : 0, + OSD_EXTMODE); + } break; } } @@ -273,15 +293,72 @@ static void _osd_set_blending_factor(struct osd_state *sd, } } +static void _osd_enable_rgb888_pixblend(struct osd_state *sd, + enum osd_win_layer osdwin) +{ + + osd_modify(sd, OSD_MISCCTL_BLDSEL, 0, OSD_MISCCTL); + switch (osdwin) { + case OSDWIN_OSD0: + osd_modify(sd, OSD_EXTMODE_OSD0BLDCHR, + OSD_EXTMODE_OSD0BLDCHR, OSD_EXTMODE); + break; + case OSDWIN_OSD1: + osd_modify(sd, OSD_EXTMODE_OSD1BLDCHR, + OSD_EXTMODE_OSD1BLDCHR, OSD_EXTMODE); + break; + } +} + static void _osd_enable_color_key(struct osd_state *sd, enum osd_win_layer osdwin, unsigned colorkey, enum osd_pix_format pixfmt) { switch (pixfmt) { + case PIXFMT_1BPP: + case PIXFMT_2BPP: + case PIXFMT_4BPP: + case PIXFMT_8BPP: + if (sd->vpbe_type == VPBE_VERSION_3) { + switch (osdwin) { + case OSDWIN_OSD0: + osd_modify(sd, OSD_TRANSPBMPIDX_BMP0, + colorkey << + OSD_TRANSPBMPIDX_BMP0_SHIFT, + OSD_TRANSPBMPIDX); + break; + case OSDWIN_OSD1: + osd_modify(sd, OSD_TRANSPBMPIDX_BMP1, + colorkey << + OSD_TRANSPBMPIDX_BMP1_SHIFT, + OSD_TRANSPBMPIDX); + break; + } + } + break; case PIXFMT_RGB565: - osd_write(sd, colorkey & OSD_TRANSPVAL_RGBTRANS, - OSD_TRANSPVAL); + if (sd->vpbe_type == VPBE_VERSION_1) { + osd_write(sd, colorkey & OSD_TRANSPVAL_RGBTRANS, + OSD_TRANSPVAL); + } else if (sd->vpbe_type == VPBE_VERSION_3) { + osd_write(sd, colorkey & OSD_TRANSPVALL_RGBL, + OSD_TRANSPVALL); + } + break; + case PIXFMT_YCbCrI: + case PIXFMT_YCrCbI: + if (sd->vpbe_type == VPBE_VERSION_3) + osd_modify(sd, OSD_TRANSPVALU_Y, colorkey, + OSD_TRANSPVALU); + break; + case PIXFMT_RGB888: + if (sd->vpbe_type == VPBE_VERSION_3) { + osd_write(sd, colorkey & OSD_TRANSPVALL_RGBL, + OSD_TRANSPVALL); + osd_modify(sd, OSD_TRANSPVALU_RGBU, colorkey >> 16, + OSD_TRANSPVALU); + } break; default: break; @@ -470,23 +547,187 @@ static int osd_enable_layer(struct osd_state *sd, enum osd_layer layer, return 0; } +#define OSD_SRC_ADDR_HIGH4 0x7800000 +#define OSD_SRC_ADDR_HIGH7 0x7F0000 +#define OSD_SRCADD_OFSET_SFT 23 +#define OSD_SRCADD_ADD_SFT 16 +#define OSD_WINADL_MASK 0xFFFF +#define OSD_WINOFST_MASK 0x1000 + static void _osd_start_layer(struct osd_state *sd, enum osd_layer layer, unsigned long fb_base_phys, unsigned long cbcr_ofst) { - switch (layer) { - case WIN_OSD0: - osd_write(sd, fb_base_phys & ~0x1F, OSD_OSDWIN0ADR); - break; - case WIN_VID0: - osd_write(sd, fb_base_phys & ~0x1F, OSD_VIDWIN0ADR); - break; - case WIN_OSD1: - osd_write(sd, fb_base_phys & ~0x1F, OSD_OSDWIN1ADR); - break; - case WIN_VID1: - osd_write(sd, fb_base_phys & ~0x1F, OSD_VIDWIN1ADR); - break; + + if (sd->vpbe_type == VPBE_VERSION_1) { + switch (layer) { + case WIN_OSD0: + osd_write(sd, fb_base_phys & ~0x1F, OSD_OSDWIN0ADR); + break; + case WIN_VID0: + osd_write(sd, fb_base_phys & ~0x1F, OSD_VIDWIN0ADR); + break; + case WIN_OSD1: + osd_write(sd, fb_base_phys & ~0x1F, OSD_OSDWIN1ADR); + break; + case WIN_VID1: + osd_write(sd, fb_base_phys & ~0x1F, OSD_VIDWIN1ADR); + break; + } + } else if (sd->vpbe_type == VPBE_VERSION_3) { + unsigned long fb_offset_32 = + (fb_base_phys - DAVINCI_DDR_BASE) >> 5; + + switch (layer) { + case WIN_OSD0: + osd_modify(sd, OSD_OSDWINADH_O0AH, + fb_offset_32 >> (OSD_SRCADD_ADD_SFT - + OSD_OSDWINADH_O0AH_SHIFT), + OSD_OSDWINADH); + osd_write(sd, fb_offset_32 & OSD_OSDWIN0ADL_O0AL, + OSD_OSDWIN0ADL); + break; + case WIN_VID0: + osd_modify(sd, OSD_VIDWINADH_V0AH, + fb_offset_32 >> (OSD_SRCADD_ADD_SFT - + OSD_VIDWINADH_V0AH_SHIFT), + OSD_VIDWINADH); + osd_write(sd, fb_offset_32 & OSD_VIDWIN0ADL_V0AL, + OSD_VIDWIN0ADL); + break; + case WIN_OSD1: + osd_modify(sd, OSD_OSDWINADH_O1AH, + fb_offset_32 >> (OSD_SRCADD_ADD_SFT - + OSD_OSDWINADH_O1AH_SHIFT), + OSD_OSDWINADH); + osd_write(sd, fb_offset_32 & OSD_OSDWIN1ADL_O1AL, + OSD_OSDWIN1ADL); + break; + case WIN_VID1: + osd_modify(sd, OSD_VIDWINADH_V1AH, + fb_offset_32 >> (OSD_SRCADD_ADD_SFT - + OSD_VIDWINADH_V1AH_SHIFT), + OSD_VIDWINADH); + osd_write(sd, fb_offset_32 & OSD_VIDWIN1ADL_V1AL, + OSD_VIDWIN1ADL); + break; + } + } else if (sd->vpbe_type == VPBE_VERSION_2) { + struct osd_window_state *win = &sd->win[layer]; + unsigned long fb_offset_32, cbcr_offset_32; + + fb_offset_32 = fb_base_phys - DAVINCI_DDR_BASE; + if (cbcr_ofst) + cbcr_offset_32 = cbcr_ofst; + else + cbcr_offset_32 = win->lconfig.line_length * + win->lconfig.ysize; + cbcr_offset_32 += fb_offset_32; + fb_offset_32 = fb_offset_32 >> 5; + cbcr_offset_32 = cbcr_offset_32 >> 5; + /* + * DM365: start address is 27-bit long address b26 - b23 are + * in offset register b12 - b9, and * bit 26 has to be '1' + */ + if (win->lconfig.pixfmt == PIXFMT_NV12) { + switch (layer) { + case WIN_VID0: + case WIN_VID1: + /* Y is in VID0 */ + osd_modify(sd, OSD_VIDWIN0OFST_V0AH, + ((fb_offset_32 & OSD_SRC_ADDR_HIGH4) >> + (OSD_SRCADD_OFSET_SFT - + OSD_WINOFST_AH_SHIFT)) | + OSD_WINOFST_MASK, OSD_VIDWIN0OFST); + osd_modify(sd, OSD_VIDWINADH_V0AH, + (fb_offset_32 & OSD_SRC_ADDR_HIGH7) >> + (OSD_SRCADD_ADD_SFT - + OSD_VIDWINADH_V0AH_SHIFT), + OSD_VIDWINADH); + osd_write(sd, fb_offset_32 & OSD_WINADL_MASK, + OSD_VIDWIN0ADL); + /* CbCr is in VID1 */ + osd_modify(sd, OSD_VIDWIN1OFST_V1AH, + ((cbcr_offset_32 & + OSD_SRC_ADDR_HIGH4) >> + (OSD_SRCADD_OFSET_SFT - + OSD_WINOFST_AH_SHIFT)) | + OSD_WINOFST_MASK, OSD_VIDWIN1OFST); + osd_modify(sd, OSD_VIDWINADH_V1AH, + (cbcr_offset_32 & + OSD_SRC_ADDR_HIGH7) >> + (OSD_SRCADD_ADD_SFT - + OSD_VIDWINADH_V1AH_SHIFT), + OSD_VIDWINADH); + osd_write(sd, cbcr_offset_32 & OSD_WINADL_MASK, + OSD_VIDWIN1ADL); + break; + default: + break; + } + } + + switch (layer) { + case WIN_OSD0: + osd_modify(sd, OSD_OSDWIN0OFST_O0AH, + ((fb_offset_32 & OSD_SRC_ADDR_HIGH4) >> + (OSD_SRCADD_OFSET_SFT - + OSD_WINOFST_AH_SHIFT)) | OSD_WINOFST_MASK, + OSD_OSDWIN0OFST); + osd_modify(sd, OSD_OSDWINADH_O0AH, + (fb_offset_32 & OSD_SRC_ADDR_HIGH7) >> + (OSD_SRCADD_ADD_SFT - + OSD_OSDWINADH_O0AH_SHIFT), OSD_OSDWINADH); + osd_write(sd, fb_offset_32 & OSD_WINADL_MASK, + OSD_OSDWIN0ADL); + break; + case WIN_VID0: + if (win->lconfig.pixfmt != PIXFMT_NV12) { + osd_modify(sd, OSD_VIDWIN0OFST_V0AH, + ((fb_offset_32 & OSD_SRC_ADDR_HIGH4) >> + (OSD_SRCADD_OFSET_SFT - + OSD_WINOFST_AH_SHIFT)) | + OSD_WINOFST_MASK, OSD_VIDWIN0OFST); + osd_modify(sd, OSD_VIDWINADH_V0AH, + (fb_offset_32 & OSD_SRC_ADDR_HIGH7) >> + (OSD_SRCADD_ADD_SFT - + OSD_VIDWINADH_V0AH_SHIFT), + OSD_VIDWINADH); + osd_write(sd, fb_offset_32 & OSD_WINADL_MASK, + OSD_VIDWIN0ADL); + } + break; + case WIN_OSD1: + osd_modify(sd, OSD_OSDWIN1OFST_O1AH, + ((fb_offset_32 & OSD_SRC_ADDR_HIGH4) >> + (OSD_SRCADD_OFSET_SFT - + OSD_WINOFST_AH_SHIFT)) | OSD_WINOFST_MASK, + OSD_OSDWIN1OFST); + osd_modify(sd, OSD_OSDWINADH_O1AH, + (fb_offset_32 & OSD_SRC_ADDR_HIGH7) >> + (OSD_SRCADD_ADD_SFT - + OSD_OSDWINADH_O1AH_SHIFT), + OSD_OSDWINADH); + osd_write(sd, fb_offset_32 & OSD_WINADL_MASK, + OSD_OSDWIN1ADL); + break; + case WIN_VID1: + if (win->lconfig.pixfmt != PIXFMT_NV12) { + osd_modify(sd, OSD_VIDWIN1OFST_V1AH, + ((fb_offset_32 & OSD_SRC_ADDR_HIGH4) >> + (OSD_SRCADD_OFSET_SFT - + OSD_WINOFST_AH_SHIFT)) | + OSD_WINOFST_MASK, OSD_VIDWIN1OFST); + osd_modify(sd, OSD_VIDWINADH_V1AH, + (fb_offset_32 & OSD_SRC_ADDR_HIGH7) >> + (OSD_SRCADD_ADD_SFT - + OSD_VIDWINADH_V1AH_SHIFT), + OSD_VIDWINADH); + osd_write(sd, fb_offset_32 & OSD_WINADL_MASK, + OSD_VIDWIN1ADL); + } + break; + } } } @@ -545,7 +786,7 @@ static int try_layer_config(struct osd_state *sd, enum osd_layer layer, { struct osd_state *osd = sd; struct osd_window_state *win = &osd->win[layer]; - int bad_config; + int bad_config = 0; /* verify that the pixel format is compatible with the layer */ switch (lconfig->pixfmt) { @@ -554,17 +795,25 @@ static int try_layer_config(struct osd_state *sd, enum osd_layer layer, case PIXFMT_4BPP: case PIXFMT_8BPP: case PIXFMT_RGB565: - bad_config = !is_osd_win(layer); + if (osd->vpbe_type == VPBE_VERSION_1) + bad_config = !is_vid_win(layer); break; case PIXFMT_YCbCrI: case PIXFMT_YCrCbI: bad_config = !is_vid_win(layer); break; case PIXFMT_RGB888: - bad_config = !is_vid_win(layer); + if (osd->vpbe_type == VPBE_VERSION_1) + bad_config = !is_vid_win(layer); + else if ((osd->vpbe_type == VPBE_VERSION_3) || + (osd->vpbe_type == VPBE_VERSION_2)) + bad_config = !is_osd_win(layer); break; case PIXFMT_NV12: - bad_config = 1; + if (osd->vpbe_type != VPBE_VERSION_2) + bad_config = 1; + else + bad_config = is_osd_win(layer); break; case PIXFMT_OSD_ATTR: bad_config = (layer != WIN_OSD1); @@ -584,7 +833,8 @@ static int try_layer_config(struct osd_state *sd, enum osd_layer layer, /* DM6446: */ /* only one OSD window at a time can use RGB pixel formats */ - if (is_osd_win(layer) && is_rgb_pixfmt(lconfig->pixfmt)) { + if ((osd->vpbe_type == VPBE_VERSION_1) && + is_osd_win(layer) && is_rgb_pixfmt(lconfig->pixfmt)) { enum osd_pix_format pixfmt; if (layer == WIN_OSD0) pixfmt = osd->win[WIN_OSD1].lconfig.pixfmt; @@ -602,7 +852,8 @@ static int try_layer_config(struct osd_state *sd, enum osd_layer layer, } /* DM6446: only one video window at a time can use RGB888 */ - if (is_vid_win(layer) && lconfig->pixfmt == PIXFMT_RGB888) { + if ((osd->vpbe_type == VPBE_VERSION_1) && is_vid_win(layer) && + lconfig->pixfmt == PIXFMT_RGB888) { enum osd_pix_format pixfmt; if (layer == WIN_VID0) @@ -652,7 +903,8 @@ static void _osd_disable_vid_rgb888(struct osd_state *sd) * The caller must ensure that neither video window is currently * configured for RGB888 pixel format. */ - osd_clear(sd, OSD_MISCCTL_RGBEN, OSD_MISCCTL); + if (sd->vpbe_type == VPBE_VERSION_1) + osd_clear(sd, OSD_MISCCTL_RGBEN, OSD_MISCCTL); } static void _osd_enable_vid_rgb888(struct osd_state *sd, @@ -665,13 +917,15 @@ static void _osd_enable_vid_rgb888(struct osd_state *sd, * currently configured for RGB888 pixel format, as this routine will * disable RGB888 pixel format for the other window. */ - if (layer == WIN_VID0) { - osd_modify(sd, OSD_MISCCTL_RGBEN | OSD_MISCCTL_RGBWIN, - OSD_MISCCTL_RGBEN, OSD_MISCCTL); - } else if (layer == WIN_VID1) { - osd_modify(sd, OSD_MISCCTL_RGBEN | OSD_MISCCTL_RGBWIN, - OSD_MISCCTL_RGBEN | OSD_MISCCTL_RGBWIN, - OSD_MISCCTL); + if (sd->vpbe_type == VPBE_VERSION_1) { + if (layer == WIN_VID0) { + osd_modify(sd, OSD_MISCCTL_RGBEN | OSD_MISCCTL_RGBWIN, + OSD_MISCCTL_RGBEN, OSD_MISCCTL); + } else if (layer == WIN_VID1) { + osd_modify(sd, OSD_MISCCTL_RGBEN | OSD_MISCCTL_RGBWIN, + OSD_MISCCTL_RGBEN | OSD_MISCCTL_RGBWIN, + OSD_MISCCTL); + } } } @@ -697,9 +951,30 @@ static void _osd_set_layer_config(struct osd_state *sd, enum osd_layer layer, switch (layer) { case WIN_OSD0: - winmd_mask |= OSD_OSDWIN0MD_RGB0E; - if (lconfig->pixfmt == PIXFMT_RGB565) - winmd |= OSD_OSDWIN0MD_RGB0E; + if (sd->vpbe_type == VPBE_VERSION_1) { + winmd_mask |= OSD_OSDWIN0MD_RGB0E; + if (lconfig->pixfmt == PIXFMT_RGB565) + winmd |= OSD_OSDWIN0MD_RGB0E; + } else if ((sd->vpbe_type == VPBE_VERSION_3) || + (sd->vpbe_type == VPBE_VERSION_2)) { + winmd_mask |= OSD_OSDWIN0MD_BMP0MD; + switch (lconfig->pixfmt) { + case PIXFMT_RGB565: + winmd |= (1 << + OSD_OSDWIN0MD_BMP0MD_SHIFT); + break; + case PIXFMT_RGB888: + winmd |= (2 << OSD_OSDWIN0MD_BMP0MD_SHIFT); + _osd_enable_rgb888_pixblend(sd, OSDWIN_OSD0); + break; + case PIXFMT_YCbCrI: + case PIXFMT_YCrCbI: + winmd |= (3 << OSD_OSDWIN0MD_BMP0MD_SHIFT); + break; + default: + break; + } + } winmd_mask |= OSD_OSDWIN0MD_BMW0 | OSD_OSDWIN0MD_OFF0; @@ -749,12 +1024,58 @@ static void _osd_set_layer_config(struct osd_state *sd, enum osd_layer layer, * For YUV420P format the register contents are * duplicated in both VID registers */ + if ((sd->vpbe_type == VPBE_VERSION_2) && + (lconfig->pixfmt == PIXFMT_NV12)) { + /* other window also */ + if (lconfig->interlaced) { + winmd_mask |= OSD_VIDWINMD_VFF1; + winmd |= OSD_VIDWINMD_VFF1; + osd_modify(sd, winmd_mask, winmd, + OSD_VIDWINMD); + } + + osd_modify(sd, OSD_MISCCTL_S420D, + OSD_MISCCTL_S420D, OSD_MISCCTL); + osd_write(sd, lconfig->line_length >> 5, + OSD_VIDWIN1OFST); + osd_write(sd, lconfig->xpos, OSD_VIDWIN1XP); + osd_write(sd, lconfig->xsize, OSD_VIDWIN1XL); + /* + * if NV21 pixfmt and line length not 32B + * aligned (e.g. NTSC), Need to set window + * X pixel size to be 32B aligned as well + */ + if (lconfig->xsize % 32) { + osd_write(sd, + ((lconfig->xsize + 31) & ~31), + OSD_VIDWIN1XL); + osd_write(sd, + ((lconfig->xsize + 31) & ~31), + OSD_VIDWIN0XL); + } + } else if ((sd->vpbe_type == VPBE_VERSION_2) && + (lconfig->pixfmt != PIXFMT_NV12)) + osd_modify(sd, OSD_MISCCTL_S420D, ~OSD_MISCCTL_S420D, + OSD_MISCCTL); + if (lconfig->interlaced) { osd_write(sd, lconfig->ypos >> 1, OSD_VIDWIN0YP); osd_write(sd, lconfig->ysize >> 1, OSD_VIDWIN0YL); + if ((sd->vpbe_type == VPBE_VERSION_2) && + lconfig->pixfmt == PIXFMT_NV12) { + osd_write(sd, lconfig->ypos >> 1, + OSD_VIDWIN1YP); + osd_write(sd, lconfig->ysize >> 1, + OSD_VIDWIN1YL); + } } else { osd_write(sd, lconfig->ypos, OSD_VIDWIN0YP); osd_write(sd, lconfig->ysize, OSD_VIDWIN0YL); + if ((sd->vpbe_type == VPBE_VERSION_2) && + lconfig->pixfmt == PIXFMT_NV12) { + osd_write(sd, lconfig->ypos, OSD_VIDWIN1YP); + osd_write(sd, lconfig->ysize, OSD_VIDWIN1YL); + } } break; case WIN_OSD1: @@ -764,14 +1085,43 @@ static void _osd_set_layer_config(struct osd_state *sd, enum osd_layer layer, * attribute mode to a normal mode. */ if (lconfig->pixfmt == PIXFMT_OSD_ATTR) { - winmd_mask |= - OSD_OSDWIN1MD_ATN1E | OSD_OSDWIN1MD_RGB1E | - OSD_OSDWIN1MD_CLUTS1 | - OSD_OSDWIN1MD_BLND1 | OSD_OSDWIN1MD_TE1; + if (sd->vpbe_type == VPBE_VERSION_1) { + winmd_mask |= OSD_OSDWIN1MD_ATN1E | + OSD_OSDWIN1MD_RGB1E | OSD_OSDWIN1MD_CLUTS1 | + OSD_OSDWIN1MD_BLND1 | OSD_OSDWIN1MD_TE1; + } else { + winmd_mask |= OSD_OSDWIN1MD_BMP1MD | + OSD_OSDWIN1MD_CLUTS1 | OSD_OSDWIN1MD_BLND1 | + OSD_OSDWIN1MD_TE1; + } } else { - winmd_mask |= OSD_OSDWIN1MD_RGB1E; - if (lconfig->pixfmt == PIXFMT_RGB565) - winmd |= OSD_OSDWIN1MD_RGB1E; + if (sd->vpbe_type == VPBE_VERSION_1) { + winmd_mask |= OSD_OSDWIN1MD_RGB1E; + if (lconfig->pixfmt == PIXFMT_RGB565) + winmd |= OSD_OSDWIN1MD_RGB1E; + } else if ((sd->vpbe_type == VPBE_VERSION_3) + || (sd->vpbe_type == VPBE_VERSION_2)) { + winmd_mask |= OSD_OSDWIN1MD_BMP1MD; + switch (lconfig->pixfmt) { + case PIXFMT_RGB565: + winmd |= + (1 << OSD_OSDWIN1MD_BMP1MD_SHIFT); + break; + case PIXFMT_RGB888: + winmd |= + (2 << OSD_OSDWIN1MD_BMP1MD_SHIFT); + _osd_enable_rgb888_pixblend(sd, + OSDWIN_OSD1); + break; + case PIXFMT_YCbCrI: + case PIXFMT_YCrCbI: + winmd |= + (3 << OSD_OSDWIN1MD_BMP1MD_SHIFT); + break; + default: + break; + } + } winmd_mask |= OSD_OSDWIN1MD_BMW1; switch (lconfig->pixfmt) { @@ -822,15 +1172,44 @@ static void _osd_set_layer_config(struct osd_state *sd, enum osd_layer layer, * For YUV420P format the register contents are * duplicated in both VID registers */ - osd_modify(sd, OSD_MISCCTL_S420D, ~OSD_MISCCTL_S420D, - OSD_MISCCTL); + if (sd->vpbe_type == VPBE_VERSION_2) { + if (lconfig->pixfmt == PIXFMT_NV12) { + /* other window also */ + if (lconfig->interlaced) { + winmd_mask |= OSD_VIDWINMD_VFF0; + winmd |= OSD_VIDWINMD_VFF0; + osd_modify(sd, winmd_mask, winmd, + OSD_VIDWINMD); + } + osd_modify(sd, OSD_MISCCTL_S420D, + OSD_MISCCTL_S420D, OSD_MISCCTL); + osd_write(sd, lconfig->line_length >> 5, + OSD_VIDWIN0OFST); + osd_write(sd, lconfig->xpos, OSD_VIDWIN0XP); + osd_write(sd, lconfig->xsize, OSD_VIDWIN0XL); + } else + osd_modify(sd, OSD_MISCCTL_S420D, + ~OSD_MISCCTL_S420D, OSD_MISCCTL); + } if (lconfig->interlaced) { osd_write(sd, lconfig->ypos >> 1, OSD_VIDWIN1YP); osd_write(sd, lconfig->ysize >> 1, OSD_VIDWIN1YL); + if ((sd->vpbe_type == VPBE_VERSION_2) && + lconfig->pixfmt == PIXFMT_NV12) { + osd_write(sd, lconfig->ypos >> 1, + OSD_VIDWIN0YP); + osd_write(sd, lconfig->ysize >> 1, + OSD_VIDWIN0YL); + } } else { osd_write(sd, lconfig->ypos, OSD_VIDWIN1YP); osd_write(sd, lconfig->ysize, OSD_VIDWIN1YL); + if ((sd->vpbe_type == VPBE_VERSION_2) && + lconfig->pixfmt == PIXFMT_NV12) { + osd_write(sd, lconfig->ypos, OSD_VIDWIN0YP); + osd_write(sd, lconfig->ysize, OSD_VIDWIN0YL); + } } break; } @@ -1089,6 +1468,11 @@ static void _osd_init(struct osd_state *sd) osd_write(sd, 0, OSD_OSDWIN1MD); osd_write(sd, 0, OSD_RECTCUR); osd_write(sd, 0, OSD_MISCCTL); + if (sd->vpbe_type == VPBE_VERSION_3) { + osd_write(sd, 0, OSD_VBNDRY); + osd_write(sd, 0, OSD_EXTMODE); + osd_write(sd, OSD_MISCCTL_DMANG, OSD_MISCCTL); + } } static void osd_set_left_margin(struct osd_state *sd, u32 val) @@ -1110,6 +1494,14 @@ static int osd_initialize(struct osd_state *osd) /* set default Cb/Cr order */ osd->yc_pixfmt = PIXFMT_YCbCrI; + if (osd->vpbe_type == VPBE_VERSION_3) { + /* + * ROM CLUT1 on the DM355 is similar (identical?) to ROM CLUT0 + * on the DM6446, so make ROM_CLUT1 the default on the DM355. + */ + osd->rom_clut = ROM_CLUT1; + } + _osd_set_field_inversion(osd, osd->field_inversion); _osd_set_rom_clut(osd, osd->rom_clut); -- 1.6.2.4 From manjunath.hadli at ti.com Mon Sep 19 00:49:18 2011 From: manjunath.hadli at ti.com (Hadli, Manjunath) Date: Mon, 19 Sep 2011 11:19:18 +0530 Subject: [PATCH RESEND 0/4] davinci vpbe: enable DM365 v4l2 display driver In-Reply-To: <1316410529-14744-1-git-send-email-manjunath.hadli@ti.com> References: <1316410529-14744-1-git-send-email-manjunath.hadli@ti.com> Message-ID: Sakari, Hans, Can I request you to have a look at these patches too? Thanks and Regards, -Manju On Mon, Sep 19, 2011 at 11:05:25, Hadli, Manjunath wrote: > The patchset adds incremental changes necessary to enable dm365 > v4l2 display driver, which includes vpbe display driver changes, osd specific changes and venc changes. The changes are incremental in nature,addind a few HD modes, and taking care of register level changes. > > The patch set does not include THS7303 amplifier driver which is planned to be sent seperately. > > > Manjunath Hadli (4): > davinci vpbe: remove unused macro. > davinci vpbe: add dm365 VPBE display driver changes > davinci vpbe: add dm365 and dm355 specific OSD changes > davinci vpbe: add VENC block changes to enable dm365 and dm355 > > drivers/media/video/davinci/vpbe.c | 55 +++- > drivers/media/video/davinci/vpbe_display.c | 1 - > drivers/media/video/davinci/vpbe_osd.c | 474 +++++++++++++++++++++++++--- > drivers/media/video/davinci/vpbe_venc.c | 205 +++++++++++-- > include/media/davinci/vpbe.h | 16 + > include/media/davinci/vpbe_venc.h | 4 + > 6 files changed, 686 insertions(+), 69 deletions(-) > > From nagabhushana.netagunte at ti.com Mon Sep 19 01:46:21 2011 From: nagabhushana.netagunte at ti.com (Netagunte, Nagabhushana) Date: Mon, 19 Sep 2011 12:16:21 +0530 Subject: DM355 capture image from MT9M112 In-Reply-To: <4E72209F.9000107@gmail.com> References: <4E72209F.9000107@gmail.com> Message-ID: I never tested soc_camera interface for dm355. But, you can directly call vpfe_capture driver through v4l2 API for capturing camera buffers. vpfe_capture driver will call sensor driver directly whenever necessary. Also post this question in Ti e2e forum, your query will reach bigger community. Regards, Nag ________________________________________ From: davinci-linux-open-source-bounces at linux.davincidsp.com [davinci-linux-open-source-bounces at linux.davincidsp.com] On Behalf Of damateem [damateem4 at gmail.com] Sent: Thursday, September 15, 2011 9:28 PM To: davinci-linux-open-source Subject: DM355 capture image from MT9M112 My kernel version is Arago/2.6.31+2.6.32-rc2-r52+gitr. I'm struggling to wrap my head around how to capture images from an MT9M112 image sensor. I found a driver in mt9m111.c that appears to include the camera driver written for the soc-camera framework, but what are the steps for using it? Before getting into the details of the problem, a general overview would help a bunch. 1.) Does this kernel version have support for the soc-camera framework on the DM355? 2.) Is there a document (other than soc-camera.txt) that describes the soc-camera framework at a high level? What files are involved and how do they fit together? Is this correct? User Application /|\ | \|/ vpfe_capture.c <---> soc_camera.c <---> mt9m111.c (User Application should point to soc_camera.c) Thanks, David _______________________________________________ Davinci-linux-open-source mailing list Davinci-linux-open-source at linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source From Jon.Povey at racelogic.co.uk Tue Sep 20 01:09:54 2011 From: Jon.Povey at racelogic.co.uk (Jon Povey) Date: Tue, 20 Sep 2011 07:09:54 +0100 Subject: [PATCH RESEND 2/4] davinci vpbe: add dm365 VPBE display driver changes In-Reply-To: <1316410529-14744-3-git-send-email-manjunath.hadli@ti.com> Message-ID: <70E876B0EA86DD4BAF101844BC814DFE0BF22415C3@Cloud.RL.local> davinci-linux-open-source-bounces at linux.davincidsp.com wrote: > This patch implements the core additions to the display driver, > mainly controlling the VENC and other encoders for dm365. > This patch also includes addition of amplifier subdevice to the > vpbe driver and interfacing with venc subdevice. One small nit. Sorry about the probably broken quoting to follow. > @@ -704,6 +717,39 @@ static int vpbe_initialize(struct device > *dev, struct vpbe_device *vpbe_dev) > + v4l2_warn(&vpbe_dev->v4l2_dev, "non-i2c amplifiers" > + " currently not supported"); > + } > + } else > + vpbe_dev->amp = NULL; iirc this is not kernel style, if the "then" side of an if needs braces then the "else" side must have them too. -- Jon Povey jon.povey at racelogic.co.uk Racelogic is a limited company registered in England. Registered number 2743719 . Registered Office Unit 10, Swan Business Centre, Osier Way, Buckingham, Bucks, MK18 1TB . The information contained in this electronic mail transmission is intended by Racelogic Ltd for the use of the named individual or entity to which it is directed and may contain information that is confidential or privileged. If you have received this electronic mail transmission in error, please delete it from your system without copying or forwarding it, and notify the sender of the error by reply email so that the sender's address records can be corrected. The views expressed by the sender of this communication do not necessarily represent those of Racelogic Ltd. Please note that Racelogic reserves the right to monitor e-mail communications passing through its network From sreecha01 at gmail.com Tue Sep 20 03:18:55 2011 From: sreecha01 at gmail.com (Appalayagari Sreedhar) Date: Tue, 20 Sep 2011 13:48:55 +0530 Subject: alsa driver playback using aplay fails Message-ID: Hi, I am working with DM365 evm board. I have interfaced conexant audio ic to the McBSP. I need to do I2S data transfer. I need to program the McBSP as master and conexant audio IC as slave. i did the macro changes in the davinci-evm.c file in AUDIO_FORMAT like this. #define AUDIO_FORMAT (SND_SOC_DAIFMT_I2S | \ SND_SOC_DAIFMT_CBS_CFS) I am using the McBSP internal clock for McBSP. I printed the McBSP registers and found that SCLKME - 0 and CLKSM - 1. by reading the registers. i have checked the PLL_DIV4 register and it shows the correct value 0x8003. when i run the aplay command i am not viewing any clocks when i probe the signals using the CRO. the mcbsp_starts and shutdown immediately. please let me know where i am doing wrong. Is there any way i can configure the McBSP as master. Please find my queries in the following thread in the ti e2e comminity. http://e2e.ti.com/support/embedded/f/354/p/134788/485628.aspx#485628 Thank you, Sreedhar. From benxuelan0402 at gmail.com Tue Sep 20 09:29:53 2011 From: benxuelan0402 at gmail.com (benxuelan0402) Date: Tue, 20 Sep 2011 22:29:53 +0800 Subject: hardware setup for dm355 and IP addresses Message-ID: <201109202229496872648@gmail.com> Hi, 1, maybe there is something wrong with your env, pls send your bootcmd and bootargs. 2, connect both your computer and the board to ethernet via separate cables or just interconnect them is both ok. 3, use printenv to see what the ip of hardware is. 2011-09-20 benxuelan0402 -------------- next part -------------- An HTML attachment was scrubbed... URL: From arnd at arndb.de Tue Sep 20 15:10:08 2011 From: arnd at arndb.de (Arnd Bergmann) Date: Tue, 20 Sep 2011 22:10:08 +0200 Subject: [GIT PULL] davinci fixes for v3.2 merge window In-Reply-To: References: Message-ID: <201109202210.08714.arnd@arndb.de> On Saturday 17 September 2011, Nori, Sekhar wrote: > Please pull the following two fixes for the v3.2 > merge window. They are not applicable to stable > tree and hence the stable tag has not been added. > > Thanks, > Sekhar > > The following changes since commit b6fd41e29dea9c6753b1843a77e50433e6123bcb: > Linus Torvalds (1): > Linux 3.1-rc6 > > are available in the git repository at: > > git://gitorious.org/linux-davinci/linux-davinci.git v3.2/fixes > > Ido Yariv (1): > ARM: davinci: Explicitly set channel controllers' default queues > > Thomas Meyer (1): > ARM: davinci: edma: use kzalloc() Hi Sekhar, Looking at the patches, they seem to be more of the cleanup category, so I think I'd apply them to the next/cleanup branch instead of the next/fixes branch. Does that make sense? Arnd From arnd at arndb.de Tue Sep 20 15:13:37 2011 From: arnd at arndb.de (Arnd Bergmann) Date: Tue, 20 Sep 2011 22:13:37 +0200 Subject: [GIT PULL] davinci features for v3.2 merge windiow In-Reply-To: References: Message-ID: <201109202213.37594.arnd@arndb.de> On Saturday 17 September 2011, Nori, Sekhar wrote: > Please pull the following feature for v3.2 merge > window. It adds TI WLAN support on AM18x board. > > Thanks, > Sekhar > > The following changes since commit b6fd41e29dea9c6753b1843a77e50433e6123bcb: > Linus Torvalds (1): > Linux 3.1-rc6 > > are available in the git repository at: > > git://gitorious.org/linux-davinci/linux-davinci.git v3.2/features > Pulled into the next/devel branch. Thanks, Arnd From sudhakar.raj at ti.com Wed Sep 21 03:38:12 2011 From: sudhakar.raj at ti.com (Rajashekhara, Sudhakar) Date: Wed, 21 Sep 2011 14:08:12 +0530 Subject: OMAP L138 evm halts when removing module davinci_spi In-Reply-To: <4E5E2667.8040001@efacec.com> References: <4E5E2667.8040001@efacec.com> Message-ID: Hi, On Wed, Aug 31, 2011 at 17:47:43, An?bal Almeida Pinto wrote: > Hi, > > I am using the OMAP L138 logic evaluation board with 3.0.0 linux-davinci > kernel. > > To the default configuration I have added spi support and build the > spi_davinci as a module. > > After the boards boot I was able to insmod davinci_spi.ko but when tried > to make rmmod davinci_spi.ko the board halted. > > Anyone have reported this ? > > Inserting printk on davinci_spi remove function it appears to be on > clk_disable. > I also noticed this issue. When I debugged this I found out that, the SPI driver enables the local low-power mode. This is achieved by setting the POWERDOWN bit (9th bit) in SPIGCR1 register. In local low-power mode, clock to SPI internal logic is stopped. At this point of time, doing a clk_disable() is not behaving properly. When SPI is not in low-power mode, clk_disable() works fine. So for rmmod to work, you need to remove all references to SPIGCR1_POWERDOWN_MASK in the code. Please test this at your end and let me know the outcome. If it is working, then I can submit a patch to the list which takes care of this. Thanks, Sudhakar From anibal.pinto at efacec.com Wed Sep 21 04:36:29 2011 From: anibal.pinto at efacec.com (=?ISO-8859-1?Q?An=EDbal_Almeida_Pinto?=) Date: Wed, 21 Sep 2011 10:36:29 +0100 Subject: OMAP L138 evm halts when removing module davinci_spi In-Reply-To: References: <4E5E2667.8040001@efacec.com> Message-ID: <4E79B01D.10000@efacec.com> Em 21-09-2011 09:38, Rajashekhara, Sudhakar escreveu: > Hi, > > On Wed, Aug 31, 2011 at 17:47:43, An?bal Almeida Pinto wrote: >> Hi, >> >> I am using the OMAP L138 logic evaluation board with 3.0.0 linux-davinci >> kernel. >> >> To the default configuration I have added spi support and build the >> spi_davinci as a module. >> >> After the boards boot I was able to insmod davinci_spi.ko but when tried >> to make rmmod davinci_spi.ko the board halted. >> >> Anyone have reported this ? >> >> Inserting printk on davinci_spi remove function it appears to be on >> clk_disable. >> > > I also noticed this issue. When I debugged this I found out that, the > SPI driver enables the local low-power mode. This is achieved by setting > the POWERDOWN bit (9th bit) in SPIGCR1 register. > > In local low-power mode, clock to SPI internal logic is stopped. At this > point of time, doing a clk_disable() is not behaving properly. When SPI > is not in low-power mode, clk_disable() works fine. So for rmmod to work, > you need to remove all references to SPIGCR1_POWERDOWN_MASK in the code. > > Please test this at your end and let me know the outcome. If it is working, > then I can submit a patch to the list which takes care of this. If I apply the patch attached I can make rmmod of the spi davinci driver. The procedure that I have tested : # insmod davinci_spi.ko spi_davinci spi_davinci.1: DMA: supported spi_davinci spi_davinci.1: DMA: RX channel: 18, TX channel: 19, event queue: 0 spi_davinci spi_davinci.1: Controller at 0xfef0e000 # rmmod davinci_spi.ko But can't insmod it again : # insmod davinci_spi.ko Unable to request DMA channel for SPI RX Trying to free nonexistent resource <0000000001f0e000-0000000001f0e000> spi_davinci: probe of spi_davinci.1 failed with error -11 insmod: can't insert 'davinci_spi.ko': No such device > > Thanks, > Sudhakar > > -------------- next part -------------- A non-text attachment was scrubbed... Name: commented_powerdown_mask.diff Type: text/x-patch Size: 418 bytes Desc: not available URL: From sudhakar.raj at ti.com Wed Sep 21 05:03:08 2011 From: sudhakar.raj at ti.com (Rajashekhara, Sudhakar) Date: Wed, 21 Sep 2011 15:33:08 +0530 Subject: OMAP L138 evm halts when removing module davinci_spi In-Reply-To: <4E79B01D.10000@efacec.com> References: <4E5E2667.8040001@efacec.com> <4E79B01D.10000@efacec.com> Message-ID: Hi, On Wed, Sep 21, 2011 at 15:06:29, An?bal Almeida Pinto wrote: > Em 21-09-2011 09:38, Rajashekhara, Sudhakar escreveu: > > Hi, > > > > On Wed, Aug 31, 2011 at 17:47:43, An?bal Almeida Pinto wrote: > >> Hi, > >> > >> I am using the OMAP L138 logic evaluation board with 3.0.0 linux-davinci > >> kernel. > >> > >> To the default configuration I have added spi support and build the > >> spi_davinci as a module. > >> > >> After the boards boot I was able to insmod davinci_spi.ko but when tried > >> to make rmmod davinci_spi.ko the board halted. > >> > >> Anyone have reported this ? > >> > >> Inserting printk on davinci_spi remove function it appears to be on > >> clk_disable. > >> > > > > I also noticed this issue. When I debugged this I found out that, the > > SPI driver enables the local low-power mode. This is achieved by setting > > the POWERDOWN bit (9th bit) in SPIGCR1 register. > > > > In local low-power mode, clock to SPI internal logic is stopped. At this > > point of time, doing a clk_disable() is not behaving properly. When SPI > > is not in low-power mode, clk_disable() works fine. So for rmmod to work, > > you need to remove all references to SPIGCR1_POWERDOWN_MASK in the code. > > > > Please test this at your end and let me know the outcome. If it is working, > > then I can submit a patch to the list which takes care of this. > > If I apply the patch attached I can make rmmod of the spi davinci driver. > > The procedure that I have tested : > > # insmod davinci_spi.ko > spi_davinci spi_davinci.1: DMA: supported > spi_davinci spi_davinci.1: DMA: RX channel: 18, TX channel: 19, event > queue: 0 > spi_davinci spi_davinci.1: Controller at 0xfef0e000 > > # rmmod davinci_spi.ko > > But can't insmod it again : > > # insmod davinci_spi.ko > Unable to request DMA channel for SPI RX > Trying to free nonexistent resource <0000000001f0e000-0000000001f0e000> > spi_davinci: probe of spi_davinci.1 failed with error -11 > insmod: can't insert 'davinci_spi.ko': No such device > I see that during module removal, the driver is not doing the following: edma_free_channel(dspi->dma.tx_channel); edma_free_channel(dspi->dma.rx_channel); edma_free_slot(dspi->dma.dummy_param_slot); Even after adding the above lines, I was not able to do the insmod again because for me, the m25p80 device was already registered. I am not sure whether you are using the same interface. If yes, you need to figure out how to handle that. Thanks, Sudhakar From nsekhar at ti.com Wed Sep 21 08:21:58 2011 From: nsekhar at ti.com (Nori, Sekhar) Date: Wed, 21 Sep 2011 18:51:58 +0530 Subject: [GIT PULL] davinci fixes for v3.2 merge window In-Reply-To: <201109202210.08714.arnd@arndb.de> References: <201109202210.08714.arnd@arndb.de> Message-ID: Hi Arnd, On Wed, Sep 21, 2011 at 01:40:08, Arnd Bergmann wrote: > Hi Sekhar, > > Looking at the patches, they seem to be more of the cleanup category, > so I think I'd apply them to the next/cleanup branch instead of > the next/fixes branch. Does that make sense? Okay. Thanks for pulling them in. Regards, Sekhar From gasparini at imavis.com Fri Sep 23 06:54:56 2011 From: gasparini at imavis.com (Andrea Gasparini) Date: Fri, 23 Sep 2011 13:54:56 +0200 Subject: What's wrong on this mmap() ? Message-ID: <201109231354.57117.gasparini@imavis.com> Hi, I'm having some problem understanding how mmap really works, I'm on a DM365, with a 2.6.32 kernel. I have a (dummy) driver that allocate some memory (4k), and gives it to a userspace through mmap() - the usual remap_pfn_range found in every example. i.e. using this: if (remap_pfn_range(vma, vma->vm_start, virt_to_phys(buffer) >> PAGE_SHIFT, vma->vm_end - vma->vm_start, vma->vm_page_prot)){ printk("remap returned something wrong\n"); return -EAGAIN; The userspace can read the memory correctly, but can't write to it. (though it maps with PROT_WRITE) As the manpage says: PROT_WRITE - Pages may be written. I'm attaching both the driver and the userspace testbed, with the hope someone tells me what's wrong with this. Note that I tested on ARM and x86 architectures, and different kernel, so It seems more likely a fault of mine, that a kernel strangeness. (obviusly, you'll say... :P ) The userspace log are something like that: Base userspace address for mmapped buffer is 0xb7786000 Wrote 00 in user-space 0xb7786000. Reading from it seems 00 Wrote 01 in user-space 0xb7786001. Reading from it seems 01 Wrote 02 in user-space 0xb7786002. Reading from it seems 02 [ .... snip ... ] While the kernel are: allocated: 4096 @virt: c7000000 @phys: 8c800000 virtToPhys(): 87000000 mmap worked. vmaflasg: 40184477 phys: 87000000 virt: c7000000 VMA open: vma->vm_start: 40236000 - vma->pgoffs: 87000 - vma->vm_end: 40237000, vma_flags: 40184477 VMA close: vma->vm_start: 40236000 - vma->pgoffs: 87000 - vma->vm_end: 40237000, vma_flags: 40184477 00 ff fe fd fc fb fa f9 f8 f7 f6 f5 f4 f3 f2 f1 f0 ef ee ed ec eb ea e9 e8 e7 e6 e5 e4 e3 e2 e1 Regards, bye! -- Andrea Gasparini ---- ImaVis S.r.l. ---- web: www.imavis.com -------------- next part -------------- A non-text attachment was scrubbed... Name: mmap_testbed.c Type: text/x-csrc Size: 3288 bytes Desc: not available URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: mmap_test.c Type: text/x-csrc Size: 4477 bytes Desc: not available URL: From gasparini at imavis.com Fri Sep 23 10:19:18 2011 From: gasparini at imavis.com (Andrea Gasparini) Date: Fri, 23 Sep 2011 17:19:18 +0200 Subject: What's wrong on this mmap() ? In-Reply-To: <201109231354.57117.gasparini@imavis.com> References: <201109231354.57117.gasparini@imavis.com> Message-ID: <201109231719.19129.gasparini@imavis.com> Andrea Gasparini wrote, Friday, September 23, 2011: > Hi, > I'm having some problem understanding how mmap really works, I'm on a > DM365, with a 2.6.32 kernel. > > I have a (dummy) driver that allocate some memory (4k), and gives it to > a userspace through mmap() - the usual remap_pfn_range found in every > example. > i.e. using this: > if (remap_pfn_range(vma, vma->vm_start, > virt_to_phys(buffer) >> PAGE_SHIFT, > vma->vm_end - vma->vm_start, > vma->vm_page_prot)){ > printk("remap returned something wrong\n"); > return -EAGAIN; > > The userspace can read the memory correctly, but can't write to it. > (though it maps with PROT_WRITE) > As the manpage says: PROT_WRITE - Pages may be written. > > I'm attaching both the driver and the userspace testbed, with the hope > someone tells me what's wrong with this. Ok, if opened with O_RDWR (and not read-only) and mapped with MAP_SHARED it works ... sorry fror the silly question :) Bye. -- Andrea Gasparini ---- ImaVis S.r.l. ---- web: www.imavis.com From m-karicheri2 at ti.com Fri Sep 23 16:26:12 2011 From: m-karicheri2 at ti.com (m-karicheri2 at ti.com) Date: Fri, 23 Sep 2011 17:26:12 -0400 Subject: [PATCH 1/2 - v3] ARM: davinci - fix incorrect offsets and mask usage in psc code Message-ID: <1316813173-31270-1-git-send-email-m-karicheri2@ti.com> From: Murali Karicheri There are 5 LSB bits defined in PDSTAT and the code currently uses a mask of 1 bit to check the status. Also there is PDSTAT and PDCTL registers defined for domain0 and domain1 where as the code always read the domain0 PDSTAT register and domain1 PDCTL register. This patch fixes these issues. Reviewed-by: Sergei Shtylyov Signed-off-by: Murali Karicheri --- change from v2-v3 - description of patch changed as per review comment - defined a constant for PDSTAT_STATE_MASK This patch applies to the davinci-next branch of linux-davinci tree arch/arm/mach-davinci/include/mach/psc.h | 3 ++- arch/arm/mach-davinci/psc.c | 18 +++++++++--------- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/arch/arm/mach-davinci/include/mach/psc.h b/arch/arm/mach-davinci/include/mach/psc.h index a47e6f2..1724d95 100644 --- a/arch/arm/mach-davinci/include/mach/psc.h +++ b/arch/arm/mach-davinci/include/mach/psc.h @@ -233,7 +233,7 @@ #define PTCMD 0x120 #define PTSTAT 0x128 #define PDSTAT 0x200 -#define PDCTL1 0x304 +#define PDCTL 0x300 #define MDSTAT 0x800 #define MDCTL 0xA00 @@ -244,6 +244,7 @@ #define PSC_STATE_ENABLE 3 #define MDSTAT_STATE_MASK 0x1f +#define PDSTAT_STATE_MASK 0x1f #ifndef __ASSEMBLER__ diff --git a/arch/arm/mach-davinci/psc.c b/arch/arm/mach-davinci/psc.c index a415804..5dbe974 100644 --- a/arch/arm/mach-davinci/psc.c +++ b/arch/arm/mach-davinci/psc.c @@ -50,7 +50,7 @@ int __init davinci_psc_is_clk_active(unsigned int ctlr, unsigned int id) void davinci_psc_config(unsigned int domain, unsigned int ctlr, unsigned int id, u32 next_state) { - u32 epcpr, ptcmd, ptstat, pdstat, pdctl1, mdstat, mdctl; + u32 epcpr, ptcmd, ptstat, pdstat, pdctl, mdstat, mdctl; void __iomem *psc_base; struct davinci_soc_info *soc_info = &davinci_soc_info; @@ -67,11 +67,11 @@ void davinci_psc_config(unsigned int domain, unsigned int ctlr, mdctl |= next_state; __raw_writel(mdctl, psc_base + MDCTL + 4 * id); - pdstat = __raw_readl(psc_base + PDSTAT); - if ((pdstat & 0x00000001) == 0) { - pdctl1 = __raw_readl(psc_base + PDCTL1); - pdctl1 |= 0x1; - __raw_writel(pdctl1, psc_base + PDCTL1); + pdstat = __raw_readl(psc_base + PDSTAT + 4 * domain); + if ((pdstat & PDSTAT_STATE_MASK) == 0) { + pdctl = __raw_readl(psc_base + PDCTL + 4 * domain); + pdctl |= 0x1; + __raw_writel(pdctl, psc_base + PDCTL + 4 * domain); ptcmd = 1 << domain; __raw_writel(ptcmd, psc_base + PTCMD); @@ -80,9 +80,9 @@ void davinci_psc_config(unsigned int domain, unsigned int ctlr, epcpr = __raw_readl(psc_base + EPCPR); } while ((((epcpr >> domain) & 1) == 0)); - pdctl1 = __raw_readl(psc_base + PDCTL1); - pdctl1 |= 0x100; - __raw_writel(pdctl1, psc_base + PDCTL1); + pdctl = __raw_readl(psc_base + PDCTL + 4 * domain); + pdctl |= 0x100; + __raw_writel(pdctl, psc_base + PDCTL + 4 * domain); } else { ptcmd = 1 << domain; __raw_writel(ptcmd, psc_base + PTCMD); -- 1.7.0.4 From m-karicheri2 at ti.com Fri Sep 23 16:26:13 2011 From: m-karicheri2 at ti.com (m-karicheri2 at ti.com) Date: Fri, 23 Sep 2011 17:26:13 -0400 Subject: [PATCH 2/2 - v3] ARM: davinci: enhancement to support multiple power domains In-Reply-To: <1316813173-31270-1-git-send-email-m-karicheri2@ti.com> References: <1316813173-31270-1-git-send-email-m-karicheri2@ti.com> Message-ID: <1316813173-31270-2-git-send-email-m-karicheri2@ti.com> From: Murali Karicheri In one of the new SoC that we are working on, there are multiple power domains similar to that in C6670. Currently clock module assumes that there are only two power domains (domain0 and domain1). This patch is added to enhance the code to support more than two power domains so as to allow porting of Linux on to the above SoC. Reviewed-by :Sergei Shtylyov Signed-off-by: Murali Karicheri --- change from v2->v3 - patch description change based on review comments. No code change - This patch applies to the davinci-next branch of linux-davinci tree arch/arm/mach-davinci/clock.c | 13 +++---------- arch/arm/mach-davinci/clock.h | 8 ++++---- arch/arm/mach-davinci/dm644x.c | 4 ++-- arch/arm/mach-davinci/dm646x.c | 2 +- 4 files changed, 10 insertions(+), 17 deletions(-) diff --git a/arch/arm/mach-davinci/clock.c b/arch/arm/mach-davinci/clock.c index e4e3af1..9356ac4 100644 --- a/arch/arm/mach-davinci/clock.c +++ b/arch/arm/mach-davinci/clock.c @@ -31,19 +31,12 @@ static LIST_HEAD(clocks); static DEFINE_MUTEX(clocks_mutex); static DEFINE_SPINLOCK(clockfw_lock); -static unsigned psc_domain(struct clk *clk) -{ - return (clk->flags & PSC_DSP) - ? DAVINCI_GPSC_DSPDOMAIN - : DAVINCI_GPSC_ARMDOMAIN; -} - static void __clk_enable(struct clk *clk) { if (clk->parent) __clk_enable(clk->parent); if (clk->usecount++ == 0 && (clk->flags & CLK_PSC)) - davinci_psc_config(psc_domain(clk), clk->gpsc, clk->lpsc, + davinci_psc_config(clk->domain, clk->gpsc, clk->lpsc, PSC_STATE_ENABLE); } @@ -53,7 +46,7 @@ static void __clk_disable(struct clk *clk) return; if (--clk->usecount == 0 && !(clk->flags & CLK_PLL) && (clk->flags & CLK_PSC)) - davinci_psc_config(psc_domain(clk), clk->gpsc, clk->lpsc, + davinci_psc_config(clk->domain, clk->gpsc, clk->lpsc, (clk->flags & PSC_SWRSTDISABLE) ? PSC_STATE_SWRSTDISABLE : PSC_STATE_DISABLE); if (clk->parent) @@ -238,7 +231,7 @@ static int __init clk_disable_unused(void) pr_debug("Clocks: disable unused %s\n", ck->name); - davinci_psc_config(psc_domain(ck), ck->gpsc, ck->lpsc, + davinci_psc_config(ck->domain, ck->gpsc, ck->lpsc, (ck->flags & PSC_SWRSTDISABLE) ? PSC_STATE_SWRSTDISABLE : PSC_STATE_DISABLE); } diff --git a/arch/arm/mach-davinci/clock.h b/arch/arm/mach-davinci/clock.h index 0dd2203..3dd8a60 100644 --- a/arch/arm/mach-davinci/clock.h +++ b/arch/arm/mach-davinci/clock.h @@ -93,6 +93,7 @@ struct clk { u8 usecount; u8 lpsc; u8 gpsc; + u8 domain; u32 flags; struct clk *parent; struct list_head children; /* list of children */ @@ -107,10 +108,9 @@ struct clk { /* Clock flags: SoC-specific flags start at BIT(16) */ #define ALWAYS_ENABLED BIT(1) #define CLK_PSC BIT(2) -#define PSC_DSP BIT(3) /* PSC uses DSP domain, not ARM */ -#define CLK_PLL BIT(4) /* PLL-derived clock */ -#define PRE_PLL BIT(5) /* source is before PLL mult/div */ -#define PSC_SWRSTDISABLE BIT(6) /* Disable state is SwRstDisable */ +#define CLK_PLL BIT(3) /* PLL-derived clock */ +#define PRE_PLL BIT(4) /* source is before PLL mult/div */ +#define PSC_SWRSTDISABLE BIT(5) /* Disable state is SwRstDisable */ #define CLK(dev, con, ck) \ { \ diff --git a/arch/arm/mach-davinci/dm644x.c b/arch/arm/mach-davinci/dm644x.c index 4c82c27..052bc7b 100644 --- a/arch/arm/mach-davinci/dm644x.c +++ b/arch/arm/mach-davinci/dm644x.c @@ -130,7 +130,7 @@ static struct clk dsp_clk = { .name = "dsp", .parent = &pll1_sysclk1, .lpsc = DAVINCI_LPSC_GEM, - .flags = PSC_DSP, + .domain = DAVINCI_GPSC_DSPDOMAIN, .usecount = 1, /* REVISIT how to disable? */ }; @@ -145,7 +145,7 @@ static struct clk vicp_clk = { .name = "vicp", .parent = &pll1_sysclk2, .lpsc = DAVINCI_LPSC_IMCOP, - .flags = PSC_DSP, + .domain = DAVINCI_GPSC_DSPDOMAIN, .usecount = 1, /* REVISIT how to disable? */ }; diff --git a/arch/arm/mach-davinci/dm646x.c b/arch/arm/mach-davinci/dm646x.c index 1e0f809..c110c1f 100644 --- a/arch/arm/mach-davinci/dm646x.c +++ b/arch/arm/mach-davinci/dm646x.c @@ -157,7 +157,7 @@ static struct clk dsp_clk = { .name = "dsp", .parent = &pll1_sysclk1, .lpsc = DM646X_LPSC_C64X_CPU, - .flags = PSC_DSP, + .domain = DAVINCI_GPSC_DSPDOMAIN, .usecount = 1, /* REVISIT how to disable? */ }; -- 1.7.0.4 From mchehab at redhat.com Fri Sep 23 18:34:26 2011 From: mchehab at redhat.com (Mauro Carvalho Chehab) Date: Fri, 23 Sep 2011 20:34:26 -0300 Subject: [PATCH RESEND 1/4] davinci vpbe: remove unused macro. In-Reply-To: <1316410529-14744-2-git-send-email-manjunath.hadli@ti.com> References: <1316410529-14744-1-git-send-email-manjunath.hadli@ti.com> <1316410529-14744-2-git-send-email-manjunath.hadli@ti.com> Message-ID: <4E7D1782.30209@redhat.com> Em 19-09-2011 02:35, Manjunath Hadli escreveu: > remove VPBE_DISPLAY_SD_BUF_SIZE as it is no longer used. > > Signed-off-by: Manjunath Hadli > --- > drivers/media/video/davinci/vpbe_display.c | 1 - > 1 files changed, 0 insertions(+), 1 deletions(-) > > diff --git a/drivers/media/video/davinci/vpbe_display.c b/drivers/media/video/davinci/vpbe_display.c > index ae7add1..09a659e 100644 > --- a/drivers/media/video/davinci/vpbe_display.c > +++ b/drivers/media/video/davinci/vpbe_display.c > @@ -43,7 +43,6 @@ > > static int debug; > > -#define VPBE_DISPLAY_SD_BUF_SIZE (720*576*2) > #define VPBE_DEFAULT_NUM_BUFS 3 > > module_param(debug, int, 0644); This is really trivial. I won't wait for your pull request to merge this one ;) Thanks, Mauro From mchehab at redhat.com Fri Sep 23 18:38:34 2011 From: mchehab at redhat.com (Mauro Carvalho Chehab) Date: Fri, 23 Sep 2011 20:38:34 -0300 Subject: [PATCH RESEND 0/4] davinci vpbe: enable DM365 v4l2 display driver In-Reply-To: <1316410529-14744-1-git-send-email-manjunath.hadli@ti.com> References: <1316410529-14744-1-git-send-email-manjunath.hadli@ti.com> Message-ID: <4E7D187A.8060005@redhat.com> Em 19-09-2011 02:35, Manjunath Hadli escreveu: > The patchset adds incremental changes necessary to enable dm365 > v4l2 display driver, which includes vpbe display driver changes, > osd specific changes and venc changes. The changes are incremental > in nature,addind a few HD modes, and taking care of register level > changes. > > The patch set does not include THS7303 amplifier driver which is planned > to be sent seperately. > > > Manjunath Hadli (4): > davinci vpbe: remove unused macro. > davinci vpbe: add dm365 VPBE display driver changes > davinci vpbe: add dm365 and dm355 specific OSD changes > davinci vpbe: add VENC block changes to enable dm365 and dm355 > > drivers/media/video/davinci/vpbe.c | 55 +++- > drivers/media/video/davinci/vpbe_display.c | 1 - > drivers/media/video/davinci/vpbe_osd.c | 474 +++++++++++++++++++++++++--- > drivers/media/video/davinci/vpbe_venc.c | 205 +++++++++++-- > include/media/davinci/vpbe.h | 16 + > include/media/davinci/vpbe_venc.h | 4 + > 6 files changed, 686 insertions(+), 69 deletions(-) Not sure why are you re-sending this patch series. To whom are you re-sending it? You have your git access at linuxtv.org. So, if the patches are ready for merge, just send me a pull request. Otherwise, please mark the patches as RFC or send to the one that will maintain the driver, c/c the mailing list. In any case, I'll mark the patches 2-4 as RFC (patch 1 is too trivial, I'll just apply it, to never see it again ;) ). Thanks, Mauro > > -- > To unsubscribe from this list: send the line "unsubscribe linux-media" in > the body of a message to majordomo at vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html From sudhakar.raj at ti.com Sun Sep 25 21:45:02 2011 From: sudhakar.raj at ti.com (Rajashekhara, Sudhakar) Date: Mon, 26 Sep 2011 08:15:02 +0530 Subject: OMAP L138 evm halts when removing module davinci_spi References: <4E5E2667.8040001@efacec.com> <4E79B01D.10000@efacec.com> Message-ID: Hi, On Wed, Sep 21, 2011 at 15:33:08, Rajashekhara, Sudhakar wrote: > Hi, > > On Wed, Sep 21, 2011 at 15:06:29, An?bal Almeida Pinto wrote: > > Em 21-09-2011 09:38, Rajashekhara, Sudhakar escreveu: > > > Hi, > > > > > > On Wed, Aug 31, 2011 at 17:47:43, An?bal Almeida Pinto wrote: > > >> Hi, > > >> [...] > > > > If I apply the patch attached I can make rmmod of the spi davinci driver. > > > > The procedure that I have tested : > > > > # insmod davinci_spi.ko > > spi_davinci spi_davinci.1: DMA: supported > > spi_davinci spi_davinci.1: DMA: RX channel: 18, TX channel: 19, event > > queue: 0 > > spi_davinci spi_davinci.1: Controller at 0xfef0e000 > > > > # rmmod davinci_spi.ko > > > > But can't insmod it again : > > > > # insmod davinci_spi.ko > > Unable to request DMA channel for SPI RX > > Trying to free nonexistent resource <0000000001f0e000-0000000001f0e000> > > spi_davinci: probe of spi_davinci.1 failed with error -11 > > insmod: can't insert 'davinci_spi.ko': No such device > > > > I see that during module removal, the driver is not doing the following: > > edma_free_channel(dspi->dma.tx_channel); > edma_free_channel(dspi->dma.rx_channel); > edma_free_slot(dspi->dma.dummy_param_slot); > > Even after adding the above lines, I was not able to do the insmod again because > for me, the m25p80 device was already registered. I am not sure whether you are > using the same interface. If yes, you need to figure out how to handle that. > Any luck with the above fix? Thanks, Sudhakar From sudhakar.raj at ti.com Sun Sep 25 23:51:02 2011 From: sudhakar.raj at ti.com (Rajashekhara, Sudhakar) Date: Mon, 26 Sep 2011 10:21:02 +0530 Subject: kernel bootlog timestamp all zeros - 3.0rcx based davinci tree In-Reply-To: <3E54258959B69E4282D79E01AB1F32B701A398@DLEE12.ent.ti.com> References: <3E54258959B69E4282D79E01AB1F32B701A398@DLEE12.ent.ti.com> Message-ID: Hi Murali, On Mon, Aug 29, 2011 at 21:23:45, Karicheri, Muralidharan wrote: > Hi All, > > I have a port of the davinci tree for a new platform that I am working on. The time stamp of the boot log shows all zeros. I am using the master branch of davinci tree at http://gitorious.org/linux-davinci/linux-davinci > > My original port based on 2.6.37 has proper time stamps displayed. Anything changes related to this in recent kernel that I need to be aware causing this issue? Thanks in advance for your help. > I tried it from the same repository which had the below commit at the top and it worked absolutely fine. commit acc2ec87c22da0655bc75ef1d8eba89010bab00e Merge: 06baeca 6e22c04 Author: Sekhar Nori Date: Sat Sep 17 16:17:23 2011 +0530 rebuild linux-davinci from branches 5.241 0.011: Bytes transferred = 1815848 (1bb528 hex) 5.331 0.091: ## Booting kernel from Legacy Image at c0700000 ... 5.331 0.000: Image Name: Linux-3.1.0-rc6-07781-gacc2ec8 5.340 0.009: Image Type: ARM Linux Kernel Image (uncompressed) 5.340 0.000: Data Size: 1815784 Bytes = 1.7 MB 5.340 0.000: Load Address: c0008000 5.340 0.000: Entry Point: c0008000 5.900 0.560: Verifying Checksum ... OK 6.500 0.600: Loading Kernel Image ... OK 6.500 0.000: OK 6.500 0.000: 6.500 0.000: Starting kernel ... 6.500 0.000: 7.880 1.380: Uncompressing Linux... done, booting the kernel. 9.830 1.950: Linux version 3.1.0-rc6-07781-gacc2ec8 (sudhakar at linux-psp-server.india.ext.ti.com) (gcc version 4.3.3 (Sourcery G++ Lite 2009q1-203) ) #1 PREEMPT Mon Sep 26 09:04:58 IST 2011 9.843 0.013: CPU: ARM926EJ-S [41069265] revision 5 (ARMv5TEJ), cr=00053177 9.843 0.000: CPU: VIVT data cache, VIVT instruction cache 9.843 0.000: Machine: DaVinci DA850/OMAP-L138/AM18x EVM 9.857 0.015: Memory policy: ECC disabled, Data cache writethrough 9.857 0.000: DaVinci da850/omap-l138 variant 0x0 Thanks, Sudhakar From hverkuil at xs4all.nl Mon Sep 26 06:16:52 2011 From: hverkuil at xs4all.nl (Hans Verkuil) Date: Mon, 26 Sep 2011 13:16:52 +0200 Subject: [PATCH RESEND 0/4] davinci vpbe: enable DM365 v4l2 display driver In-Reply-To: References: <1316410529-14744-1-git-send-email-manjunath.hadli@ti.com> Message-ID: <201109261316.52134.hverkuil@xs4all.nl> On Monday, September 19, 2011 07:49:18 Hadli, Manjunath wrote: > Sakari, Hans, > Can I request you to have a look at these patches too? It's on my TODO list for this week. Regards, Hans > > Thanks and Regards, > -Manju > > On Mon, Sep 19, 2011 at 11:05:25, Hadli, Manjunath wrote: > > The patchset adds incremental changes necessary to enable dm365 > > v4l2 display driver, which includes vpbe display driver changes, osd specific changes and venc changes. The changes are incremental in nature,addind a few HD modes, and taking care of register level changes. > > > > The patch set does not include THS7303 amplifier driver which is planned to be sent seperately. > > > > > > Manjunath Hadli (4): > > davinci vpbe: remove unused macro. > > davinci vpbe: add dm365 VPBE display driver changes > > davinci vpbe: add dm365 and dm355 specific OSD changes > > davinci vpbe: add VENC block changes to enable dm365 and dm355 > > > > drivers/media/video/davinci/vpbe.c | 55 +++- > > drivers/media/video/davinci/vpbe_display.c | 1 - > > drivers/media/video/davinci/vpbe_osd.c | 474 +++++++++++++++++++++++++--- > > drivers/media/video/davinci/vpbe_venc.c | 205 +++++++++++-- > > include/media/davinci/vpbe.h | 16 + > > include/media/davinci/vpbe_venc.h | 4 + > > 6 files changed, 686 insertions(+), 69 deletions(-) > > > > > > -- > To unsubscribe from this list: send the line "unsubscribe linux-media" in > the body of a message to majordomo at vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html > From manjunath.hadli at ti.com Mon Sep 26 06:25:22 2011 From: manjunath.hadli at ti.com (Hadli, Manjunath) Date: Mon, 26 Sep 2011 16:55:22 +0530 Subject: [PATCH RESEND 1/4] davinci vpbe: remove unused macro. In-Reply-To: <4E7D1782.30209@redhat.com> References: <1316410529-14744-1-git-send-email-manjunath.hadli@ti.com> <1316410529-14744-2-git-send-email-manjunath.hadli@ti.com> <4E7D1782.30209@redhat.com> Message-ID: On Sat, Sep 24, 2011 at 05:04:26, Mauro Carvalho Chehab wrote: > Em 19-09-2011 02:35, Manjunath Hadli escreveu: > > remove VPBE_DISPLAY_SD_BUF_SIZE as it is no longer used. > > > > Signed-off-by: Manjunath Hadli > > --- > > drivers/media/video/davinci/vpbe_display.c | 1 - > > 1 files changed, 0 insertions(+), 1 deletions(-) > > > > diff --git a/drivers/media/video/davinci/vpbe_display.c > > b/drivers/media/video/davinci/vpbe_display.c > > index ae7add1..09a659e 100644 > > --- a/drivers/media/video/davinci/vpbe_display.c > > +++ b/drivers/media/video/davinci/vpbe_display.c > > @@ -43,7 +43,6 @@ > > > > static int debug; > > > > -#define VPBE_DISPLAY_SD_BUF_SIZE (720*576*2) #define > > VPBE_DEFAULT_NUM_BUFS 3 > > > > module_param(debug, int, 0644); > > This is really trivial. I won't wait for your pull request to merge this one ;) Thank you Mauro. > > Thanks, > Mauro > Thx, -Manju From manjunath.hadli at ti.com Mon Sep 26 06:26:37 2011 From: manjunath.hadli at ti.com (Hadli, Manjunath) Date: Mon, 26 Sep 2011 16:56:37 +0530 Subject: [PATCH RESEND 0/4] davinci vpbe: enable DM365 v4l2 display driver In-Reply-To: <4E7D187A.8060005@redhat.com> References: <1316410529-14744-1-git-send-email-manjunath.hadli@ti.com> <4E7D187A.8060005@redhat.com> Message-ID: On Sat, Sep 24, 2011 at 05:08:34, Mauro Carvalho Chehab wrote: > Em 19-09-2011 02:35, Manjunath Hadli escreveu: > > The patchset adds incremental changes necessary to enable dm365 > > v4l2 display driver, which includes vpbe display driver changes, osd > > specific changes and venc changes. The changes are incremental in > > nature,addind a few HD modes, and taking care of register level > > changes. > > > > The patch set does not include THS7303 amplifier driver which is > > planned to be sent seperately. > > > > > > Manjunath Hadli (4): > > davinci vpbe: remove unused macro. > > davinci vpbe: add dm365 VPBE display driver changes > > davinci vpbe: add dm365 and dm355 specific OSD changes > > davinci vpbe: add VENC block changes to enable dm365 and dm355 > > > > drivers/media/video/davinci/vpbe.c | 55 +++- > > drivers/media/video/davinci/vpbe_display.c | 1 - > > drivers/media/video/davinci/vpbe_osd.c | 474 +++++++++++++++++++++++++--- > > drivers/media/video/davinci/vpbe_venc.c | 205 +++++++++++-- > > include/media/davinci/vpbe.h | 16 + > > include/media/davinci/vpbe_venc.h | 4 + > > 6 files changed, 686 insertions(+), 69 deletions(-) > > > Not sure why are you re-sending this patch series. To whom are you re-sending it? You have your git access at linuxtv.org. So, if the patches are ready for merge, just send me a pull request. Otherwise, please mark the patches as RFC or send to the one that will maintain the driver, c/c the mailing list. Thank you Mauro. I will send you a pull request for the rest of the three patches. -Manju > > In any case, I'll mark the patches 2-4 as RFC (patch 1 is too trivial, I'll just apply it, to never see it again ;) ). > > Thanks, > Mauro > > > > -- > > To unsubscribe from this list: send the line "unsubscribe linux-media" > > in the body of a message to majordomo at vger.kernel.org More majordomo > > info at http://vger.kernel.org/majordomo-info.html > > From manjunath.hadli at ti.com Mon Sep 26 06:28:31 2011 From: manjunath.hadli at ti.com (Hadli, Manjunath) Date: Mon, 26 Sep 2011 16:58:31 +0530 Subject: [PATCH RESEND 0/4] davinci vpbe: enable DM365 v4l2 display driver In-Reply-To: <201109261316.52134.hverkuil@xs4all.nl> References: <1316410529-14744-1-git-send-email-manjunath.hadli@ti.com> <201109261316.52134.hverkuil@xs4all.nl> Message-ID: On Mon, Sep 26, 2011 at 16:46:52, Hans Verkuil wrote: > On Monday, September 19, 2011 07:49:18 Hadli, Manjunath wrote: > > Sakari, Hans, > > Can I request you to have a look at these patches too? > > It's on my TODO list for this week. Thank you Hans. I will pull request nevertheless, and Mauro can take a call if he wants to defer. Thx, -Manju > > Regards, > > Hans > > > > > Thanks and Regards, > > -Manju > > > > On Mon, Sep 19, 2011 at 11:05:25, Hadli, Manjunath wrote: > > > The patchset adds incremental changes necessary to enable dm365 > > > v4l2 display driver, which includes vpbe display driver changes, osd specific changes and venc changes. The changes are incremental in nature,addind a few HD modes, and taking care of register level changes. > > > > > > The patch set does not include THS7303 amplifier driver which is planned to be sent seperately. > > > > > > > > > Manjunath Hadli (4): > > > davinci vpbe: remove unused macro. > > > davinci vpbe: add dm365 VPBE display driver changes > > > davinci vpbe: add dm365 and dm355 specific OSD changes > > > davinci vpbe: add VENC block changes to enable dm365 and dm355 > > > > > > drivers/media/video/davinci/vpbe.c | 55 +++- > > > drivers/media/video/davinci/vpbe_display.c | 1 - > > > drivers/media/video/davinci/vpbe_osd.c | 474 +++++++++++++++++++++++++--- > > > drivers/media/video/davinci/vpbe_venc.c | 205 +++++++++++-- > > > include/media/davinci/vpbe.h | 16 + > > > include/media/davinci/vpbe_venc.h | 4 + > > > 6 files changed, 686 insertions(+), 69 deletions(-) > > > > > > > > > > -- > > To unsubscribe from this list: send the line "unsubscribe linux-media" > > in the body of a message to majordomo at vger.kernel.org More majordomo > > info at http://vger.kernel.org/majordomo-info.html > > > From hverkuil at xs4all.nl Mon Sep 26 08:01:48 2011 From: hverkuil at xs4all.nl (Hans Verkuil) Date: Mon, 26 Sep 2011 15:01:48 +0200 Subject: [PATCH RESEND 2/4] davinci vpbe: add dm365 VPBE display driver changes In-Reply-To: <1316410529-14744-3-git-send-email-manjunath.hadli@ti.com> References: <1316410529-14744-1-git-send-email-manjunath.hadli@ti.com> <1316410529-14744-3-git-send-email-manjunath.hadli@ti.com> Message-ID: <201109261501.49077.hverkuil@xs4all.nl> On Monday, September 19, 2011 07:35:27 Manjunath Hadli wrote: > This patch implements the core additions to the display driver, > mainly controlling the VENC and other encoders for dm365. > This patch also includes addition of amplifier subdevice to the > vpbe driver and interfacing with venc subdevice. > > Signed-off-by: Manjunath Hadli > --- > drivers/media/video/davinci/vpbe.c | 55 ++++++++++++++++++++++++++++++++++-- > include/media/davinci/vpbe.h | 16 ++++++++++ > 2 files changed, 68 insertions(+), 3 deletions(-) > > diff --git a/drivers/media/video/davinci/vpbe.c b/drivers/media/video/davinci/vpbe.c > index d773d30..21a8645 100644 > --- a/drivers/media/video/davinci/vpbe.c > +++ b/drivers/media/video/davinci/vpbe.c > @@ -141,11 +141,12 @@ static int vpbe_enum_outputs(struct vpbe_device *vpbe_dev, > return 0; > } > > -static int vpbe_get_mode_info(struct vpbe_device *vpbe_dev, char *mode) > +static int vpbe_get_mode_info(struct vpbe_device *vpbe_dev, char *mode, > + int output_index) > { > struct vpbe_config *cfg = vpbe_dev->cfg; > struct vpbe_enc_mode_info var; > - int curr_output = vpbe_dev->current_out_index; > + int curr_output = output_index; > int i; > > if (NULL == mode) > @@ -245,6 +246,8 @@ static int vpbe_set_output(struct vpbe_device *vpbe_dev, int index) > struct encoder_config_info *curr_enc_info = > vpbe_current_encoder_info(vpbe_dev); > struct vpbe_config *cfg = vpbe_dev->cfg; > + struct venc_platform_data *venc_device = vpbe_dev->venc_device; > + enum v4l2_mbus_pixelcode if_params; > int enc_out_index; > int sd_index; > int ret = 0; > @@ -274,6 +277,8 @@ static int vpbe_set_output(struct vpbe_device *vpbe_dev, int index) > goto out; > } > > + if_params = cfg->outputs[index].if_params; > + venc_device->setup_if_config(if_params); > if (ret) > goto out; > } > @@ -293,7 +298,7 @@ static int vpbe_set_output(struct vpbe_device *vpbe_dev, int index) > * encoder. > */ > ret = vpbe_get_mode_info(vpbe_dev, > - cfg->outputs[index].default_mode); > + cfg->outputs[index].default_mode, index); > if (!ret) { > struct osd_state *osd_device = vpbe_dev->osd_device; > > @@ -367,6 +372,11 @@ static int vpbe_s_dv_preset(struct vpbe_device *vpbe_dev, > > ret = v4l2_subdev_call(vpbe_dev->encoders[sd_index], video, > s_dv_preset, dv_preset); > + if (!ret && (vpbe_dev->amp != NULL)) { > + /* Call amplifier subdevice */ > + ret = v4l2_subdev_call(vpbe_dev->amp, video, > + s_dv_preset, dv_preset); > + } > /* set the lcd controller output for the given mode */ > if (!ret) { > struct osd_state *osd_device = vpbe_dev->osd_device; > @@ -566,6 +576,8 @@ static int platform_device_get(struct device *dev, void *data) > > if (strcmp("vpbe-osd", pdev->name) == 0) > vpbe_dev->osd_device = platform_get_drvdata(pdev); > + if (strcmp("vpbe-venc", pdev->name) == 0) > + vpbe_dev->venc_device = dev_get_platdata(&pdev->dev); > > return 0; > } > @@ -584,6 +596,7 @@ static int platform_device_get(struct device *dev, void *data) > static int vpbe_initialize(struct device *dev, struct vpbe_device *vpbe_dev) > { > struct encoder_config_info *enc_info; > + struct amp_config_info *amp_info; > struct v4l2_subdev **enc_subdev; > struct osd_state *osd_device; > struct i2c_adapter *i2c_adap; > @@ -704,6 +717,39 @@ static int vpbe_initialize(struct device *dev, struct vpbe_device *vpbe_dev) > v4l2_warn(&vpbe_dev->v4l2_dev, "non-i2c encoders" > " currently not supported"); > } > + /* Add amplifier subdevice for dm365 */ > + if ((strcmp(vpbe_dev->cfg->module_name, "dm365-vpbe-display") == 0) && > + vpbe_dev->cfg->amp != NULL) { > + vpbe_dev->amp = kmalloc(sizeof(struct v4l2_subdev *), > + GFP_KERNEL); Huh? Why alloc a struct v4l2_subdev pointer here? > + if (vpbe_dev->amp == NULL) { > + v4l2_err(&vpbe_dev->v4l2_dev, > + "unable to allocate memory for sub device"); > + ret = -ENOMEM; > + goto vpbe_fail_v4l2_device; > + } > + amp_info = vpbe_dev->cfg->amp; > + if (amp_info->is_i2c) { > + vpbe_dev->amp = v4l2_i2c_new_subdev_board( > + &vpbe_dev->v4l2_dev, i2c_adap, > + &_info->board_info, NULL); Especially since it is overwritten here! And so causes a memory leak. The kmalloc above (and the kfree below) feels like old code that should have been removed. > + if (!vpbe_dev->amp) { > + v4l2_err(&vpbe_dev->v4l2_dev, > + "amplifier %s failed to register", > + amp_info->module_name); > + ret = -ENODEV; > + goto vpbe_fail_amp_register; > + } > + v4l2_info(&vpbe_dev->v4l2_dev, > + "v4l2 sub device %s registered\n", > + amp_info->module_name); > + } else { > + vpbe_dev->amp = NULL; > + v4l2_warn(&vpbe_dev->v4l2_dev, "non-i2c amplifiers" > + " currently not supported"); > + } > + } else > + vpbe_dev->amp = NULL; > > /* set the current encoder and output to that of venc by default */ > vpbe_dev->current_sd_index = 0; > @@ -731,6 +777,8 @@ static int vpbe_initialize(struct device *dev, struct vpbe_device *vpbe_dev) > /* TBD handling of bootargs for default output and mode */ > return 0; > > +vpbe_fail_amp_register: > + kfree(vpbe_dev->amp); > vpbe_fail_sd_register: > kfree(vpbe_dev->encoders); > vpbe_fail_v4l2_device: > @@ -757,6 +805,7 @@ static void vpbe_deinitialize(struct device *dev, struct vpbe_device *vpbe_dev) > if (strcmp(vpbe_dev->cfg->module_name, "dm644x-vpbe-display") != 0) > clk_put(vpbe_dev->dac_clk); > > + kfree(vpbe_dev->amp); > kfree(vpbe_dev->encoders); > vpbe_dev->initialized = 0; > /* disable vpss clocks */ > diff --git a/include/media/davinci/vpbe.h b/include/media/davinci/vpbe.h > index 8b11fb0..8bc1b3c 100644 > --- a/include/media/davinci/vpbe.h > +++ b/include/media/davinci/vpbe.h > @@ -63,6 +63,7 @@ struct vpbe_output { > * output basis. If per mode is needed, we may have to move this to > * mode_info structure > */ > + enum v4l2_mbus_pixelcode if_params; > }; > > /* encoder configuration info */ > @@ -74,6 +75,15 @@ struct encoder_config_info { > struct i2c_board_info board_info; > }; > > +/*amplifier configuration info */ > +struct amp_config_info { > + char module_name[32]; > + /* Is this an i2c device ? */ > + unsigned int is_i2c:1; > + /* i2c subdevice board info */ > + struct i2c_board_info board_info; > +}; > + > /* structure for defining vpbe display subsystem components */ > struct vpbe_config { > char module_name[32]; > @@ -84,6 +94,8 @@ struct vpbe_config { > /* external encoder information goes here */ > int num_ext_encoders; > struct encoder_config_info *ext_encoders; > + /* amplifier information goes here */ > + struct amp_config_info *amp; > int num_outputs; > /* Order is venc outputs followed by LCD and then external encoders */ > struct vpbe_output *outputs; > @@ -158,6 +170,8 @@ struct vpbe_device { > struct v4l2_subdev **encoders; > /* current encoder index */ > int current_sd_index; > + /* external amplifier v4l2 subdevice */ > + struct v4l2_subdev *amp; > struct mutex lock; > /* device initialized */ > int initialized; > @@ -165,6 +179,8 @@ struct vpbe_device { > struct clk *dac_clk; > /* osd_device pointer */ > struct osd_state *osd_device; > + /* venc device pointer */ > + struct venc_platform_data *venc_device; > /* > * fields below are accessed by users of vpbe_device. Not the > * ones above > Regards, Hans From hverkuil at xs4all.nl Mon Sep 26 08:09:05 2011 From: hverkuil at xs4all.nl (Hans Verkuil) Date: Mon, 26 Sep 2011 15:09:05 +0200 Subject: [PATCH RESEND 0/4] davinci vpbe: enable DM365 v4l2 display driver In-Reply-To: <1316410529-14744-1-git-send-email-manjunath.hadli@ti.com> References: <1316410529-14744-1-git-send-email-manjunath.hadli@ti.com> Message-ID: <201109261509.05809.hverkuil@xs4all.nl> On Monday, September 19, 2011 07:35:25 Manjunath Hadli wrote: > The patchset adds incremental changes necessary to enable dm365 > v4l2 display driver, which includes vpbe display driver changes, > osd specific changes and venc changes. The changes are incremental > in nature,addind a few HD modes, and taking care of register level > changes. > > The patch set does not include THS7303 amplifier driver which is planned > to be sent seperately. Looks OK, except for patch 2/4. For patches 1, 3 and 4: Acked-by: Hans Verkuil Regards, Hans > > > Manjunath Hadli (4): > davinci vpbe: remove unused macro. > davinci vpbe: add dm365 VPBE display driver changes > davinci vpbe: add dm365 and dm355 specific OSD changes > davinci vpbe: add VENC block changes to enable dm365 and dm355 > > drivers/media/video/davinci/vpbe.c | 55 +++- > drivers/media/video/davinci/vpbe_display.c | 1 - > drivers/media/video/davinci/vpbe_osd.c | 474 +++++++++++++++++++++++++--- > drivers/media/video/davinci/vpbe_venc.c | 205 +++++++++++-- > include/media/davinci/vpbe.h | 16 + > include/media/davinci/vpbe_venc.h | 4 + > 6 files changed, 686 insertions(+), 69 deletions(-) > > -- > To unsubscribe from this list: send the line "unsubscribe linux-media" in > the body of a message to majordomo at vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html > From manjunath.hadli at ti.com Mon Sep 26 08:35:09 2011 From: manjunath.hadli at ti.com (Manjunath Hadli) Date: Mon, 26 Sep 2011 19:05:09 +0530 Subject: [RFC PATCH 3/3] davinci: vpbe: add build infrastructure for fbdev driver In-Reply-To: <1317044109-7429-1-git-send-email-manjunath.hadli@ti.com> References: <1317044109-7429-1-git-send-email-manjunath.hadli@ti.com> Message-ID: <1317044109-7429-4-git-send-email-manjunath.hadli@ti.com> add Kconfig and Makefile changes to build the fbdev driver Signed-off-by: Manjunath Hadli --- drivers/media/video/davinci/Kconfig | 13 +++++++++++++ drivers/media/video/davinci/Makefile | 1 + 2 files changed, 14 insertions(+), 0 deletions(-) diff --git a/drivers/media/video/davinci/Kconfig b/drivers/media/video/davinci/Kconfig index a7f11e7..0ea27b8 100644 --- a/drivers/media/video/davinci/Kconfig +++ b/drivers/media/video/davinci/Kconfig @@ -113,3 +113,16 @@ config VIDEO_VPBE_DISPLAY To compile this driver as a module, choose M here: the module will be called vpbe_display. + +config VIDEO_VPBE_FB + tristate "VPBE Framebuffer driver" + depends on FB && ARCH_DAVINCI + select VIDEO_DMXXX_VPBE + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + default y + help + Enables VPBE Framebuffer driver on a DMXXX device + To compile this driver as a module, choose M here: the + module will be called vpbe_fb. diff --git a/drivers/media/video/davinci/Makefile b/drivers/media/video/davinci/Makefile index ae7dafb..da4a5b4 100644 --- a/drivers/media/video/davinci/Makefile +++ b/drivers/media/video/davinci/Makefile @@ -18,3 +18,4 @@ obj-$(CONFIG_VIDEO_DM355_CCDC) += dm355_ccdc.o obj-$(CONFIG_VIDEO_ISIF) += isif.o obj-$(CONFIG_VIDEO_DM644X_VPBE) += vpbe.o vpbe_osd.o vpbe_venc.o obj-$(CONFIG_VIDEO_VPBE_DISPLAY) += vpbe_display.o +obj-$(CONFIG_VIDEO_VPBE_FB) += vpbe_fb.o -- 1.6.2.4 From manjunath.hadli at ti.com Mon Sep 26 08:35:06 2011 From: manjunath.hadli at ti.com (Manjunath Hadli) Date: Mon, 26 Sep 2011 19:05:06 +0530 Subject: [RFC PATCH 0/3] fbdev driver for dm644x Message-ID: <1317044109-7429-1-git-send-email-manjunath.hadli@ti.com> This patch series adds an fbdev driver for Texas Instruments Davinci SoC.The display subsystem consists of OSD and VENC, with OSD supporting 2 RGb planes and 2 video planes. http://focus.ti.com/general/docs/lit/ getliterature.tsp?literatureNumber=sprue37d&fileType=pdf A good amount of the OSD and VENC enabling code is present in the kernel, and this patch series adds the fbdev interface. The fbdev driver exports 4 nodes representing each plane to the user - from fb0 to fb3. Manjunath Hadli (3): davinci: vpbe: enable vpbe for fbdev addition davinci: vpbe: add fbdev driver for dm644x davinci: vpbe: add build infrastructure for fbdev driver drivers/media/video/davinci/Kconfig | 13 + drivers/media/video/davinci/Makefile | 1 + drivers/media/video/davinci/vpbe_display.c | 6 + drivers/media/video/davinci/vpbe_fb.c | 2537 +++++++++++++++++++++++++++ drivers/media/video/davinci/vpbe_fb.h | 66 + drivers/media/video/davinci/vpbe_fb_ioctl.h | 159 ++ drivers/media/video/davinci/vpbe_osd.c | 793 +++++++++- drivers/media/video/davinci/vpbe_venc.c | 84 + include/media/davinci/vpbe_osd.h | 64 +- include/media/davinci/vpbe_venc.h | 21 + 10 files changed, 3735 insertions(+), 9 deletions(-) create mode 100644 drivers/media/video/davinci/vpbe_fb.c create mode 100644 drivers/media/video/davinci/vpbe_fb.h create mode 100644 drivers/media/video/davinci/vpbe_fb_ioctl.h From manjunath.hadli at ti.com Mon Sep 26 08:35:07 2011 From: manjunath.hadli at ti.com (Manjunath Hadli) Date: Mon, 26 Sep 2011 19:05:07 +0530 Subject: [RFC PATCH 1/3] davinci: vpbe: enable vpbe for fbdev addition In-Reply-To: <1317044109-7429-1-git-send-email-manjunath.hadli@ti.com> References: <1317044109-7429-1-git-send-email-manjunath.hadli@ti.com> Message-ID: <1317044109-7429-2-git-send-email-manjunath.hadli@ti.com> enable the venc, osd and vpbe display driver for addition of fbdev driver. Mainly includes fbdev ops structure inclusion, palette and osd layer related functionality for OSD block. Signed-off-by: Manjunath Hadli --- drivers/media/video/davinci/vpbe_display.c | 6 + drivers/media/video/davinci/vpbe_osd.c | 793 +++++++++++++++++++++++++++- drivers/media/video/davinci/vpbe_venc.c | 84 +++ include/media/davinci/vpbe_osd.h | 64 +++- include/media/davinci/vpbe_venc.h | 21 + 5 files changed, 959 insertions(+), 9 deletions(-) diff --git a/drivers/media/video/davinci/vpbe_display.c b/drivers/media/video/davinci/vpbe_display.c index 09a659e..9eb97f6 100644 --- a/drivers/media/video/davinci/vpbe_display.c +++ b/drivers/media/video/davinci/vpbe_display.c @@ -119,9 +119,11 @@ static void vpbe_isr_odd_field(struct vpbe_display *disp_obj, static irqreturn_t venc_isr(int irq, void *arg) { struct vpbe_display *disp_dev = (struct vpbe_display *)arg; + struct vpbe_device *vpbe_dev = disp_dev->vpbe_dev; struct vpbe_layer *layer; static unsigned last_event; unsigned event = 0; + int ret; int fid; int i; @@ -194,6 +196,10 @@ static irqreturn_t venc_isr(int irq, void *arg) vpbe_isr_odd_field(disp_dev, layer); } } + ret = v4l2_subdev_call(vpbe_dev->venc, core, ioctl, VENC_INTERRUPT, + &event); + if (ret < 0) + v4l2_err(&vpbe_dev->v4l2_dev, "Error in getting Field ID 0\n"); return IRQ_HANDLED; } diff --git a/drivers/media/video/davinci/vpbe_osd.c b/drivers/media/video/davinci/vpbe_osd.c index 2dc21fa..eb07d61 100644 --- a/drivers/media/video/davinci/vpbe_osd.c +++ b/drivers/media/video/davinci/vpbe_osd.c @@ -158,6 +158,13 @@ static int _osd_dm6446_vid0_pingpong(struct osd_state *sd, return 0; } +static int osd_get_field_inversion(struct osd_state *sd) +{ + struct osd_state *osd = sd; + + return osd->field_inversion; +} + static void _osd_set_field_inversion(struct osd_state *sd, int enable) { unsigned fsinv = 0; @@ -168,6 +175,359 @@ static void _osd_set_field_inversion(struct osd_state *sd, int enable) osd_modify(sd, OSD_MODE_FSINV, fsinv, OSD_MODE); } +static void osd_set_field_inversion(struct osd_state *sd, int enable) +{ + struct osd_state *osd = sd; + unsigned long flags; + + spin_lock_irqsave(&osd->lock, flags); + + osd->field_inversion = (enable != 0); + _osd_set_field_inversion(sd, enable); + + osd->pingpong = _osd_dm6446_vid0_pingpong(sd, osd->field_inversion, + osd->win[WIN_VID0].fb_base_phys, + &osd->win[WIN_VID0].lconfig); + + spin_unlock_irqrestore(&osd->lock, flags); +} + +static void osd_get_background(struct osd_state *sd, enum osd_clut *clut, + unsigned char *clut_index) +{ + struct osd_state *osd = sd; + unsigned long flags; + + spin_lock_irqsave(&osd->lock, flags); + + *clut = osd->backg_clut; + *clut_index = osd->backg_clut_index; + + spin_unlock_irqrestore(&osd->lock, flags); +} + +static void _osd_set_background(struct osd_state *sd, enum osd_clut clut, + unsigned char clut_index) +{ + u32 mode = 0; + + if (clut == RAM_CLUT) + mode |= OSD_MODE_BCLUT; + mode |= clut_index; + osd_modify(sd, OSD_MODE_BCLUT | OSD_MODE_CABG, mode, OSD_MODE); +} + +static void osd_set_background(struct osd_state *sd, enum osd_clut clut, + unsigned char clut_index) +{ + struct osd_state *osd = sd; + unsigned long flags; + spin_lock_irqsave(&osd->lock, flags); + + osd->backg_clut = clut; + osd->backg_clut_index = clut_index; + _osd_set_background(sd, clut, clut_index); + + spin_unlock_irqrestore(&osd->lock, flags); +} + +static int osd_get_interpolation_filter(struct osd_state *sd) +{ + struct osd_state *osd = sd; + + return osd->interpolation_filter; +} + +static void _osd_set_interpolation_filter(struct osd_state *sd, int filter) +{ + struct osd_state *osd = sd; + + if (osd->vpbe_type == VPBE_VERSION_3 || + osd->vpbe_type == VPBE_VERSION_2) + osd_clear(sd, OSD_EXTMODE_EXPMDSEL, OSD_EXTMODE); + osd_modify(sd, OSD_MODE_EF, filter ? OSD_MODE_EF : 0, OSD_MODE); +} + +static void osd_set_interpolation_filter(struct osd_state *sd, int filter) +{ + struct osd_state *osd = sd; + unsigned long flags; + + spin_lock_irqsave(&osd->lock, flags); + + osd->interpolation_filter = (filter != 0); + _osd_set_interpolation_filter(sd, filter); + + spin_unlock_irqrestore(&osd->lock, flags); +} + +static void osd_get_cursor_config(struct osd_state *sd, + struct osd_cursor_config *cursor) +{ + struct osd_state *osd = sd; + unsigned long flags; + + spin_lock_irqsave(&osd->lock, flags); + + *cursor = osd->cursor.config; + + spin_unlock_irqrestore(&osd->lock, flags); +} + +static void _osd_set_cursor_config(struct osd_state *sd, + const struct osd_cursor_config *cursor) +{ + struct osd_state *osd = sd; + unsigned rectcur = 0; + + osd_write(sd, cursor->xsize, OSD_CURXL); + osd_write(sd, cursor->xpos, OSD_CURXP); + + if (cursor->interlaced) { + osd_write(sd, cursor->ypos >> 1, OSD_CURYP); + if (osd->vpbe_type == VPBE_VERSION_1) + /* Must add 1 to ysize due to device erratum. */ + osd_write(sd, (cursor->ysize >> 1) + 1, OSD_CURYL); + else + osd_write(sd, cursor->ysize >> 1, OSD_CURYL); + } else { + osd_write(sd, cursor->ypos, OSD_CURYP); + if (osd->vpbe_type == VPBE_VERSION_1) + /* Must add 1 to ysize due to device erratum. */ + osd_write(sd, cursor->ysize + 1, OSD_CURYL); + else + osd_write(sd, cursor->ysize, OSD_CURYL); + } + + if (cursor->clut == RAM_CLUT) + rectcur |= OSD_RECTCUR_CLUTSR; + rectcur |= (cursor->clut_index << OSD_RECTCUR_RCAD_SHIFT); + rectcur |= (cursor->h_width << OSD_RECTCUR_RCHW_SHIFT); + rectcur |= (cursor->v_width << OSD_RECTCUR_RCVW_SHIFT); + osd_modify(sd, OSD_RECTCUR_RCAD | OSD_RECTCUR_CLUTSR | + OSD_RECTCUR_RCHW | OSD_RECTCUR_RCVW, rectcur, OSD_RECTCUR); +} + +static void osd_set_cursor_config(struct osd_state *sd, + struct osd_cursor_config *cursor) +{ + struct osd_state *osd = sd; + unsigned long flags; + + spin_lock_irqsave(&osd->lock, flags); + + cursor->xsize = min(cursor->xsize, (unsigned)OSD_CURXL_RCSW); + cursor->ysize = min(cursor->ysize, (unsigned)OSD_CURYL_RCSH); + cursor->xpos = min(cursor->xpos, (unsigned)OSD_CURXP_RCSX); + cursor->ypos = min(cursor->ypos, (unsigned)OSD_CURYP_RCSY); + cursor->interlaced = (cursor->interlaced != 0); + if (cursor->interlaced) { + cursor->ysize &= ~1; + cursor->ypos &= ~1; + } + cursor->h_width &= (OSD_RECTCUR_RCHW >> OSD_RECTCUR_RCHW_SHIFT); + cursor->v_width &= (OSD_RECTCUR_RCVW >> OSD_RECTCUR_RCVW_SHIFT); + cursor->clut = (cursor->clut == RAM_CLUT) ? RAM_CLUT : ROM_CLUT; + + osd->cursor.config = *cursor; + _osd_set_cursor_config(sd, cursor); + + spin_unlock_irqrestore(&osd->lock, flags); +} + +static int osd_cursor_is_enabled(struct osd_state *sd) +{ + struct osd_state *osd = sd; + + return osd->cursor.is_enabled; +} + +static void _osd_cursor_disable(struct osd_state *sd) +{ + osd_clear(sd, OSD_RECTCUR_RCACT, OSD_RECTCUR); +} + +static void osd_cursor_disable(struct osd_state *sd) +{ + struct osd_state *osd = sd; + unsigned long flags; + + spin_lock_irqsave(&osd->lock, flags); + + osd->cursor.is_enabled = 0; + _osd_cursor_disable(sd); + + spin_unlock_irqrestore(&osd->lock, flags); +} + +static void _osd_cursor_enable(struct osd_state *sd) +{ + osd_set(sd, OSD_RECTCUR_RCACT, OSD_RECTCUR); +} + +static void osd_cursor_enable(struct osd_state *sd) +{ + struct osd_state *osd = sd; + unsigned long flags; + + spin_lock_irqsave(&osd->lock, flags); + + osd->cursor.is_enabled = 1; + _osd_cursor_enable(sd); + + spin_unlock_irqrestore(&osd->lock, flags); +} + +static void osd_get_vid_expansion(struct osd_state *sd, + enum osd_h_exp_ratio *h_exp, + enum osd_v_exp_ratio *v_exp) +{ + struct osd_state *osd = sd; + unsigned long flags; + + spin_lock_irqsave(&osd->lock, flags); + + *h_exp = osd->vid_h_exp; + *v_exp = osd->vid_v_exp; + + spin_unlock_irqrestore(&osd->lock, flags); +} + +static void _osd_set_vid_expansion(struct osd_state *sd, + enum osd_h_exp_ratio h_exp, + enum osd_v_exp_ratio v_exp) +{ + struct osd_state *osd = sd; + u32 mode = 0; + u32 extmode = 0; + + switch (h_exp) { + case H_EXP_OFF: + break; + case H_EXP_9_OVER_8: + mode |= OSD_MODE_VHRSZ; + break; + case H_EXP_3_OVER_2: + extmode |= OSD_EXTMODE_VIDHRSZ15; + break; + } + + switch (v_exp) { + case V_EXP_OFF: + break; + case V_EXP_6_OVER_5: + mode |= OSD_MODE_VVRSZ; + break; + } + + if (osd->vpbe_type == VPBE_VERSION_3 || + osd->vpbe_type == VPBE_VERSION_2) + osd_modify(sd, OSD_EXTMODE_VIDHRSZ15, extmode, OSD_EXTMODE); + osd_modify(sd, OSD_MODE_VHRSZ | OSD_MODE_VVRSZ, mode, OSD_MODE); +} + +static int osd_set_vid_expansion(struct osd_state *sd, + enum osd_h_exp_ratio h_exp, + enum osd_v_exp_ratio v_exp) +{ + struct osd_state *osd = sd; + unsigned long flags; + + if (h_exp == H_EXP_3_OVER_2 && (osd->vpbe_type == VPBE_VERSION_1)) + return -EINVAL; + + spin_lock_irqsave(&osd->lock, flags); + + osd->vid_h_exp = h_exp; + osd->vid_v_exp = v_exp; + _osd_set_vid_expansion(sd, h_exp, v_exp); + + spin_unlock_irqrestore(&osd->lock, flags); + return 0; +} + +static void osd_get_osd_expansion(struct osd_state *sd, + enum osd_h_exp_ratio *h_exp, + enum osd_v_exp_ratio *v_exp) +{ + struct osd_state *osd = sd; + unsigned long flags; + + spin_lock_irqsave(&osd->lock, flags); + + *h_exp = osd->osd_h_exp; + *v_exp = osd->osd_v_exp; + + spin_unlock_irqrestore(&osd->lock, flags); +} + +static void _osd_set_osd_expansion(struct osd_state *sd, + enum osd_h_exp_ratio h_exp, + enum osd_v_exp_ratio v_exp) +{ + struct osd_state *osd = sd; + u32 mode = 0; + u32 extmode = 0; + + switch (h_exp) { + case H_EXP_OFF: + break; + case H_EXP_9_OVER_8: + mode |= OSD_MODE_OHRSZ; + break; + case H_EXP_3_OVER_2: + extmode |= OSD_EXTMODE_OSDHRSZ15; + break; + } + + switch (v_exp) { + case V_EXP_OFF: + break; + case V_EXP_6_OVER_5: + mode |= OSD_MODE_OVRSZ; + break; + } + + if (osd->vpbe_type == VPBE_VERSION_3 || + osd->vpbe_type == VPBE_VERSION_2) + osd_modify(sd, OSD_EXTMODE_OSDHRSZ15, extmode, OSD_EXTMODE); + osd_modify(sd, OSD_MODE_OHRSZ | OSD_MODE_OVRSZ, mode, OSD_MODE); +} + +static int osd_set_osd_expansion(struct osd_state *sd, + enum osd_h_exp_ratio h_exp, + enum osd_v_exp_ratio v_exp) +{ + struct osd_state *osd = sd; + unsigned long flags; + + if (h_exp == H_EXP_3_OVER_2 && (osd->vpbe_type == VPBE_VERSION_1)) + return -EINVAL; + + spin_lock_irqsave(&osd->lock, flags); + + osd->osd_h_exp = h_exp; + osd->osd_v_exp = v_exp; + _osd_set_osd_expansion(sd, h_exp, v_exp); + + spin_unlock_irqrestore(&osd->lock, flags); + return 0; +} + +static void osd_get_blink_attribute(struct osd_state *sd, int *enable, + enum osd_blink_interval *blink) +{ + struct osd_state *osd = sd; + unsigned long flags; + + spin_lock_irqsave(&osd->lock, flags); + + *enable = osd->is_blinking; + *blink = osd->blink; + + spin_unlock_irqrestore(&osd->lock, flags); +} + static void _osd_set_blink_attribute(struct osd_state *sd, int enable, enum osd_blink_interval blink) { @@ -182,6 +542,29 @@ static void _osd_set_blink_attribute(struct osd_state *sd, int enable, OSD_OSDATRMD); } +static void osd_set_blink_attribute(struct osd_state *sd, int enable, + enum osd_blink_interval blink) +{ + struct osd_state *osd = sd; + unsigned long flags; + + spin_lock_irqsave(&osd->lock, flags); + + osd->is_blinking = (enable != 0); + osd->blink = blink; + if (osd->win[WIN_OSD1].lconfig.pixfmt == PIXFMT_OSD_ATTR) + _osd_set_blink_attribute(sd, enable, blink); + + spin_unlock_irqrestore(&osd->lock, flags); +} + +static enum osd_rom_clut osd_get_rom_clut(struct osd_state *sd) +{ + struct osd_state *osd = sd; + + return osd->rom_clut; +} + static void _osd_set_rom_clut(struct osd_state *sd, enum osd_rom_clut rom_clut) { @@ -191,6 +574,150 @@ static void _osd_set_rom_clut(struct osd_state *sd, osd_set(sd, OSD_MISCCTL_RSEL, OSD_MISCCTL); } +static void osd_set_rom_clut(struct osd_state *sd, + enum osd_rom_clut rom_clut) +{ + struct osd_state *osd = sd; + unsigned long flags; + + spin_lock_irqsave(&osd->lock, flags); + + osd->rom_clut = rom_clut; + _osd_set_rom_clut(sd, rom_clut); + + spin_unlock_irqrestore(&osd->lock, flags); +} + +static void _osd_set_clut_ycbcr(struct osd_state *sd, + unsigned char clut_index, + unsigned char y, unsigned char cb, + unsigned char cr) +{ + /* wait until any previous writes to the CLUT RAM have completed */ + while (osd_read(sd, OSD_MISCCTL) & OSD_MISCCTL_CPBSY) + cpu_relax(); + + osd_write(sd, (y << OSD_CLUTRAMYCB_Y_SHIFT) | cb, OSD_CLUTRAMYCB); + osd_write(sd, (cr << OSD_CLUTRAMCR_CR_SHIFT) | clut_index, + OSD_CLUTRAMCR); +} + +static void osd_set_clut_ycbcr(struct osd_state *sd, + unsigned char clut_index, unsigned char y, + unsigned char cb, unsigned char cr) +{ + struct osd_state *osd = sd; + unsigned long flags; + + spin_lock_irqsave(&osd->lock, flags); + + osd->clut_ram[clut_index][0] = y; + osd->clut_ram[clut_index][1] = cb; + osd->clut_ram[clut_index][2] = cr; + _osd_set_clut_ycbcr(sd, clut_index, y, cb, cr); + + spin_unlock_irqrestore(&osd->lock, flags); +} + +static void _osd_rgb_to_ycbcr(const unsigned char rgb[3], + unsigned char ycbcr[3]) +{ + int y, cb, cr; + int r = rgb[0]; + int g = rgb[1]; + int b = rgb[2]; + /* + * This conversion matrix corresponds to the conversion matrix used + * by the OSD to convert RGB values to YCbCr values. All coefficients + * have been scaled by a factor of 2^22. + */ + static const int rgb_to_ycbcr[3][3] = { + {1250330, 2453618, 490352}, + {-726093, -1424868, 2150957}, + {2099836, -1750086, -349759} + }; + + y = rgb_to_ycbcr[0][0] * r + rgb_to_ycbcr[0][1] * g + + rgb_to_ycbcr[0][2] * b; + cb = rgb_to_ycbcr[1][0] * r + rgb_to_ycbcr[1][1] * g + + rgb_to_ycbcr[1][2] * b; + cr = rgb_to_ycbcr[2][0] * r + rgb_to_ycbcr[2][1] * g + + rgb_to_ycbcr[2][2] * b; + + /* round and scale */ + y = ((y + (1 << 21)) >> 22); + cb = ((cb + (1 << 21)) >> 22) + 128; + cr = ((cr + (1 << 21)) >> 22) + 128; + + /* clip */ + y = (y < 0) ? 0 : y; + y = (y > 255) ? 255 : y; + cb = (cb < 0) ? 0 : cb; + cb = (cb > 255) ? 255 : cb; + cr = (cr < 0) ? 0 : cr; + cr = (cr > 255) ? 255 : cr; + + ycbcr[0] = y; + ycbcr[1] = cb; + ycbcr[2] = cr; +} + +static void osd_set_clut_rgb(struct osd_state *sd, unsigned char clut_index, + unsigned char r, unsigned char g, unsigned char b) +{ + struct osd_state *osd = sd; + unsigned char rgb[3], ycbcr[3]; + unsigned long flags; + + rgb[0] = r; + rgb[1] = g; + rgb[2] = b; + _osd_rgb_to_ycbcr(rgb, ycbcr); + + spin_lock_irqsave(&osd->lock, flags); + + osd->clut_ram[clut_index][0] = ycbcr[0]; + osd->clut_ram[clut_index][1] = ycbcr[1]; + osd->clut_ram[clut_index][2] = ycbcr[2]; + _osd_set_clut_ycbcr(sd, clut_index, ycbcr[0], ycbcr[1], ycbcr[2]); + + spin_unlock_irqrestore(&osd->lock, flags); +} + +static unsigned char osd_get_palette_map(struct osd_state *sd, + enum osd_win_layer osdwin, + unsigned char pixel_value) +{ + struct osd_state *osd = sd; + enum osd_layer layer = + (osdwin == OSDWIN_OSD0) ? WIN_OSD0 : WIN_OSD1; + struct osd_window_state *win = &osd->win[layer]; + struct osd_osdwin_state *osdwin_state = &osd->osdwin[osdwin]; + unsigned char clut_index; + unsigned long flags; + + spin_lock_irqsave(&osd->lock, flags); + + switch (win->lconfig.pixfmt) { + case PIXFMT_1BPP: + clut_index = osdwin_state->palette_map[pixel_value & 0x1]; + break; + case PIXFMT_2BPP: + clut_index = osdwin_state->palette_map[pixel_value & 0x3]; + break; + case PIXFMT_4BPP: + clut_index = osdwin_state->palette_map[pixel_value & 0xf]; + break; + default: + clut_index = 0; + break; + } + + spin_unlock_irqrestore(&osd->lock, flags); + + return clut_index; +} + static void _osd_set_palette_map(struct osd_state *sd, enum osd_win_layer osdwin, unsigned char pixel_value, @@ -240,14 +767,55 @@ static void _osd_set_palette_map(struct osd_state *sd, osd_modify(sd, bmp_mask, clut_index << bmp_shift, bmp_offset); } +static void osd_set_palette_map(struct osd_state *sd, + enum osd_win_layer osdwin, + unsigned char pixel_value, + unsigned char clut_index) +{ + struct osd_state *osd = sd; + enum osd_layer layer = + (osdwin == OSDWIN_OSD0) ? WIN_OSD0 : WIN_OSD1; + struct osd_window_state *win = &osd->win[layer]; + struct osd_osdwin_state *osdwin_state = &osd->osdwin[osdwin]; + unsigned long flags; + + spin_lock_irqsave(&osd->lock, flags); + + switch (win->lconfig.pixfmt) { + case PIXFMT_1BPP: + osdwin_state->palette_map[pixel_value & 0x1] = clut_index; + break; + case PIXFMT_2BPP: + osdwin_state->palette_map[pixel_value & 0x3] = clut_index; + break; + case PIXFMT_4BPP: + osdwin_state->palette_map[pixel_value & 0xf] = clut_index; + break; + default: + spin_unlock_irqrestore(&osd->lock, flags); + return; + } + + _osd_set_palette_map(sd, osdwin, pixel_value, clut_index, + win->lconfig.pixfmt); + + spin_unlock_irqrestore(&osd->lock, flags); +} + +static int osd_get_rec601_attenuation(struct osd_state *sd, + enum osd_win_layer osdwin) +{ + struct osd_state *osd = sd; + struct osd_osdwin_state *osdwin_state = &osd->osdwin[osdwin]; + + return osdwin_state->rec601_attenuation; +} + static void _osd_set_rec601_attenuation(struct osd_state *sd, enum osd_win_layer osdwin, int enable) { switch (osdwin) { case OSDWIN_OSD0: - osd_modify(sd, OSD_OSDWIN0MD_ATN0E, - enable ? OSD_OSDWIN0MD_ATN0E : 0, - OSD_OSDWIN0MD); if (sd->vpbe_type == VPBE_VERSION_1) osd_modify(sd, OSD_OSDWIN0MD_ATN0E, enable ? OSD_OSDWIN0MD_ATN0E : 0, @@ -259,9 +827,6 @@ static void _osd_set_rec601_attenuation(struct osd_state *sd, OSD_EXTMODE); break; case OSDWIN_OSD1: - osd_modify(sd, OSD_OSDWIN1MD_ATN1E, - enable ? OSD_OSDWIN1MD_ATN1E : 0, - OSD_OSDWIN1MD); if (sd->vpbe_type == VPBE_VERSION_1) osd_modify(sd, OSD_OSDWIN1MD_ATN1E, enable ? OSD_OSDWIN1MD_ATN1E : 0, @@ -275,6 +840,35 @@ static void _osd_set_rec601_attenuation(struct osd_state *sd, } } +static void osd_set_rec601_attenuation(struct osd_state *sd, + enum osd_win_layer osdwin, + int enable) +{ + struct osd_state *osd = sd; + enum osd_layer layer = + (osdwin == OSDWIN_OSD0) ? WIN_OSD0 : WIN_OSD1; + struct osd_window_state *win = &osd->win[layer]; + struct osd_osdwin_state *osdwin_state = &osd->osdwin[osdwin]; + unsigned long flags; + + spin_lock_irqsave(&osd->lock, flags); + + osdwin_state->rec601_attenuation = (enable != 0); + if (win->lconfig.pixfmt != PIXFMT_OSD_ATTR) + _osd_set_rec601_attenuation(sd, osdwin, enable); + + spin_unlock_irqrestore(&osd->lock, flags); +} + +static enum osd_blending_factor +osd_get_blending_factor(struct osd_state *sd, enum osd_win_layer osdwin) +{ + struct osd_state *osd = sd; + struct osd_osdwin_state *osdwin_state = &osd->osdwin[osdwin]; + + return osdwin_state->blend; +} + static void _osd_set_blending_factor(struct osd_state *sd, enum osd_win_layer osdwin, enum osd_blending_factor blend) @@ -291,6 +885,26 @@ static void _osd_set_blending_factor(struct osd_state *sd, } } +static void osd_set_blending_factor(struct osd_state *sd, + enum osd_win_layer osdwin, + enum osd_blending_factor blend) +{ + struct osd_state *osd = sd; + enum osd_layer layer = + (osdwin == OSDWIN_OSD0) ? WIN_OSD0 : WIN_OSD1; + struct osd_window_state *win = &osd->win[layer]; + struct osd_osdwin_state *osdwin_state = &osd->osdwin[osdwin]; + unsigned long flags; + + spin_lock_irqsave(&osd->lock, flags); + + osdwin_state->blend = blend; + if (win->lconfig.pixfmt != PIXFMT_OSD_ATTR) + _osd_set_blending_factor(sd, osdwin, blend); + + spin_unlock_irqrestore(&osd->lock, flags); +} + static void _osd_enable_rgb888_pixblend(struct osd_state *sd, enum osd_win_layer osdwin) { @@ -371,6 +985,29 @@ static void _osd_enable_color_key(struct osd_state *sd, } } +static void osd_enable_color_key(struct osd_state *sd, + enum osd_win_layer osdwin, + unsigned colorkey) +{ + struct osd_state *osd = sd; + enum osd_layer layer = + (osdwin == OSDWIN_OSD0) ? WIN_OSD0 : WIN_OSD1; + struct osd_window_state *win = &osd->win[layer]; + struct osd_osdwin_state *osdwin_state = &osd->osdwin[osdwin]; + unsigned long flags; + + spin_lock_irqsave(&osd->lock, flags); + + osdwin_state->colorkey_blending = 1; + osdwin_state->colorkey = colorkey; + if (win->lconfig.pixfmt != PIXFMT_OSD_ATTR) { + _osd_enable_color_key(sd, osdwin, colorkey, + win->lconfig.pixfmt); + } + + spin_unlock_irqrestore(&osd->lock, flags); +} + static void _osd_disable_color_key(struct osd_state *sd, enum osd_win_layer osdwin) { @@ -384,6 +1021,25 @@ static void _osd_disable_color_key(struct osd_state *sd, } } +static void osd_disable_color_key(struct osd_state *sd, + enum osd_win_layer osdwin) +{ + struct osd_state *osd = sd; + enum osd_layer layer = + (osdwin == OSDWIN_OSD0) ? WIN_OSD0 : WIN_OSD1; + struct osd_window_state *win = &osd->win[layer]; + struct osd_osdwin_state *osdwin_state = &osd->osdwin[osdwin]; + unsigned long flags; + + spin_lock_irqsave(&osd->lock, flags); + + osdwin_state->colorkey_blending = 0; + if (win->lconfig.pixfmt != PIXFMT_OSD_ATTR) + _osd_disable_color_key(sd, osdwin); + + spin_unlock_irqrestore(&osd->lock, flags); +} + static void _osd_set_osd_clut(struct osd_state *sd, enum osd_win_layer osdwin, enum osd_clut clut) @@ -404,6 +1060,50 @@ static void _osd_set_osd_clut(struct osd_state *sd, } } +static void osd_set_osd_clut(struct osd_state *sd, enum osd_win_layer osdwin, + enum osd_clut clut) +{ + struct osd_state *osd = sd; + enum osd_layer layer = + (osdwin == OSDWIN_OSD0) ? WIN_OSD0 : WIN_OSD1; + struct osd_window_state *win = &osd->win[layer]; + struct osd_osdwin_state *osdwin_state = &osd->osdwin[osdwin]; + unsigned long flags; + + spin_lock_irqsave(&osd->lock, flags); + + osdwin_state->clut = clut; + if (win->lconfig.pixfmt != PIXFMT_OSD_ATTR) + _osd_set_osd_clut(sd, osdwin, clut); + + spin_unlock_irqrestore(&osd->lock, flags); +} + +static enum osd_clut osd_get_osd_clut(struct osd_state *sd, + enum osd_win_layer osdwin) +{ + struct osd_state *osd = sd; + struct osd_osdwin_state *osdwin_state = &osd->osdwin[osdwin]; + + return osdwin_state->clut; +} + +static void osd_get_zoom(struct osd_state *sd, enum osd_layer layer, + enum osd_zoom_factor *h_zoom, + enum osd_zoom_factor *v_zoom) +{ + struct osd_state *osd = sd; + struct osd_window_state *win = &osd->win[layer]; + unsigned long flags; + + spin_lock_irqsave(&osd->lock, flags); + + *h_zoom = win->h_zoom; + *v_zoom = win->v_zoom; + + spin_unlock_irqrestore(&osd->lock, flags); +} + static void _osd_set_zoom(struct osd_state *sd, enum osd_layer layer, enum osd_zoom_factor h_zoom, enum osd_zoom_factor v_zoom) @@ -438,6 +1138,32 @@ static void _osd_set_zoom(struct osd_state *sd, enum osd_layer layer, } } +static void osd_set_zoom(struct osd_state *sd, enum osd_layer layer, + enum osd_zoom_factor h_zoom, + enum osd_zoom_factor v_zoom) +{ + struct osd_state *osd = sd; + struct osd_window_state *win = &osd->win[layer]; + unsigned long flags; + + spin_lock_irqsave(&osd->lock, flags); + + win->h_zoom = h_zoom; + win->v_zoom = v_zoom; + _osd_set_zoom(sd, layer, h_zoom, v_zoom); + + spin_unlock_irqrestore(&osd->lock, flags); +} + + +static int osd_layer_is_enabled(struct osd_state *sd, enum osd_layer layer) +{ + struct osd_state *osd = sd; + struct osd_window_state *win = &osd->win[layer]; + + return win->is_enabled; +} + static void _osd_disable_layer(struct osd_state *sd, enum osd_layer layer) { switch (layer) { @@ -480,7 +1206,7 @@ static void osd_disable_layer(struct osd_state *sd, enum osd_layer layer) static void _osd_enable_attribute_mode(struct osd_state *sd) { /* enable attribute mode for OSD1 */ - osd_set(sd, OSD_OSDWIN1MD_OASW, OSD_OSDWIN1MD); + osd_set(sd, OSD_OSDWIN1MD_OASW | OSD_OSDWIN1MD_OACT1, OSD_OSDWIN1MD); } static void _osd_enable_layer(struct osd_state *sd, enum osd_layer layer) @@ -793,7 +1519,7 @@ static int try_layer_config(struct osd_state *sd, enum osd_layer layer, case PIXFMT_8BPP: case PIXFMT_RGB565: if (osd->vpbe_type == VPBE_VERSION_1) - bad_config = !is_vid_win(layer); + bad_config = !is_osd_win(layer); break; case PIXFMT_YCbCrI: case PIXFMT_YCrCbI: @@ -892,6 +1618,22 @@ static int try_layer_config(struct osd_state *sd, enum osd_layer layer, return 0; } +static int osd_try_layer_config(struct osd_state *sd, enum osd_layer layer, + struct osd_layer_config *lconfig) +{ + struct osd_state *osd = sd; + int reject_config; + unsigned long flags; + + spin_lock_irqsave(&osd->lock, flags); + + reject_config = try_layer_config(sd, layer, lconfig); + + spin_unlock_irqrestore(&osd->lock, flags); + + return reject_config; +} + static void _osd_disable_vid_rgb888(struct osd_state *sd) { /* @@ -1512,13 +2254,48 @@ static int osd_initialize(struct osd_state *osd) } static const struct vpbe_osd_ops osd_ops = { + .set_clut_ycbcr = osd_set_clut_ycbcr, + .set_clut_rgb = osd_set_clut_rgb, + .set_osd_clut = osd_set_osd_clut, + .get_osd_clut = osd_get_osd_clut, + .enable_color_key = osd_enable_color_key, + .disable_color_key = osd_disable_color_key, + .set_blending_factor = osd_set_blending_factor, + .get_blending_factor = osd_get_blending_factor, + .set_rec601_attenuation = osd_set_rec601_attenuation, + .get_rec601_attenuation = osd_get_rec601_attenuation, + .set_palette_map = osd_set_palette_map, + .get_palette_map = osd_get_palette_map, + .set_blink_attribute = osd_set_blink_attribute, + .get_blink_attribute = osd_get_blink_attribute, + .cursor_enable = osd_cursor_enable, + .cursor_disable = osd_cursor_disable, + .cursor_is_enabled = osd_cursor_is_enabled, + .set_cursor_config = osd_set_cursor_config, + .get_cursor_config = osd_get_cursor_config, + .set_field_inversion = osd_set_field_inversion, + .get_field_inversion = osd_get_field_inversion, .initialize = osd_initialize, .request_layer = osd_request_layer, .release_layer = osd_release_layer, .enable_layer = osd_enable_layer, .disable_layer = osd_disable_layer, + .layer_is_enabled = osd_layer_is_enabled, .set_layer_config = osd_set_layer_config, + .try_layer_config = osd_try_layer_config, .get_layer_config = osd_get_layer_config, + .set_interpolation_filter = osd_set_interpolation_filter, + .get_interpolation_filter = osd_get_interpolation_filter, + .set_osd_expansion = osd_set_osd_expansion, + .get_osd_expansion = osd_get_osd_expansion, + .set_vid_expansion = osd_set_vid_expansion, + .get_vid_expansion = osd_get_vid_expansion, + .set_zoom = osd_set_zoom, + .get_zoom = osd_get_zoom, + .set_background = osd_set_background, + .get_background = osd_get_background, + .set_rom_clut = osd_set_rom_clut, + .get_rom_clut = osd_get_rom_clut, .start_layer = osd_start_layer, .set_left_margin = osd_set_left_margin, .set_top_margin = osd_set_top_margin, diff --git a/drivers/media/video/davinci/vpbe_venc.c b/drivers/media/video/davinci/vpbe_venc.c index a24fcab..b5178f3 100644 --- a/drivers/media/video/davinci/vpbe_venc.c +++ b/drivers/media/video/davinci/vpbe_venc.c @@ -36,6 +36,7 @@ #include #include #include +#include #include "vpbe_venc_regs.h" @@ -49,6 +50,7 @@ struct venc_state { struct v4l2_subdev sd; struct venc_callback *callback; struct venc_platform_data *pdata; + enum v4l2_mbus_pixelcode if_params; struct device *pdev; u32 output; v4l2_std_id std; @@ -445,6 +447,9 @@ static int venc_set_720p60_external(struct v4l2_subdev *sd, if (pdata->setup_clock(VPBE_ENC_DV_PRESET, V4L2_DV_720P60) < 0) return -EINVAL; + if (pdata->setup_pinmux(venc->if_params, 0) < 0) + return -EINVAL; + vdaccfg_write(sd, VDAC_CONFIG_HD_V2); /* Reset video encoder module */ @@ -533,6 +538,8 @@ static int venc_set_1080i30_external(struct v4l2_subdev *sd, if (pdata->setup_clock(VPBE_ENC_DV_PRESET, V4L2_DV_1080I30) < 0) return -EINVAL; + if (pdata->setup_pinmux(venc->if_params, 1) < 0) + return -EINVAL; /* setup pinmux */ vdaccfg_write(sd, VDAC_CONFIG_HD_V2); @@ -646,6 +653,44 @@ static int venc_set_ycc16_modes(struct v4l2_subdev *sd, return ret; } +static int venc_configure_lcd_port(struct v4l2_subdev *sd, + struct vpbe_enc_mode_info *mode_info) +{ + struct venc_state *venc = to_state(sd); + int ret; + + /* + * Only if the interface is other than VPBE_ANALOG_TV_IF, we need + * execute this + */ + if (venc == NULL) + return -EINVAL; + + if (venc->if_params == V4L2_MBUS_FMT_FIXED) + return 0; + + if (mode_info == NULL) + return -EINVAL; + + switch (venc->if_params) { + case V4L2_MBUS_FMT_RGB565_2X8_BE: + ret = venc_set_prgb(sd, mode_info); + break; + case V4L2_MBUS_FMT_SGRBG8_1X8: + ret = venc_set_srgb(sd, mode_info); + break; + case V4L2_MBUS_FMT_YUYV10_1X20: + ret = venc_set_ycc16_modes(sd, mode_info); + break; + case V4L2_MBUS_FMT_Y10_1X10: + ret = venc_set_ycc8_modes(sd, mode_info); + break; + default: + ret = -EINVAL; + } + return ret; +} + /* * venc_set_625p * @@ -812,6 +857,10 @@ static long venc_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) { + struct venc_callback *next, *prev, *callback; + struct venc_state *venc = to_state(sd); + unsigned long flags; + unsigned event = 0; u32 val; switch (cmd) { @@ -820,6 +869,41 @@ static long venc_ioctl(struct v4l2_subdev *sd, *((int *)arg) = ((val & VENC_VSTAT_FIDST) == VENC_VSTAT_FIDST); break; + case VENC_REG_CALLBACK: + spin_lock_irqsave(&venc->lock, flags); + callback = (struct venc_callback *)arg; + next = venc->callback; + venc->callback = callback; + callback->next = next; + spin_unlock_irqrestore(&venc->lock, flags); + break; + case VENC_UNREG_CALLBACK: + spin_lock_irqsave(&venc->lock, flags); + callback = (struct venc_callback *)arg; + prev = venc->callback; + if (!prev) + return -EINVAL; + else if (prev == callback) + venc->callback = callback->next; + else { + while (prev->next && (prev->next != callback)) + prev = prev->next; + if (!prev->next) + return -EINVAL; + else + prev->next = callback->next; + } + spin_unlock_irqrestore(&venc->lock, flags); + break; + case VENC_INTERRUPT: + callback = venc->callback; + event = *((unsigned *)arg); + while (callback) { + if (callback->mask & event) + callback->handler(event, callback->arg); + callback = callback->next; + } + break; default: v4l2_err(sd, "Wrong IOCTL cmd\n"); break; diff --git a/include/media/davinci/vpbe_osd.h b/include/media/davinci/vpbe_osd.h index d7e397a..7f41a04 100644 --- a/include/media/davinci/vpbe_osd.h +++ b/include/media/davinci/vpbe_osd.h @@ -325,22 +325,74 @@ struct osd_cursor_state { struct osd_state; struct vpbe_osd_ops { + void (*set_clut_ycbcr)(struct osd_state *sd, + unsigned char clut_index, unsigned char y, + unsigned char cb, unsigned char cr); + void (*set_clut_rgb)(struct osd_state *sd, unsigned char clut_index, + unsigned char r, unsigned char g, + unsigned char b); + void (*set_osd_clut)(struct osd_state *sd, enum osd_win_layer osdwin, + enum osd_clut clut); + enum osd_clut (*get_osd_clut)(struct osd_state *sd, + enum osd_win_layer osdwin); + void (*enable_color_key)(struct osd_state *sd, + enum osd_win_layer osdwin, unsigned colorkey); + void (*disable_color_key)(struct osd_state *sd, + enum osd_win_layer osdwin); + void (*set_blending_factor)(struct osd_state *sd, + enum osd_win_layer osdwin, + enum osd_blending_factor blend); + enum osd_blending_factor (*get_blending_factor)(struct osd_state *sd, + enum osd_win_layer osdwin); + void (*set_rec601_attenuation)(struct osd_state *sd, + enum osd_win_layer osdwin, int enable); + int (*get_rec601_attenuation)(struct osd_state *sd, + enum osd_win_layer osdwin); + void (*set_palette_map)(struct osd_state *sd, + enum osd_win_layer osdwin, + unsigned char pixel_value, + unsigned char clut_index); + unsigned char (*get_palette_map)(struct osd_state *sd, + enum osd_win_layer osdwin, unsigned char pixel_value); + void (*set_blink_attribute)(struct osd_state *sd, int enable, + enum osd_blink_interval blink); + void (*get_blink_attribute)(struct osd_state *sd, int *enable, + enum osd_blink_interval *blink); + void (*cursor_enable)(struct osd_state *sd); + void (*cursor_disable)(struct osd_state *sd); + int (*cursor_is_enabled)(struct osd_state *sd); + void (*set_cursor_config)(struct osd_state *sd, + struct osd_cursor_config *cursor); + void (*get_cursor_config)(struct osd_state *sd, + struct osd_cursor_config *cursor); + void (*set_field_inversion)(struct osd_state *sd, int enable); + int (*get_field_inversion)(struct osd_state *sd); int (*initialize)(struct osd_state *sd); int (*request_layer)(struct osd_state *sd, enum osd_layer layer); void (*release_layer)(struct osd_state *sd, enum osd_layer layer); int (*enable_layer)(struct osd_state *sd, enum osd_layer layer, int otherwin); void (*disable_layer)(struct osd_state *sd, enum osd_layer layer); + int (*layer_is_enabled)(struct osd_state *sd, enum osd_layer layer); int (*set_layer_config)(struct osd_state *sd, enum osd_layer layer, struct osd_layer_config *lconfig); + int (*try_layer_config)(struct osd_state *sd, enum osd_layer layer, + struct osd_layer_config *lconfig); void (*get_layer_config)(struct osd_state *sd, enum osd_layer layer, struct osd_layer_config *lconfig); void (*start_layer)(struct osd_state *sd, enum osd_layer layer, unsigned long fb_base_phys, unsigned long cbcr_ofst); + void (*set_interpolation_filter)(struct osd_state *sd, int filter); + int (*get_interpolation_filter)(struct osd_state *sd); + int (*set_osd_expansion)(struct osd_state *sd, + enum osd_h_exp_ratio h_exp, + enum osd_v_exp_ratio v_exp); + void (*get_osd_expansion)(struct osd_state *sd, + enum osd_h_exp_ratio *h_exp, + enum osd_v_exp_ratio *v_exp); void (*set_left_margin)(struct osd_state *sd, u32 val); void (*set_top_margin)(struct osd_state *sd, u32 val); - void (*set_interpolation_filter)(struct osd_state *sd, int filter); int (*set_vid_expansion)(struct osd_state *sd, enum osd_h_exp_ratio h_exp, enum osd_v_exp_ratio v_exp); @@ -350,6 +402,16 @@ struct vpbe_osd_ops { void (*set_zoom)(struct osd_state *sd, enum osd_layer layer, enum osd_zoom_factor h_zoom, enum osd_zoom_factor v_zoom); + void (*get_zoom)(struct osd_state *sd, enum osd_layer layer, + enum osd_zoom_factor *h_zoom, + enum osd_zoom_factor *v_zoom); + void (*set_background)(struct osd_state *sd, enum osd_clut clut, + unsigned char clut_index); + void (*get_background)(struct osd_state *sd, enum osd_clut *clut, + unsigned char *clut_index); + void (*set_rom_clut)(struct osd_state *sd, + enum osd_rom_clut rom_clut); + enum osd_rom_clut (*get_rom_clut)(struct osd_state *sd); }; struct osd_state { diff --git a/include/media/davinci/vpbe_venc.h b/include/media/davinci/vpbe_venc.h index 6b57334..d9836ef 100644 --- a/include/media/davinci/vpbe_venc.h +++ b/include/media/davinci/vpbe_venc.h @@ -27,6 +27,24 @@ #define VENC_FIRST_FIELD BIT(1) #define VENC_SECOND_FIELD BIT(2) +/** + * struct venc_callback + * @next: used internally by the venc driver to maintain a linked list of + * callbacks + * @mask: a bitmask specifying the venc event(s) for which the + * callback will be invoked + * @handler: the callback routine + * @arg: a null pointer that is passed as the second argument to the callback + * routine + */ +struct venc_callback { + struct venc_callback *next; + char *owner; + unsigned mask; + void (*handler) (unsigned event, void *arg); + void *arg; +}; + struct venc_platform_data { enum vpbe_version venc_type; int (*setup_pinmux)(enum v4l2_mbus_pixelcode if_type, @@ -41,6 +59,9 @@ struct venc_platform_data { enum venc_ioctls { VENC_GET_FLD = 1, + VENC_REG_CALLBACK, + VENC_UNREG_CALLBACK, + VENC_INTERRUPT, }; /* exported functions */ -- 1.6.2.4 From manjunath.hadli at ti.com Mon Sep 26 08:35:08 2011 From: manjunath.hadli at ti.com (Manjunath Hadli) Date: Mon, 26 Sep 2011 19:05:08 +0530 Subject: [RFC PATCH 2/3] davinci: vpbe: add fbdev driver for dm644x In-Reply-To: <1317044109-7429-1-git-send-email-manjunath.hadli@ti.com> References: <1317044109-7429-1-git-send-email-manjunath.hadli@ti.com> Message-ID: <1317044109-7429-3-git-send-email-manjunath.hadli@ti.com> add the fbdev driver for dm644x which uses an OSD layer with RGB565/RGB888 support and an attribute window which can also be doubled as another RGB565 window. The fbdev supports fb0 and fb2 for OSD0 and OSD1, and also supports video windows with fb1 and fb3. Signed-off-by: Manjunath Hadli --- drivers/media/video/davinci/vpbe_fb.c | 2537 +++++++++++++++++++++++++++ drivers/media/video/davinci/vpbe_fb.h | 66 + drivers/media/video/davinci/vpbe_fb_ioctl.h | 159 ++ 3 files changed, 2762 insertions(+), 0 deletions(-) create mode 100644 drivers/media/video/davinci/vpbe_fb.c create mode 100644 drivers/media/video/davinci/vpbe_fb.h create mode 100644 drivers/media/video/davinci/vpbe_fb_ioctl.h diff --git a/drivers/media/video/davinci/vpbe_fb.c b/drivers/media/video/davinci/vpbe_fb.c new file mode 100644 index 0000000..acd164d --- /dev/null +++ b/drivers/media/video/davinci/vpbe_fb.c @@ -0,0 +1,2537 @@ +/* + * Copyright (C) 2007 MontaVista Software Inc. + * Copyright (C) 2006 Texas Instruments Inc + * + * Andy Lowe (alowe at mvista.com), MontaVista Software + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option)any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include "vpbe_fb_ioctl.h" +#include "vpbe_fb.h" + +#include + +static struct osd_state *osd_device; + +/* return non-zero if the info structure corresponds to OSD0 or OSD1 */ +static int is_osd_win(const struct fb_info *info) +{ + const struct vpbe_dm_win_info *win = info->par; + + if (win->layer == WIN_OSD0 || win->layer == WIN_OSD1) + return 1; + return 0; +} + +/* return non-zero if the info structure corresponds to VID0 or VID1 */ +#define is_vid_win(info) (!is_osd_win(info)) + +/* + * Convert a framebuffer info pointer to a osd_layer enumeration. + * It is up to the caller to verify that the info structure corresponds to + * either OSD0 or OSD1. + */ +static enum osd_layer fb_info_to_osd_enum(const struct fb_info *info) +{ + const struct vpbe_dm_win_info *win = info->par; + + if (win->layer == WIN_OSD1) + return OSDWIN_OSD1; + return OSDWIN_OSD0; +} + +/* macros for testing fb_var_screeninfo attributes */ +#define is_attribute_mode(var) (((var)->bits_per_pixel == 4) && \ + ((var)->nonstd != 0)) +#define is_yuv(var) ((((var)->bits_per_pixel == 16) || \ + ((var)->bits_per_pixel == 8)) && \ + ((var)->nonstd != 0)) +#define is_window_interlaced(var) (((var)->vmode & FB_VMODE_INTERLACED) \ + == FB_VMODE_INTERLACED) + +/* macros for testing fb_videomode attributes */ +#define is_display_interlaced(mode) (((mode)->vmode & FB_VMODE_INTERLACED) \ + == FB_VMODE_INTERLACED) + +static unsigned int fb_cbcr_ofst; + +/* + * Convert an fb_var_screeninfo struct to a Davinci display layer configuration. + * lconfig->xpos, lconfig->ypos, and lconfig->line_length are not modified + * because no information about them is contained in var. + * The value of the yc_pixfmt argument is returned in lconfig->pixfmt if a + * the var specifies a YC pixel format. The value of yc_pixfmt must be either + * PIXFMT_YCbCrI or PIXFMT_YCrCbI. + */ +static void convert_fb_var_to_osd(const struct fb_var_screeninfo *var, + struct osd_layer_config *lconfig, + enum osd_pix_format yc_pixfmt) +{ + lconfig->xsize = var->xres; + lconfig->ysize = var->yres; + lconfig->interlaced = is_window_interlaced(var); + + switch (var->bits_per_pixel) { + case 1: + lconfig->pixfmt = PIXFMT_1BPP; + break; + case 2: + lconfig->pixfmt = PIXFMT_2BPP; + break; + case 4: + if (is_attribute_mode(var)) + lconfig->pixfmt = PIXFMT_OSD_ATTR; + else + lconfig->pixfmt = PIXFMT_4BPP; + break; + case 8: + if (is_yuv(var)) + lconfig->pixfmt = PIXFMT_NV12; + else + lconfig->pixfmt = PIXFMT_8BPP; + break; + case 16: + default: + if (is_yuv(var)) + lconfig->pixfmt = yc_pixfmt; + else + lconfig->pixfmt = PIXFMT_RGB565; + break; + case 24: + case 32: + lconfig->pixfmt = PIXFMT_RGB888; + break; + } +} + +/* + * Convert an fb_info struct to a OSD display layer configuration. + */ +static void convert_fb_info_to_osd(const struct fb_info *info, + struct osd_layer_config *lconfig) +{ + const struct vpbe_dm_win_info *win = info->par; + + lconfig->line_length = info->fix.line_length; + lconfig->xpos = win->xpos; + lconfig->ypos = win->ypos; + convert_fb_var_to_osd(&info->var, lconfig, win->dm->yc_pixfmt); +} + +/* + * Convert a OSD display layer configuration to var info. + * The following members of var are not modified: + * var->xres_virtual + * var->yres_virtual + * var->xoffset + * var->yoffset + * var->pixclock + * var->left_margin + * var->right_margin + * var->upper_margin + * var->lower_margin + * var->hsync_len + * var->vsync_len + * var->sync + * Only bit 0 of var->vmode (FB_VMODE_INTERLACED) is modified. All other bits + * of var->vmode are retained. + */ +static void convert_osd_to_fb_var(const struct osd_layer_config *lconfig, + struct fb_var_screeninfo *var) +{ + var->xres = lconfig->xsize; + var->yres = lconfig->ysize; + if (lconfig->interlaced) + var->vmode |= FB_VMODE_INTERLACED; + else + var->vmode &= ~FB_VMODE_INTERLACED; + + var->red.offset = var->green.offset = var->blue.offset = 0; + var->red.msb_right = var->green.msb_right = var->blue.msb_right = 0; + var->transp.offset = var->transp.length = var->transp.msb_right = 0; + var->nonstd = 0; + + switch (lconfig->pixfmt) { + case PIXFMT_1BPP: + var->bits_per_pixel = 1; + var->red.length = var->green.length = var->blue.length = + var->bits_per_pixel; + break; + case PIXFMT_2BPP: + var->bits_per_pixel = 2; + var->red.length = var->green.length = var->blue.length = + var->bits_per_pixel; + break; + case PIXFMT_4BPP: + var->bits_per_pixel = 4; + var->red.length = var->green.length = var->blue.length = + var->bits_per_pixel; + break; + case PIXFMT_8BPP: + var->bits_per_pixel = 8; + var->red.length = var->green.length = var->blue.length = + var->bits_per_pixel; + break; + case PIXFMT_RGB565: + var->bits_per_pixel = 16; + var->red.offset = 11; + var->red.length = 5; + var->green.offset = 5; + var->green.length = 6; + var->blue.offset = 0; + var->blue.length = 5; + break; + case PIXFMT_YCbCrI: + case PIXFMT_YCrCbI: + var->bits_per_pixel = 16; + var->red.length = var->green.length = var->blue.length = 0; + var->nonstd = 1; + break; + case PIXFMT_NV12: + if (cpu_is_davinci_dm365()) { + var->bits_per_pixel = 8; + var->red.length = var->green.length = var->blue.length = + 0; + var->nonstd = 1; + } + case PIXFMT_RGB888: + if (cpu_is_davinci_dm644x()) { + var->bits_per_pixel = 24; + var->red.offset = 0; + var->red.length = 8; + var->green.offset = 8; + var->green.length = 8; + var->blue.offset = 16; + var->blue.length = 8; + } else { + var->bits_per_pixel = 32; + var->red.offset = 16; + var->red.length = 8; + var->green.offset = 8; + var->green.length = 8; + var->blue.offset = 0; + var->blue.length = 8; + var->transp.offset = 24; + var->transp.length = 3; + } + break; + case PIXFMT_OSD_ATTR: + var->bits_per_pixel = 4; + var->red.length = var->green.length = var->blue.length = 0; + var->nonstd = 1; + break; + } + + var->grayscale = 0; + var->activate = FB_ACTIVATE_NOW; + var->height = 0; + var->width = 0; + var->accel_flags = 0; + var->rotate = 0; +} + +/* + * Get the video mode from the encoder manager. + */ +static int get_video_mode(struct vpbe_device *vpbe_dev, + struct fb_videomode *mode) +{ + struct vpbe_enc_mode_info mode_info; + int ret; + + memset(&mode_info, 0, sizeof(mode_info)); + memset(mode, 0, sizeof(*mode)); + + ret = vpbe_dev->ops.get_mode_info(vpbe_dev, &mode_info); + if (ret < 0) + return ret; + + mode->name = mode_info.name; + if (mode_info.fps.denominator) { + unsigned fps_1000; /* frames per 1000 seconds */ + unsigned lps; /* lines per second */ + unsigned pps; /* pixels per second */ + unsigned vtotal; /* total lines per frame */ + unsigned htotal; /* total pixels per line */ + unsigned interlace = (mode_info.interlaced) ? 2 : 1; + + fps_1000 = (1000 * mode_info.fps.numerator + + mode_info.fps.denominator / 2) / mode_info.fps.denominator; + + mode->refresh = (interlace * fps_1000 + 1000 / 2) / 1000; + + vtotal = mode_info.yres + mode_info.lower_margin + + mode_info.vsync_len + mode_info.upper_margin; + lps = (fps_1000 * vtotal + 1000 / 2) / 1000; + + htotal = mode_info.xres + mode_info.right_margin + + mode_info.hsync_len + mode_info.left_margin; + pps = lps * htotal; + + if (pps) + mode->pixclock = + ((1000000000UL + pps / 2) / pps) * 1000; + } + mode->xres = mode_info.xres; + mode->yres = mode_info.yres; + mode->left_margin = mode_info.left_margin; + mode->right_margin = mode_info.right_margin; + mode->upper_margin = mode_info.upper_margin; + mode->lower_margin = mode_info.lower_margin; + mode->hsync_len = mode_info.hsync_len; + mode->vsync_len = mode_info.vsync_len; + if (mode_info.flags & (1 << 0)) + mode->sync |= FB_SYNC_HOR_HIGH_ACT; + if (mode_info.flags & (1 << 1)) + mode->sync |= FB_SYNC_VERT_HIGH_ACT; + if ((mode_info.timings_type & VPBE_ENC_STD) || + (mode_info.timings_type & VPBE_ENC_DV_PRESET)) + mode->sync |= FB_SYNC_BROADCAST; + if (mode_info.interlaced) + mode->vmode |= FB_VMODE_INTERLACED; + + return 0; +} + +/* + * Set a video mode with the encoder manager. + */ +static int set_video_mode(struct vpbe_device *vpbe_dev, + struct fb_videomode *mode) +{ + struct vpbe_enc_mode_info mode_info; + int ret; + + ret = vpbe_dev->ops.get_mode_info(vpbe_dev, &mode_info); + if (ret < 0) + return ret; + + mode_info.name = (unsigned char *)mode->name; + mode_info.fps.numerator = 0; + mode_info.fps.denominator = 0; + if (mode->pixclock && mode->xres && mode->yres) { + unsigned fps_1000; /* frames per 1000 seconds */ + unsigned lps; /* lines per second */ + unsigned pps; /* pixels per second */ + unsigned vtotal; /* total lines per frame */ + unsigned htotal; /* total pixels per line */ + + pps = ((1000000000UL + mode->pixclock / 2) / mode->pixclock) * + 1000; + + htotal = mode->xres + mode->right_margin + mode->hsync_len + + mode->left_margin; + lps = (pps + htotal / 2) / htotal; + + vtotal = mode->yres + mode->lower_margin + mode->vsync_len + + mode->upper_margin; + fps_1000 = (lps * 1000 + vtotal / 2) / vtotal; + + mode_info.fps.numerator = fps_1000; + mode_info.fps.denominator = 1000; + + /* + * 1000 == 2*2*2*5*5*5, so factor out any common multiples of 2 + * or 5 + */ + while ((((mode_info.fps.numerator / 2) * 2) == + mode_info.fps.numerator) && + (((mode_info.fps.denominator / 2) * 2) == + mode_info.fps.denominator)) { + mode_info.fps.numerator = mode_info.fps.numerator / 2; + mode_info.fps.denominator = + mode_info.fps.denominator / 2; + } + while ((((mode_info.fps.numerator / 5) * 5) == + mode_info.fps.numerator) && + (((mode_info.fps.denominator / 5) * 5) == + mode_info.fps.denominator)) { + mode_info.fps.numerator = mode_info.fps.numerator / 5; + mode_info.fps.denominator = + mode_info.fps.denominator / 5; + } + } + mode_info.xres = mode->xres; + mode_info.yres = mode->yres; + mode_info.left_margin = mode->left_margin; + mode_info.right_margin = mode->right_margin; + mode_info.upper_margin = mode->upper_margin; + mode_info.lower_margin = mode->lower_margin; + mode_info.hsync_len = mode->hsync_len; + mode_info.vsync_len = mode->vsync_len; + if (mode->sync & FB_SYNC_HOR_HIGH_ACT) + mode_info.flags |= (1 << 0); + else + mode_info.flags &= ~(1 << 0); + if (mode->sync & FB_SYNC_VERT_HIGH_ACT) + mode_info.flags |= (1 << 1); + else + mode_info.flags &= ~(1 << 1); + /* + * seems like a flag std is used in earlier version of the driver to + * indicate if it is a standard timings non standard timings. We use + * timings_type for the same. + */ + if (mode->sync & FB_SYNC_BROADCAST) + mode_info.timings_type = VPBE_ENC_TIMINGS_INVALID; + else + mode_info.timings_type = VPBE_ENC_CUSTOM_TIMINGS; + if (mode->vmode & FB_VMODE_INTERLACED) + mode_info.interlaced = 1; + else + mode_info.interlaced = 0; + + ret = vpbe_dev->ops.set_mode(vpbe_dev, &mode_info); + + return ret; +} + +/* + * Construct an fb_var_screeninfo structure from an fb_videomode structure + * describing the display and a osd_layer_config structure describing a window. + * The following members of var not modified: + * var->xoffset + * var->yoffset + * var->xres_virtual + * var->yres_virtual + * The following members of var are loaded with values derived from mode: + * var->pixclock + * var->left_margin + * var->hsync_len + * var->vsync_len + * var->right_margin + * var->upper_margin + * var->lower_margin + * var->sync + * var->vmode (all bits except bit 0: FB_VMODE_INTERLACED) + * The following members of var are loaded with values derived from lconfig: + * var->xres + * var->yres + * var->bits_per_pixel + * var->red + * var->green + * var->blue + * var->transp + * var->nonstd + * var->grayscale + * var->activate + * var->height + * var->width + * var->accel_flags + * var->rotate + * var->vmode (only bit 0: FB_VMODE_INTERLACED) + * + * If the display resolution (xres and yres) specified in mode matches the + * window resolution specified in lconfig, then the display timing info returned + * in var is valid and var->pixclock will be the value derived from mode. + * If the display resolution does not match the window resolution, then + * var->pixclock will be set to 0 to indicate that the display timing info + * returned in var is not valid. + * + * mode and lconfig are not modified. + */ +static void construct_fb_var(struct fb_var_screeninfo *var, + struct fb_videomode *mode, + struct osd_layer_config *lconfig) +{ + fb_videomode_to_var(var, mode); + convert_osd_to_fb_var(lconfig, var); + if (lconfig->xsize != mode->xres || lconfig->ysize != mode->yres) + var->pixclock = 0; +} + +/* + * Update the values in an fb_fix_screeninfo structure based on the values in an + * fb_var_screeninfo structure. + * The following members of fix are updated: + * fix->visual + * fix->xpanstep + * fix->ypanstep + * fix->ywrapstep + * fix->line_length + * All other members of fix are unmodified. + */ +static void update_fix_info(const struct fb_var_screeninfo *var, + struct fb_fix_screeninfo *fix) +{ + fix->visual = (var->bits_per_pixel > 8) ? FB_VISUAL_TRUECOLOR : + FB_VISUAL_PSEUDOCOLOR; + /* + * xpanstep must correspond to a multiple of the 32-byte cache line size + */ + switch (var->bits_per_pixel) { + case 1: + case 2: + case 4: + case 8: + case 12: + case 16: + case 32: + fix->xpanstep = (8 * 32) / var->bits_per_pixel; + break; + case 24: + fix->xpanstep = 32; /* 32 pixels = 3 cache lines */ + break; + default: + fix->xpanstep = 0; + break; + } + fix->ypanstep = 1; + fix->ywrapstep = 0; + fix->line_length = (var->xres_virtual * var->bits_per_pixel + 7) / 8; + /* line_length must be a multiple of the 32-byte cache line size */ + fix->line_length = ((fix->line_length + 31) / 32) * 32; +} + +/* + * Determine if the window configuration specified by var will fit in a + * framebuffer of size fb_size. + * Returns 1 if the window will fit in the framebuffer, or 0 otherwise. + */ +static int window_will_fit_framebuffer(const struct fb_var_screeninfo *var, + unsigned fb_size) +{ + unsigned line_length; + + line_length = (var->bits_per_pixel * var->xres_virtual + 7) / 8; + /* line length must be a multiple of the cache line size (32) */ + line_length = ((line_length + 31) / 32) * 32; + + if (var->yres_virtual * line_length <= fb_size) + return 1; + return 0; +} + +/* + * FBIO_WAITFORVSYNC handler + */ +static int vpbe_fb_wait_for_vsync(struct fb_info *info) +{ + struct vpbe_dm_win_info *win = info->par; + unsigned long cnt; + wait_queue_t wq; + int ret; + + init_waitqueue_entry(&wq, current); + + cnt = win->dm->vsync_cnt; + ret = wait_event_interruptible_timeout(win->dm->vsync_wait, + cnt != win->dm->vsync_cnt, win->dm->timeout); + if (ret < 0) + return ret; + if (ret == 0) + return -ETIMEDOUT; + + return 0; +} + +static void vpbe_fb_vsync_callback(unsigned event, void *arg) +{ + struct vpbe_dm_info *dm = (struct vpbe_dm_info *)arg; + static unsigned last_event; + unsigned long addr = 0; + + event &= ~VENC_END_OF_FRAME; + if (event == last_event) { + /* progressive */ + xchg(&addr, dm->win[WIN_OSD0].sdram_address); + if (addr) { + osd_device->ops.start_layer(osd_device, + dm->win[WIN_OSD0].layer, + dm->win[WIN_OSD0].sdram_address, + fb_cbcr_ofst); + dm->win[WIN_OSD0].sdram_address = 0; + } + addr = 0; + xchg(&addr, dm->win[WIN_OSD1].sdram_address); + if (addr) { + osd_device->ops.start_layer(osd_device, + dm->win[WIN_OSD1].layer, + dm->win[WIN_OSD1].sdram_address, + fb_cbcr_ofst); + dm->win[WIN_OSD1].sdram_address = 0; + } + addr = 0; + xchg(&addr, dm->win[WIN_VID0].sdram_address); + if (addr) { + osd_device->ops.start_layer(osd_device, + dm->win[WIN_VID0].layer, + dm->win[WIN_VID0].sdram_address, + fb_cbcr_ofst); + dm->win[WIN_VID0].sdram_address = 0; + } + addr = 0; + xchg(&addr, dm->win[WIN_VID1].sdram_address); + if (addr) { + osd_device->ops.start_layer(osd_device, + dm->win[WIN_VID1].layer, + dm->win[WIN_VID1].sdram_address, + fb_cbcr_ofst); + + dm->win[WIN_VID1].sdram_address = 0; + } + ++dm->vsync_cnt; + wake_up_interruptible(&dm->vsync_wait); + last_event = event; + return; + } + /* interlaced */ + if (!(event & VENC_SECOND_FIELD)) { + ++dm->vsync_cnt; + wake_up_interruptible(&dm->vsync_wait); + last_event = event; + return; + } + xchg(&addr, dm->win[WIN_OSD0].sdram_address); + if (addr) { + osd_device->ops.start_layer(osd_device, + dm->win[WIN_OSD0].layer, + dm->win[WIN_OSD0].sdram_address, + fb_cbcr_ofst); + + dm->win[WIN_OSD0].sdram_address = 0; + } + addr = 0; + xchg(&addr, dm->win[WIN_OSD1].sdram_address); + if (addr) { + osd_device->ops.start_layer(osd_device, + dm->win[WIN_OSD1].layer, + dm->win[WIN_OSD1].sdram_address, + fb_cbcr_ofst); + dm->win[WIN_OSD1].sdram_address = 0; + } + addr = 0; + xchg(&addr, dm->win[WIN_VID0].sdram_address); + if (addr) { + osd_device->ops.start_layer(osd_device, + dm->win[WIN_VID0].layer, + dm->win[WIN_VID0].sdram_address, + fb_cbcr_ofst); + dm->win[WIN_VID0].sdram_address = 0; + } + addr = 0; + xchg(&addr, dm->win[WIN_VID1].sdram_address); + if (addr) { + osd_device->ops.start_layer(osd_device, + dm->win[WIN_VID1].layer, + dm->win[WIN_VID1].sdram_address, + fb_cbcr_ofst); + dm->win[WIN_VID1].sdram_address = 0; + } + last_event = event; +} + +/* + * FBIO_SETATTRIBUTE handler + * + * This ioctl is deprecated. The user can write the attribute values directly + * to the OSD1 framebuffer. + * + * Set a uniform attribute value over a rectangular area on the attribute + * window. The attribute value (0 to 15) is passed through the fb_fillrect's + * color parameter. r->dx and r->width must both be even. If not, they are + * rounded down. + */ +static int vpbe_set_attr_blend(struct fb_info *info, struct fb_fillrect *r) +{ + struct fb_var_screeninfo *var = &info->var; + struct vpbe_dm_win_info *win = info->par; + char __iomem *start; + u32 width_bytes; + u8 blend; + + if (win->layer != WIN_OSD1) + return -EINVAL; + if (!is_attribute_mode(var)) + return -EINVAL; + + if (r->dx + r->width > var->xres_virtual) + return -EINVAL; + if (r->dy + r->height > var->yres_virtual) + return -EINVAL; + if (r->color > 15) + return -EINVAL; + width_bytes = (r->width * var->bits_per_pixel) / 8; + start = info->screen_base + r->dy * info->fix.line_length + + (r->dx * var->bits_per_pixel) / 8; + + blend = (((u8) r->color & 0xf) << 4) | ((u8) r->color); + while (r->height--) { + memset(start, blend, width_bytes); + start += info->fix.line_length * 3; + } + + return 0; +} + +/* + * FBIO_SETPOSX handler + */ +static int vpbe_setposx(struct fb_info *info, unsigned xpos) +{ + struct fb_var_screeninfo *var = &info->var; + struct vpbe_dm_win_info *win = info->par; + unsigned old_xpos = win->xpos; + struct fb_var_screeninfo v; + int retval; + + if (!win->own_window) + return -ENODEV; + + memcpy(&v, var, sizeof(v)); + win->xpos = xpos; + retval = info->fbops->fb_check_var(&v, info); + if (retval) { + win->xpos = old_xpos; + return retval; + } + + /* update the window position */ + memcpy(var, &v, sizeof(v)); + retval = info->fbops->fb_set_par(info); + + return retval; +} + +/* + * FBIO_SETPOSY handler + */ +static int vpbe_setposy(struct fb_info *info, unsigned ypos) +{ + struct fb_var_screeninfo *var = &info->var; + struct vpbe_dm_win_info *win = info->par; + unsigned old_ypos = win->ypos; + struct fb_var_screeninfo v; + int retval; + + if (!win->own_window) + return -ENODEV; + + memcpy(&v, var, sizeof(v)); + win->ypos = ypos; + retval = info->fbops->fb_check_var(&v, info); + if (retval) { + win->ypos = old_ypos; + return retval; + } + + /* update the window position */ + memcpy(var, &v, sizeof(v)); + retval = info->fbops->fb_set_par(info); + + return retval; +} + +/* + * FBIO_SETZOOM handler + */ +static int vpbe_set_zoom(struct fb_info *info, struct zoom_params *zoom) +{ + struct vpbe_dm_win_info *win = info->par; + enum osd_zoom_factor h_zoom, v_zoom; + + if (!win->own_window) + return -ENODEV; + + switch (zoom->zoom_h) { + case 0: + h_zoom = ZOOM_X1; + break; + case 1: + h_zoom = ZOOM_X2; + break; + case 2: + h_zoom = ZOOM_X4; + break; + default: + return -EINVAL; + } + + switch (zoom->zoom_v) { + case 0: + v_zoom = ZOOM_X1; + break; + case 1: + v_zoom = ZOOM_X2; + break; + case 2: + v_zoom = ZOOM_X4; + break; + default: + return -EINVAL; + } + osd_device->ops.set_zoom(osd_device, + win->layer, h_zoom, v_zoom); + return 0; +} + +/* + * FBIO_ENABLE_DISABLE_WIN handler + * + * This ioctl is deprecated. Use the standard FBIOBLANK ioctl instead. + */ +static int vpbe_enable_disable_win(struct fb_info *info, int enable) +{ + struct vpbe_dm_win_info *win = info->par; + int retval = 0; + + if (!win->own_window) + return -ENODEV; + + if (!enable) { + win->display_window = 0; + osd_device->ops.disable_layer(osd_device, win->layer); + return retval; + } + win->display_window = 1; + retval = info->fbops->fb_check_var(&info->var, info); + if (retval) + return retval; + retval = info->fbops->fb_set_par(info); + return retval; +} + +/* + * FBIO_SET_BITMAP_BLEND_FACTOR handler + */ +static int vpbe_bitmap_set_blend_factor(struct fb_info *info, + struct vpbe_bitmap_blend_params *para) +{ + enum osd_layer osdwin = fb_info_to_osd_enum(info); + + if (!is_osd_win(info)) + return -EINVAL; + + if (para->bf > OSD_8_VID_0) + return -EINVAL; + + osd_device->ops.set_blending_factor(osd_device, osdwin, para->bf); + if (para->enable_colorkeying) + osd_device->ops.enable_color_key(osd_device, + osdwin, para->colorkey); + else + osd_device->ops.disable_color_key(osd_device, osdwin); + return 0; +} + +/* + * FBIO_SET_BITMAP_WIN_RAM_CLUT handler + * + * This ioctl is deprecated. Use the standard framebuffer ioctl FBIOPUTCMAP + * instead. Note that FBIOPUTCMAP colors are expressed in RGB space instead of + * YCbCr space. + */ +static int vpbe_bitmap_set_ram_clut(struct fb_info *info, + unsigned char ram_clut[256][3]) +{ + int i; + + if (!is_osd_win(info)) + return -EINVAL; + + for (i = 0; i < 256; i++) + osd_device->ops.set_clut_ycbcr(osd_device, i, ram_clut[i][0], + ram_clut[i][1], ram_clut[i][2]); + + return 0; +} + +/* + * FBIO_ENABLE_DISABLE_ATTRIBUTE_WIN handler + * + * This ioctl is deprecated. Attribute mode can be enabled via the standard + * framebuffer ioctl FBIOPUT_VSCREENINFO by setting var->bits_per_pixel to 4 + * and var->nonstd to a non-zero value. Attribute mode can be disabled by using + * FBIOPUT_VSCREENINFO to set a standard pixel format. + * + * The enabled/disabled status of OSD1 is unchanged by this ioctl. To avoid + * display glitches, you should disable OSD1 prior to calling this ioctl. + * + * When enabling attribute mode, var->bits_per_pixel is set to 4. var->xres, + * var->yres, var->xres_virtual, var->yres_virtual, win->xpos, and win->ypos are + * all copied from OSD0. var->xoffset and var->yoffset are set to 0. + * fix->line_length is updated to be consistent with 4 bits per pixel. No + * changes are made to the OSD1 configuration if OSD1 is already in attribute + * mode. + * + * When disabling attribute mode, the window geometry is unchanged. + * var->bits_per_pixel remains set to 4. No changes are made to the OSD1 + * configuration if OSD1 is not in attribute mode. + */ +static int vpbe_enable_disable_attribute_window(struct fb_info *info, u32 flag) +{ + struct fb_var_screeninfo *var = &info->var; + struct vpbe_dm_win_info *win = info->par; + struct osd_layer_config lconfig; + struct fb_var_screeninfo v; + int retval; + + if (win->layer != WIN_OSD1) + return -EINVAL; + + /* return with no error if there is nothing to do */ + if ((is_attribute_mode(var) && flag) || + (!is_attribute_mode(var) && !flag)) + return 0; + + /* start with the current OSD1 var */ + memcpy(&v, var, sizeof(v)); + + if (flag) { + /* enable attribute mode */ + const struct vpbe_dm_win_info *osd0 = &win->dm->win[WIN_OSD0]; + const struct fb_var_screeninfo *osd0_var = &osd0->info->var; + unsigned old_xpos = win->xpos; + unsigned old_ypos = win->ypos; + /* get the OSD0 window configuration */ + convert_fb_var_to_osd(osd0_var, &lconfig, win->dm->yc_pixfmt); + /* change the pixfmt to attribute mode */ + lconfig.pixfmt = PIXFMT_OSD_ATTR; + /* update the var for OSD1 */ + convert_osd_to_fb_var(&lconfig, &v); + /* copy xres_virtual and yres_virtual from OSD0 */ + v.xres_virtual = osd0_var->xres_virtual; + v.yres_virtual = osd0_var->yres_virtual; + /* zero xoffset and yoffset */ + v.xoffset = 0; + v.yoffset = 0; + /* copy xpos and ypos from OSD0 */ + win->xpos = osd0->xpos; + win->ypos = osd0->ypos; + + retval = info->fbops->fb_check_var(&v, info); + if (retval) { + win->xpos = old_xpos; + win->ypos = old_ypos; + return retval; + } + + /* + * Enable attribute mode by replacing info->var and calling + * the fb_set_par method to activate it. + */ + memcpy(var, &v, sizeof(v)); + retval = info->fbops->fb_set_par(info); + return retval; + } + /* disable attribute mode */ + /* get the current OSD1 window configuration */ + convert_fb_var_to_osd(var, &lconfig, win->dm->yc_pixfmt); + /* change the pixfmt to 4-bits-per-pixel bitmap */ + lconfig.pixfmt = PIXFMT_4BPP; + /* update the var for OSD1 */ + convert_osd_to_fb_var(&lconfig, &v); + + retval = info->fbops->fb_check_var(&v, info); + if (retval) + return retval; + + /* + * Disable attribute mode by replacing info->var and calling + * the fb_set_par method to activate it. + */ + memcpy(var, &v, sizeof(v)); + retval = info->fbops->fb_set_par(info); + return retval; +} + +/* + * FBIO_GET_BLINK_INTERVAL handler + */ +static int vpbe_get_blinking(struct fb_info *info, + struct vpbe_blink_option *blink_option) +{ + struct vpbe_dm_win_info *win = info->par; + enum osd_blink_interval blink; + int enabled; + + if (win->layer != WIN_OSD1) + return -EINVAL; + + osd_device->ops.get_blink_attribute(osd_device, &enabled, &blink); + blink_option->blinking = enabled; + blink_option->interval = blink; + + return 0; +} + +/* + * FBIO_SET_BLINK_INTERVAL handler + */ +static int vpbe_set_blinking(struct fb_info *info, + struct vpbe_blink_option *blink_option) +{ + struct vpbe_dm_win_info *win = info->par; + + if (win->layer != WIN_OSD1) + return -EINVAL; + + if (blink_option->interval > BLINK_X4) + return -EINVAL; + osd_device->ops.set_blink_attribute(osd_device, + blink_option->blinking, blink_option->interval); + + return 0; +} + +/* + * FBIO_GET_VIDEO_CONFIG_PARAMS handler + * + * Despite the name, this ioctl can be used on both video windows and OSD + * (bitmap) windows. + */ +static int vpbe_get_vid_params(struct fb_info *info, + struct vpbe_video_config_params *vid_conf_params) +{ + struct vpbe_dm_win_info *win = info->par; + enum osd_h_exp_ratio h_exp; + enum osd_v_exp_ratio v_exp; + + if (!win->own_window) + return -ENODEV; + + if (is_vid_win(info)) + osd_device->ops.get_vid_expansion(osd_device, + &h_exp, &v_exp); + else + osd_device->ops.get_osd_expansion(osd_device, + &h_exp, &v_exp); + + vid_conf_params->cb_cr_order = + (win->dm->yc_pixfmt == PIXFMT_YCbCrI) ? 0 : 1; + vid_conf_params->exp_info.horizontal = h_exp; + vid_conf_params->exp_info.vertical = v_exp; + + return 0; +} + +/* + * FBIO_SET_VIDEO_CONFIG_PARAMS handler + * + * Despite the name, this ioctl can be used on both video windows and OSD + * (bitmap) windows. + * + * NOTE: If the cb_cr_order is changed, it won't take effect until an + * FBIOPUT_VSCREENINFO ioctl is executed on a window with a YC pixel format. + */ +static int vpbe_set_vid_params(struct fb_info *info, + struct vpbe_video_config_params *vid_conf_params) +{ + struct vpbe_dm_win_info *win = info->par; + enum osd_h_exp_ratio h_exp; + enum osd_v_exp_ratio v_exp; + + if (!win->own_window) + return -ENODEV; + + if (vid_conf_params->exp_info.horizontal > H_EXP_3_OVER_2) + return -EINVAL; + + if (vid_conf_params->exp_info.vertical > V_EXP_6_OVER_5) + return -EINVAL; + + win->dm->yc_pixfmt = + vid_conf_params->cb_cr_order ? PIXFMT_YCrCbI : PIXFMT_YCbCrI; + + h_exp = vid_conf_params->exp_info.horizontal; + v_exp = vid_conf_params->exp_info.vertical; + if (is_vid_win(info)) + osd_device->ops.set_vid_expansion(osd_device, + h_exp, v_exp); + else + osd_device->ops.set_osd_expansion(osd_device, + h_exp, v_exp); + + return 0; +} + +/* + * FBIO_GET_BITMAP_CONFIG_PARAMS handler + */ +static int vpbe_bitmap_get_params(struct fb_info *info, + struct vpbe_bitmap_config_params* + bitmap_conf_params) +{ + enum osd_layer osdwin = fb_info_to_osd_enum(info); + enum osd_clut clut; + + if (!is_osd_win(info)) + return -EINVAL; + + clut = osd_device->ops.get_osd_clut(osd_device, osdwin); + if (clut == ROM_CLUT) + bitmap_conf_params->clut_select = + osd_device->ops.get_rom_clut(osd_device); + else + bitmap_conf_params->clut_select = 2; + + bitmap_conf_params->attenuation_enable = + osd_device->ops.get_rec601_attenuation(osd_device, + osdwin); + + memset(&bitmap_conf_params->clut_idx, 0, + sizeof(bitmap_conf_params->clut_idx)); + + switch (info->var.bits_per_pixel) { + case 1: + bitmap_conf_params->clut_idx.for_1bit_bitmap.bitmap_val_0 = + osd_device->ops.get_palette_map(osd_device, + osdwin, 0); + bitmap_conf_params->clut_idx.for_1bit_bitmap.bitmap_val_1 = + osd_device->ops.get_palette_map(osd_device, + osdwin, 1); + break; + case 2: + bitmap_conf_params->clut_idx.for_2bit_bitmap.bitmap_val_0 = + osd_device->ops.get_palette_map(osd_device, + osdwin, 0); + bitmap_conf_params->clut_idx.for_2bit_bitmap.bitmap_val_1 = + osd_device->ops.get_palette_map(osd_device, + osdwin, 1); + + bitmap_conf_params->clut_idx.for_2bit_bitmap.bitmap_val_2 = + osd_device->ops.get_palette_map(osd_device, + osdwin, 2); + bitmap_conf_params->clut_idx.for_2bit_bitmap.bitmap_val_3 = + osd_device->ops.get_palette_map(osd_device, + osdwin, 3); + break; + case 4: + bitmap_conf_params->clut_idx.for_4bit_bitmap.bitmap_val_0 = + osd_device->ops.get_palette_map(osd_device, + osdwin, 0); + bitmap_conf_params->clut_idx.for_4bit_bitmap.bitmap_val_1 = + osd_device->ops.get_palette_map(osd_device, + osdwin, 1); + bitmap_conf_params->clut_idx.for_4bit_bitmap.bitmap_val_2 = + osd_device->ops.get_palette_map(osd_device, + osdwin, 2); + bitmap_conf_params->clut_idx.for_4bit_bitmap.bitmap_val_3 = + osd_device->ops.get_palette_map(osd_device, + osdwin, 3); + bitmap_conf_params->clut_idx.for_4bit_bitmap.bitmap_val_4 = + osd_device->ops.get_palette_map(osd_device, + osdwin, 4); + bitmap_conf_params->clut_idx.for_4bit_bitmap.bitmap_val_5 = + osd_device->ops.get_palette_map(osd_device, + osdwin, 5); + bitmap_conf_params->clut_idx.for_4bit_bitmap.bitmap_val_6 = + osd_device->ops.get_palette_map(osd_device, + osdwin, 6); + + bitmap_conf_params->clut_idx.for_4bit_bitmap.bitmap_val_7 = + osd_device->ops.get_palette_map(osd_device, + osdwin, 7); + bitmap_conf_params->clut_idx.for_4bit_bitmap.bitmap_val_8 = + osd_device->ops.get_palette_map(osd_device, + osdwin, 8); + bitmap_conf_params->clut_idx.for_4bit_bitmap.bitmap_val_9 = + osd_device->ops.get_palette_map(osd_device, + osdwin, 9); + + bitmap_conf_params->clut_idx.for_4bit_bitmap.bitmap_val_10 = + osd_device->ops.get_palette_map(osd_device, + osdwin, 10); + + bitmap_conf_params->clut_idx.for_4bit_bitmap.bitmap_val_11 = + osd_device->ops.get_palette_map(osd_device, + osdwin, 11); + + bitmap_conf_params->clut_idx.for_4bit_bitmap.bitmap_val_12 = + osd_device->ops.get_palette_map(osd_device, + osdwin, 12); + bitmap_conf_params->clut_idx.for_4bit_bitmap.bitmap_val_13 = + osd_device->ops.get_palette_map(osd_device, + osdwin, 13); + bitmap_conf_params->clut_idx.for_4bit_bitmap.bitmap_val_14 = + osd_device->ops.get_palette_map(osd_device, + osdwin, 14); + bitmap_conf_params->clut_idx.for_4bit_bitmap.bitmap_val_15 = + osd_device->ops.get_palette_map(osd_device, + osdwin, 15); + break; + default: + break; + } + + return 0; +} + +/* + * FBIO_SET_BITMAP_CONFIG_PARAMS handler + * + * The palette map is ignored unless the color depth is set to 1, 2, or 4 bits + * per pixel. A default palette map is supplied for these color depths where + * the clut index is equal to the pixel value. It is not necessary to change + * the default palette map when using the RAM clut, because the RAM clut values + * can be changed. It is only necessary to modify the default palette map when + * using a ROM clut. + */ +static int vpbe_bitmap_set_params(struct fb_info *info, + struct vpbe_bitmap_config_params* + bitmap_conf_params) +{ + enum osd_layer osdwin = fb_info_to_osd_enum(info); + enum osd_clut clut = ROM_CLUT; + + if (!is_osd_win(info)) + return -EINVAL; + + if (bitmap_conf_params->clut_select == 0) + osd_device->ops.set_rom_clut(osd_device, ROM_CLUT0); + else if (bitmap_conf_params->clut_select == 1) + osd_device->ops.set_rom_clut(osd_device, ROM_CLUT1); + else if (bitmap_conf_params->clut_select == 2) + clut = RAM_CLUT; + else + return -EINVAL; + + osd_device->ops.set_osd_clut(osd_device, osdwin, clut); + + osd_device->ops.set_rec601_attenuation(osd_device, osdwin, + bitmap_conf_params->attenuation_enable); + + switch (info->var.bits_per_pixel) { + case 1: + osd_device->ops.set_palette_map(osd_device, + osdwin, 0, bitmap_conf_params->clut_idx. + for_1bit_bitmap.bitmap_val_0); + osd_device->ops.set_palette_map(osd_device, + osdwin, 1, bitmap_conf_params->clut_idx. + for_1bit_bitmap.bitmap_val_1); + break; + case 2: + osd_device->ops.set_palette_map(osd_device, + osdwin, 0, bitmap_conf_params->clut_idx. + for_2bit_bitmap.bitmap_val_0); + osd_device->ops.set_palette_map(osd_device, + osdwin, 1, bitmap_conf_params->clut_idx. + for_2bit_bitmap.bitmap_val_1); + osd_device->ops.set_palette_map(osd_device, + osdwin, 2, bitmap_conf_params->clut_idx. + for_2bit_bitmap.bitmap_val_2); + osd_device->ops.set_palette_map(osd_device, + osdwin, 3, bitmap_conf_params->clut_idx. + for_2bit_bitmap.bitmap_val_3); + + break; + case 4: + osd_device->ops.set_palette_map(osd_device, + osdwin, 0, bitmap_conf_params->clut_idx. + for_4bit_bitmap.bitmap_val_0); + osd_device->ops.set_palette_map(osd_device, + osdwin, 1, bitmap_conf_params->clut_idx. + for_4bit_bitmap.bitmap_val_1); + osd_device->ops.set_palette_map(osd_device, + osdwin, 2, bitmap_conf_params->clut_idx. + for_4bit_bitmap.bitmap_val_2); + osd_device->ops.set_palette_map(osd_device, + osdwin, 3, bitmap_conf_params->clut_idx. + for_4bit_bitmap.bitmap_val_3); + osd_device->ops.set_palette_map(osd_device, + osdwin, 4, bitmap_conf_params->clut_idx. + for_4bit_bitmap.bitmap_val_4); + osd_device->ops.set_palette_map(osd_device, + osdwin, 5, bitmap_conf_params->clut_idx. + for_4bit_bitmap.bitmap_val_5); + osd_device->ops.set_palette_map(osd_device, + osdwin, 6, bitmap_conf_params->clut_idx. + for_4bit_bitmap.bitmap_val_6); + osd_device->ops.set_palette_map(osd_device, + osdwin, 7, bitmap_conf_params->clut_idx. + for_4bit_bitmap.bitmap_val_7); + osd_device->ops.set_palette_map(osd_device, + osdwin, 8, bitmap_conf_params->clut_idx. + for_4bit_bitmap.bitmap_val_8); + osd_device->ops.set_palette_map(osd_device, + osdwin, 9, bitmap_conf_params->clut_idx. + for_4bit_bitmap.bitmap_val_9); + osd_device->ops.set_palette_map(osd_device, + osdwin, 10, bitmap_conf_params->clut_idx. + for_4bit_bitmap.bitmap_val_10); + osd_device->ops.set_palette_map(osd_device, + osdwin, 11, bitmap_conf_params->clut_idx. + for_4bit_bitmap.bitmap_val_11); + osd_device->ops.set_palette_map(osd_device, + osdwin, 12, bitmap_conf_params->clut_idx. + for_4bit_bitmap.bitmap_val_12); + osd_device->ops.set_palette_map(osd_device, + osdwin, 13, bitmap_conf_params->clut_idx. + for_4bit_bitmap.bitmap_val_13); + osd_device->ops.set_palette_map(osd_device, + osdwin, 14, bitmap_conf_params->clut_idx. + for_4bit_bitmap.bitmap_val_14); + osd_device->ops.set_palette_map(osd_device, + osdwin, 15, bitmap_conf_params->clut_idx. + for_4bit_bitmap.bitmap_val_15); + + break; + default: + break; + } + + return 0; +} + +/* + * FBIO_SET_BACKG_COLOR handler + */ +static int vpbe_set_backg_color(struct fb_info *info, + struct vpbe_backg_color *backg_color) +{ + enum osd_clut clut = ROM_CLUT; + + if (backg_color->clut_select == 0) + osd_device->ops.set_rom_clut(osd_device, ROM_CLUT0); + else if (backg_color->clut_select == 1) + osd_device->ops.set_rom_clut(osd_device, ROM_CLUT1); + else if (backg_color->clut_select == 2) + clut = RAM_CLUT; + else + return -EINVAL; + + osd_device->ops.set_background(osd_device, clut, + backg_color->color_offset); + + return 0; +} + +/* + * FBIO_SETPOS handler + */ +static int vpbe_setpos(struct fb_info *info, + struct vpbe_window_position *win_pos) +{ + struct vpbe_dm_win_info *win = info->par; + struct fb_var_screeninfo *var = &info->var; + unsigned old_xpos = win->xpos; + unsigned old_ypos = win->ypos; + struct fb_var_screeninfo v; + int retval; + + if (!win->own_window) + return -ENODEV; + + memcpy(&v, var, sizeof(v)); + win->xpos = win_pos->xpos; + win->ypos = win_pos->ypos; + retval = info->fbops->fb_check_var(&v, info); + if (retval) { + win->xpos = old_xpos; + win->ypos = old_ypos; + return retval; + } + /* update the window position */ + memcpy(var, &v, sizeof(v)); + retval = info->fbops->fb_set_par(info); + + return retval; +} + +/* + * FBIO_SET_CURSOR handler + */ +static int vpbe_set_cursor_params(struct fb_info *info, + struct fb_cursor *fbcursor) +{ + struct osd_cursor_config cursor; + + if (!fbcursor->enable) { + osd_device->ops.cursor_disable(osd_device); + return 0; + } + + cursor.xsize = fbcursor->image.width; + cursor.ysize = fbcursor->image.height; + cursor.xpos = fbcursor->image.dx; + cursor.ypos = fbcursor->image.dy; + cursor.interlaced = is_window_interlaced(&info->var); + cursor.h_width = + (fbcursor->image.depth > 7) ? 7 : fbcursor->image.depth; + cursor.v_width = cursor.h_width; + cursor.clut = ROM_CLUT; + cursor.clut_index = fbcursor->image.fg_color; + osd_device->ops.set_cursor_config(osd_device, &cursor); + osd_device->ops.cursor_enable(osd_device); + + return 0; +} + +/* + * fb_ioctl method + */ +static int +vpbe_fb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg) +{ + struct vpbe_bitmap_config_params bitmap_conf_params; + struct vpbe_video_config_params vid_conf_params; + struct vpbe_bitmap_blend_params blend_para; + struct vpbe_dm_win_info *win = info->par; + void __user *argp = (void __user *)arg; + struct vpbe_blink_option blink_option; + struct vpbe_backg_color backg_color; + struct vpbe_window_position win_pos; + struct fb_fillrect rect; + struct zoom_params zoom; + struct fb_cursor cursor; + int retval = 0; + + switch (cmd) { + case FBIO_WAITFORVSYNC: + /* This ioctl accepts an integer argument to specify a + * display. We only support one display, so we will + * simply ignore the argument. + */ + return vpbe_fb_wait_for_vsync(info); + + case FBIO_SETATTRIBUTE: + if (copy_from_user(&rect, argp, sizeof(rect))) + return -EFAULT; + return vpbe_set_attr_blend(info, &rect); + + case FBIO_SETPOSX: + return vpbe_setposx(info, arg); + + case FBIO_SETPOSY: + return vpbe_setposy(info, arg); + + case FBIO_SETZOOM: + if (copy_from_user(&zoom, argp, sizeof(zoom))) + return -EFAULT; + return vpbe_set_zoom(info, &zoom); + + case FBIO_ENABLE_DISABLE_WIN: + return vpbe_enable_disable_win(info, arg); + + case FBIO_SET_BITMAP_BLEND_FACTOR: + if (copy_from_user(&blend_para, argp, sizeof(blend_para))) + return -EFAULT; + return vpbe_bitmap_set_blend_factor(info, &blend_para); + + case FBIO_SET_BITMAP_WIN_RAM_CLUT: + if (copy_from_user(win->dm->ram_clut[0], argp, RAM_CLUT_SIZE)) + return -EFAULT; + return vpbe_bitmap_set_ram_clut(info, win->dm->ram_clut); + + case FBIO_ENABLE_DISABLE_ATTRIBUTE_WIN: + return vpbe_enable_disable_attribute_window(info, arg); + + case FBIO_GET_BLINK_INTERVAL: + retval = vpbe_get_blinking(info, &blink_option); + if (retval < 0) + return retval; + if (copy_to_user(argp, &blink_option, sizeof(blink_option))) + return -EFAULT; + return 0; + + case FBIO_SET_BLINK_INTERVAL: + if (copy_from_user(&blink_option, argp, sizeof(blink_option))) + return -EFAULT; + return vpbe_set_blinking(info, &blink_option); + + case FBIO_GET_VIDEO_CONFIG_PARAMS: + retval = vpbe_get_vid_params(info, &vid_conf_params); + if (retval < 0) + return retval; + if (copy_to_user + (argp, &vid_conf_params, sizeof(vid_conf_params))) + return -EFAULT; + return 0; + + case FBIO_SET_VIDEO_CONFIG_PARAMS: + if (copy_from_user + (&vid_conf_params, argp, sizeof(vid_conf_params))) + return -EFAULT; + return vpbe_set_vid_params(info, &vid_conf_params); + + case FBIO_GET_BITMAP_CONFIG_PARAMS: + retval = vpbe_bitmap_get_params(info, &bitmap_conf_params); + if (retval < 0) + return retval; + if (copy_to_user + (argp, &bitmap_conf_params, sizeof(bitmap_conf_params))) + return -EFAULT; + return 0; + + case FBIO_SET_BITMAP_CONFIG_PARAMS: + if (copy_from_user + (&bitmap_conf_params, argp, sizeof(bitmap_conf_params))) + return -EFAULT; + return vpbe_bitmap_set_params(info, &bitmap_conf_params); + + case FBIO_SET_BACKG_COLOR: + if (copy_from_user(&backg_color, argp, sizeof(backg_color))) + return -EFAULT; + return vpbe_set_backg_color(info, &backg_color); + + case FBIO_SETPOS: + if (copy_from_user(&win_pos, argp, sizeof(win_pos))) + return -EFAULT; + return vpbe_setpos(info, &win_pos); + + case FBIO_SET_CURSOR: + if (copy_from_user(&cursor, argp, sizeof(cursor))) + return -EFAULT; + return vpbe_set_cursor_params(info, &cursor); + + default: + return -EINVAL; + } +} + + +/* + * fb_check_var method + */ +static int +vpbe_fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) +{ + struct vpbe_dm_win_info *win = info->par; + struct fb_videomode *mode = &win->dm->mode; + struct osd_layer_config lconfig; + struct fb_fix_screeninfo fix; + + /* + * Get an updated copy of the video mode from the encoder manager, just + * in case the display has been switched. + */ + get_video_mode(win->dm->vpbe_dev, mode); + + /* + * xres, yres, xres_virtual, or yres_virtual equal to zero is treated as + * a special case. It indicates that the window should be disabled. If + * the window is a video window, it will also be released. + */ + if (var->xres == 0 || var->yres == 0 || var->xres_virtual == 0 || + var->yres_virtual == 0) { + var->xres = 0; + var->yres = 0; + var->xres_virtual = 0; + var->yres_virtual = 0; + return 0; + } + + switch (var->bits_per_pixel) { + case 1: + case 2: + case 4: + case 8: + case 16: + break; + case 24: + if (cpu_is_davinci_dm355()) + return -EINVAL; + break; + case 32: + if (cpu_is_davinci_dm644x()) + return -EINVAL; + break; + default: + return -EINVAL; + } + if (var->xres_virtual < var->xres || var->yres_virtual < var->yres) + return -EINVAL; + if (var->xoffset > var->xres_virtual - var->xres) + return -EINVAL; + if (var->yoffset > var->yres_virtual - var->yres) + return -EINVAL; + if (mode->xres < var->xres || mode->yres < var->yres) + return -EINVAL; + if (win->xpos > mode->xres - var->xres) + return -EINVAL; + if (win->ypos > mode->yres - var->yres) + return -EINVAL; + convert_fb_var_to_osd(var, &lconfig, win->dm->yc_pixfmt); + + update_fix_info(var, &fix); + lconfig.line_length = fix.line_length; + lconfig.xpos = win->xpos; + lconfig.ypos = win->ypos; + /* xoffset must be a multiple of xpanstep */ + if (var->xoffset & ~(fix.xpanstep - 1)) + return -EINVAL; + + /* check if we have enough video memory to support this mode */ + if (!window_will_fit_framebuffer(var, info->fix.smem_len)) + return -EINVAL; + /* see if the OSD manager approves of this configuration */ + if (osd_device->ops.try_layer_config(osd_device, + win->layer, &lconfig)) + return -EINVAL; + /* + * Reject this var if the OSD manager would have to modify the window + * geometry to make it work. + */ + if (lconfig.xsize != var->xres || lconfig.ysize != var->yres) + return -EINVAL; + if (lconfig.xpos != win->xpos || lconfig.ypos != win->ypos) + return -EINVAL; + /* + * At this point we have accepted the var, so now we convert our layer + * configuration struct back to the var in order to make all of the + * pixel format and geometry values consistent. The var timing values + * will be unmodified, as we have no way to verify them. + */ + convert_osd_to_fb_var(&lconfig, var); + return 0; +} + +/* + * fb_set_par method + */ +static int vpbe_fb_set_par(struct fb_info *info) +{ + struct vpbe_dm_win_info *win = info->par; + struct vpbe_device *vpbe_dev = win->dm->vpbe_dev; + struct fb_var_screeninfo *var = &info->var; + struct osd_layer_config lconfig; + struct fb_videomode mode; + unsigned start; + + /* update the fix info to be consistent with the var */ + update_fix_info(var, &info->fix); + convert_fb_info_to_osd(info, &lconfig); + + /* See if we need to pass the timing values to the encoder manager. */ + memcpy(&mode, &win->dm->mode, sizeof(mode)); + fb_var_to_videomode(&mode, var); + mode.name = win->dm->mode.name; + if (mode.xres == win->dm->mode.xres && mode.yres == + win->dm->mode.yres && mode.pixclock != 0 && + !fb_mode_is_equal(&mode, &win->dm->mode)) { + /* + * If the timing parameters from the var are different than the + * timing parameters from the encoder, try to update the + * timing parameters with the encoder manager. + */ + set_video_mode(vpbe_dev, &mode); + } + /* update our copy of the encoder video mode */ + get_video_mode(vpbe_dev, &win->dm->mode); + + /* turn off ping-pong buffer and field inversion to fix + the image shaking problem in 1080I mode. The problem i.d. by the + DM6446 Advisory 1.3.8 is not seen in 1080I mode, but the ping-pong + buffer workaround created a shaking problem. */ +#if 0 + if (win->layer == WIN_VID0 && + strcmp(mode.name, VID_ENC_STD_1080I_30) == 0 && + (cpu_is_davinci_dm644x_pg1x() || cpu_is_davinci_dm357())) + davinci_disp_set_field_inversion(0); +#endif + /* + * Update the var with the encoder timing info. The window geometry + * will be preserved. + */ + construct_fb_var(var, &win->dm->mode, &lconfig); + + /* need to update interlaced since the mode may have changed */ + lconfig.interlaced = var->vmode = win->dm->mode.vmode; + /* + * xres, yres, xres_virtual, or yres_virtual equal to zero is treated as + * a special case. It indicates that the window should be disabled. If + * the window is a video window, it will also be released. + * Note that we disable the window, but we do not set the + * win->disable_window flag. This allows the window to be re-enabled + * simply by using the FBIOPUT_VSCREENINFO ioctl to set a valid + * configuration. + */ + if (lconfig.xsize == 0 || lconfig.ysize == 0) { + if (win->own_window) { + osd_device->ops.disable_layer(osd_device, win->layer); + if (is_vid_win(info)) { + win->own_window = 0; + osd_device->ops.release_layer(osd_device, + win->layer); + } + } + return 0; + } + + /* + * If we don't currently own this window, we must claim it from the OSD + * manager. + */ + if (!win->own_window) { + if (osd_device->ops.request_layer(osd_device, + win->layer)) + return -ENODEV; + win->own_window = 1; + } + + if (!win->own_window) { + if (osd_device->ops.request_layer(osd_device, + win->layer)) + return -ENODEV; + win->own_window = 1; + } + + /* DM365 YUV420 Planar */ + if (cpu_is_davinci_dm365() && info->var.bits_per_pixel == 8 && + (win->layer == WIN_VID0 || win->layer == WIN_VID1)) + start = info->fix.smem_start + (var->xoffset * 12) / 8 + + var->yoffset * 3 / 2 * info->fix.line_length; + else + start = info->fix.smem_start + (var->xoffset * + var->bits_per_pixel) / 8 + var->yoffset * + info->fix.line_length; + + osd_device->ops.set_layer_config(osd_device, win->layer, &lconfig); + osd_device->ops.start_layer(osd_device, win->layer, start, + fb_cbcr_ofst); + if (win->display_window) + osd_device->ops.enable_layer(osd_device, + win->layer, 0); + + return 0; +} + +/* + * This macro converts a 16-bit color passed to fb_setcolreg to the width + * supported by the pixel format. + */ +#define CNVT_TOHW(val, width) ((((val)<<(width))+0x7FFF-(val))>>16) + +/* + * fb_setcolreg method + */ +static int vpbe_fb_setcolreg(unsigned regno, unsigned red, unsigned green, + unsigned blue, unsigned transp, + struct fb_info *info) +{ + unsigned r; + unsigned g; + unsigned b; + unsigned t; + + /* no. of hw registers */ + if (regno >= 256) + return -EINVAL; + + /* + * An RGB color palette isn't applicable to a window with a YUV pixel + * format or to a window in attribute mode. + */ + if (is_yuv(&info->var) || is_attribute_mode(&info->var)) + return -EINVAL; + + switch (info->fix.visual) { + case FB_VISUAL_TRUECOLOR: + r = CNVT_TOHW(red, info->var.red.length); + g = CNVT_TOHW(green, info->var.green.length); + b = CNVT_TOHW(blue, info->var.blue.length); + t = CNVT_TOHW(transp, info->var.transp.length); + break; + case FB_VISUAL_PSEUDOCOLOR: + default: + r = CNVT_TOHW(red, 8); + g = CNVT_TOHW(green, 8); + b = CNVT_TOHW(blue, 8); + t = 0; + break; + } + + /* Truecolor has hardware independent palette */ + if (info->fix.visual == FB_VISUAL_TRUECOLOR) { + u32 v; + + if (regno >= 16) + return -EINVAL; + + v = (r << info->var.red.offset) | + (g << info->var.green.offset) | + (b << info->var.blue.offset) | + (t << info->var.transp.offset); + + switch (info->var.bits_per_pixel) { + case 16: + ((u16 *) (info->pseudo_palette))[regno] = v; + break; + case 24: + case 32: + ((u32 *) (info->pseudo_palette))[regno] = v; + break; + } + return 0; + } + + if (!is_osd_win(info)) + return -EINVAL; + + osd_device->ops.set_clut_rgb(osd_device, regno, r, g, b); + + return 0; +} + +static int venc_is_second_field(struct vpbe_device *vpbe_dev) +{ + int ret; + int val = 0; + ret = v4l2_subdev_call(vpbe_dev->venc, core, ioctl, VENC_GET_FLD, + &val); + if (ret < 0) + dev_err(vpbe_dev->pdev, "Error in getting Field ID 0\n"); + return val; +} + +/* + * fb_pan_display method + * + * Pan the display using the `xoffset' and `yoffset' fields of the `var' + * structure. We don't support wrapping and ignore the FB_VMODE_YWRAP flag. + */ +static int +vpbe_fb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info) +{ + struct vpbe_dm_win_info *win = info->par; + struct vpbe_device *vpbe_dev = win->dm->vpbe_dev; + unsigned start; + + if (!win->own_window) + return -ENODEV; + + if (var->xoffset > info->var.xres_virtual - info->var.xres) + return -EINVAL; + if (var->yoffset > info->var.yres_virtual - info->var.yres) + return -EINVAL; + + /* xoffset must be a multiple of xpanstep */ + if (var->xoffset & ~(info->fix.xpanstep - 1)) + return -EINVAL; + + /* For DM365 video windows: + * using bits_per_pixel to calculate start/offset address + * needs to be changed for YUV420 planar format since + * it is 8. But consider CbCr the real (avg) bits per pixel + * is 12. line_length is calcuate using 8, so offset needs + * to time 1.5 to take C plane into account. + */ + if (cpu_is_davinci_dm365() && info->var.bits_per_pixel == 8 && + (win->layer == WIN_VID0 || win->layer == WIN_VID1)) + start = info->fix.smem_start + (var->xoffset * 12) / 8 + + var->yoffset * 3 / 2 * info->fix.line_length; + else + start = info->fix.smem_start + (var->xoffset * + info->var.bits_per_pixel) / 8 + var->yoffset * + info->fix.line_length; + + if (venc_is_second_field(vpbe_dev)) + osd_device->ops.start_layer(osd_device, win->layer, start, + fb_cbcr_ofst); + else + win->sdram_address = start; + + return 0; +} + +/* + * fb_blank method + * + * Blank the screen if blank_mode != 0, else unblank. + */ +int vpbe_fb_blank(int blank_mode, struct fb_info *info) +{ + struct vpbe_dm_win_info *win = info->par; + int retval = 0; + + if (!win->own_window) + return -ENODEV; + + if (blank_mode) { + win->display_window = 0; + osd_device->ops.disable_layer(osd_device, win->layer); + return retval; + } + win->display_window = 1; + retval = info->fbops->fb_check_var(&info->var, info); + if (retval) + return retval; + retval = info->fbops->fb_set_par(info); + return retval; +} + +/* + * Frame buffer operations + */ +static struct fb_ops vpbe_fb_ops = { + .owner = THIS_MODULE, + .fb_check_var = vpbe_fb_check_var, + .fb_set_par = vpbe_fb_set_par, + .fb_setcolreg = vpbe_fb_setcolreg, + .fb_blank = vpbe_fb_blank, + .fb_pan_display = vpbe_fb_pan_display, + .fb_fillrect = cfb_fillrect, + .fb_copyarea = cfb_copyarea, + .fb_imageblit = cfb_imageblit, + .fb_rotate = NULL, + .fb_sync = NULL, + .fb_ioctl = vpbe_fb_ioctl, +}; + +static void vpbe_fb_release_window(struct device *dev, + struct vpbe_dm_win_info *win) +{ + struct fb_info *info = win->info; + + if (info) { + unregister_framebuffer(info); + win->info = NULL; + } + + if (win->own_window) { + osd_device->ops.release_layer(osd_device, + win->layer); + win->own_window = 0; + } + win->display_window = 0; + + if (info) { + dma_free_coherent(dev, info->fix.smem_len, info->screen_base, + info->fix.smem_start); + fb_dealloc_cmap(&info->cmap); + kfree(info); + } +} + +static int vpbe_fb_init_window(struct device *dev, + struct vpbe_dm_win_info *win, + struct osd_layer_config *lconfig, + unsigned fb_size, const char *name) +{ + struct fb_info *info; + int err = 0; + + if (!fb_size) + return 0; + + info = kzalloc(sizeof(*info), GFP_KERNEL); + if (!info) { + dev_err(dev, "%s: Can't allocate memory for fb_info struct.\n", + name); + return -ENOMEM; + } + + win->info = info; + /* initialize fb_info */ + info->par = win; + info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_COPYAREA | + FBINFO_HWACCEL_FILLRECT | FBINFO_HWACCEL_IMAGEBLIT | + FBINFO_HWACCEL_XPAN | FBINFO_HWACCEL_YPAN; + info->fbops = &vpbe_fb_ops; + info->screen_size = fb_size; + info->pseudo_palette = win->pseudo_palette; + if (fb_alloc_cmap(&info->cmap, 256, 0) < 0) { + dev_err(dev, "%s: Can't allocate color map.\n", name); + err = -ENODEV; + goto cmap_out; + } + + /* initialize fb_fix_screeninfo */ + strlcpy(info->fix.id, name, sizeof(info->fix.id)); + info->fix.smem_len = fb_size; + info->fix.type = FB_TYPE_PACKED_PIXELS; + + /* allocate the framebuffer */ + info->screen_base = dma_alloc_coherent(dev, info->fix.smem_len, + (dma_addr_t *) &info->fix.smem_start, + GFP_KERNEL | GFP_DMA); + if (!info->screen_base) { + dev_err(dev, "%s: dma_alloc_coherent failed when allocating " + "framebuffer.\n", name); + err = -ENOMEM; + goto fb_alloc_out; + } + + /* + * Fill the framebuffer with zeros unless it is an OSD1 window in + * attribute mode, in which case we fill it with 0x77 to make the OSD0 + * pixels opaque. + */ + memset(info->screen_base, + (lconfig->pixfmt == PIXFMT_OSD_ATTR) ? 0x77 : 0, + info->fix.smem_len); + + /* initialize fb_var_screeninfo */ + construct_fb_var(&info->var, &win->dm->mode, lconfig); + win->xpos = lconfig->xpos; + win->ypos = lconfig->ypos; + info->var.xres_virtual = info->var.xres; + info->var.yres_virtual = info->var.yres; + + /* update the fix info to be consistent with the var */ + update_fix_info(&info->var, &info->fix); + + /* + * Request ownership of the window from the OSD manager unless this is + * a video window and the window size is 0. + */ + + if ((is_osd_win(info) || (info->var.xres != 0 && info->var.yres != + 0)) && !osd_device->ops.request_layer(osd_device, win->layer)) { + win->own_window = 1; + } + /* bail out if this is an OSD window and we don't own it */ + if (is_osd_win(info) && !win->own_window) { + dev_err(dev, "%s: Failed to obtain ownership of OSD " + "window.\n", name); + err = -ENODEV; + goto own_out; + } + + win->display_window = 1; + + if (win->own_window) { + /* check if our initial window configuration is valid */ + if (info->fbops->fb_check_var(&info->var, info)) + dev_warn(dev, "%s: Initial window configuration is " + "invalid.\n", name); + else + info->fbops->fb_set_par(info); + } + + /* register the framebuffer */ + if (register_framebuffer(info)) { + dev_err(dev, "%s: Failed to register framebuffer.\n", name); + err = -ENODEV; + goto register_out; + } + + dev_info(dev, "%s: %dx%dx%d@%d,%d with framebuffer size %dKB\n", + info->fix.id, info->var.xres, info->var.yres, + info->var.bits_per_pixel, win->xpos, win->ypos, + info->fix.smem_len >> 10); + + return 0; + +register_out: + if (win->own_window) + osd_device->ops.release_layer(osd_device, + win->layer); + win->own_window = 0; +own_out: + dma_free_coherent(dev, info->fix.smem_len, info->screen_base, + info->fix.smem_start); +fb_alloc_out: + fb_dealloc_cmap(&info->cmap); +cmap_out: + kfree(info); + + return err; +} + +static int vpbe_fb_remove(struct platform_device *pdev) +{ + struct vpbe_dm_info *dm = platform_get_drvdata(pdev); + struct vpbe_device *vpbe_dev = dm->vpbe_dev; + + platform_set_drvdata(pdev, NULL); + + v4l2_subdev_call(vpbe_dev->venc, core, ioctl, + VENC_UNREG_CALLBACK, &dm->vsync_callback); + + vpbe_fb_release_window(&pdev->dev, &dm->win[WIN_VID1]); + vpbe_fb_release_window(&pdev->dev, &dm->win[WIN_OSD1]); + vpbe_fb_release_window(&pdev->dev, &dm->win[WIN_VID0]); + vpbe_fb_release_window(&pdev->dev, &dm->win[WIN_OSD0]); + kfree(dm); + + return 0; +} + +/* + * Return the maximum number of bytes per screen for a display layer at a + * resolution specified by an fb_videomode struct. + */ +static unsigned vpbe_fb_max_screen_size(enum osd_layer layer, + const struct fb_videomode *mode) +{ + unsigned max_bpp = 32; + unsigned line_length; + unsigned size; + + switch (layer) { + case WIN_OSD0: + case WIN_OSD1: + if (cpu_is_davinci_dm355()) + max_bpp = 32; + else + max_bpp = 16; + break; + case WIN_VID0: + case WIN_VID1: + if (cpu_is_davinci_dm355()) + max_bpp = 16; + else + max_bpp = 24; + break; + } + + line_length = (mode->xres * max_bpp + 7) / 8; + line_length = ((line_length + 31) / 32) * 32; + size = mode->yres * line_length; + + return size; +} + +static void parse_win_params(struct vpbe_dm_win_info *win, + struct osd_layer_config *lconfig, + unsigned *fb_size, char *opt) +{ + unsigned bits_per_pixel; + char c = 0; + char *s; + char *p; + + if (!opt) + return; + + /* xsize */ + p = strpbrk(opt, "x,@"); + if (p) + c = *p; + s = strsep(&opt, "x,@"); + if (s == NULL) + return; + if (*s) + lconfig->xsize = simple_strtoul(s, NULL, 0); + if (!p || !opt) + return; + + /* ysize */ + if (c == 'x') { + p = strpbrk(opt, "x,@"); + if (p) + c = *p; + s = strsep(&opt, "x,@"); + if (s == NULL) + return; + if (*s) + lconfig->ysize = simple_strtoul(s, NULL, 0); + if (!p || !opt) + return; + } + + /* bits per pixel */ + if (c == 'x') { + p = strpbrk(opt, ",@"); + if (p) + c = *p; + s = strsep(&opt, ",@"); + if (s == NULL) + return; + + if (!*s) + goto bits_per_pixel_out; + + bits_per_pixel = simple_strtoul(s, NULL, 0); + switch (bits_per_pixel) { + case 1: + if (win->layer == WIN_OSD0 || + win->layer == WIN_OSD1) + lconfig->pixfmt = PIXFMT_1BPP; + break; + case 2: + if (win->layer == WIN_OSD0 || + win->layer == WIN_OSD1) + lconfig->pixfmt = PIXFMT_2BPP; + break; + case 4: + if (win->layer == WIN_OSD0 || + win->layer == WIN_OSD1) + lconfig->pixfmt = PIXFMT_4BPP; + break; + case 8: + if (win->layer == WIN_OSD0 || + win->layer == WIN_OSD1) + lconfig->pixfmt = PIXFMT_8BPP; + if (cpu_is_davinci_dm365()) + if (win->layer == WIN_VID0 || + win->layer == WIN_VID1) + lconfig->pixfmt = PIXFMT_NV12; + break; + case 16: + if (win->layer == WIN_OSD0 || + win->layer == WIN_OSD1) + lconfig->pixfmt = PIXFMT_RGB565; + else + lconfig->pixfmt = win->dm->yc_pixfmt; + break; + case 24: + if (cpu_is_davinci_dm644x() && + (win->layer == WIN_VID0 || + win->layer == WIN_VID1)) + lconfig->pixfmt = PIXFMT_RGB888; + break; + case 32: + if (cpu_is_davinci_dm355() && + (win->layer == WIN_OSD0 || win->layer == WIN_OSD1)) + lconfig->pixfmt = PIXFMT_RGB888; + break; + default: + break; + } + +bits_per_pixel_out: + if (!p || !opt) + return; + } + + /* framebuffer size */ + if (c == ',') { + p = strpbrk(opt, "@"); + if (p) + c = *p; + s = strsep(&opt, "@"); + if (s == NULL) + return; + if (*s) { + *fb_size = simple_strtoul(s, &s, 0); + if (*s == 'K') + *fb_size <<= 10; + if (*s == 'M') + *fb_size <<= 20; + } + if (!p || !opt) + return; + } + + /* xpos */ + if (c == '@') { + p = strpbrk(opt, ","); + if (p) + c = *p; + s = strsep(&opt, ","); + if (s == NULL) + return; + if (*s) + lconfig->xpos = simple_strtoul(s, NULL, 0); + if (!p || !opt) + return; + } + + /* ypos */ + if (c == ',') { + s = opt; + if (*s) + lconfig->ypos = simple_strtoul(s, NULL, 0); + } + + return; +} + +/* + * Pass boot-time options by adding the following string to the boot params: + * video=vpbe_fb:options + * Valid options: + * osd0=[MxNxP,S at X,Y] + * osd1=[MxNxP,S at X,Y] + * vid0=[off|MxNxP,S at X,Y] + * vid1=[off|MxNxP,S at X,Y] + * MxN are the horizontal and vertical window size + * P is the color depth (bits per pixel) + * S is the framebuffer size with a size suffix such as 'K' or 'M' + * X,Y are the window position + * + * Only video windows can be turned off. Turning off a video window means that + * no framebuffer device will be registered for it, + * + * To cause a window to be supported by the framebuffer driver but not displayed + * initially, pass a value of 0 struct vpbe_dm_win_info *win = info->par; + * struct vpbe_device *vpbe_dev = win->dm->vpbe_dev; for the window size. + * + * For example: + * video=vpbe_fb:osd0=720x480x16 at 0,0:osd1=720x480:vid0=off:vid1=off + * + * This routine returns 1 if the window is to be turned off, or 0 otherwise. + */ +static int vpbe_fb_get_default_win_config(struct device *dev, + struct vpbe_dm_win_info *win, + struct osd_layer_config *lconfig, + unsigned *fb_size, + const char *options) +{ + const char *win_names[] = { "osd0=", "vid0=", "osd1=", "vid1=" }; + static char opt_buf[128]; + const char *this_opt; + const char *next_opt; + int this_len; + int opt_len; + + /* supply default values for lconfig and fb_size */ + switch (win->layer) { + case WIN_OSD0: + lconfig->pixfmt = PIXFMT_RGB565; + lconfig->xsize = win->dm->mode.xres; + lconfig->ysize = win->dm->mode.yres; + break; + case WIN_OSD1: + lconfig->pixfmt = PIXFMT_OSD_ATTR; + lconfig->xsize = win->dm->mode.xres; + lconfig->ysize = win->dm->mode.yres; + break; + case WIN_VID0: + case WIN_VID1: + lconfig->pixfmt = win->dm->yc_pixfmt; + lconfig->xsize = 0; + lconfig->ysize = 0; + break; + } + lconfig->xpos = 0; + lconfig->ypos = 0; + + lconfig->interlaced = is_display_interlaced(&win->dm->mode); + *fb_size = vpbe_fb_max_screen_size(win->layer, &win->dm->mode); + + next_opt = options; + while ((this_opt = next_opt)) { + this_len = strcspn(this_opt, ":"); + next_opt = strpbrk(this_opt, ":"); + if (next_opt) + ++next_opt; + + opt_len = strlen(win_names[win->layer]); + if (this_len >= opt_len) { + if (strncmp(this_opt, win_names[win->layer], opt_len)) + continue; + this_len -= opt_len; + this_opt += opt_len; + if ((this_len >= strlen("off")) && + !strncmp(this_opt, "off", strlen("off"))) + return 1; + else { + strlcpy(opt_buf, this_opt, + min_t(int, sizeof(opt_buf), + this_len + 1)); + parse_win_params(win, lconfig, fb_size, + opt_buf); + return 0; + } + } + } + + return 0; +} + +/* + * Module parameter definitions + */ +static char *options = ""; + +module_param(options, charp, S_IRUGO); + +static int vpbe_fb_callback_init(struct device *dev, void *data) +{ + struct platform_device *pdev = to_platform_device(dev); + struct vpbe_dm_info *dm = (struct vpbe_dm_info *)data; + + if (strcmp("vpbe_controller", pdev->name) == 0) + dm->vpbe_dev = platform_get_drvdata(pdev); + return 0; +} + +static int vpbe_device_get(struct device *dev, void *data) +{ + struct platform_device *pdev = to_platform_device(dev); + if (strcmp("vpbe-osd", pdev->name) == 0) + osd_device = platform_get_drvdata(pdev); + + return 0; +} + +static int vpbe_fb_probe(struct platform_device *pdev) +{ + struct osd_layer_config lconfig; + struct device_driver *drv; + struct vpbe_dm_info *dm; + unsigned fb_size; + int err; + + dm = kzalloc(sizeof(*dm), GFP_KERNEL); + if (!dm) { + dev_err(&pdev->dev, "Can't allocate memory for driver state.\n"); + return -ENOMEM; + } + + /* + * Scan all the platform devices to find the vpbe + * controller device and get the vpbe_dev object + */ + drv = driver_find("vpbe_controller", &platform_bus_type); + err = driver_for_each_device(drv, NULL, dm, vpbe_fb_callback_init); + if ((err < 0) || (dm->vpbe_dev == NULL)) + return -ENODEV; + + if (!dm->vpbe_dev->initialized) { + dev_err(&pdev->dev, "vpbe controller not initialized\n"); + return -ENODEV; + } + + err = bus_for_each_dev(&platform_bus_type, NULL, NULL, + vpbe_device_get); + if (err < 0) + return err; + + platform_set_drvdata(pdev, dm); + + /* get the video mode from the encoder manager */ + get_video_mode(dm->vpbe_dev, &dm->mode); + + /* set the default Cb/Cr order */ + dm->yc_pixfmt = PIXFMT_YCbCrI; + + /* initialize OSD0 */ + dm->win[WIN_OSD0].layer = WIN_OSD0; + dm->win[WIN_OSD0].dm = dm; + dm->win[WIN_OSD0].sdram_address = 0; + vpbe_fb_get_default_win_config(&pdev->dev, &dm->win[WIN_OSD0], + &lconfig, &fb_size, options); + err = vpbe_fb_init_window(&pdev->dev, &dm->win[WIN_OSD0], + &lconfig, fb_size, OSD0_FBNAME); + if (err) + goto osd0_out; + + /* initialize VID0 */ + dm->win[WIN_VID0].layer = WIN_VID0; + dm->win[WIN_VID0].dm = dm; + dm->win[WIN_VID0].sdram_address = 0; + if (!vpbe_fb_get_default_win_config(&pdev->dev, &dm->win[WIN_VID0], + &lconfig, &fb_size, options)) { + err = vpbe_fb_init_window(&pdev->dev, &dm->win[WIN_VID0], + &lconfig, fb_size, VID0_FBNAME); + if (err) + goto vid0_out; + } + + /* initialize OSD1 */ + dm->win[WIN_OSD1].layer = WIN_OSD1; + dm->win[WIN_OSD1].dm = dm; + dm->win[WIN_OSD1].sdram_address = 0; + vpbe_fb_get_default_win_config(&pdev->dev, &dm->win[WIN_OSD1], + &lconfig, &fb_size, options); + err = + vpbe_fb_init_window(&pdev->dev, &dm->win[WIN_OSD1], + &lconfig, fb_size, OSD1_FBNAME); + if (err) + goto osd1_out; + + /* initialize VID1 */ + dm->win[WIN_VID1].layer = WIN_VID1; + dm->win[WIN_VID1].dm = dm; + dm->win[WIN_VID1].sdram_address = 0; + if (!vpbe_fb_get_default_win_config(&pdev->dev, &dm->win[WIN_VID1], + &lconfig, &fb_size, options)) { + err = vpbe_fb_init_window(&pdev->dev, &dm->win[WIN_VID1], + &lconfig, fb_size, VID1_FBNAME); + if (err) + goto vid1_out; + } + + /* initialize the vsync wait queue */ + init_waitqueue_head(&dm->vsync_wait); + dm->timeout = HZ / 5; + + /* register the end-of-frame callback */ + dm->vsync_callback.mask = VENC_FIRST_FIELD | + VENC_SECOND_FIELD | VENC_END_OF_FRAME; + + dm->vsync_callback.handler = vpbe_fb_vsync_callback; + dm->vsync_callback.arg = dm; + + v4l2_subdev_call(dm->vpbe_dev->venc, core, ioctl, + VENC_REG_CALLBACK, &dm->vsync_callback); + + printk(KERN_NOTICE "VPBE FB Driver probe success\n"); + return 0; + +vid1_out: + vpbe_fb_release_window(&pdev->dev, &dm->win[WIN_OSD1]); +osd1_out: + vpbe_fb_release_window(&pdev->dev, &dm->win[WIN_VID0]); +vid0_out: + vpbe_fb_release_window(&pdev->dev, &dm->win[WIN_OSD0]); +osd0_out: + kfree(dm); + + return err; +} + +static struct platform_driver vpbe_fb_driver = { + .driver = { + .name = "vpbe-fb", + .owner = THIS_MODULE, + .bus = &platform_bus_type, + }, + .probe = vpbe_fb_probe, + .remove = __devexit_p(vpbe_fb_remove), +}; + + +static int __init vpbe_fb_init(void) +{ +#ifndef MODULE + { + char *names[] = { "vpbe_fb", "dm64xxfb", "dm355fb" }; + int i, num_names = 3; + + for (i = 0; i < num_names; i++) { + if (fb_get_options(names[i], &options)) { + printk(KERN_ERR " Disabled on command-line.\n"); + return -ENODEV; + } + if (options) + break; + } + } +#endif + /* Register the driver with LDM */ + if (platform_driver_register(&vpbe_fb_driver)) { + printk(KERN_ERR "failed to register vpbe_fb driver\n"); + return -ENODEV; + } + return 0; +} + +static void __exit vpbe_fb_cleanup(void) +{ + platform_driver_unregister(&vpbe_fb_driver); +} + +module_init(vpbe_fb_init); +module_exit(vpbe_fb_cleanup); + +MODULE_DESCRIPTION("TI VPBE Framebuffer driver"); +MODULE_AUTHOR("Texas Instruments Ltd"); +MODULE_LICENSE("GPL"); diff --git a/drivers/media/video/davinci/vpbe_fb.h b/drivers/media/video/davinci/vpbe_fb.h new file mode 100644 index 0000000..4f312b7 --- /dev/null +++ b/drivers/media/video/davinci/vpbe_fb.h @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2009 MontaVista Software Inc. + * Copyright (C) 2006 Texas Instruments Inc + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option)any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef VPBE_FB_H +#define VPBE_FB_H + +#include +#include + +#define DAVINCIFB_NAME "davincifb" + +/* There are 4 framebuffer devices, one per window. */ +#define OSD0_FBNAME "dm_osd0_fb" +#define OSD1_FBNAME "dm_osd1_fb" +#define VID0_FBNAME "dm_vid0_fb" +#define VID1_FBNAME "dm_vid1_fb" + +/* Structure for each window */ +struct vpbe_dm_win_info { + struct fb_info *info; + struct vpbe_dm_info *dm; + enum osd_layer layer; + unsigned xpos; + unsigned ypos; + unsigned own_window; /* Does the framebuffer driver own this window? */ + unsigned display_window; + unsigned sdram_address; + unsigned int pseudo_palette[16]; +}; + +/* + * Structure for the driver holding information of windows, + * memory base addresses etc. + */ +struct vpbe_dm_info { + struct vpbe_dm_win_info win[4]; + + wait_queue_head_t vsync_wait; + unsigned int vsync_cnt; + int timeout; + struct venc_callback vsync_callback; + + unsigned char ram_clut[256][3]; + enum osd_pix_format yc_pixfmt; + + struct fb_videomode mode; + struct vpbe_device *vpbe_dev; +}; + +#endif /* ifndef DAVINCIFB__H */ diff --git a/drivers/media/video/davinci/vpbe_fb_ioctl.h b/drivers/media/video/davinci/vpbe_fb_ioctl.h new file mode 100644 index 0000000..1787e69 --- /dev/null +++ b/drivers/media/video/davinci/vpbe_fb_ioctl.h @@ -0,0 +1,159 @@ +/* + * Copyright (C) 2009 Texas Instruments Inc + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option)any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef DAVINCIFB_IOCTL_H +#define DAVINCIFB_IOCTL_H + +/* + * Structures and Union Definitions + */ + +struct zoom_params { + u_int32_t window_id; + u_int32_t zoom_h; + u_int32_t zoom_v; +}; + +/* Structure for transparency and the blending factor for the bitmap window */ +struct vpbe_bitmap_blend_params { + unsigned int colorkey; /* color key to be blended */ + unsigned int enable_colorkeying; /* enable color keying */ + unsigned int bf; /* valid range from 0 to 7 only. */ +}; + +/* Structure for window expansion */ +struct vpbe_win_expansion { + unsigned char horizontal; + unsigned char vertical; /* 1: Enable 0:disable */ +}; + +/* Structure for OSD window blinking options */ +struct vpbe_blink_option { + unsigned char blinking; /* 1: Enable blinking 0: Disable */ + unsigned int interval; /* Valid only if blinking is 1 */ +}; + +/* Structure for background color */ +struct vpbe_backg_color { + /* 2: RAM CLUT 1:ROM1 CLUT 0:ROM0 CLUT */ + unsigned char clut_select; + unsigned char color_offset; /* index of color */ +}; + +/* Structure for Video window configurable parameters */ +struct vpbe_video_config_params { + /* Cb/Cr order in input data for a pixel. */ + unsigned char cb_cr_order; /* 0: cb cr 1: cr cb */ + /* HZ/VT Expansion enable disable */ + struct vpbe_win_expansion exp_info; +}; + +/* + * Union of structures giving the CLUT index for the 1, 2, 4 bit bitmap values + */ +union vpbe_clut_idx { + struct _for_4bit_bitmap { + unsigned char bitmap_val_0; + unsigned char bitmap_val_1; + unsigned char bitmap_val_2; + unsigned char bitmap_val_3; + unsigned char bitmap_val_4; + unsigned char bitmap_val_5; + unsigned char bitmap_val_6; + unsigned char bitmap_val_7; + unsigned char bitmap_val_8; + unsigned char bitmap_val_9; + unsigned char bitmap_val_10; + unsigned char bitmap_val_11; + unsigned char bitmap_val_12; + unsigned char bitmap_val_13; + unsigned char bitmap_val_14; + unsigned char bitmap_val_15; + } for_4bit_bitmap; + struct _for_2bit_bitmap { + unsigned char bitmap_val_0; + unsigned char dummy0[4]; + unsigned char bitmap_val_1; + unsigned char dummy1[4]; + unsigned char bitmap_val_2; + unsigned char dummy2[4]; + unsigned char bitmap_val_3; + } for_2bit_bitmap; + struct _for_1bit_bitmap { + unsigned char bitmap_val_0; + unsigned char dummy0[14]; + unsigned char bitmap_val_1; + } for_1bit_bitmap; +}; + +/* Structure for bitmap window configurable parameters */ +struct vpbe_bitmap_config_params { + /* Only for bitmap width = 1,2,4 bits */ + union vpbe_clut_idx clut_idx; + /* Attenuation value for YUV o/p for bitmap window */ + unsigned char attenuation_enable; + /* 0: ROM DM270, 1:ROM DM320, 2:RAM CLUT */ + unsigned char clut_select; +}; + +/* Structure to hold window position */ +struct vpbe_window_position { + unsigned int xpos; /* X position of the window */ + unsigned int ypos; /* Y position of the window */ +}; + +#define RAM_CLUT_SIZE (256*3) + +#define FBIO_SETATTRIBUTE _IOW('F', 0x21, struct fb_fillrect) +#define FBIO_SETPOSX _IOW('F', 0x22, u_int32_t) +#define FBIO_SETPOSY _IOW('F', 0x23, u_int32_t) +#define FBIO_SETZOOM _IOW('F', 0x24, struct zoom_params) +#define FBIO_ENABLE_DISABLE_WIN \ + _IOW('F', 0x30, unsigned char) +#define FBIO_SET_BITMAP_BLEND_FACTOR \ + _IOW('F', 0x31, struct vpbe_bitmap_blend_params) +#define FBIO_SET_BITMAP_WIN_RAM_CLUT \ + _IOW('F', 0x32, unsigned char[RAM_CLUT_SIZE]) +#define FBIO_ENABLE_DISABLE_ATTRIBUTE_WIN \ + _IOW('F', 0x33, unsigned int) +#define FBIO_GET_BLINK_INTERVAL \ + _IOR('F', 0x34, struct vpbe_blink_option) +#define FBIO_SET_BLINK_INTERVAL \ + _IOW('F', 0x35, struct vpbe_blink_option) +#define FBIO_GET_VIDEO_CONFIG_PARAMS \ + _IOR('F', 0x36, struct vpbe_video_config_params) +#define FBIO_SET_VIDEO_CONFIG_PARAMS \ + _IOW('F', 0x37, struct vpbe_video_config_params) +#define FBIO_GET_BITMAP_CONFIG_PARAMS \ + _IOR('F', 0x38, struct vpbe_bitmap_config_params) +#define FBIO_SET_BITMAP_CONFIG_PARAMS \ + _IOW('F', 0x39, struct vpbe_bitmap_config_params) +#define FBIO_SET_BACKG_COLOR \ + _IOW('F', 0x47, struct vpbe_backg_color) +#define FBIO_SETPOS \ + _IOW('F', 0x49, u_int32_t) +#define FBIO_SET_CURSOR \ + _IOW('F', 0x50, struct fb_cursor) + +/* Window ID definitions */ +#define OSD0 0 +#define VID0 1 +#define OSD1 2 +#define VID1 3 + +#endif /* ifndef DAVINCIFB_IOCTL_H */ -- 1.6.2.4 From sakari.ailus at iki.fi Tue Sep 27 09:01:35 2011 From: sakari.ailus at iki.fi (Sakari Ailus) Date: Tue, 27 Sep 2011 17:01:35 +0300 Subject: [PATCH v2 3/8] davinci: vpfe: add IPIPE support for media controller driver In-Reply-To: <1314630439-1122-4-git-send-email-manjunath.hadli@ti.com> References: <1314630439-1122-1-git-send-email-manjunath.hadli@ti.com> <1314630439-1122-4-git-send-email-manjunath.hadli@ti.com> Message-ID: <4E81D73F.7000601@iki.fi> Hi Manju, My apologies for the very late review for these patches. A general comment: all the functions that do need to use device specific information must take the device as a parameter. Look at the OMAP 3 ISP driver for an example. Manjunath Hadli wrote: > From: Nagabhushana Netagunte > > Add the IPIPE interfacing layer to the vpfe driver. This patch adds dm365 > specific implementation of the genric imp_hw_interface interface for > programming the IPIPE block, mainly setting the resizer and previewer > configuration parameters. This is built as an independent module. > > Signed-off-by: Manjunath Hadli > Signed-off-by: Nagabhushana Netagunte > --- > drivers/media/video/davinci/dm365_def_para.c | 486 ++++ > drivers/media/video/davinci/dm365_def_para.h | 39 + > drivers/media/video/davinci/dm365_ipipe.c | 3966 ++++++++++++++++++++++++++ > drivers/media/video/davinci/dm365_ipipe.h | 300 ++ > drivers/media/video/davinci/imp_common.h | 85 + > drivers/media/video/davinci/imp_hw_if.h | 178 ++ > 6 files changed, 5054 insertions(+), 0 deletions(-) > create mode 100644 drivers/media/video/davinci/dm365_def_para.c > create mode 100644 drivers/media/video/davinci/dm365_def_para.h > create mode 100644 drivers/media/video/davinci/dm365_ipipe.c > create mode 100644 drivers/media/video/davinci/dm365_ipipe.h > create mode 100644 drivers/media/video/davinci/imp_common.h > create mode 100644 drivers/media/video/davinci/imp_hw_if.h > > diff --git a/drivers/media/video/davinci/dm365_def_para.c b/drivers/media/video/davinci/dm365_def_para.c > new file mode 100644 > index 0000000..d5af73b > --- /dev/null > +++ b/drivers/media/video/davinci/dm365_def_para.c > @@ -0,0 +1,486 @@ > +/* > +* Copyright (C) 2011 Texas Instruments Inc > +* > +* This program is free software; you can redistribute it and/or > +* modify it under the terms of the GNU General Public License as > +* published by the Free Software Foundation version 2. > +* > +* This program is distributed in the hope that it will be useful, > +* but WITHOUT ANY WARRANTY; without even the implied warranty of > +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > +* GNU General Public License for more details. > +* > +* You should have received a copy of the GNU General Public License > +* along with this program; if not, write to the Free Software > +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA > +*/ > +#include > +#include > +#include "dm365_ipipe.h" > + > +/* Defaults for lutdpc */ > +struct prev_lutdpc dm365_lutdpc_defaults = { > + .en = 0 > +}; > + > +/* Defaults for otfdpc */ > +struct prev_lutdpc dm365_otfdpc_defaults = { > + .en = 0 > +}; > + > +/* Defaults for 2D - nf */ > +struct prev_nf dm365_nf_defaults = { > + .en = 0 > +}; > + > +/* defaults for GIC */ > +struct prev_gic dm365_gic_defaults = { > + .en = 0 > +}; > + > +/* Defaults for white balance */ > +struct prev_wb dm365_wb_defaults = { > + .gain_r = {2, 0x00}, > + .gain_gr = {2, 0x00}, > + .gain_gb = {2, 0x00}, > + .gain_b = {2, 0x00} > +}; > + > +/* Defaults for CFA */ > +struct prev_cfa dm365_cfa_defaults = { > + .alg = IPIPE_CFA_ALG_2DIRAC, > + .hpf_thr_2dir = 0, > + .hpf_slp_2dir = 0, > + .hp_mix_thr_2dir = 0, > + .hp_mix_slope_2dir = 0, > + .dir_thr_2dir = 0, > + .dir_slope_2dir = 0, > + .nd_wt_2dir = 0, > + .hue_fract_daa = 0, > + .edge_thr_daa = 0, > + .thr_min_daa = 0, > + .thr_slope_daa = 0, > + .slope_min_daa = 0, > + .slope_slope_daa = 0, > + .lp_wt_daa = 0 > +}; Statically allocated memory is zero by default. You might want to do this kind of initisation in a function initialising the device specific structures rather than storing defaults to memory as almost all of this is zeros. > +/* Defaults for rgb2rgb */ > +struct prev_rgb2rgb dm365_rgb2rgb_defaults = { > + .coef_rr = {1, 0}, /* 256 */ > + .coef_gr = {0, 0}, > + .coef_br = {0, 0}, > + .coef_rg = {0, 0}, > + .coef_gg = {1, 0}, /* 256 */ > + .coef_bg = {0, 0}, > + .coef_rb = {0, 0}, > + .coef_gb = {0, 0}, > + .coef_bb = {1, 0}, /* 256 */ > + .out_ofst_r = 0, > + .out_ofst_g = 0, > + .out_ofst_b = 0 > +}; > + > +/* Defaults for gamma correction */ > +struct prev_gamma dm365_gamma_defaults = { > + .bypass_r = 0, > + .bypass_b = 0, > + .bypass_g = 0, > + .tbl_sel = IPIPE_GAMMA_TBL_ROM > +}; > + > +/* Defaults for 3d lut */ > +struct prev_3d_lut dm365_3d_lut_defaults = { > + .en = 0 > +}; > + > +/* Defaults for lumina adjustments */ > +struct prev_lum_adj dm365_lum_adj_defaults = { > + .brightness = 0, > + .contrast = 16 > +}; This should probably be implemented as V4L2 controls. There are control ids for both brightness and contrast. > +/* Defaults for rgb2yuv conversion */ > +struct prev_rgb2yuv dm365_rgb2yuv_defaults = { > + .coef_ry = {0, 0x4D}, > + .coef_gy = {0, 0x96}, > + .coef_by = {0, 0x1D}, > + .coef_rcb = {0xF, 0xD5}, > + .coef_gcb = {0xF, 0xAB}, > + .coef_bcb = {0, 0x80}, > + .coef_rcr = {0, 0x80}, > + .coef_gcr = {0xF, 0x95}, > + .coef_bcr = {0xF, 0xEB}, > + .out_ofst_y = 0, > + .out_ofst_cb = 0x80, > + .out_ofst_cr = 0x80 > +}; Lower case hexadecimals, please. > +/* Defaults for GBCE */ > +struct prev_gbce dm365_gbce_defaults = { > + .en = 0 > +}; > + > +/* Defaults for yuv 422 conversion */ > +struct prev_yuv422_conv dm365_yuv422_conv_defaults = { > + .en_chrom_lpf = 0, > + .chrom_pos = IPIPE_YUV422_CHR_POS_COSITE > +}; > + > +/* Defaults for Edge Ehnancements */ > +struct prev_yee dm365_yee_defaults = { > + .en = 0, > +}; > + > +/* Defaults for CAR conversion */ > +struct prev_car dm365_car_defaults = { > + .en = 0, > +}; > + > +/* Defaults for CGS */ > +struct prev_cgs dm365_cgs_defaults = { > + .en = 0, > +}; > + > +#define WIDTH_I 640 > +#define HEIGHT_I 480 > +#define WIDTH_O 640 > +#define HEIGHT_O 480 Is the image size that this hardware block process static? > +/* default ipipeif settings */ > +struct ipipeif_5_1 ipipeif_5_1_defaults = { > + .pack_mode = IPIPEIF_5_1_PACK_16_BIT, > + .data_shift = IPIPEIF_BITS11_0, > + .source1 = IPIPEIF_SRC1_PARALLEL_PORT, > + .clk_div = { > + .m = 1, /* clock = sdram clock * (m/n) */ > + .n = 6 > + }, > + .dpc = { > + .en = 0, > + }, > + .dpcm = { > + .en = 0, > + .type = IPIPEIF_DPCM_8BIT_12BIT, > + .pred = IPIPEIF_DPCM_SIMPLE_PRED > + }, > + .pix_order = IPIPEIF_CBCR_Y, > + .isif_port = { > + .if_type = V4L2_MBUS_FMT_SBGGR10_1X10, > + .hdpol = VPFE_PINPOL_POSITIVE, > + .vdpol = VPFE_PINPOL_POSITIVE > + }, > + .clip = 4095, > + .align_sync = 0, > + .rsz_start = 0, > + .df_gain_en = 0 > +}; > + > +struct ipipe_params dm365_ipipe_defs = { > + .ipipeif_param = { > + .mode = IPIPEIF_ONE_SHOT, > + .source = IPIPEIF_SDRAM_RAW, > + .clock_select = IPIPEIF_SDRAM_CLK, > + .glob_hor_size = WIDTH_I + 8, > + .glob_ver_size = HEIGHT_I + 10, > + .hnum = WIDTH_I, > + .vnum = HEIGHT_I, > + .adofs = WIDTH_I * 2, > + .rsz = 16, /* resize ratio 16/rsz */ > + .decimation = IPIPEIF_DECIMATION_OFF, > + .avg_filter = IPIPEIF_AVG_OFF, > + .gain = 0x200, /* U10Q9 */ > + }, > + .ipipe_mode = IPIPEIF_ONE_SHOT, > + .ipipe_dpaths_fmt = IPIPE_RAW2YUV, > + .ipipe_colpat_olop = IPIPE_GREEN_BLUE, > + .ipipe_colpat_olep = IPIPE_BLUE, > + .ipipe_colpat_elop = IPIPE_RED, > + .ipipe_colpat_elep = IPIPE_GREEN_RED, > + .ipipe_vps = 0, > + .ipipe_vsz = HEIGHT_I - 1, > + .ipipe_hps = 0, > + .ipipe_hsz = WIDTH_I - 1, > + .rsz_common = { > + .vps = 0, > + .vsz = HEIGHT_I - 1, > + .hps = 0, > + .hsz = WIDTH_I - 1, > + .src_img_fmt = RSZ_IMG_422, > + .y_c = 0, > + .raw_flip = 1, /* flip preserve Raw format */ > + .source = IPIPE_DATA, > + .passthrough = IPIPE_BYPASS_OFF, > + .yuv_y_min = 0, > + .yuv_y_max = 255, > + .yuv_c_min = 0, > + .yuv_c_max = 255, > + .rsz_seq_crv = DISABLE, > + .out_chr_pos = IPIPE_YUV422_CHR_POS_COSITE > + }, > + .rsz_rsc_param = { > + { > + .mode = IPIPEIF_ONE_SHOT, > + .h_flip = DISABLE, > + .v_flip = DISABLE, > + .cen = DISABLE, > + .yen = DISABLE, > + .i_vps = 0, > + .i_hps = 0, > + .o_vsz = HEIGHT_O - 1, > + .o_hsz = WIDTH_O - 1, > + .v_phs_y = 0, > + .v_phs_c = 0, > + .v_dif = 256, > + .v_typ_y = RSZ_INTP_CUBIC, > + .h_typ_c = RSZ_INTP_CUBIC, > + .v_lpf_int_y = 0, > + .v_lpf_int_c = 0, > + .h_phs = 0, > + .h_dif = 256, > + .h_typ_y = RSZ_INTP_CUBIC, > + .h_typ_c = RSZ_INTP_CUBIC, > + .h_lpf_int_y = 0, > + .h_lpf_int_c = 0, > + .dscale_en = 0, > + .h_dscale_ave_sz = IPIPE_DWN_SCALE_1_OVER_2, > + .v_dscale_ave_sz = IPIPE_DWN_SCALE_1_OVER_2, > + .f_div.en = 0 > + }, > + { > + .mode = IPIPEIF_ONE_SHOT, > + .h_flip = DISABLE, > + .v_flip = DISABLE, > + .cen = DISABLE, > + .yen = DISABLE, > + .i_vps = 0, > + .i_hps = 0, > + .o_vsz = HEIGHT_O - 1, > + .o_hsz = WIDTH_O - 1, > + .v_phs_y = 0, > + .v_phs_c = 0, > + .v_dif = 256, > + .v_typ_y = RSZ_INTP_CUBIC, > + .h_typ_c = RSZ_INTP_CUBIC, > + .v_lpf_int_y = 0, > + .v_lpf_int_c = 0, > + .h_phs = 0, > + .h_dif = 256, > + .h_typ_y = RSZ_INTP_CUBIC, > + .h_typ_c = RSZ_INTP_CUBIC, > + .h_lpf_int_y = 0, > + .h_lpf_int_c = 0, > + .dscale_en = 0, > + .h_dscale_ave_sz = IPIPE_DWN_SCALE_1_OVER_2, > + .v_dscale_ave_sz = IPIPE_DWN_SCALE_1_OVER_2, > + .f_div.en = 0 > + }, > + }, > + .rsz2rgb = { > + { > + .rgb_en = DISABLE > + }, > + { > + .rgb_en = DISABLE > + } > + }, > + .ext_mem_param = { > + { > + .rsz_sdr_oft_y = WIDTH_O << 1, > + .rsz_sdr_ptr_s_y = 0, > + .rsz_sdr_ptr_e_y = HEIGHT_O, > + .rsz_sdr_oft_c = WIDTH_O, > + .rsz_sdr_ptr_s_c = 0, > + .rsz_sdr_ptr_e_c = HEIGHT_O >> 1, > + .flip_ofst_y = 0, > + .flip_ofst_c = 0, > + .c_offset = 0, > + .user_y_ofst = 0, > + .user_c_ofst = 0 > + }, > + { > + .rsz_sdr_oft_y = WIDTH_O << 1, > + .rsz_sdr_ptr_s_y = 0, > + .rsz_sdr_ptr_e_y = HEIGHT_O, > + .rsz_sdr_oft_c = WIDTH_O, > + .rsz_sdr_ptr_s_c = 0, > + .rsz_sdr_ptr_e_c = HEIGHT_O, > + .flip_ofst_y = 0, > + .flip_ofst_c = 0, > + .c_offset = 0, > + .user_y_ofst = 0, > + .user_c_ofst = 0 > + }, > + }, > + .rsz_en[0] = ENABLE, > + .rsz_en[1] = DISABLE > +}; > + > +struct prev_single_shot_config dm365_prev_ss_config_defs = { > + .bypass = IPIPE_BYPASS_OFF, > + .input = { > + .image_width = WIDTH_I, > + .image_height = HEIGHT_I, > + .vst = 0, > + .hst = 0, > + .ppln = WIDTH_I + 8, > + .lpfr = HEIGHT_I + 10, > + .pred = IPIPEIF_DPCM_SIMPLE_PRED, > + .clk_div = {1, 6}, > + .data_shift = IPIPEIF_BITS11_0, > + .dec_en = 0, > + .rsz = 16, /* resize ratio 16/rsz */ > + .frame_div_mode_en = 0, > + .avg_filter_en = IPIPEIF_AVG_OFF, > + .dpc = {0, 0}, > + .gain = 512, > + .clip = 4095, > + .align_sync = 0, > + .rsz_start = 0, > + .pix_fmt = IPIPE_BAYER, > + .colp_olop = IPIPE_GREEN_BLUE, > + .colp_olep = IPIPE_BLUE, > + .colp_elop = IPIPE_RED, > + .colp_elep = IPIPE_GREEN_RED > + }, > + .output = { > + .pix_fmt = IPIPE_UYVY > + } > +}; > + > +struct prev_continuous_config dm365_prev_cont_config_defs = { > + .bypass = IPIPE_BYPASS_OFF, > + .input = { > + .en_df_sub = 0, > + .dec_en = 0, > + .rsz = 16, > + .avg_filter_en = IPIPEIF_AVG_OFF, > + .gain = 512, > + .clip = 4095, > + .colp_olop = IPIPE_GREEN_BLUE, > + .colp_olep = IPIPE_BLUE, > + .colp_elop = IPIPE_RED, > + .colp_elep = IPIPE_GREEN_RED > + }, > +}; > + > +struct rsz_single_shot_config dm365_rsz_ss_config_defs = { > + .input = { > + .image_width = WIDTH_I, > + .image_height = HEIGHT_I, > + .vst = 0, > + .hst = 0, > + .ppln = WIDTH_I + 8, > + .lpfr = HEIGHT_I + 10, > + .clk_div = {1, 6}, > + .dec_en = 0, > + .rsz = 16, /* resize ratio 16/rsz */ > + .frame_div_mode_en = 0, > + .avg_filter_en = IPIPEIF_AVG_OFF, > + .align_sync = 0, > + .rsz_start = 0, > + .pix_fmt = IPIPE_UYVY > + }, > + .output1 = { > + .enable = 1, > + .pix_fmt = IPIPE_UYVY, > + .h_flip = 0, > + .v_flip = 0, > + .width = WIDTH_O, > + .height = HEIGHT_O, > + .vst_y = 0, > + .vst_c = 0, > + .v_typ_y = RSZ_INTP_CUBIC, > + .v_typ_c = RSZ_INTP_CUBIC, > + .v_lpf_int_y = 0, > + .v_lpf_int_c = 0, > + .h_typ_y = RSZ_INTP_CUBIC, > + .h_typ_c = RSZ_INTP_CUBIC, > + .h_lpf_int_y = 0, > + .h_lpf_int_c = 0, > + .en_down_scale = 0, > + .h_dscale_ave_sz = IPIPE_DWN_SCALE_1_OVER_2, > + .v_dscale_ave_sz = IPIPE_DWN_SCALE_1_OVER_2, > + .user_y_ofst = 0, > + .user_c_ofst = 0 > + }, > + .output2 = { > + .enable = 1, > + .pix_fmt = IPIPE_UYVY, > + .h_flip = 0, > + .v_flip = 0, > + .width = WIDTH_O, > + .height = HEIGHT_O, > + .vst_y = 0, > + .vst_c = 0, > + .v_typ_y = RSZ_INTP_CUBIC, > + .v_typ_c = RSZ_INTP_CUBIC, > + .v_lpf_int_y = 0, > + .v_lpf_int_c = 0, > + .h_typ_y = RSZ_INTP_CUBIC, > + .h_typ_c = RSZ_INTP_CUBIC, > + .h_lpf_int_y = 0, > + .h_lpf_int_c = 0, > + .en_down_scale = 0, > + .h_dscale_ave_sz = IPIPE_DWN_SCALE_1_OVER_2, > + .v_dscale_ave_sz = IPIPE_DWN_SCALE_1_OVER_2, > + .user_y_ofst = 0, > + .user_c_ofst = 0 > + }, > + .chroma_sample_even = 0, > + .yuv_y_min = 0, > + .yuv_y_max = 255, > + .yuv_c_min = 0, > + .yuv_c_max = 255, > + .out_chr_pos = IPIPE_YUV422_CHR_POS_COSITE, > +}; > + > +struct rsz_continuous_config dm365_rsz_cont_config_defs = { > + .output1 = { > + .enable = 1, > + .h_flip = 0, > + .v_flip = 0, > + .v_typ_y = RSZ_INTP_CUBIC, > + .v_typ_c = RSZ_INTP_CUBIC, > + .v_lpf_int_y = 0, > + .v_lpf_int_c = 0, > + .h_typ_y = RSZ_INTP_CUBIC, > + .h_typ_c = RSZ_INTP_CUBIC, > + .h_lpf_int_y = 0, > + .h_lpf_int_c = 0, > + .en_down_scale = 0, > + .h_dscale_ave_sz = IPIPE_DWN_SCALE_1_OVER_2, > + .v_dscale_ave_sz = IPIPE_DWN_SCALE_1_OVER_2, > + .user_y_ofst = 0, > + .user_c_ofst = 0 > + }, > + .output2 = { > + .enable = 1, > + .pix_fmt = IPIPE_UYVY, > + .h_flip = 0, > + .v_flip = 0, > + .width = WIDTH_O, > + .height = HEIGHT_O, > + .vst_y = 0, > + .vst_c = 0, > + .v_typ_y = RSZ_INTP_CUBIC, > + .v_typ_c = RSZ_INTP_CUBIC, > + .v_lpf_int_y = 0, > + .v_lpf_int_c = 0, > + .h_typ_y = RSZ_INTP_CUBIC, > + .h_typ_c = RSZ_INTP_CUBIC, > + .h_lpf_int_y = 0, > + .h_lpf_int_c = 0, > + .en_down_scale = 0, > + .h_dscale_ave_sz = IPIPE_DWN_SCALE_1_OVER_2, > + .v_dscale_ave_sz = IPIPE_DWN_SCALE_1_OVER_2, > + .user_y_ofst = 0, > + .user_c_ofst = 0 > + }, > + .chroma_sample_even = 0, > + .yuv_y_min = 0, > + .yuv_y_max = 255, > + .yuv_c_min = 0, > + .yuv_c_max = 255, > + .out_chr_pos = IPIPE_YUV422_CHR_POS_COSITE, > +}; > diff --git a/drivers/media/video/davinci/dm365_def_para.h b/drivers/media/video/davinci/dm365_def_para.h > new file mode 100644 > index 0000000..872b3cb > --- /dev/null > +++ b/drivers/media/video/davinci/dm365_def_para.h > @@ -0,0 +1,39 @@ > +/* > + * Copyright (C) 2011 Texas Instruments Inc > + * > + * This program is free software; you can redistribute it and/or > + * modify it under the terms of the GNU General Public License as > + * published by the Free Software Foundation version 2. > + * > + * This program is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > + * GNU General Public License for more details. > + * > + * You should have received a copy of the GNU General Public License > + * along with this program; if not, write to the Free Software > + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA > + */ > +#include "dm365_ipipe.h" > +extern struct prev_lutdpc dm365_lutdpc_defaults; > +extern struct prev_otfdpc dm365_otfdpc_defaults; > +extern struct prev_nf dm365_nf_defaults; > +extern struct prev_gic dm365_gic_defaults; > +extern struct prev_wb dm365_wb_defaults; > +extern struct prev_cfa dm365_cfa_defaults; > +extern struct prev_rgb2rgb dm365_rgb2rgb_defaults; > +extern struct prev_gamma dm365_gamma_defaults; > +extern struct prev_3d_lut dm365_3d_lut_defaults; > +extern struct prev_lum_adj dm365_lum_adj_defaults; > +extern struct prev_rgb2yuv dm365_rgb2yuv_defaults; > +extern struct prev_yuv422_conv dm365_yuv422_conv_defaults; > +extern struct prev_gbce dm365_gbce_defaults; > +extern struct prev_yee dm365_yee_defaults; > +extern struct prev_car dm365_car_defaults; > +extern struct prev_cgs dm365_cgs_defaults; > +extern struct ipipe_params dm365_ipipe_defs; > +extern struct prev_single_shot_config dm365_prev_ss_config_defs; > +extern struct prev_continuous_config dm365_prev_cont_config_defs; > +extern struct rsz_single_shot_config dm365_rsz_ss_config_defs; > +extern struct rsz_continuous_config dm365_rsz_cont_config_defs; > +extern struct ipipeif_5_1 ipipeif_5_1_defaults; > diff --git a/drivers/media/video/davinci/dm365_ipipe.c b/drivers/media/video/davinci/dm365_ipipe.c > new file mode 100644 > index 0000000..9f41784 > --- /dev/null > +++ b/drivers/media/video/davinci/dm365_ipipe.c > @@ -0,0 +1,3966 @@ > +/* > +* Copyright (C) 2011 Texas Instruments Inc > +* > +* This program is free software; you can redistribute it and/or > +* modify it under the terms of the GNU General Public License as > +* published by the Free Software Foundation version 2. > +* > +* This program is distributed in the hope that it will be useful, > +* but WITHOUT ANY WARRANTY; without even the implied warranty of > +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > +* GNU General Public License for more details. > +* > +* You should have received a copy of the GNU General Public License > +* along with this program; if not, write to the Free Software > +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA > +*/ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include "dm365_ipipe.h" > +#include "imp_hw_if.h" > + > +#include "dm365_ipipe_hw.h" > +#include "dm365_def_para.h" > + > +/* IPIPE module operation state */ > +struct ipipe_oper_state { > + /* Operation state in continuous mode */ > + unsigned int state; What does operation state mean and which values are possible? > + /* Semaphore to protect the common hardware configuration */ > + struct mutex lock; > + /* previewer config state */ > + unsigned int prev_config_state; > + /* Shared configuration of the hardware */ > + struct ipipe_params *shared_config_param; > + /* shared resource in use */ > + unsigned int resource_in_use; > + /* resizer config state */ > + unsigned int rsz_config_state; > + /* resizer chained with previewer */ > + unsigned int rsz_chained; > + /* Buffer type, interleaved or field seperated for interlaced > + * scan > + */ > + unsigned int buffer_type; > + /* frame format, 0 - interlaced, 1 - progressive */ > + unsigned int frame_format; > + /* input pixel format */ > + enum imp_pix_formats in_pixel_format; > + /* input pixel format */ > + enum imp_pix_formats out_pixel_format; How about using v4l2_mbus_pixelcode instead? Or does using imp_pix_formats have an advantage that I can't see? > +}; > + > +/* Operation mode of image processor (imp) */ > +static u32 oper_mode = IMP_MODE_NOT_CONFIGURED; > +/* enable/disable serializer */ > +static u32 en_serializer; > + > +#define CONFIG_IPIPE_PARAM_VALIDATION > +/* ipipe module operation state & configuration */ > +static struct ipipe_oper_state oper_state; > + > +/* LUT Defect pixel correction data */ > +static struct prev_lutdpc lutdpc; > + > +/* LUT Defect pixel correction data */ > +static struct prev_otfdpc otfdpc; > + > +/* Noise filter */ > +static struct prev_nf nf1; > +static struct prev_nf nf2; > + > +/* Green Imbalance Correction */ > +static struct prev_gic gic; > + > +/* White Balance */ > +static struct prev_wb wb; > + > +/* CFA */ > +static struct prev_cfa cfa; > + > +/* RGB2RGB conversion */ > +static struct prev_rgb2rgb rgb2rgb_1; > +static struct prev_rgb2rgb rgb2rgb_2; > + > +/* Gamma correction */ > +static struct prev_gamma gamma; > + > +/* 3D LUT */ > +static struct prev_3d_lut lut_3d; > + > +/* Lumina Adjustment */ > +static struct prev_lum_adj lum_adj; > + > +/* RGB2YUV conversion */ > +static struct prev_rgb2yuv rgb2yuv; > + > +/* YUV 422 conversion */ > +static struct prev_yuv422_conv yuv422_conv; > + > +/* GBCE */ > +static struct prev_gbce gbce; > + > +/* Edge Enhancement */ > +static struct prev_yee yee; > + > +/* Chromatic Artifact Reduction, CAR */ > +static struct prev_car car; > + > +/* Chromatic Artifact Reduction, CAR */ > +static struct prev_cgs cgs; > + > +/* Tables for various tuning modules */ > +static struct ipipe_lutdpc_entry ipipe_lutdpc_table[MAX_SIZE_DPC]; > +static struct ipipe_3d_lut_entry ipipe_3d_lut_table[MAX_SIZE_3D_LUT]; > +static unsigned short ipipe_gbce_table[MAX_SIZE_GBCE_LUT]; > +static struct ipipe_gamma_entry ipipe_gamma_table_r[MAX_SIZE_GAMMA]; > +static struct ipipe_gamma_entry ipipe_gamma_table_b[MAX_SIZE_GAMMA]; > +static struct ipipe_gamma_entry ipipe_gamma_table_g[MAX_SIZE_GAMMA]; > +static short ipipe_yee_table[MAX_SIZE_YEE_LUT]; > + > +/* Raw YUV formats */ > +static u32 ipipe_raw_yuv_pix_formats[] = { V4L2_PIX_FMT_UYVY, > + V4L2_PIX_FMT_NV12}; Shouldn't all this be part of the device specific structure? > +static int ipipe_enum_pix(u32 *pix, int i) > +{ > + if (i >= ARRAY_SIZE(ipipe_raw_yuv_pix_formats)) > + return -EINVAL; > + > + *pix = ipipe_raw_yuv_pix_formats[i]; > + return 0; > +} > + > +/* IPIPE hardware limits */ > +#define IPIPE_MAX_OUTPUT_WIDTH_A 2176 > +#define IPIPE_MAX_OUTPUT_WIDTH_B 640 > + > +static int ipipe_get_max_output_width(int rsz) > +{ > + if (rsz == RSZ_A) > + return IPIPE_MAX_OUTPUT_WIDTH_A; > + return IPIPE_MAX_OUTPUT_WIDTH_B; > +} > + > +/* Based on max resolution supported. QXGA */ > +#define IPIPE_MAX_OUTPUT_HEIGHT_A 1536 > +/* Based on max resolution supported. VGA */ > +#define IPIPE_MAX_OUTPUT_HEIGHT_B 480 > + > +static int ipipe_get_max_output_height(int rsz) > +{ > + if (rsz == RSZ_A) > + return IPIPE_MAX_OUTPUT_HEIGHT_A; > + return IPIPE_MAX_OUTPUT_HEIGHT_B; > +} > + > +static int ipipe_serialize(void) > +{ > + return en_serializer; > +} > + > +static int ipipe_set_ipipe_if_address(void *config, unsigned int address) address should probably be u32. > +{ > + struct ipipeif *if_params; > + > + if (ISNULL(config)) > + return -EINVAL; Please just use !config or config == NULL. > + if_params = &((struct ipipe_params *)config)->ipipeif_param; > + > + return ipipeif_set_address(if_params, address); > +} > + > +static void ipipe_lock_chain(void) > +{ > + mutex_lock(&oper_state.lock); > + oper_state.resource_in_use = 1; > + mutex_unlock(&oper_state.lock); > +} > + > +static void ipipe_unlock_chain(void) > +{ > + mutex_lock(&oper_state.lock); > + oper_state.resource_in_use = 0; > + oper_state.prev_config_state = STATE_NOT_CONFIGURED; > + oper_state.rsz_config_state = STATE_NOT_CONFIGURED; > + oper_state.rsz_chained = 0; > + mutex_unlock(&oper_state.lock); > +} > +static int ipipe_process_pix_fmts(enum ipipe_pix_formats in_pix_fmt, > + enum ipipe_pix_formats out_pix_fmt, > + struct ipipe_params *param) > +{ > + enum ipipe_pix_formats temp_pix_fmt; > + > + switch (in_pix_fmt) { > + case IPIPE_BAYER_8BIT_PACK: > + temp_pix_fmt = IPIPE_BAYER; > + param->ipipeif_param.var.if_5_1.pack_mode > + = IPIPEIF_5_1_PACK_8_BIT; > + break; > + case IPIPE_BAYER_8BIT_PACK_ALAW: > + param->ipipeif_param.var.if_5_1.pack_mode > + = IPIPEIF_5_1_PACK_8_BIT_A_LAW; > + temp_pix_fmt = IPIPE_BAYER; > + break; > + case IPIPE_BAYER_8BIT_PACK_DPCM: > + param->ipipeif_param.var.if_5_1.pack_mode > + = IPIPEIF_5_1_PACK_8_BIT; > + param->ipipeif_param.var.if_5_1.dpcm.en = 1; > + temp_pix_fmt = IPIPE_BAYER; > + break; > + case IPIPE_BAYER: > + param->ipipeif_param.var.if_5_1.pack_mode > + = IPIPEIF_5_1_PACK_16_BIT; > + temp_pix_fmt = IPIPE_BAYER; > + break; > + case IPIPE_BAYER_12BIT_PACK: > + param->ipipeif_param.var.if_5_1.pack_mode > + = IPIPEIF_5_1_PACK_12_BIT; > + temp_pix_fmt = IPIPE_BAYER; > + break; > + default: > + temp_pix_fmt = IPIPE_UYVY; > + } > + > + if (temp_pix_fmt == IPIPE_BAYER) > + if (out_pix_fmt == IPIPE_BAYER) > + param->ipipe_dpaths_fmt = IPIPE_RAW2RAW; > + else if ((out_pix_fmt == IPIPE_UYVY) || > + (out_pix_fmt == IPIPE_YUV420SP)) > + param->ipipe_dpaths_fmt = IPIPE_RAW2YUV; > + else > + return -EINVAL; Using braces in the outermost if might make sense. > + else if (temp_pix_fmt == IPIPE_UYVY) { > + if (out_pix_fmt == IPIPE_UYVY) > + param->ipipe_dpaths_fmt = IPIPE_YUV2YUV; > + else if (out_pix_fmt == IPIPE_YUV420SP) > + param->ipipe_dpaths_fmt = IPIPE_YUV2YUV; > + else > + return -EINVAL; > + } > + return 0; > +} I wonder if the above function should rather deal with the v4l2_mbus_pixelcodes instead. Shouldn't VIDIOC_SUBDEV_S_FMT be used to configure this? > +/* > + * calculate_resize_ratios() > + * calculates resize ratio for resizer A or B. This is called after setting > + * the input size or output size > + */ > +static void calculate_resize_ratios(struct ipipe_params *param, int index) > +{ > + param->rsz_rsc_param[index].h_dif = > + ((param->ipipe_hsz + 1) * 256) / > + (param->rsz_rsc_param[index].o_hsz + 1); > + param->rsz_rsc_param[index].v_dif = > + ((param->ipipe_vsz + 1) * 256) / > + (param->rsz_rsc_param[index].o_vsz + 1); > +} > + > +static int ipipe_do_hw_setup(struct device *dev, void *config) > +{ > + struct ipipe_params *param = (struct ipipe_params *)config; > + int ret; > + > + dev_dbg(dev, "ipipe_do_hw_setup\n"); > + ret = mutex_lock_interruptible(&oper_state.lock); > + if (ret) > + return ret; > + > + if ((ISNULL(config)) && (oper_mode == IMP_MODE_CONTINUOUS)) { > + /* continuous mode */ > + param = oper_state.shared_config_param; > + if (param->rsz_en[RSZ_A]) > + calculate_resize_ratios(param, RSZ_A); > + if (param->rsz_en[RSZ_B]) > + calculate_resize_ratios(param, RSZ_B); > + ret = ipipe_hw_setup(param); > + } > + mutex_unlock(&oper_state.lock); > + > + return ret; > +} > + > +static unsigned int ipipe_rsz_chain_state(void) > +{ > + return oper_state.rsz_chained; > +} > + > +static void ipipe_update_outbuf1_address(void *config, unsigned int address) > +{ > + if ((ISNULL(config)) && (oper_mode == IMP_MODE_CONTINUOUS)) > + rsz_set_output_address(oper_state.shared_config_param, > + 0, > + address); > + else > + rsz_set_output_address((struct ipipe_params *)config, > + 0, > + address); > +} > + > +static void ipipe_update_outbuf2_address(void *config, unsigned int address) > +{ > + if ((ISNULL(config)) && (oper_mode == IMP_MODE_CONTINUOUS)) > + rsz_set_output_address(oper_state.shared_config_param, > + 1, > + address); > + else > + rsz_set_output_address((struct ipipe_params *)config, > + 1, > + address); > +} > + > +static void ipipe_enable(unsigned char en, void *config) > +{ > + unsigned char val = 0, ret = 0; > + struct ipipe_params *param = (struct ipipe_params *)config; > + > + if (en) > + val = 1; You can en = !!en and drop val. > + if (oper_mode == IMP_MODE_CONTINUOUS) > + param = oper_state.shared_config_param; > + > + if (en && param->rsz_common.source == IPIPE_DATA) { > + /* wait for IPIPE to become inactive */ > + do { > + ret = regr_ip(IPIPE_SRC_EN); > + } while (ret); > + > + regw_ip(val, IPIPE_SRC_EN); > + } else > + regw_ip(0, IPIPE_SRC_EN); > + > + if (en) { > + /* wait for RSZ_SRC_EN to be reset by hardware */ > + do { > + ret = regr_rsz(RSZ_SRC_EN); > + } while (ret); > + } > + > + if (param->rsz_en[RSZ_A]) { > + if (en) { > + /* wait for RSZ-A to become inactive */ > + do { > + ret = regr_rsz(RSZ_A); > + } while (ret); > + } > + > + rsz_enable(RSZ_A, en); > + } > + if (param->rsz_en[RSZ_B]) { > + if (en) { > + /* wait for RSZ-B to become inactive */ > + do { > + ret = regr_rsz(RSZ_B); > + } while (ret); > + } > + > + rsz_enable(RSZ_B, en); > + } > + if (oper_mode == IMP_MODE_SINGLE_SHOT) { > + /* wait for IPIPEIF ENABLE.ENABLE to be reset by hardware */ > + if (en) { > + do { > + ret = ipipeif_get_enable(); > + } while (ret & 0x1); > + } > + > + ipipeif_set_enable(val, oper_mode); Indentation. > + } > +} > + > +static int validate_lutdpc_params(struct device *dev) > +{ > +#ifdef CONFIG_IPIPE_PARAM_VALIDATION > + int i; > + > + if (lutdpc.en > 1 || > + lutdpc.repl_white > 1 || > + lutdpc.dpc_size > LUT_DPC_MAX_SIZE) > + return -EINVAL; > + if (lutdpc.en && (ISNULL(lutdpc.table))) > + return -EINVAL; > + for (i = 0; i < lutdpc.dpc_size; i++) { > + if (lutdpc.table[i].horz_pos > LUT_DPC_H_POS_MASK || > + lutdpc.table[i].vert_pos > LUT_DPC_V_POS_MASK) > + return -EINVAL; > + } > +#endif > + return 0; > +} > + > +static int set_lutdpc_params(struct device *dev, void *param, int len) > +{ > + struct ipipe_lutdpc_entry *temp_lutdpc; > + struct prev_lutdpc dpc_param; > + > + if (ISNULL(param)) { > + /* Copy defaults for dfc */ > + temp_lutdpc = lutdpc.table; > + memcpy((void *)&lutdpc, > + (void *)&dm365_lutdpc_defaults, > + sizeof(struct prev_lutdpc)); > + lutdpc.table = temp_lutdpc; > + goto success; > + } > + > + if (len != sizeof(struct prev_lutdpc)) { > + dev_err(dev, > + "set_lutdpc_params: param struct length" > + " mismatch\n"); > + return -EINVAL; > + } > + if (copy_from_user(&dpc_param, > + (struct prev_lutdpc *)param, > + sizeof(struct prev_lutdpc))) { > + dev_err(dev, > + "set_lutdpc_params: Error in copy to kernel\n"); > + return -EFAULT; > + } > + > + if (ISNULL(dpc_param.table)) { > + dev_err(dev, "Invalid user dpc table ptr\n"); > + return -EINVAL; > + } > + lutdpc.en = dpc_param.en; > + lutdpc.repl_white = dpc_param.repl_white; > + lutdpc.dpc_size = dpc_param.dpc_size; > + if (copy_from_user > + (lutdpc.table, > + (struct ipipe_dpc_entry *)dpc_param.table, > + (lutdpc.dpc_size * > + sizeof(struct ipipe_lutdpc_entry)))) { > + dev_err(dev, > + "set_lutdpc_params: Error in copying " > + "dfc table to kernel\n"); > + return -EFAULT; > + } > + > + if (validate_lutdpc_params(dev) < 0) > + return -EINVAL; > + > + > +success: > + ipipe_set_lutdpc_regs(&lutdpc); > + > + return 0; > +} > + > +static int get_lutdpc_params(struct device *dev, void *param, int len) > +{ > + struct prev_lutdpc *lut_param = (struct prev_lutdpc *)param; > + struct prev_lutdpc user_lutdpc; > + > + if (ISNULL(lut_param)) { > + dev_err(dev, "get_lutdpc_params: invalid user ptr"); > + return -EINVAL; > + } > + if (len != sizeof(struct prev_lutdpc)) { > + dev_err(dev, > + "get_lutdpc_params: param struct length mismatch\n"); > + return -EINVAL; > + } > + if (copy_from_user(&user_lutdpc, > + lut_param, > + sizeof(struct prev_lutdpc))) { > + dev_err(dev, "get_lutdpc_params: Error in copy to kernel\n"); > + return -EFAULT; > + } > + > + user_lutdpc.en = lutdpc.en; > + user_lutdpc.repl_white = lutdpc.repl_white; > + user_lutdpc.dpc_size = lutdpc.dpc_size; > + if (ISNULL(user_lutdpc.table)) { > + dev_err(dev, "get_lutdpc_params:" " Invalid table ptr"); > + return -EINVAL; > + } > + if (copy_to_user(user_lutdpc.table, > + lutdpc.table, > + (lutdpc.dpc_size * > + sizeof(struct ipipe_lutdpc_entry)))) { > + dev_err(dev, > + "get_lutdpc_params:Table Error in" " copy to user\n"); > + return -EFAULT; > + } > + > + if (copy_to_user(lut_param, > + &user_lutdpc, > + sizeof(struct prev_lutdpc))) { > + dev_err(dev, "get_lutdpc_params: Error in copy" " to user\n"); > + return -EFAULT; > + } > + > + return 0; > +} > + > +static int validate_otfdpc_params(struct device *dev) > +{ > +#ifdef CONFIG_IPIPE_PARAM_VALIDATION Are there cases where you wouldn't want the parameters to be validated? > + struct prev_otfdpc *dpc_param = (struct prev_otfdpc *)&otfdpc; > + struct prev_otfdpc_2_0 *dpc_2_0; > + struct prev_otfdpc_3_0 *dpc_3_0; > + > + if (dpc_param->en > 1) > + return -EINVAL; > + if (dpc_param->alg == IPIPE_OTFDPC_2_0) { > + dpc_2_0 = &dpc_param->alg_cfg.dpc_2_0; > + if (dpc_2_0->det_thr.r > OTFDPC_DPC2_THR_MASK || > + dpc_2_0->det_thr.gr > OTFDPC_DPC2_THR_MASK || > + dpc_2_0->det_thr.gb > OTFDPC_DPC2_THR_MASK || > + dpc_2_0->det_thr.b > OTFDPC_DPC2_THR_MASK || > + dpc_2_0->corr_thr.r > OTFDPC_DPC2_THR_MASK || > + dpc_2_0->corr_thr.gr > OTFDPC_DPC2_THR_MASK || > + dpc_2_0->corr_thr.gb > OTFDPC_DPC2_THR_MASK || > + dpc_2_0->corr_thr.b > OTFDPC_DPC2_THR_MASK) > + return -EINVAL; > + } else { > + dpc_3_0 = &dpc_param->alg_cfg.dpc_3_0; > + if (dpc_3_0->act_adj_shf > OTF_DPC3_0_SHF_MASK || > + dpc_3_0->det_thr > OTF_DPC3_0_DET_MASK || > + dpc_3_0->det_slp > OTF_DPC3_0_SLP_MASK || > + dpc_3_0->det_thr_min > OTF_DPC3_0_DET_MASK || > + dpc_3_0->det_thr_max > OTF_DPC3_0_DET_MASK || > + dpc_3_0->corr_thr > OTF_DPC3_0_CORR_MASK || > + dpc_3_0->corr_slp > OTF_DPC3_0_SLP_MASK || > + dpc_3_0->corr_thr_min > OTF_DPC3_0_CORR_MASK || > + dpc_3_0->corr_thr_max > OTF_DPC3_0_CORR_MASK) > + return -EINVAL; > + } > +#endif > + return 0; > +} > + > +static int set_otfdpc_params(struct device *dev, void *param, int len) > +{ > + struct prev_otfdpc *dpc_param = (struct prev_otfdpc *)param; > + > + if (ISNULL(param)) { > + /* Copy defaults for dpc2.0 defaults */ > + memcpy((void *)&otfdpc, > + (void *)&dm365_otfdpc_defaults, > + sizeof(struct ipipe_otfdpc_2_0)); > + } else { > + if (len != sizeof(struct prev_otfdpc)) { > + dev_err(dev, > + "set_otfdpc_params: param struct length" > + " mismatch\n"); > + return -EINVAL; > + } > + if (copy_from_user(&otfdpc, > + dpc_param, > + sizeof(struct prev_otfdpc))) { > + dev_err(dev, > + "set_otfdpc_params: Error in " > + "copy to kernel\n"); > + return -EFAULT; > + } > + > + if (validate_otfdpc_params(dev) < 0) > + return -EINVAL; > + } > + > + ipipe_set_otfdpc_regs(&otfdpc); > + > + return 0; > +} > + > +static int get_otfdpc_params(struct device *dev, void *param, int len) > +{ > + struct prev_otfdpc *dpc_param = (struct prev_otfdpc *)param; > + > + if (ISNULL(dpc_param)) { > + dev_err(dev, "get_otfdpc_params: invalid user ptr"); > + return -EINVAL; > + } > + if (len != sizeof(struct prev_otfdpc)) { > + dev_err(dev, > + "get_otfdpc_params: param struct length mismatch\n"); > + return -EINVAL; > + } > + if (copy_to_user(dpc_param, > + &otfdpc, > + sizeof(struct prev_otfdpc))) { > + dev_err(dev, > + "get_otfdpc_params: Error in copy dpc " > + "table to user\n"); > + return -EFAULT; > + } > + > + return 0; > +} > + > +static int validate_nf_params(struct device *dev, unsigned int id) > +{ > +#ifdef CONFIG_IPIPE_PARAM_VALIDATION > + struct prev_nf *nf_param = &nf1; > + int i; > + > + if (id) > + nf_param = &nf2; > + if (nf_param->en > 1 || > + nf_param->shft_val > D2F_SHFT_VAL_MASK || > + nf_param->spread_val > D2F_SPR_VAL_MASK || > + nf_param->apply_lsc_gain > 1 || > + nf_param->edge_det_min_thr > D2F_EDGE_DET_THR_MASK || > + nf_param->edge_det_max_thr > D2F_EDGE_DET_THR_MASK) > + return -EINVAL; > + > + for (i = 0; i < IPIPE_NF_THR_TABLE_SIZE; i++) > + if (nf_param->thr[i] > D2F_THR_VAL_MASK) > + return -EINVAL; > + for (i = 0; i < IPIPE_NF_STR_TABLE_SIZE; i++) > + if (nf_param->str[i] > D2F_STR_VAL_MASK) > + return -EINVAL; > +#endif > + return 0; > +} > + > +static int set_nf_params(struct device *dev, unsigned int id, > + void *param, int len) > +{ > + struct prev_nf *nf_param = (struct prev_nf *)param; > + struct prev_nf *nf = &nf1; > + > + if (id) > + nf = &nf2; > + > + if (ISNULL(nf_param)) { > + /* Copy defaults for nf */ > + memcpy((void *)nf, > + (void *)&dm365_nf_defaults, > + sizeof(struct prev_nf)); > + memset((void *)nf->thr, 0, IPIPE_NF_THR_TABLE_SIZE); > + memset((void *)nf->str, 0, IPIPE_NF_THR_TABLE_SIZE); > + } else { > + if (len != sizeof(struct prev_nf)) { > + dev_err(dev, > + "set_nf_params: param struct length" > + " mismatch\n"); > + return -EINVAL; > + } > + if (copy_from_user(nf, nf_param, sizeof(struct prev_nf))) { > + dev_err(dev, > + "set_nf_params: Error in copy to kernel\n"); > + return -EFAULT; > + } > + if (validate_nf_params(dev, id) < 0) > + return -EINVAL; > + } > + /* Now set the values in the hw */ > + ipipe_set_d2f_regs(id, nf); > + > + return 0; > +} > + > +static int set_nf1_params(struct device *dev, void *param, int len) > +{ > + return set_nf_params(dev, 0, param, len); > +} > + > +static int set_nf2_params(struct device *dev, void *param, int len) > +{ > + return set_nf_params(dev, 1, param, len); > +} > + > +static int get_nf_params(struct device *dev, unsigned int id, void *param, > + int len) > +{ > + struct prev_nf *nf_param = (struct prev_nf *)param; > + struct prev_nf *nf = &nf1; > + > + if (ISNULL(nf_param)) { > + dev_err(dev, "get_nf_params: invalid user ptr"); > + return -EINVAL; > + } > + if (len != sizeof(struct prev_nf)) { > + dev_err(dev, > + "get_nf_params: param struct length mismatch\n"); > + return -EINVAL; > + } > + if (id) > + nf = &nf2; > + if (copy_to_user((struct prev_nf *)nf_param, nf, > + sizeof(struct prev_nf))) { > + dev_err(dev, "get_nf_params: Error in copy from kernel\n"); > + return -EFAULT; > + } > + > + return 0; > +} > + > +static int get_nf1_params(struct device *dev, void *param, int len) > +{ > + return get_nf_params(dev, 0, param, len); > +} > + > +static int get_nf2_params(struct device *dev, void *param, int len) > +{ > + return get_nf_params(dev, 1, param, len); > +} > + > +static int validate_gic_params(struct device *dev) > +{ > +#ifdef CONFIG_IPIPE_PARAM_VALIDATION > + if (gic.en > 1 || > + gic.gain > GIC_GAIN_MASK || > + gic.thr > GIC_THR_MASK || > + gic.slope > GIC_SLOPE_MASK || > + gic.apply_lsc_gain > 1 || > + gic.nf2_thr_gain.integer > GIC_NFGAN_INT_MASK || > + gic.nf2_thr_gain.decimal > GIC_NFGAN_DECI_MASK) > + return -1; > +#endif > + return 0; > +} > + > +static int set_gic_params(struct device *dev, void *param, int len) > +{ > + struct prev_gic *gic_param = (struct prev_gic *)param; > + > + if (ISNULL(gic_param)) { > + /* Copy defaults for nf */ > + memcpy((void *)&gic, > + (void *)&dm365_gic_defaults, > + sizeof(struct prev_gic)); > + } else { > + if (len != sizeof(struct prev_gic)) { > + dev_err(dev, > + "set_gic_params: param struct length" > + " mismatch\n"); > + return -EINVAL; > + } > + if (copy_from_user(&gic, gic_param, sizeof(struct prev_gic))) { > + dev_err(dev, > + "set_gic_params: Error in copy to kernel\n"); > + return -EFAULT; > + } > + if (validate_gic_params(dev) < 0) > + return -EINVAL; > + } > + /* Now set the values in the hw */ > + ipipe_set_gic_regs(&gic); > + > + return 0; > +} > + > +static int get_gic_params(struct device *dev, void *param, int len) > +{ > + struct prev_gic *gic_param = (struct prev_gic *)param; > + > + if (ISNULL(gic_param)) { > + dev_err(dev, "get_gic_params: invalid user ptr"); > + return -EINVAL; > + } > + > + if (len != sizeof(struct prev_gic)) { > + dev_err(dev, > + "get_gic_params: param struct length mismatch\n"); > + return -EINVAL; > + } > + > + if (copy_to_user((struct prev_gic *)gic_param, > + &gic, > + sizeof(struct prev_gic))) { > + dev_err(dev, "get_gic_params: Error in copy from kernel\n"); > + return -EFAULT; > + } > + > + return 0; > +} > + > +static int validate_wb_params(struct device *dev) > +{ > +#ifdef CONFIG_IPIPE_PARAM_VALIDATION > + if (wb.ofst_r > WB_OFFSET_MASK || > + wb.ofst_gr > WB_OFFSET_MASK || > + wb.ofst_gb > WB_OFFSET_MASK || > + wb.ofst_b > WB_OFFSET_MASK || > + wb.gain_r.integer > WB_GAIN_INT_MASK || > + wb.gain_r.decimal > WB_GAIN_DECI_MASK || > + wb.gain_gr.integer > WB_GAIN_INT_MASK || > + wb.gain_gr.decimal > WB_GAIN_DECI_MASK || > + wb.gain_gb.integer > WB_GAIN_INT_MASK || > + wb.gain_gb.decimal > WB_GAIN_DECI_MASK || > + wb.gain_b.integer > WB_GAIN_INT_MASK || > + wb.gain_b.decimal > WB_GAIN_DECI_MASK) > + return -EINVAL; > +#endif > + return 0; > +} > +static int set_wb_params(struct device *dev, void *param, int len) > +{ > + struct prev_wb *wb_param = (struct prev_wb *)param; > + > + dev_dbg(dev, "set_wb_params"); > + if (ISNULL(wb_param)) { > + /* Copy defaults for wb */ > + memcpy((void *)&wb, > + (void *)&dm365_wb_defaults, > + sizeof(struct prev_wb)); > + } else { > + if (len != sizeof(struct prev_wb)) { > + dev_err(dev, > + "set_wb_params: param struct length" > + " mismatch\n"); > + return -EINVAL; > + } > + if (copy_from_user(&wb, wb_param, sizeof(struct prev_wb))) { > + dev_err(dev, > + "set_wb_params: Error in copy to kernel\n"); > + return -EFAULT; > + } > + if (validate_wb_params(dev) < 0) > + return -EINVAL; > + } > + > + /* Now set the values in the hw */ > + ipipe_set_wb_regs(&wb); > + > + return 0; > +} > +static int get_wb_params(struct device *dev, void *param, int len) > +{ > + struct prev_wb *wb_param = (struct prev_wb *)param; > + > + if (ISNULL(wb_param)) { > + dev_err(dev, "get_wb_params: invalid user ptr"); > + return -EINVAL; > + } > + if (len != sizeof(struct prev_wb)) { > + dev_err(dev, > + "get_wb_params: param struct length mismatch\n"); > + return -EINVAL; > + } > + if (copy_to_user((struct prev_wb *)wb_param, > + &wb, > + sizeof(struct prev_wb))) { > + dev_err(dev, "get_wb_params: Error in copy from kernel\n"); > + return -EFAULT; > + } > + > + return 0; > +} > + > +static int validate_cfa_params(struct device *dev) > +{ > +#ifdef CONFIG_IPIPE_PARAM_VALIDATION > + if (cfa.hpf_thr_2dir > CFA_HPF_THR_2DIR_MASK || > + cfa.hpf_slp_2dir > CFA_HPF_SLOPE_2DIR_MASK || > + cfa.hp_mix_thr_2dir > CFA_HPF_MIX_THR_2DIR_MASK || > + cfa.hp_mix_slope_2dir > CFA_HPF_MIX_SLP_2DIR_MASK || > + cfa.dir_thr_2dir > CFA_DIR_THR_2DIR_MASK || > + cfa.dir_slope_2dir > CFA_DIR_SLP_2DIR_MASK || > + cfa.nd_wt_2dir > CFA_ND_WT_2DIR_MASK || > + cfa.hue_fract_daa > CFA_DAA_HUE_FRA_MASK || > + cfa.edge_thr_daa > CFA_DAA_EDG_THR_MASK || > + cfa.thr_min_daa > CFA_DAA_THR_MIN_MASK || > + cfa.thr_slope_daa > CFA_DAA_THR_SLP_MASK || > + cfa.slope_min_daa > CFA_DAA_SLP_MIN_MASK || > + cfa.slope_slope_daa > CFA_DAA_SLP_SLP_MASK || > + cfa.lp_wt_daa > CFA_DAA_LP_WT_MASK) > + return -EINVAL; > +#endif > + return 0; > +} > +static int set_cfa_params(struct device *dev, void *param, int len) > +{ > + struct prev_cfa *cfa_param = (struct prev_cfa *)param; > + > + dev_dbg(dev, "set_cfa_params"); > + if (ISNULL(cfa_param)) { > + /* Copy defaults for wb */ > + memcpy((void *)&cfa, > + (void *)&dm365_cfa_defaults, > + sizeof(struct prev_cfa)); > + } else { > + if (len != sizeof(struct prev_cfa)) { > + dev_err(dev, > + "set_cfa_params: param struct length" > + " mismatch\n"); > + return -EINVAL; > + } > + if (copy_from_user(&cfa, cfa_param, sizeof(struct prev_cfa))) { > + dev_err(dev, > + "set_cfa_params: Error in copy to kernel\n"); > + return -EFAULT; > + } > + if (validate_cfa_params(dev) < 0) > + return -EINVAL; > + } > + > + /* Now set the values in the hw */ > + ipipe_set_cfa_regs(&cfa); > + > + return 0; > +} > +static int get_cfa_params(struct device *dev, void *param, int len) > +{ > + struct prev_cfa *cfa_param = (struct prev_cfa *)param; > + > + dev_dbg(dev, "get_cfa_params\n"); > + if (ISNULL(cfa_param)) { > + dev_err(dev, "get_cfa_params: invalid user ptr"); > + return -EINVAL; > + } > + if (len != sizeof(struct prev_cfa)) { > + dev_err(dev, > + "get_cfa_params: param struct length mismatch\n"); > + return -EINVAL; > + } > + if (copy_to_user((struct prev_cfa *)cfa_param, > + &cfa, > + sizeof(struct prev_cfa))) { > + dev_err(dev, "get_cfa_params: Error in copy from kernel\n"); > + return -EFAULT; > + } > + > + return 0; > +} > + > +static int validate_rgb2rgb_params(struct device *dev, unsigned int id) > +{ > +#ifdef CONFIG_IPIPE_PARAM_VALIDATION > + struct prev_rgb2rgb *rgb2rgb = &rgb2rgb_1; > + u32 gain_int_upper = RGB2RGB_1_GAIN_INT_MASK; > + u32 offset_upper = RGB2RGB_1_OFST_MASK; > + > + if (id) { > + rgb2rgb = &rgb2rgb_2; > + offset_upper = RGB2RGB_2_OFST_MASK; > + gain_int_upper = RGB2RGB_2_GAIN_INT_MASK; > + } > + if (rgb2rgb->coef_rr.decimal > RGB2RGB_GAIN_DECI_MASK || > + rgb2rgb->coef_rr.integer > gain_int_upper) > + return -EINVAL; > + > + if (rgb2rgb->coef_gr.decimal > RGB2RGB_GAIN_DECI_MASK || > + rgb2rgb->coef_gr.integer > gain_int_upper) > + return -EINVAL; > + > + if (rgb2rgb->coef_br.decimal > RGB2RGB_GAIN_DECI_MASK || > + rgb2rgb->coef_br.integer > gain_int_upper) > + return -EINVAL; > + > + if (rgb2rgb->coef_rg.decimal > RGB2RGB_GAIN_DECI_MASK || > + rgb2rgb->coef_rg.integer > gain_int_upper) > + return -EINVAL; > + > + if (rgb2rgb->coef_gg.decimal > RGB2RGB_GAIN_DECI_MASK || > + rgb2rgb->coef_gg.integer > gain_int_upper) > + return -EINVAL; > + > + if (rgb2rgb->coef_bg.decimal > RGB2RGB_GAIN_DECI_MASK || > + rgb2rgb->coef_bg.integer > gain_int_upper) > + return -EINVAL; > + > + if (rgb2rgb->coef_rb.decimal > RGB2RGB_GAIN_DECI_MASK || > + rgb2rgb->coef_rb.integer > gain_int_upper) > + return -EINVAL; > + > + if (rgb2rgb->coef_gb.decimal > RGB2RGB_GAIN_DECI_MASK || > + rgb2rgb->coef_gb.integer > gain_int_upper) > + return -EINVAL; > + > + if (rgb2rgb->coef_bb.decimal > RGB2RGB_GAIN_DECI_MASK || > + rgb2rgb->coef_bb.integer > gain_int_upper) > + return -EINVAL; > + > + if (rgb2rgb->out_ofst_r > offset_upper || > + rgb2rgb->out_ofst_g > offset_upper || > + rgb2rgb->out_ofst_b > offset_upper) > + return -EINVAL; > +#endif > + return 0; > +} > + > +static int set_rgb2rgb_params(struct device *dev, unsigned int id, > + void *param, int len) > +{ > + struct prev_rgb2rgb *rgb2rgb_param = (struct prev_rgb2rgb *)param; > + struct prev_rgb2rgb *rgb2rgb = &rgb2rgb_1; > + > + if (id) > + rgb2rgb = &rgb2rgb_2; > + if (ISNULL(rgb2rgb_param)) { > + /* Copy defaults for rgb2rgb conversion */ > + memcpy((void *)rgb2rgb, > + (void *)&dm365_rgb2rgb_defaults, > + sizeof(struct prev_rgb2rgb)); > + } else { > + > + if (len != sizeof(struct prev_rgb2rgb)) { > + dev_err(dev, > + "set_rgb2rgb_params: param struct length" > + " mismatch\n"); > + return -EINVAL; > + } > + > + if (copy_from_user(rgb2rgb, > + rgb2rgb_param, > + sizeof(struct prev_rgb2rgb))) { > + dev_err(dev, > + "set_rgb2rgb_params: Error in " > + "copy to kernel\n"); > + return -EFAULT; > + } > + if (validate_rgb2rgb_params(dev, id) < 0) > + return -EINVAL; > + } > + > + ipipe_set_rgb2rgb_regs(id, rgb2rgb); > + > + return 0; > +} > + > +static int set_rgb2rgb_1_params(struct device *dev, void *param, int len) > +{ > + return set_rgb2rgb_params(dev, 0, param, len); > +} > + > +static int set_rgb2rgb_2_params(struct device *dev, void *param, int len) > +{ > + return set_rgb2rgb_params(dev, 1, param, len); > +} > + > +static int get_rgb2rgb_params(struct device *dev, unsigned int id, > + void *param, int len) > +{ > + struct prev_rgb2rgb *rgb2rgb_param = (struct prev_rgb2rgb *)param; > + struct prev_rgb2rgb *rgb2rgb = &rgb2rgb_1; > + > + if (ISNULL(rgb2rgb_param)) { > + dev_err(dev, "get_rgb2rgb_params: invalid user ptr"); > + return -EINVAL; > + } > + > + if (len != sizeof(struct prev_rgb2rgb)) { > + dev_err(dev, > + "get_rgb2rgb_params: param struct length mismatch\n"); > + return -EINVAL; > + } > + > + if (id) > + rgb2rgb = &rgb2rgb_2; > + if (copy_to_user((struct prev_rgb2rgb *)rgb2rgb_param, > + rgb2rgb, > + sizeof(struct prev_rgb2rgb))) { > + dev_err(dev, "get_rgb2rgb_params: Error in copy to user\n"); > + return -EFAULT; > + } > + > + return 0; > +} > + > +static int get_rgb2rgb_1_params(struct device *dev, void *param, int len) > +{ > + return get_rgb2rgb_params(dev, 0, param, len); > +} > + > +static int get_rgb2rgb_2_params(struct device *dev, void *param, int len) > +{ > + return get_rgb2rgb_params(dev, 1, param, len); > +} > + > +static int validate_gamma_entry(struct ipipe_gamma_entry *table, int size) > +{ > +#ifdef CONFIG_IPIPE_PARAM_VALIDATION > + int i; > + > + if (ISNULL(table)) > + return -EINVAL; > + > + for (i = 0; i < size; i++) { > + if (table[i].slope > GAMMA_MASK || > + table[i].offset > GAMMA_MASK) > + return -EINVAL; > + } > +#endif > + return 0; > +} > + > +static int validate_gamma_params(struct device *dev) > +{ > +#ifdef CONFIG_IPIPE_PARAM_VALIDATION > + int table_size; > + int err; > + > + if (gamma.bypass_r > 1 || > + gamma.bypass_b > 1 || > + gamma.bypass_g > 1) > + return -EINVAL; > + > + if (gamma.tbl_sel != IPIPE_GAMMA_TBL_RAM) > + return 0; > + > + table_size = gamma.tbl_size; > + if (!gamma.bypass_r) { > + err = validate_gamma_entry(gamma.table_r, table_size); > + if (err) { > + dev_err(dev, "GAMMA R - table entry invalid\n"); > + return err; > + } > + } > + if (!gamma.bypass_b) { > + err = validate_gamma_entry(gamma.table_b, table_size); > + if (err) { > + dev_err(dev, "GAMMA B - table entry invalid\n"); > + return err; > + } > + } > + if (!gamma.bypass_g) { > + err = validate_gamma_entry(gamma.table_g, table_size); > + if (err) { > + dev_err(dev, "GAMMA G - table entry invalid\n"); > + return err; > + } > + } > +#endif > + return 0; > +} > +static int set_gamma_params(struct device *dev, void *param, int len) > +{ > + > + struct prev_gamma *gamma_param = (struct prev_gamma *)param; > + struct prev_gamma user_gamma; > + int table_size; > + > + if (ISNULL(gamma_param)) { > + /* Copy defaults for gamma */ > + gamma.bypass_r = dm365_gamma_defaults.bypass_r; > + gamma.bypass_g = dm365_gamma_defaults.bypass_g; > + gamma.bypass_b = dm365_gamma_defaults.bypass_b; > + gamma.tbl_sel = dm365_gamma_defaults.tbl_sel; > + gamma.tbl_size = dm365_gamma_defaults.tbl_size; > + /* By default, we bypass the gamma correction. > + * So no values by default for tables > + */ > + goto success; > + } > + > + if (len != sizeof(struct prev_gamma)) { > + dev_err(dev, > + "set_gamma_params: param struct length" > + " mismatch\n"); > + return -EINVAL; > + } > + if (copy_from_user(&user_gamma, gamma_param, > + sizeof(struct prev_gamma))) { > + dev_err(dev, > + "set_gamma_params: Error in copy to kernel\n"); > + return -EFAULT; > + } > + > + if (validate_gamma_params(dev) < 0) > + return -EINVAL; > + > + gamma.bypass_r = user_gamma.bypass_r; > + gamma.bypass_b = user_gamma.bypass_b; > + gamma.bypass_g = user_gamma.bypass_g; > + gamma.tbl_sel = user_gamma.tbl_sel; > + gamma.tbl_size = user_gamma.tbl_size; > + > + if (user_gamma.tbl_sel != IPIPE_GAMMA_TBL_RAM) > + goto success; > + > + table_size = user_gamma.tbl_size; > + > + if (!user_gamma.bypass_r) { > + if (ISNULL(user_gamma.table_r)) { > + dev_err(dev, > + "set_gamma_params: Invalid" > + " table ptr for R\n"); > + return -EINVAL; > + } > + if (copy_from_user(gamma.table_r, > + user_gamma.table_r, > + (table_size * > + sizeof(struct \ > + ipipe_gamma_entry)))) { > + dev_err(dev, > + "set_gamma_params: R-Error" > + " in copy to kernel\n"); > + return -EFAULT; > + } > + } > + > + if (!user_gamma.bypass_b) { > + if (ISNULL(user_gamma.table_b)) { > + dev_err(dev, > + "set_gamma_params: Invalid" > + " table ptr for B\n"); > + return -EINVAL; > + } > + if (copy_from_user(gamma.table_b, > + user_gamma.table_b, > + (table_size * > + sizeof(struct \ > + ipipe_gamma_entry)))) { > + dev_err(dev, > + "set_gamma_params: B-Error" > + " in copy to kernel\n"); > + return -EFAULT; > + } > + } > + > + if (!user_gamma.bypass_g) { > + if (ISNULL(user_gamma.table_g)) { > + dev_err(dev, > + "set_gamma_params: Invalid" > + " table ptr for G\n"); > + return -EINVAL; > + } > + if (copy_from_user(gamma.table_g, > + user_gamma.table_g, > + (table_size * > + sizeof(struct \ > + ipipe_gamma_entry)))) { > + dev_err(dev, > + "set_gamma_params: G-Error " > + "in copy to kernel\n"); > + return -EFAULT; > + } > + } > + > +success: > + ipipe_set_gamma_regs(&gamma); > + > + return 0; > +} > + > +static int get_gamma_params(struct device *dev, void *param, int len) > +{ > + struct prev_gamma *gamma_param = (struct prev_gamma *)param; > + struct prev_gamma user_gamma; > + int table_size; > + > + if (ISNULL(gamma_param)) { > + dev_err(dev, "get_gamma_params: invalid user ptr"); > + return -EINVAL; > + } > + if (len != sizeof(struct prev_gamma)) { > + dev_err(dev, > + "get_gamma_params: param struct length mismatch\n"); > + return -EINVAL; > + } > + if (copy_from_user(&user_gamma, > + gamma_param, > + sizeof(struct prev_gamma))) { > + dev_err(dev, "get_gamma_params: Error in copy to kernel\n"); > + return -EFAULT; > + } > + > + user_gamma.bypass_r = gamma.bypass_r; > + user_gamma.bypass_g = gamma.bypass_g; > + user_gamma.bypass_b = gamma.bypass_b; > + user_gamma.tbl_sel = gamma.tbl_sel; > + user_gamma.tbl_size = gamma.tbl_size; > + if (gamma.tbl_sel == IPIPE_GAMMA_TBL_RAM) { > + table_size = gamma.tbl_size; > + > + if ((!gamma.bypass_r) && ((ISNULL(user_gamma.table_r)))) { > + dev_err(dev, > + "get_gamma_params: table ptr empty for R\n"); > + return -EINVAL; > + } else { > + if (copy_to_user(user_gamma.table_r, > + gamma.table_r, > + (table_size * > + sizeof(struct ipipe_gamma_entry)))) { > + dev_err(dev, > + "set_gamma_params: R-Table Error in" > + " copy to user\n"); > + return -EFAULT; > + } > + } > + > + if ((!gamma.bypass_b) && ((ISNULL(user_gamma.table_b)))) { > + dev_err(dev, > + "get_gamma_params: table ptr empty for B\n"); > + return -EINVAL; > + } else { > + if (copy_to_user(user_gamma.table_b, > + gamma.table_b, > + (table_size * > + sizeof(struct ipipe_gamma_entry)))) { > + dev_err(dev, > + "set_gamma_params: B-Table Error in" > + " copy to user\n"); > + return -EFAULT; > + } > + } > + > + if ((!gamma.bypass_g) && ((ISNULL(user_gamma.table_g)))) { > + dev_err(dev, > + "get_gamma_params: table ptr empty for G\n"); > + return -EINVAL; > + } else { > + if (copy_from_user(gamma.table_g, > + user_gamma.table_g, > + (table_size * > + sizeof(struct ipipe_gamma_entry)))) { > + dev_err(dev, > + "set_gamma_params: G-Table" > + "copy error\n"); > + return -EFAULT; > + } > + } > + > + } > + if (copy_to_user(gamma_param, &user_gamma, > + sizeof(struct prev_gamma))) { > + dev_err(dev, "get_dfc_params: Error in copy from kernel\n"); > + return -EFAULT; > + } > + > + return 0; > +} > + > +static int validate_3d_lut_params(struct device *dev) > +{ > +#ifdef CONFIG_IPIPE_PARAM_VALIDATION > + int i; > + > + if (!lut_3d.en) > + return 0; > + > + for (i = 0; i < MAX_SIZE_3D_LUT; i++) { > + if (lut_3d.table[i].r > D3_LUT_ENTRY_MASK || > + lut_3d.table[i].g > D3_LUT_ENTRY_MASK || > + lut_3d.table[i].b > D3_LUT_ENTRY_MASK) > + return -EINVAL; > + } > +#endif > + return 0; > +} > +static int set_3d_lut_params(struct device *dev, void *param, int len) > +{ > + struct prev_3d_lut *lut_param = (struct prev_3d_lut *)param; > + struct prev_3d_lut user_3d_lut; > + > + if (ISNULL(lut_param)) { > + /* Copy defaults for gamma */ > + lut_3d.en = dm365_3d_lut_defaults.en; > + /* By default, 3D lut is disabled > + */ > + } else { > + if (len != sizeof(struct prev_3d_lut)) { > + dev_err(dev, > + "set_3d_lut_params: param struct" > + " length mismatch\n"); > + return -EINVAL; > + } > + if (copy_from_user(&user_3d_lut, > + lut_param, > + sizeof(struct prev_3d_lut))) { > + dev_err(dev, > + "set_3d_lut_params: Error in copy to" > + " kernel\n"); > + return -EFAULT; > + } > + lut_3d.en = user_3d_lut.en; > + if (ISNULL(user_3d_lut.table)) { > + dev_err(dev, "set_3d_lut_params: Invalid table ptr"); > + return -EINVAL; > + } > + if (copy_from_user(lut_3d.table, > + user_3d_lut.table, > + (MAX_SIZE_3D_LUT * > + sizeof(struct ipipe_3d_lut_entry)))) { > + dev_err(dev, > + "set_3d_lut_params:Error" > + " in copy to kernel\n"); > + return -EFAULT; > + } > + > + if (validate_3d_lut_params(dev) < 0) > + return -EINVAL; > + } > + > + ipipe_set_3d_lut_regs(&lut_3d); > + > + return 0; > +} > +static int get_3d_lut_params(struct device *dev, void *param, int len) > +{ > + struct prev_3d_lut *lut_param = (struct prev_3d_lut *)param; > + struct prev_3d_lut user_3d_lut; > + > + if (ISNULL(lut_param)) { > + dev_err(dev, "get_3d_lut_params: invalid user ptr"); > + return -EINVAL; > + } > + if (len != sizeof(struct prev_3d_lut)) { > + dev_err(dev, > + "get_3d_lut_params: param struct length mismatch\n"); > + return -EINVAL; > + } > + if (copy_from_user(&user_3d_lut, > + lut_param, > + sizeof(struct prev_3d_lut))) { > + dev_err(dev, "get_3d_lut_params: Error in copy to kernel\n"); > + return -EFAULT; > + } > + > + user_3d_lut.en = lut_3d.en; > + if (ISNULL(user_3d_lut.table)) { > + dev_err(dev, "get_3d_lut_params:" " Invalid table ptr"); > + return -EINVAL; > + } > + if (copy_to_user(user_3d_lut.table, lut_3d.table, > + (MAX_SIZE_3D_LUT * > + sizeof(struct ipipe_3d_lut_entry)))) { > + dev_err(dev, > + "get_3d_lut_params:Table Error in" " copy to user\n"); > + return -EFAULT; > + } > + > + if (copy_to_user(lut_param, &user_3d_lut, > + sizeof(struct prev_3d_lut))) { > + dev_err(dev, "get_3d_lut_params: Error in copy" " to user\n"); > + return -EFAULT; > + } > + > + return 0; > +} > + > +static int validate_lum_adj_params(struct device *dev) > +{ > + /* nothing to validate */ > + return 0; > +} > + > +static int set_lum_adj_params(struct device *dev, void *param, int len) > +{ > + struct prev_lum_adj *lum_adj_param = (struct prev_lum_adj *)param; > + > + if (ISNULL(lum_adj_param)) { > + /* Copy defaults for Luminance adjustments */ > + memcpy((void *)&lum_adj, > + (void *)&dm365_lum_adj_defaults, > + sizeof(struct prev_lum_adj)); > + } else { > + if (len != sizeof(struct prev_lum_adj)) { > + dev_err(dev, > + "set_lum_adj_params: param struct length" > + " mismatch\n"); > + return -EINVAL; > + } > + if (copy_from_user(&lum_adj, > + lum_adj_param, > + sizeof(struct prev_lum_adj))) { > + dev_err(dev, > + "set_lum_adj_params: Error in copy" > + " from user\n"); > + return -EFAULT; > + } > + if (validate_lum_adj_params(dev) < 0) > + return -EINVAL; > + } > + > + ipipe_set_lum_adj_regs(&lum_adj); > + > + return 0; > +} > + > +static int get_lum_adj_params(struct device *dev, void *param, int len) > +{ > + struct prev_lum_adj *lum_adj_param = (struct prev_lum_adj *)param; > + > + if (ISNULL(lum_adj_param)) { > + dev_err(dev, "get_lum_adj_params: invalid user ptr"); > + return -EINVAL; > + } > + > + if (len != sizeof(struct prev_lum_adj)) { > + dev_err(dev, > + "get_lum_adj_params: param struct length mismatch\n"); > + return -EINVAL; > + } > + > + if (copy_to_user(lum_adj_param, > + &lum_adj, > + sizeof(struct prev_lum_adj))) { > + dev_err(dev, "get_lum_adj_params: Error in copy to" " user\n"); > + return -EFAULT; > + } > + > + return 0; > +} > + > +static int validate_rgb2yuv_params(struct device *dev) > +{ > +#ifdef CONFIG_IPIPE_PARAM_VALIDATION > + if (rgb2yuv.coef_ry.decimal > RGB2YCBCR_COEF_DECI_MASK || > + rgb2yuv.coef_ry.integer > RGB2YCBCR_COEF_INT_MASK) > + return -EINVAL; > + > + if (rgb2yuv.coef_gy.decimal > RGB2YCBCR_COEF_DECI_MASK || > + rgb2yuv.coef_gy.integer > RGB2YCBCR_COEF_INT_MASK) > + return -EINVAL; > + > + if (rgb2yuv.coef_by.decimal > RGB2YCBCR_COEF_DECI_MASK || > + rgb2yuv.coef_by.integer > RGB2YCBCR_COEF_INT_MASK) > + return -EINVAL; > + > + if (rgb2yuv.coef_rcb.decimal > RGB2YCBCR_COEF_DECI_MASK || > + rgb2yuv.coef_rcb.integer > RGB2YCBCR_COEF_INT_MASK) > + return -EINVAL; > + > + if (rgb2yuv.coef_gcb.decimal > RGB2YCBCR_COEF_DECI_MASK || > + rgb2yuv.coef_gcb.integer > RGB2YCBCR_COEF_INT_MASK) > + return -EINVAL; > + > + if (rgb2yuv.coef_bcb.decimal > RGB2YCBCR_COEF_DECI_MASK || > + rgb2yuv.coef_bcb.integer > RGB2YCBCR_COEF_INT_MASK) > + return -EINVAL; > + > + if (rgb2yuv.coef_rcr.decimal > RGB2YCBCR_COEF_DECI_MASK || > + rgb2yuv.coef_rcr.integer > RGB2YCBCR_COEF_INT_MASK) > + return -EINVAL; > + > + if (rgb2yuv.coef_gcr.decimal > RGB2YCBCR_COEF_DECI_MASK || > + rgb2yuv.coef_gcr.integer > RGB2YCBCR_COEF_INT_MASK) > + return -EINVAL; > + > + if (rgb2yuv.coef_bcr.decimal > RGB2YCBCR_COEF_DECI_MASK || > + rgb2yuv.coef_bcr.integer > RGB2YCBCR_COEF_INT_MASK) > + return -EINVAL; > + > + if (rgb2yuv.out_ofst_y > RGB2YCBCR_OFST_MASK || > + rgb2yuv.out_ofst_cb > RGB2YCBCR_OFST_MASK || > + rgb2yuv.out_ofst_cr > RGB2YCBCR_OFST_MASK) > + return -EINVAL; > +#endif > + return 0; > +} > +static int set_rgb2yuv_params(struct device *dev, void *param, int len) > +{ > + struct prev_rgb2yuv *rgb2yuv_param = (struct prev_rgb2yuv *)param; > + > + if (ISNULL(rgb2yuv_param)) { > + /* Copy defaults for rgb2yuv conversion */ > + memcpy((void *)&rgb2yuv, > + (void *)&dm365_rgb2yuv_defaults, > + sizeof(struct prev_rgb2yuv)); > + } else { > + if (len != sizeof(struct prev_rgb2yuv)) { > + dev_err(dev, > + "set_rgb2yuv_params: param struct" > + " length mismatch\n"); > + return -EINVAL; > + } > + if (copy_from_user(&rgb2yuv, > + rgb2yuv_param, > + sizeof(struct prev_rgb2yuv))) { > + dev_err(dev, > + "set_rgb2yuv_params: Error in copy from" > + " user\n"); > + return -EFAULT; > + } > + if (validate_rgb2yuv_params(dev) < 0) > + return -EINVAL; > + } > + > + ipipe_set_rgb2ycbcr_regs(&rgb2yuv); > + > + return 0; > +} > +static int get_rgb2yuv_params(struct device *dev, void *param, int len) > +{ > + struct prev_rgb2yuv *rgb2yuv_param = (struct prev_rgb2yuv *)param; > + > + if (ISNULL(rgb2yuv_param)) { > + dev_err(dev, "get_rgb2yuv_params: invalid user ptr"); > + return -EINVAL; > + } > + if (len != sizeof(struct prev_rgb2yuv)) { > + dev_err(dev, > + "get_rgb2yuv_params: param struct length mismatch\n"); > + return -EINVAL; > + } > + if (copy_to_user((struct prev_rgb2yuv *)rgb2yuv_param, > + &rgb2yuv, > + sizeof(struct prev_rgb2yuv))) { > + dev_err(dev, "get_rgb2yuv_params: Error in copy from" > + " kernel\n"); > + return -EFAULT; > + } > + > + return 0; > +} > + > +static int validate_gbce_params(struct device *dev) > +{ > +#ifdef CONFIG_IPIPE_PARAM_VALIDATION > + u32 max = GBCE_Y_VAL_MASK; > + int i; > + > + if (!gbce.en) > + return 0; > + > + if (gbce.type == IPIPE_GBCE_GAIN_TBL) > + max = GBCE_GAIN_VAL_MASK; > + for (i = 0; i < MAX_SIZE_GBCE_LUT; i++) > + if (gbce.table[i] > max) > + return -EINVAL; > +#endif > + return 0; > +} > +static int set_gbce_params(struct device *dev, void *param, int len) > +{ > + struct prev_gbce *gbce_param = (struct prev_gbce *)param; > + struct prev_gbce user_gbce; > + > + if (ISNULL(gbce_param)) > + /* Copy defaults for gamma */ > + gbce.en = dm365_gbce_defaults.en; > + /* By default, GBCE is disabled > + */ > + else { > + if (len != sizeof(struct prev_gbce)) { > + dev_err(dev, > + "set_gbce_params: param struct" > + " length mismatch\n"); > + return -EINVAL; > + } > + if (copy_from_user(&user_gbce, > + gbce_param, > + sizeof(struct prev_gbce))) { > + dev_err(dev, > + "set_gbce_params: Error in copy to" > + " kernel\n"); > + return -EFAULT; > + } > + gbce.en = user_gbce.en; > + gbce.type = user_gbce.type; > + if (ISNULL(user_gbce.table)) { > + dev_err(dev, "set_gbce_params:" " Invalid table ptr"); > + return -EINVAL; > + } > + > + if (copy_from_user(gbce.table, > + user_gbce.table, > + (MAX_SIZE_GBCE_LUT * > + sizeof(unsigned short)))) { > + dev_err(dev, "set_gbce_params:Error" > + " in copy to kernel\n"); > + return -EFAULT; > + } > + if (validate_gbce_params(dev) < 0) > + return -EINVAL; > + } > + > + ipipe_set_gbce_regs(&gbce); > + > + return 0; > +} > +static int get_gbce_params(struct device *dev, void *param, int len) > +{ > + struct prev_gbce *gbce_param = (struct prev_gbce *)param; > + struct prev_gbce user_gbce; > + > + if (ISNULL(gbce_param)) { > + dev_err(dev, "get_gbce_params: invalid user ptr"); > + return -EINVAL; > + } > + if (len != sizeof(struct prev_gbce)) { > + dev_err(dev, > + "get_gbce_params: param struct length mismatch\n"); > + return -EINVAL; > + } > + if (copy_from_user(&user_gbce, gbce_param, sizeof(struct prev_gbce))) { > + dev_err(dev, "get_gbce_params: Error in copy to" " kernel\n"); > + return -EFAULT; > + } > + > + user_gbce.en = gbce.en; > + user_gbce.type = gbce.type; > + if (ISNULL(user_gbce.table)) { > + dev_err(dev, "get_gbce_params:" " Invalid table ptr"); > + return -EINVAL; > + } > + if (copy_to_user(user_gbce.table, > + gbce.table, > + (MAX_SIZE_GBCE_LUT * > + sizeof(unsigned short)))) { > + dev_err(dev, > + "get_gbce_params:Table Error in" " copy to user\n"); > + return -EFAULT; > + } > + > + if (copy_to_user(gbce_param, &user_gbce, sizeof(struct prev_gbce))) { > + dev_err(dev, "get_gbce_params: Error in copy" " to user\n"); > + return -EFAULT; > + } > + > + return 0; > +} > + > +static int validate_yuv422_conv_params(struct device *dev) > +{ > +#ifdef CONFIG_IPIPE_PARAM_VALIDATION > + if (yuv422_conv.en_chrom_lpf > 1) > + return -EINVAL; > +#endif > + return 0; > +} > + > +static int set_yuv422_conv_params(struct device *dev, void *param, int len) > +{ > + struct prev_yuv422_conv *yuv422_conv_param = > + (struct prev_yuv422_conv *)param; > + > + if (ISNULL(yuv422_conv_param)) { > + /* Copy defaults for yuv 422 conversion */ > + memcpy((void *)&yuv422_conv, > + (void *)&dm365_yuv422_conv_defaults, > + sizeof(struct prev_yuv422_conv)); > + } else { > + if (len != sizeof(struct prev_yuv422_conv)) { > + dev_err(dev, > + "set_yuv422_conv_params: param struct" > + " length mismatch\n"); > + return -EINVAL; > + } > + if (copy_from_user(&yuv422_conv, > + yuv422_conv_param, > + sizeof(struct prev_yuv422_conv))) { > + dev_err(dev, > + "set_yuv422_conv_params: Error in copy" > + " from user\n"); > + return -EFAULT; > + } > + if (validate_yuv422_conv_params(dev) < 0) > + return -EINVAL; > + } > + > + ipipe_set_yuv422_conv_regs(&yuv422_conv); > + > + return 0; > +} > +static int get_yuv422_conv_params(struct device *dev, void *param, int len) > +{ > + struct prev_yuv422_conv *yuv422_conv_param = > + (struct prev_yuv422_conv *)param; > + > + if (ISNULL(yuv422_conv_param)) { > + dev_err(dev, "get_yuv422_conv_params: invalid user ptr"); > + return -EINVAL; > + } > + if (len != sizeof(struct prev_yuv422_conv)) { > + dev_err(dev, > + "get_yuv422_conv_params: param struct" > + " length mismatch\n"); > + return -EINVAL; > + } > + if (copy_to_user(yuv422_conv_param, > + &yuv422_conv, > + sizeof(struct prev_yuv422_conv))) { > + dev_err(dev, > + "get_yuv422_conv_params: Error in copy from kernel\n"); > + return -EFAULT; > + } > + > + return 0; > +} > + > +static int validate_yee_params(struct device *dev) > +{ > +#ifdef CONFIG_IPIPE_PARAM_VALIDATION > + int i; > + > + if (yee.en > 1 || > + yee.en_halo_red > 1 || > + yee.hpf_shft > YEE_HPF_SHIFT_MASK) > + return -EINVAL; > + > + if (yee.hpf_coef_00 > YEE_COEF_MASK || > + yee.hpf_coef_01 > YEE_COEF_MASK || > + yee.hpf_coef_02 > YEE_COEF_MASK || > + yee.hpf_coef_10 > YEE_COEF_MASK || > + yee.hpf_coef_11 > YEE_COEF_MASK || > + yee.hpf_coef_12 > YEE_COEF_MASK || > + yee.hpf_coef_20 > YEE_COEF_MASK || > + yee.hpf_coef_21 > YEE_COEF_MASK || > + yee.hpf_coef_22 > YEE_COEF_MASK) > + return -EINVAL; > + > + if (yee.yee_thr > YEE_THR_MASK || > + yee.es_gain > YEE_ES_GAIN_MASK || > + yee.es_thr1 > YEE_ES_THR1_MASK || > + yee.es_thr2 > YEE_THR_MASK || > + yee.es_gain_grad > YEE_THR_MASK || > + yee.es_ofst_grad > YEE_THR_MASK) > + return -EINVAL; > + > + for (i = 0; i < MAX_SIZE_YEE_LUT ; i++) > + if (yee.table[i] > YEE_ENTRY_MASK) > + return -EINVAL; > +#endif > + return 0; > +} > +static int set_yee_params(struct device *dev, void *param, int len) > +{ > + struct prev_yee *yee_param = (struct prev_yee *)param; > + struct prev_yee user_yee; > + short *temp_table; > + > + if (ISNULL(yee_param)) { > + temp_table = yee.table; > + /* Copy defaults for ns */ > + memcpy((void *)&yee, > + (void *)&dm365_yee_defaults, > + sizeof(struct prev_yee)); > + yee.table = temp_table; > + } else { > + if (len != sizeof(struct prev_yee)) { > + dev_err(dev, > + "set_yee_params: param struct" > + " length mismatch\n"); > + return -EINVAL; > + } > + if (copy_from_user(&user_yee, > + yee_param, > + sizeof(struct prev_yee))) { > + dev_err(dev, > + "set_yee_params: Error in copy from user\n"); > + return -EFAULT; > + } > + if (ISNULL(user_yee.table)) { > + dev_err(dev, "get_yee_params: yee table ptr null\n"); > + return -EINVAL; > + } > + if (copy_from_user(yee.table, > + user_yee.table, > + (MAX_SIZE_YEE_LUT * sizeof(short)))) { > + dev_err(dev, > + "set_yee_params: Error in copy from user\n"); > + return -EFAULT; > + } > + temp_table = yee.table; > + memcpy(&yee, &user_yee, sizeof(struct prev_yee)); > + yee.table = temp_table; > + if (validate_yee_params(dev) < 0) > + return -EINVAL; > + } > + > + ipipe_set_ee_regs(&yee); > + > + return 0; > +} > +static int get_yee_params(struct device *dev, void *param, int len) > +{ > + struct prev_yee *yee_param = (struct prev_yee *)param; > + struct prev_yee user_yee; > + short *temp_table; > + > + if (ISNULL(yee_param)) { > + dev_err(dev, "get_yee_params: invalid user ptr"); > + return -EINVAL; > + } > + if (len != sizeof(struct prev_yee)) { > + dev_err(dev, > + "get_yee_params: param struct" > + " length mismatch\n"); > + return -EINVAL; > + } > + if (copy_from_user(&user_yee, yee_param, sizeof(struct prev_yee))) { > + dev_err(dev, "get_yee_params: Error in copy to kernel\n"); > + return -EFAULT; > + } > + if (ISNULL(user_yee.table)) { > + dev_err(dev, "get_yee_params: yee table ptr null\n"); > + return -EINVAL; > + } > + if (copy_to_user(user_yee.table, yee.table, > + (MAX_SIZE_YEE_LUT * sizeof(short)))) { > + dev_err(dev, "get_yee_params: Error in copy from kernel\n"); > + return -EFAULT; > + } > + temp_table = user_yee.table; > + memcpy(&user_yee, &yee, sizeof(struct prev_yee)); > + user_yee.table = temp_table; > + > + if (copy_to_user(yee_param, &user_yee, sizeof(struct prev_yee))) { > + dev_err(dev, "get_yee_params: Error in copy from kernel\n"); > + return -EFAULT; > + } > + > + return 0; > +} > + > +static int validate_car_params(struct device *dev) > +{ > +#ifdef CONFIG_IPIPE_PARAM_VALIDATION > + if (car.en > 1 || > + car.hpf_shft > CAR_HPF_SHIFT_MASK || > + car.gain1.shft > CAR_GAIN1_SHFT_MASK || > + car.gain1.gain_min > CAR_GAIN_MIN_MASK || > + car.gain2.shft > CAR_GAIN2_SHFT_MASK || > + car.gain2.gain_min > CAR_GAIN_MIN_MASK) > + return -EINVAL; > +#endif > + return 0; > +} > + > +static int set_car_params(struct device *dev, void *param, int len) > +{ > + struct prev_car *car_param = (struct prev_car *)param; > + > + if (ISNULL(car_param)) { > + /* Copy defaults for ns */ > + memcpy((void *)&car, > + (void *)&dm365_car_defaults, > + sizeof(struct prev_car)); > + } else { > + if (len != sizeof(struct prev_car)) { > + dev_err(dev, > + "set_car_params: param struct" > + " length mismatch\n"); > + return -EINVAL; > + } > + if (copy_from_user(&car, car_param, sizeof(struct prev_car))) { > + dev_err(dev, > + "set_car_params: Error in copy from user\n"); > + return -EFAULT; > + } > + if (validate_car_params(dev) < 0) > + return -EINVAL; > + } > + > + ipipe_set_car_regs(&car); > + > + return 0; > +} > +static int get_car_params(struct device *dev, void *param, int len) > +{ > + struct prev_car *car_param = (struct prev_car *)param; > + > + if (ISNULL(car_param)) { > + dev_err(dev, "get_car_params: invalid user ptr"); > + return -EINVAL; > + } > + if (len != sizeof(struct prev_car)) { > + dev_err(dev, > + "get_car_params: param struct" > + " length mismatch\n"); > + return -EINVAL; > + } > + if (copy_to_user(car_param, &car, sizeof(struct prev_car))) { > + dev_err(dev, "get_car_params: Error in copy from kernel\n"); > + return -EFAULT; > + } > + > + return 0; > +} > + > +static int validate_cgs_params(struct device *dev) > +{ > +#ifdef CONFIG_IPIPE_PARAM_VALIDATION > + if (cgs.en > 1 || > + cgs.h_shft > CAR_SHIFT_MASK) > + return -EINVAL; > +#endif > + return 0; > +} > + > +static int set_cgs_params(struct device *dev, void *param, int len) > +{ > + struct prev_cgs *cgs_param = (struct prev_cgs *)param; > + > + if (ISNULL(cgs_param)) { > + /* Copy defaults for ns */ > + memcpy((void *)&cgs, > + (void *)&dm365_cgs_defaults, > + sizeof(struct prev_cgs)); > + } else { > + if (len != sizeof(struct prev_cgs)) { > + dev_err(dev, > + "set_cgs_params: param struct" > + " length mismatch\n"); > + return -EINVAL; > + } > + if (copy_from_user(&cgs, cgs_param, sizeof(struct prev_cgs))) { > + dev_err(dev, > + "set_cgs_params: Error in copy from user\n"); > + return -EFAULT; > + } > + if (validate_cgs_params(dev) < 0) > + return -EINVAL; > + } > + > + ipipe_set_cgs_regs(&cgs); > + > + return 0; > +} > + > +static int get_cgs_params(struct device *dev, void *param, int len) > +{ > + struct prev_cgs *cgs_param = (struct prev_cgs *)param; > + > + if (ISNULL(cgs_param)) { > + dev_err(dev, "get_cgs_params: invalid user ptr"); > + return -EINVAL; > + } > + if (len != sizeof(struct prev_cgs)) { > + dev_err(dev, > + "get_cgs_params: param struct" > + " length mismatch\n"); > + return -EINVAL; > + } > + if (copy_to_user(cgs_param, &cgs, sizeof(struct prev_cgs))) { > + dev_err(dev, "get_cgs_params: Error in copy from kernel\n"); > + return -EFAULT; > + } > + > + return 0; > +} > + > +static struct prev_module_if prev_modules[PREV_MAX_MODULES] = { > + { > + .version = "5.1", > + .module_id = PREV_LUTDPC, > + .module_name = "LUT Defect Correction", > + .control = 0, > + .path = IMP_RAW2RAW | IMP_RAW2YUV, > + .set = set_lutdpc_params, > + .get = get_lutdpc_params > + }, > + { > + .version = "5.1", > + .module_id = PREV_OTFDPC, > + .module_name = "OTF Defect Pixel Correction", > + .control = 0, > + .path = IMP_RAW2RAW | IMP_RAW2YUV, > + .set = set_otfdpc_params, > + .get = get_otfdpc_params > + }, > + { > + .version = "5.1", > + .module_id = PREV_NF1, > + .module_name = "2-D Noise filter - 1", > + .control = 0, > + .path = IMP_RAW2RAW | IMP_RAW2YUV, > + .set = set_nf1_params, > + .get = get_nf1_params > + }, > + { > + .version = "5.1", > + .module_id = PREV_NF2, > + .module_name = "2-D Noise filter - 2", > + .control = 0, > + .path = IMP_RAW2RAW | IMP_RAW2YUV, > + .set = set_nf2_params, > + .get = get_nf2_params > + }, > + { > + .version = "5.1", > + .module_id = PREV_GIC, > + .module_name = "Green Imbalance Correction", > + .control = 0, > + .path = IMP_RAW2RAW | IMP_RAW2YUV, > + .set = set_gic_params, > + .get = get_gic_params > + }, > + { > + .version = "5.1", > + .module_id = PREV_WB, > + .module_name = "White balance", > + .control = 1, > + .path = IMP_RAW2RAW | IMP_RAW2YUV, > + .set = set_wb_params, > + .get = get_wb_params > + }, > + { > + .version = "5.1", > + .module_id = PREV_CFA, > + .module_name = "CFA Interpolation", > + .control = 0, > + .path = IMP_RAW2YUV, > + .set = set_cfa_params, > + .get = get_cfa_params > + }, > + { > + .version = "5.1", > + .module_id = PREV_RGB2RGB_1, > + .module_name = "RGB-RGB Conversion - 1", > + .control = 0, > + .path = IMP_RAW2YUV, > + .set = set_rgb2rgb_1_params, > + .get = get_rgb2rgb_1_params > + }, > + { > + .version = "5.1", > + .module_id = PREV_GAMMA, > + .module_name = "Gamma Correction", > + .control = 0, > + .path = IMP_RAW2YUV, > + .set = set_gamma_params, > + .get = get_gamma_params > + }, > + { > + .version = "5.1", > + .module_id = PREV_RGB2RGB_2, > + .module_name = "RGB-RGB Conversion - 2", > + .control = 0, > + .path = IMP_RAW2YUV, > + .set = set_rgb2rgb_2_params, > + .get = get_rgb2rgb_2_params > + }, > + { > + .version = "5.1", > + .module_id = PREV_3D_LUT, > + .module_name = "3D LUT", > + .control = 0, > + .path = IMP_RAW2YUV, > + .set = set_3d_lut_params, > + .get = get_3d_lut_params > + }, > + { > + .version = "5.1", > + .module_id = PREV_RGB2YUV, > + .module_name = "RGB-YCbCr conversion", > + .control = 0, > + .path = IMP_RAW2YUV, > + .set = set_rgb2yuv_params, > + .get = get_rgb2yuv_params > + }, > + { > + .version = "5.1", > + .module_id = PREV_GBCE, > + .module_name = "Global Brightness,Contrast Control", > + .control = 0, > + .path = IMP_RAW2YUV, > + .set = set_gbce_params, > + .get = get_gbce_params > + }, > + { > + .version = "5.1", > + .module_id = PREV_YUV422_CONV, > + .module_name = "YUV 422 conversion", > + .control = 0, > + .path = IMP_RAW2YUV, > + .set = set_yuv422_conv_params, > + .get = get_yuv422_conv_params > + }, > + { > + .version = "5.1", > + .module_id = PREV_LUM_ADJ, > + .module_name = "Luminance Adjustment", > + .control = 1, > + .path = IMP_RAW2YUV, > + .set = set_lum_adj_params, > + .get = get_lum_adj_params > + }, > + { > + .version = "5.1", > + .module_id = PREV_YEE, > + .module_name = "Edge Enhancer", > + .control = 1, > + .path = IMP_RAW2YUV | IMP_YUV2YUV, > + .set = set_yee_params, > + .get = get_yee_params > + }, > + { > + .version = "5.1", > + .module_id = PREV_CAR, > + .module_name = "Chromatic Artifact Reduction", > + .control = 1, > + .path = IMP_RAW2YUV | IMP_YUV2YUV, > + .set = set_car_params, > + .get = get_car_params > + }, > + { > + .version = "5.1", > + .module_id = PREV_CGS, > + .module_name = "Chromatic Gain Suppression", > + .control = 1, > + .path = IMP_RAW2YUV | IMP_YUV2YUV, > + .set = set_cgs_params, > + .get = get_cgs_params > + } > +}; > + > +static struct prev_module_if *prev_enum_preview_cap(struct device *dev, > + int index) > +{ > + dev_dbg(dev, "prev_enum_preview_cap: index = %d\n", index); > + > + if ((index + 1) > PREV_MAX_MODULES) > + return NULL; if (index < 0 || index >= PREV_MAX_MODULES) return NULL; You might want to use unsigned for index as well. That avoids some traps. > + return &prev_modules[index]; > +} > + > +static int ipipe_set_oper_mode(unsigned int mode) > +{ > + if (oper_mode == IMP_MODE_NOT_CONFIGURED) > + oper_mode = mode; > + else { > + printk(KERN_ERR "IPIPE is already active!\n"); > + return -EINVAL; > + } > + > + return 0; > +} > + > +static void ipipe_reset_oper_mode(void) > +{ > + oper_mode = IMP_MODE_NOT_CONFIGURED; > + oper_state.prev_config_state = STATE_NOT_CONFIGURED; > + oper_state.rsz_config_state = STATE_NOT_CONFIGURED; > + oper_state.rsz_chained = 0; > +} > + > +static unsigned int prev_get_oper_mode(void) > +{ > + return oper_mode; > +} > + > +static unsigned int ipipe_get_oper_state(void) > +{ > + return oper_state.state; > +} > + > +static void ipipe_set_oper_state(unsigned int state) > +{ > + mutex_lock(&oper_state.lock); > + oper_state.state = state; > + mutex_unlock(&oper_state.lock); > +} > + > +static unsigned int ipipe_get_prev_config_state(void) > +{ > + return oper_state.prev_config_state; > +} > + > +static unsigned int ipipe_get_rsz_config_state(void) > +{ > + return oper_state.rsz_config_state; > +} > + > +/* function: calculate_normal_f_div_param > + * Algorithm to calculate the frame division parameters for resizer. > + * in normal mode. Please refer the application note in DM360 functional > + * spec for details of the algorithm > + */ > +static int calculate_normal_f_div_param(struct device *dev, > + int input_width, > + int output_width, > + struct ipipe_rsz_rescale_param *param) > +{ > + /* rsz = R, input_width = H, output width = h in the equation */ > + unsigned int val1; > + unsigned int rsz; > + unsigned int val; > + unsigned int h1; > + unsigned int h2; > + unsigned int o; > + > + if (output_width > input_width) { > + dev_err(dev, "frame div mode is used for scale down only\n"); > + return -EINVAL; > + } > + > + rsz = (input_width << 8) / output_width; > + val = rsz << 1; > + val = ((input_width << 8) / val) + 1; > + o = 14; > + if (!(val % 2)) { > + h1 = val; > + } else { > + val = (input_width << 7); > + val -= (rsz >> 1); > + val /= (rsz << 1); > + val <<= 1; > + val += 2; > + o += ((CEIL(rsz, 1024)) << 1); > + h1 = val; > + } > + h2 = output_width - h1; > + /* phi */ > + val = (h1 * rsz) - (((input_width >> 1) - o) << 8); > + /* skip */ > + val1 = ((val - 1024) >> 9) << 1; > + param->f_div.num_passes = IPIPE_MAX_PASSES; > + param->f_div.pass[0].o_hsz = h1 - 1; > + param->f_div.pass[0].i_hps = 0; > + param->f_div.pass[0].h_phs = 0; > + param->f_div.pass[0].src_hps = 0; > + param->f_div.pass[0].src_hsz = (input_width >> 2) + o; > + param->f_div.pass[1].o_hsz = h2 - 1; > + param->f_div.pass[1].i_hps = val1; > + param->f_div.pass[1].h_phs = (val - (val1 << 8)); > + param->f_div.pass[1].src_hps = (input_width >> 2) - o; > + param->f_div.pass[1].src_hsz = (input_width >> 2) + o; > + > + return 0; > +} > + > +/* function: calculate_down_scale_f_div_param > + * Algorithm to calculate the frame division parameters for resizer in > + * downscale mode. Please refer the application note in DM360 functional > + * spec for details of the algorithm > + */ > +static int calculate_down_scale_f_div_param(struct device *dev, > + int input_width, > + int output_width, > + struct ipipe_rsz_rescale_param > + *param) > +{ > + /* rsz = R, input_width = H, output width = h in the equation */ > + unsigned int two_power; > + unsigned int upper_h1; > + unsigned int upper_h2; > + unsigned int val1; > + unsigned int val; > + unsigned int rsz; > + unsigned int h1; > + unsigned int h2; > + unsigned int o; > + unsigned int n; > + > + upper_h1 = input_width >> 1; > + n = param->h_dscale_ave_sz; > + /* 2 ^ (scale+1) */ > + two_power = 1 << (n + 1); > + upper_h1 = (upper_h1 >> (n + 1)) << (n + 1); > + upper_h2 = input_width - upper_h1; > + if (upper_h2 % two_power) { > + dev_err(dev, "frame halves to be a multiple of 2 power n+1\n"); > + return -EINVAL; > + } > + two_power = 1 << n; > + rsz = (input_width << 8) / output_width; > + val = rsz * two_power; > + val = ((upper_h1 << 8) / val) + 1; > + if (!(val % 2)) > + h1 = val; > + else { > + val = (upper_h1 << 8); > + val >>= (n + 1); > + val -= (rsz >> 1); > + val /= (rsz << 1); > + val <<= 1; > + val += 2; > + h1 = val; > + } > + o = 10 + (two_power << 2); > + if (((input_width << 7) / rsz) % 2) > + o += (((CEIL(rsz, 1024)) << 1) << n); > + h2 = output_width - h1; > + /* phi */ > + val = (h1 * rsz) - (((upper_h1 - (o - 10)) / two_power) << 8); > + /* skip */ > + val1 = ((val - 1024) >> 9) << 1; > + param->f_div.num_passes = IPIPE_MAX_PASSES; > + param->f_div.pass[0].o_hsz = h1 - 1; > + param->f_div.pass[0].i_hps = 0; > + param->f_div.pass[0].h_phs = 0; > + param->f_div.pass[0].src_hps = 0; > + param->f_div.pass[0].src_hsz = upper_h1 + o; > + param->f_div.pass[1].o_hsz = h2 - 1; > + param->f_div.pass[1].i_hps = 10 + (val1 * two_power); > + param->f_div.pass[1].h_phs = (val - (val1 << 8)); > + param->f_div.pass[1].src_hps = (upper_h1 - o); > + param->f_div.pass[1].src_hsz = (upper_h2 + o); > + > + return 0; > +} > + > +/* update the parameter in param for a given input and output width */ > +static int update_preview_f_div_params(struct device *dev, > + int input_width, > + int output_width, > + struct ipipe_rsz_rescale_param *param) > +{ > + unsigned int val; > + > + val = input_width >> 1; > + if (val < 8) { > + dev_err(dev, "input width must me atleast 16 pixels\n"); > + return -EINVAL; > + } > + param->f_div.en = 1; > + param->f_div.num_passes = IPIPE_MAX_PASSES; > + param->f_div.pass[0].o_hsz = val; > + param->f_div.pass[0].i_hps = 0; > + param->f_div.pass[0].h_phs = 0; > + param->f_div.pass[0].src_hps = 0; > + param->f_div.pass[0].src_hsz = val + 10; > + param->f_div.pass[1].o_hsz = val; > + param->f_div.pass[1].i_hps = 0; > + param->f_div.pass[1].h_phs = 0; > + param->f_div.pass[1].src_hps = val - 8; > + param->f_div.pass[1].src_hsz = val + 10; > + > + return 0; > +} > + > +/* Use shared to allocate exclusive blocks as required > + * by resize applications in single shot mode > + */ > +static void *ipipe_alloc_config_block(struct device *dev) > +{ > + /* return common data block */ > + mutex_lock(&oper_state.lock); > + if (oper_state.resource_in_use) { > + dev_err(dev, "resource in use\n"); > + mutex_unlock(&oper_state.lock); > + return NULL; > + } > + mutex_unlock(&oper_state.lock); > + > + return oper_state.shared_config_param; > +} > + > +/* Used to free only non-shared config block allocated through > + * imp_alloc_config_block > + */ > +static void ipipe_dealloc_config_block(struct device *dev, void *config_block) > +{ > + if (config_block) { > + if (config_block != oper_state.shared_config_param) > + kfree(config_block); > + else > + dev_err(dev, "Trying to free shared config block\n"); > + } > +} > + > +static void ipipe_dealloc_user_config_block(struct device *dev, > + void *config_block) > +{ > + kfree(config_block); > +} > + > +static void *ipipe_alloc_user_config_block(struct device *dev, > + enum imp_log_chan_t chan_type, > + int *len) > +{ > + void *config = NULL; > + > + if (oper_mode == IMP_MODE_SINGLE_SHOT) { > + if (chan_type == IMP_PREVIEWER) { > + config = > + kmalloc(sizeof(struct prev_single_shot_config), > + GFP_KERNEL); > + *len = sizeof(struct prev_single_shot_config); > + } else if (chan_type == IMP_RESIZER) { > + config = > + kmalloc(sizeof(struct rsz_single_shot_config), > + GFP_KERNEL); > + *len = sizeof(struct rsz_single_shot_config); > + } > + > + } else { > + if (chan_type == IMP_PREVIEWER) { > + config = > + kmalloc(sizeof(struct prev_continuous_config), > + GFP_KERNEL); > + *len = sizeof(struct prev_continuous_config); > + } else if (chan_type == IMP_RESIZER) { > + config = > + kmalloc(sizeof(struct rsz_continuous_config), > + GFP_KERNEL); > + *len = sizeof(struct rsz_continuous_config); > + } > + } > + > + return config; > +} > + > +static void ipipe_set_user_config_defaults(struct device *dev, > + enum imp_log_chan_t chan_type, > + void *config) > +{ > + dev_dbg(dev, "ipipe_set_user_config_defaults\n"); > + > + if (oper_mode == IMP_MODE_SINGLE_SHOT) { > + if (chan_type == IMP_PREVIEWER) { > + dev_dbg(dev, "SS-Preview\n"); > + /* preview channel in single shot mode */ > + memcpy(config, > + (void *)&dm365_prev_ss_config_defs, > + sizeof(struct prev_single_shot_config)); > + } else { > + dev_dbg(dev, "SS-Resize\n"); > + /* resizer channel in single shot mode */ > + memcpy(config, > + (void *)&dm365_rsz_ss_config_defs, > + sizeof(struct rsz_single_shot_config)); > + } > + } else if (oper_mode == IMP_MODE_CONTINUOUS) { > + /* Continuous mode */ > + if (chan_type == IMP_PREVIEWER) { > + dev_dbg(dev, "Cont Preview\n"); > + /* previewer defaults */ > + memcpy(config, > + (void *)&dm365_prev_cont_config_defs, > + sizeof(struct prev_continuous_config)); > + } else { > + dev_dbg(dev, "Cont resize\n"); > + /* resizer defaults */ > + memcpy(config, > + (void *)&dm365_rsz_cont_config_defs, > + sizeof(struct rsz_continuous_config)); > + } > + } else > + dev_err(dev, "Incorrect mode used\n"); > +} > + > +/* function :calculate_sdram_offsets() > + * This function calculates the offsets from start of buffer for the C > + * plane when output format is YUV420SP. It also calculates the offsets > + * from the start of the buffer when the image is flipped vertically > + * or horizontally for ycbcr/y/c planes > + */ > +static int calculate_sdram_offsets(struct ipipe_params *param, int index) > +{ > + int bytesperline = 2; > + int image_height; > + int image_width; > + int yuv_420; > + int offset; > + > + if (!param->rsz_en[index]) > + return -EINVAL; > + > + image_height = param->rsz_rsc_param[index].o_vsz + 1; > + image_width = param->rsz_rsc_param[index].o_hsz + 1; > + param->ext_mem_param[index].c_offset = 0; > + param->ext_mem_param[index].flip_ofst_y = 0; > + param->ext_mem_param[index].flip_ofst_c = 0; > + if ((param->ipipe_dpaths_fmt != IPIPE_RAW2RAW) && > + (param->ipipe_dpaths_fmt != IPIPE_RAW2BOX) && No need for extra parenthesis. > + param->rsz_rsc_param[index].cen && > + param->rsz_rsc_param[index].yen) { > + /* YUV 420 */ > + yuv_420 = 1; > + bytesperline = 1; bytesperline == 1? Really? > + } > + > + /* set offset value */ > + offset = 0; > + > + if (param->rsz_rsc_param[index].h_flip) > + /* width * bytesperline - 1 */ > + offset = (image_width * bytesperline) - 1; > + if (param->rsz_rsc_param[index].v_flip) > + offset += (image_height - 1) * > + param->ext_mem_param[index].rsz_sdr_oft_y; > + param->ext_mem_param[index].flip_ofst_y = offset; > + if (yuv_420) { > + offset = 0; > + /* half height for c-plane */ > + if (param->rsz_rsc_param[index].h_flip) > + /* width * bytesperline - 1 */ > + offset = image_width - 1; > + if (param->rsz_rsc_param[index].v_flip) > + offset += (((image_height >> 1) - 1) * > + param->ext_mem_param[index]. > + rsz_sdr_oft_c); > + param->ext_mem_param[index].flip_ofst_c = > + offset; > + param->ext_mem_param[index].c_offset = > + param->ext_mem_param[index]. > + rsz_sdr_oft_y * image_height; > + } > + > + return 0; > +} > + > +static void enable_422_420_conversion(struct ipipe_params *param, > + int index, enum enable_disable_t en) > +{ > + /* Enable 422 to 420 conversion */ > + param->rsz_rsc_param[index].cen = en; > + param->rsz_rsc_param[index].yen = en; > +} > + > +static void configure_resizer_out_params(struct ipipe_params *param, > + int index, > + void *output_spec, > + unsigned char partial, unsigned flag) > +{ > + if (partial) { > + struct rsz_part_output_spec *partial_output = > + (struct rsz_part_output_spec *)output_spec; > + if (partial_output->enable) { > + param->rsz_en[index] = ENABLE; > + param->rsz_rsc_param[index].h_flip = > + partial_output->h_flip; > + param->rsz_rsc_param[index].v_flip = > + partial_output->v_flip; > + param->rsz_rsc_param[index].v_typ_y = > + partial_output->v_typ_y; > + param->rsz_rsc_param[index].v_typ_c = > + partial_output->v_typ_c; > + param->rsz_rsc_param[index].v_lpf_int_y = > + partial_output->v_lpf_int_y; > + param->rsz_rsc_param[index].v_lpf_int_c = > + partial_output->v_lpf_int_c; > + param->rsz_rsc_param[index].h_typ_y = > + partial_output->h_typ_y; > + param->rsz_rsc_param[index].h_typ_c = > + partial_output->h_typ_c; > + param->rsz_rsc_param[index].h_lpf_int_y = > + partial_output->h_lpf_int_y; > + param->rsz_rsc_param[index].h_lpf_int_c = > + partial_output->h_lpf_int_c; > + param->rsz_rsc_param[index].dscale_en = > + partial_output->en_down_scale; > + param->rsz_rsc_param[index].h_dscale_ave_sz = > + partial_output->h_dscale_ave_sz; > + param->rsz_rsc_param[index].v_dscale_ave_sz = > + partial_output->v_dscale_ave_sz; > + param->ext_mem_param[index].user_y_ofst = > + (partial_output->user_y_ofst + 31) & ~0x1F; > + param->ext_mem_param[index].user_c_ofst = > + (partial_output->user_c_ofst + 31) & ~0x1F; > + > + } else > + param->rsz_en[index] = DISABLE; > + > + } else { > + struct rsz_output_spec *output = > + (struct rsz_output_spec *)output_spec; > + if (output->enable) { > + param->rsz_en[index] = ENABLE; > + param->rsz_rsc_param[index].o_vsz = output->height - 1; > + param->rsz_rsc_param[index].o_hsz = output->width - 1; > + param->ext_mem_param[index].rsz_sdr_ptr_s_y = > + output->vst_y; > + param->ext_mem_param[index].rsz_sdr_ptr_e_y = > + output->height; > + param->ext_mem_param[index].rsz_sdr_ptr_s_c = > + output->vst_c; > + param->ext_mem_param[index].rsz_sdr_ptr_e_c = > + output->height; > + > + if (flag) { > + /* update common parameters */ > + param->rsz_rsc_param[index].h_flip = > + output->h_flip; > + param->rsz_rsc_param[index].v_flip = > + output->v_flip; > + param->rsz_rsc_param[index].v_typ_y = > + output->v_typ_y; > + param->rsz_rsc_param[index].v_typ_c = > + output->v_typ_c; > + param->rsz_rsc_param[index].v_lpf_int_y = > + output->v_lpf_int_y; > + param->rsz_rsc_param[index].v_lpf_int_c = > + output->v_lpf_int_c; > + param->rsz_rsc_param[index].h_typ_y = > + output->h_typ_y; > + param->rsz_rsc_param[index].h_typ_c = > + output->h_typ_c; > + param->rsz_rsc_param[index].h_lpf_int_y = > + output->h_lpf_int_y; > + param->rsz_rsc_param[index].h_lpf_int_c = > + output->h_lpf_int_c; > + param->rsz_rsc_param[index].dscale_en = > + output->en_down_scale; > + param->rsz_rsc_param[index].h_dscale_ave_sz = > + output->h_dscale_ave_sz; > + param->rsz_rsc_param[index].v_dscale_ave_sz = > + output->h_dscale_ave_sz; > + param->ext_mem_param[index].user_y_ofst = > + (output->user_y_ofst + 31) & ~0x1F; > + param->ext_mem_param[index].user_c_ofst = > + (output->user_c_ofst + 31) & ~0x1F; > + } > + } else > + param->rsz_en[index] = DISABLE; > + } > + > +} > + > +/* function :calculate_line_length() > + * This function calculates the line length of various image > + * planes at the input and output > + */ > +static void calculate_line_length(enum ipipe_pix_formats pix, > + int width, > + int height, int *line_len, int *line_len_c) > +{ > + *line_len = 0; > + *line_len_c = 0; > + > + if ((pix == IPIPE_UYVY) || (pix == IPIPE_BAYER)) > + *line_len = width << 1; > + else if (pix == IPIPE_420SP_Y || pix == IPIPE_420SP_C) { > + *line_len = width; > + *line_len_c = width; > + } else { > + /* YUV 420 */ > + /* round width to upper 32 byte boundary */ > + *line_len = width; > + *line_len_c = width; > + } > + /* adjust the line len to be a multiple of 32 */ > + *line_len += 31; > + *line_len &= ~0x1f; > + *line_len_c += 31; > + *line_len_c &= ~0x1f; > +} > + > +static inline int rsz_validate_input_image_format(struct device *dev, > + enum ipipe_pix_formats pix, > + int width, > + int height, int *line_len) > +{ > + int val; > + > + if (pix != IPIPE_UYVY && pix != IPIPE_420SP_Y && > + pix != IPIPE_420SP_C) { > + dev_err(dev, > + "rsz_validate_out_pix_formats" > + "pix format not supported, %d\n", pix); > + return -EINVAL; > + } > + > + if (width == 0 || height == 0) { > + dev_err(dev, "validate_line_length: invalid " > + "width or height\n"); > + return -EINVAL; > + } > + > + if (pix == IPIPE_420SP_C) > + calculate_line_length(pix, > + width, > + height, > + &val, > + line_len); > + else > + calculate_line_length(pix, > + width, > + height, > + line_len, > + &val); > + > + return 0; > +} > + > +static inline int rsz_validate_output_image_format(struct device *dev, > + enum ipipe_pix_formats pix, > + int width, > + int height, > + int *in_line_len, > + int *in_line_len_c) > +{ > + if (pix != IPIPE_UYVY && pix != IPIPE_420SP_Y && > + pix != IPIPE_420SP_C && pix != IPIPE_YUV420SP && > + pix != IPIPE_BAYER) { > + dev_err(dev, > + "rsz_validate_out_pix_formats" > + "pix format not supported, %d\n", pix); > + return -EINVAL; > + } > + > + if (width == 0 || height == 0) { > + dev_err(dev, "validate_line_length: invalid" > + " width or height\n"); > + return -EINVAL; > + } > + > + calculate_line_length(pix, > + width, > + height, in_line_len, in_line_len_c); > + return 0; > +} > + > +static void configure_common_rsz_params(struct device *dev, > + struct ipipe_params *param, > + struct rsz_single_shot_config *ss_config) > +{ > + param->rsz_common.yuv_y_min = ss_config->yuv_y_min; > + param->rsz_common.yuv_y_max = ss_config->yuv_y_max; > + param->rsz_common.yuv_c_min = ss_config->yuv_c_min; > + param->rsz_common.yuv_c_max = ss_config->yuv_c_max; > + param->rsz_common.out_chr_pos = ss_config->out_chr_pos; > + param->rsz_common.rsz_seq_crv = ss_config->chroma_sample_even; > + > +} > + > +static int configure_common_rsz_in_params(struct device *dev, > + struct ipipe_params *param, > + int flag, int rsz_chained, > + void *input_spec) > +{ > + enum ipipe_pix_formats pix; > + > + if (!flag) { > + struct prev_ss_input_spec *in_specs = > + (struct prev_ss_input_spec *)input_spec; > + param->rsz_common.vsz = in_specs->image_height - 1; > + param->rsz_common.hsz = in_specs->image_width - 1; > + pix = in_specs->pix_fmt; > + } else { > + struct rsz_ss_input_spec *in_specs = > + (struct rsz_ss_input_spec *)input_spec; > + if (!rsz_chained) { > + param->rsz_common.vps = in_specs->vst; > + param->rsz_common.hps = in_specs->hst; > + } > + param->rsz_common.vsz = in_specs->image_height - 1; > + param->rsz_common.hsz = in_specs->image_width - 1; > + pix = in_specs->pix_fmt; > + } > + switch (pix) { > + case IPIPE_BAYER_8BIT_PACK: > + case IPIPE_BAYER_8BIT_PACK_ALAW: > + case IPIPE_BAYER_8BIT_PACK_DPCM: > + case IPIPE_BAYER_12BIT_PACK: > + case IPIPE_BAYER: > + param->rsz_common.src_img_fmt = RSZ_IMG_422; > + param->rsz_common.source = IPIPE_DATA; > + break; > + case IPIPE_UYVY: > + param->rsz_common.src_img_fmt = RSZ_IMG_422; > + if (rsz_chained) > + param->rsz_common.source = IPIPE_DATA; > + else > + param->rsz_common.source = IPIPEIF_DATA; > + param->rsz_common.raw_flip = 0; > + break; > + case IPIPE_420SP_Y: > + param->rsz_common.src_img_fmt = RSZ_IMG_420; > + /* Select y */ > + param->rsz_common.y_c = 0; > + param->rsz_common.source = IPIPEIF_DATA; > + param->rsz_common.raw_flip = 0; > + break; > + case IPIPE_420SP_C: > + param->rsz_common.src_img_fmt = RSZ_IMG_420; > + /* Select y */ > + param->rsz_common.y_c = 1; > + param->rsz_common.source = IPIPEIF_DATA; > + param->rsz_common.raw_flip = 0; > + break; > + default: > + return -EINVAL; > + } > + > + return 0; > +} > + > +static int validate_ipipeif_decimation(struct device *dev, > + enum ipipeif_decimation dec_en, > + unsigned char rsz, > + unsigned char frame_div_mode_en, > + int width) > +{ > + if (dec_en && frame_div_mode_en) { > + dev_err(dev, > + "Both dec_en & frame_div_mode_en" > + "can not enabled simultaneously\n"); > + return -EINVAL; > + } > + if (frame_div_mode_en) { > + dev_err(dev, "frame_div_mode mode not supported"); > + return -EINVAL; > + } > + if (dec_en) { > + if (width <= IPIPE_MAX_INPUT_WIDTH) { > + dev_err(dev, > + "image width to be more than" > + " %d for decimation\n", IPIPE_MAX_INPUT_WIDTH); > + return -EINVAL; > + } > + if ((rsz < IPIPEIF_RSZ_MIN) || (rsz > IPIPEIF_RSZ_MAX)) { > + dev_err(dev, "rsz range is %d to %d\n", > + IPIPEIF_RSZ_MIN, IPIPEIF_RSZ_MAX); > + return -EINVAL; > + } > + } > + > + return 0; > +} > + > +static int configure_resizer_in_ss_mode(struct device *dev, > + void *user_config, > + int resizer_chained, > + struct ipipe_params *param) > +{ > + /* resizer in standalone mode. In this mode if serializer > + * is enabled, we need to set config params in the hw. > + */ > + struct rsz_single_shot_config *ss_config = > + (struct rsz_single_shot_config *)user_config; > + int line_len_c; > + int line_len; > + int ret; > + > + ret = rsz_validate_input_image_format(dev, > + ss_config->input.pix_fmt, > + ss_config->input.image_width, > + ss_config->input.image_height, > + &line_len); > + > + if (ret) > + return -EINVAL; > + > + /* shared block */ > + if ((!ss_config->output1.enable) && (!ss_config->output2.enable)) { > + dev_err(dev, "One of the resizer output must be enabled\n"); > + return -EINVAL; > + } > + ret = mutex_lock_interruptible(&oper_state.lock); > + if (ret) > + return ret; > + if (!ss_config->input.line_length) > + param->ipipeif_param.adofs = line_len; > + else { > + param->ipipeif_param.adofs = ss_config->input.line_length; > + param->ipipeif_param.adofs = > + (param->ipipeif_param.adofs + 31) & ~0x1f; > + } > + if (ss_config->output1.enable) { > + param->rsz_en[RSZ_A] = ENABLE; > + param->rsz_rsc_param[RSZ_A].mode = IPIPEIF_ONE_SHOT; > + ret = rsz_validate_output_image_format(dev, > + ss_config->output1.pix_fmt, > + ss_config->output1.width, > + ss_config->output1.height, > + &line_len, &line_len_c); > + if (ret) { > + mutex_unlock(&oper_state.lock); > + return ret; > + } > + param->ext_mem_param[RSZ_A].rsz_sdr_oft_y = line_len; > + param->ext_mem_param[RSZ_A].rsz_sdr_oft_c = line_len_c; > + configure_resizer_out_params(param, > + RSZ_A, > + &ss_config->output1, > + 0, > + 1); > + > + if (ss_config->output1.pix_fmt == IMP_BAYER) > + param->rsz_common.raw_flip = 1; > + else > + param->rsz_common.raw_flip = 0; > + > + if (ss_config->output1.pix_fmt == IPIPE_YUV420SP) > + enable_422_420_conversion(param, RSZ_A, ENABLE); > + else > + enable_422_420_conversion(param, RSZ_A, > + DISABLE); > + } > + > + if (ss_config->output2.enable) { > + param->rsz_en[RSZ_A] = ENABLE; > + param->rsz_rsc_param[RSZ_B].mode = IPIPEIF_ONE_SHOT; > + ret = rsz_validate_output_image_format(dev, > + ss_config->output2.pix_fmt, > + ss_config->output2.width, > + ss_config->output2.height, > + &line_len, &line_len_c); > + if (ret) { > + mutex_unlock(&oper_state.lock); > + return ret; > + } > + param->ext_mem_param[RSZ_B].rsz_sdr_oft_y = line_len; > + param->ext_mem_param[RSZ_B].rsz_sdr_oft_c = line_len_c; > + configure_resizer_out_params(param, > + RSZ_B, > + &ss_config->output2, > + 0, > + 1); > + if (ss_config->output2.pix_fmt == IPIPE_YUV420SP) > + enable_422_420_conversion(param, RSZ_B, ENABLE); > + else > + enable_422_420_conversion(param, > + RSZ_B, > + DISABLE); > + } > + configure_common_rsz_params(dev, param, ss_config); > + if (resizer_chained) { > + oper_state.rsz_chained = 1; > + oper_state.rsz_config_state = STATE_CONFIGURED; > + } else { > + oper_state.rsz_chained = 0; > + ret = validate_ipipeif_decimation(dev, > + ss_config->input.dec_en, > + ss_config->input.rsz, > + ss_config->input. > + frame_div_mode_en, > + ss_config->input. > + image_width); > + if (ret) { > + mutex_unlock(&oper_state.lock); > + return ret; > + } > + > + if (ipipe_process_pix_fmts(ss_config->input.pix_fmt, > + ss_config->output1.pix_fmt, > + param) < 0) { > + dev_err(dev, "error in input or output pix format\n"); > + mutex_unlock(&oper_state.lock); > + return -EINVAL; > + } > + > + param->ipipeif_param.source = IPIPEIF_SDRAM_YUV; > + param->ipipeif_param.glob_hor_size = ss_config->input.ppln; > + param->ipipeif_param.glob_ver_size = ss_config->input.lpfr; > + param->ipipeif_param.hnum = ss_config->input.image_width; > + param->ipipeif_param.vnum = ss_config->input.image_height; > + param->ipipeif_param.var.if_5_1.clk_div = > + ss_config->input.clk_div; > + if (ss_config->input.dec_en) { > + param->ipipeif_param.decimation = IPIPEIF_DECIMATION_ON; > + param->ipipeif_param.rsz = ss_config->input.rsz; > + param->ipipeif_param.avg_filter = > + (enum ipipeif_avg_filter)ss_config->input. > + avg_filter_en; > + param->ipipe_hsz = > + (((ss_config->input.image_width * > + IPIPEIF_RSZ_CONST) / ss_config->input.rsz) - 1); > + } > + if (ss_config->input.pix_fmt == IPIPE_420SP_Y || > + ss_config->input.pix_fmt == IPIPE_420SP_C) { > + param->ipipeif_param.var.if_5_1.pack_mode > + = IPIPEIF_5_1_PACK_8_BIT; > + param->ipipeif_param.var.if_5_1.source1 = IPIPEIF_CCDC; > + param->ipipeif_param.var.if_5_1.isif_port.if_type > + = V4L2_MBUS_FMT_YUYV8_1X16; > + param->ipipeif_param.var.if_5_1.data_shift > + = IPIPEIF_5_1_BITS11_0; > + > + param->ipipeif_param.source = IPIPEIF_SDRAM_RAW; > + > + > + } > + if (ss_config->input.pix_fmt == IPIPE_420SP_C) > + param->ipipeif_param.var.if_5_1.isif_port.if_type > + = V4L2_MBUS_FMT_SBGGR10_1X10; > + param->ipipe_hsz = ss_config->input.image_width - 1; > + param->ipipe_vsz = ss_config->input.image_height - 1; > + param->ipipe_vps = ss_config->input.vst; > + param->ipipe_hps = ss_config->input.hst; > + param->ipipe_dpaths_fmt = IPIPE_YUV2YUV; > + configure_common_rsz_in_params(dev, param, 1, resizer_chained, > + &ss_config->input); > + if (param->rsz_en[RSZ_A]) { > + > + calculate_resize_ratios(param, RSZ_A); > + calculate_sdram_offsets(param, RSZ_A); > + > + /* Overriding resize ratio calculation */ > + if (ss_config->input.pix_fmt == IPIPE_420SP_C) { > + param->rsz_rsc_param[RSZ_A].v_dif = > + (((param->ipipe_vsz + 1) * 2) * 256) / > + (param->rsz_rsc_param[RSZ_A].o_vsz + 1); > + } > + } > + > + if (param->rsz_en[RSZ_B]) { > + calculate_resize_ratios(param, RSZ_B); > + calculate_sdram_offsets(param, RSZ_B); > + > + /* Overriding resize ratio calculation */ > + if (ss_config->input.pix_fmt == IPIPE_420SP_C) { > + param->rsz_rsc_param[RSZ_B].v_dif = > + (((param->ipipe_vsz + 1) * 2) * 256) / > + (param->rsz_rsc_param[RSZ_B].o_vsz + 1); > + } > + } > + } > + mutex_unlock(&oper_state.lock); > + > + return 0; > +} > + > +static int configure_resizer_in_cont_mode(struct device *dev, > + void *user_config, > + int resizer_chained, > + struct ipipe_params *param) > +{ > + /* Continuous mode. This is a shared config block */ > + struct rsz_continuous_config *cont_config = > + (struct rsz_continuous_config *)user_config; > + int line_len_c; > + int line_len; > + int ret; > + > + if (!resizer_chained) { > + dev_err(dev, "Resizer cannot be configured in standalone" > + "for continuous mode\n"); > + return -EINVAL; > + } > + > + ret = mutex_lock_interruptible(&oper_state.lock); > + if (ret) > + return ret; > + if (!cont_config->output1.enable) { > + dev_err(dev, "enable resizer - 0\n"); > + mutex_unlock(&oper_state.lock); > + return -EINVAL; > + } > + param->rsz_en[RSZ_A] = ENABLE; > + param->rsz_rsc_param[RSZ_A].mode = IPIPEIF_CONTINUOUS; > + configure_resizer_out_params(param, > + RSZ_A, > + &cont_config->output1, > + 1, > + 0); > + param->rsz_en[RSZ_B] = DISABLE; > + > + if (cont_config->output2.enable) { > + param->rsz_rsc_param[RSZ_B].mode = IPIPEIF_CONTINUOUS; > + ret = rsz_validate_output_image_format(dev, > + cont_config->output2. > + pix_fmt, > + cont_config->output2. > + width, > + cont_config->output2. > + height, > + &line_len, > + &line_len_c); > + if (ret) { > + mutex_unlock(&oper_state.lock); > + return ret; > + } > + param->ext_mem_param[RSZ_B].rsz_sdr_oft_y = line_len; > + param->ext_mem_param[RSZ_B].rsz_sdr_oft_c = line_len_c; > + configure_resizer_out_params(param, > + RSZ_B, > + &cont_config->output2, > + 0, > + 1); > + if (cont_config->output2.pix_fmt == IPIPE_YUV420SP) > + enable_422_420_conversion(param, > + RSZ_B, ENABLE); > + else > + enable_422_420_conversion(param, > + RSZ_B, DISABLE); > + } > + oper_state.rsz_chained = 1; > + oper_state.rsz_config_state = STATE_CONFIGURED; > + mutex_unlock(&oper_state.lock); > + > + return 0; > +} > +static int ipipe_set_resize_config(struct device *dev, > + int resizer_chained, > + void *user_config, void *config) > +{ > + struct ipipe_params *param = (struct ipipe_params *)config; > + int ret; > + > + dev_dbg(dev, "ipipe_set_resize_config, resizer_chained = %d\n", > + resizer_chained); > + if ((ISNULL(user_config)) || (ISNULL(config))) { > + dev_err(dev, "Invalid user_config or config ptr\n"); > + return -EINVAL; > + } > + > + memcpy((void *)config, > + (void *)&dm365_ipipe_defs, > + sizeof(struct ipipe_params)); > + > + if (oper_mode != IMP_MODE_SINGLE_SHOT) > + return configure_resizer_in_cont_mode(dev, > + user_config, > + resizer_chained, > + param); > + > + ret = configure_resizer_in_ss_mode(dev, > + user_config, > + resizer_chained, > + param); > + if (!ret && (!en_serializer && !resizer_chained)) > + ret = ipipe_hw_setup(config); > + > + return ret; > +} > + > +static void configure_resize_passthru(struct ipipe_params *param, int bypass) > +{ > + param->rsz_rsc_param[RSZ_A].cen = DISABLE; > + param->rsz_rsc_param[RSZ_A].yen = DISABLE; > + param->rsz_rsc_param[RSZ_A].v_phs_y = 0; > + param->rsz_rsc_param[RSZ_A].v_phs_c = 0; > + param->rsz_rsc_param[RSZ_A].v_dif = 256; > + param->rsz_rsc_param[RSZ_A].v_lpf_int_y = 0; > + param->rsz_rsc_param[RSZ_A].v_lpf_int_c = 0; > + param->rsz_rsc_param[RSZ_A].h_phs = 0; > + param->rsz_rsc_param[RSZ_A].h_dif = 256; > + param->rsz_rsc_param[RSZ_A].h_lpf_int_y = 0; > + param->rsz_rsc_param[RSZ_A].h_lpf_int_c = 0; > + param->rsz_rsc_param[RSZ_A].dscale_en = DISABLE; > + param->rsz2rgb[RSZ_A].rgb_en = DISABLE; > + param->rsz_en[RSZ_A] = ENABLE; > + param->rsz_en[RSZ_B] = DISABLE; > + if (bypass) { > + param->rsz_rsc_param[RSZ_A].i_vps = 0; > + param->rsz_rsc_param[RSZ_A].i_hps = 0; > + /* Raw Bypass */ > + param->rsz_common.passthrough = IPIPE_BYPASS_ON; > + } > +} > + > +static inline int prev_validate_output_image_format(struct device *dev, > + enum ipipe_pix_formats pix, > + int *line_len, > + int in_width, int in_height) > +{ > + if (pix != IPIPE_UYVY && pix != IPIPE_BAYER) { > + dev_err(dev, > + "prev_validate_output_image_format" > + "pix format not supported, %d\n", pix); > + return -EINVAL; > + } > + > + if ((in_width == 0) || (in_height == 0)) { > + dev_err(dev, > + "prev_validate_output_image_format:" > + " invalid width or height\n"); > + return -EINVAL; > + } > + > + *line_len = in_width * 2; > + > + /* Adjust line length to be a multiple of 32 */ > + *line_len += 31; > + *line_len &= ~0x1f; > + > + return 0; > +} > + > +static inline int validate_preview_input_spec(struct device *dev, > + enum ipipe_pix_formats pix, > + int width, > + int height, int *line_len) > +{ > + if (pix != IPIPE_UYVY && pix != IPIPE_BAYER && > + pix != IPIPE_BAYER_8BIT_PACK && pix != IPIPE_BAYER_8BIT_PACK_ALAW && > + pix != IPIPE_BAYER_8BIT_PACK_DPCM && > + pix != IPIPE_BAYER_12BIT_PACK) { > + dev_err(dev, > + "validate_preview_input_spec:" > + "pix format not supported, %d\n", pix); > + return -EINVAL; > + } > + if (width == 0 || height == 0) { > + dev_err(dev, > + "rsz_validate_out_image_formats: " > + "invalid width or height\n"); > + return -EINVAL; > + } > + > + if (pix == IPIPE_UYVY || pix == IPIPE_BAYER) > + *line_len = width * 2; > + else if (pix == IPIPE_BAYER_8BIT_PACK || > + pix == IPIPE_BAYER_8BIT_PACK_ALAW || > + pix == IPIPE_BAYER_8BIT_PACK_DPCM) > + *line_len = width; > + else > + /* 12 bit */ > + *line_len = width + (width >> 1); > + /* Adjust line length to be a multiple of 32 */ > + *line_len += 31; > + *line_len &= ~0x1f; > + > + return 0; > +} > + > +static int configure_previewer_in_cont_mode(struct device *dev, > + void *user_config, > + struct ipipe_params *param) > +{ > + struct prev_continuous_config *cont_config = > + (struct prev_continuous_config *)user_config; > + int ret; > + > + if (cont_config->input.en_df_sub) { > + dev_err(dev, "DF suV4L2_MBUS_FMT_SBGGR10_1X10btraction " > + "is not supported\n"); > + return -EINVAL; > + } > + if (cont_config->input.dec_en && ((cont_config->input.rsz < > + IPIPEIF_RSZ_MIN) || (cont_config->input.rsz > > + IPIPEIF_RSZ_MAX))) { > + dev_err(dev, "rsz range is %d to %d\n", > + IPIPEIF_RSZ_MIN, IPIPEIF_RSZ_MAX); > + return -EINVAL; > + } > + ret = mutex_lock_interruptible(&oper_state.lock); > + if (ret) > + return ret; > + param->rsz_common.passthrough = cont_config->bypass; > + param->ipipeif_param.source = IPIPEIF_CCDC; > + param->ipipeif_param.clock_select = IPIPEIF_PIXCEL_CLK; > + param->ipipeif_param.mode = IPIPEIF_CONTINUOUS; > + if (cont_config->input.dec_en) { > + param->ipipeif_param.decimation = IPIPEIF_DECIMATION_ON; > + param->ipipeif_param.rsz = cont_config->input.rsz; > + param->ipipeif_param.avg_filter = > + (enum ipipeif_avg_filter)cont_config->input.avg_filter_en; > + } > + /* IPIPE mode */ > + param->ipipe_mode = IPIPEIF_CONTINUOUS; > + param->ipipe_colpat_olop = cont_config->input.colp_olop; > + param->ipipe_colpat_olep = cont_config->input.colp_olep; > + param->ipipe_colpat_elop = cont_config->input.colp_elop; > + param->ipipe_colpat_elep = cont_config->input.colp_elep; > + param->ipipeif_param.gain = cont_config->input.gain; > + param->ipipeif_param.var.if_5_1.clip = cont_config->input.clip; > + param->ipipeif_param.var.if_5_1.dpc = cont_config->input.dpc; > + param->ipipeif_param.var.if_5_1.align_sync = > + cont_config->input.align_sync; > + param->ipipeif_param.var.if_5_1.rsz_start = > + cont_config->input.rsz_start; > + if (!oper_state.rsz_chained) { > + param->rsz_rsc_param[0].mode = IPIPEIF_CONTINUOUS; > + /* setup bypass resizer */ > + configure_resize_passthru(param, 0); > + } > + if (cont_config->bypass) > + configure_resize_passthru(param, 1); > + oper_state.prev_config_state = STATE_CONFIGURED; > + mutex_unlock(&oper_state.lock); > + > + return 0; > +} > + > +static int configure_previewer_in_ss_mode(struct device *dev, > + void *user_config, > + struct ipipe_params *param) > +{ > + struct prev_single_shot_config *ss_config = > + (struct prev_single_shot_config *)user_config; > + int line_len; > + int ret; > + > + ret = validate_preview_input_spec(dev, > + ss_config->input.pix_fmt, > + ss_config->input.image_width, > + ss_config->input.image_height, > + &line_len); > + if (ret) > + return -EINVAL; > + > + ret = mutex_lock_interruptible(&oper_state.lock); > + if (ret) > + return ret; > + > + if (!ss_config->input.line_length) > + param->ipipeif_param.adofs = line_len; > + else { > + param->ipipeif_param.adofs = ss_config->input.line_length; > + param->ipipeif_param.adofs = > + (param->ipipeif_param.adofs + 31) & ~0x1f; > + } > + if (ss_config->input.dec_en && ss_config->input.frame_div_mode_en) { > + dev_err(dev, > + "Both dec_en & frame_div_mode_en" > + "can not enabled simultaneously\n"); > + mutex_unlock(&oper_state.lock); > + return -EINVAL; > + } > + > + ret = validate_ipipeif_decimation(dev, > + ss_config->input.dec_en, > + ss_config->input.rsz, > + ss_config->input.frame_div_mode_en, > + ss_config->input.image_width); > + if (ret) { > + mutex_unlock(&oper_state.lock); > + return -EINVAL; > + } > + > + if (!oper_state.rsz_chained) { > + ret = prev_validate_output_image_format(dev, > + ss_config->output. > + pix_fmt, &line_len, > + ss_config->input. > + image_width, > + ss_config->input. > + image_height); > + if (ret) { > + mutex_unlock(&oper_state.lock); > + return -EINVAL; > + } > + param->ext_mem_param[RSZ_A].rsz_sdr_oft_y = line_len; > + if (ss_config->input.frame_div_mode_en) > + ret = update_preview_f_div_params(dev, > + ss_config->input. > + image_width, > + ss_config->input. > + image_width, > + ¶m-> > + rsz_rsc_param[RSZ_A]); > + if (ret) { > + mutex_unlock(&oper_state.lock); > + return -EINVAL; > + } > + } else { > + if (ss_config->input.frame_div_mode_en && > + param->rsz_en[RSZ_A]) { > + if (!param->rsz_rsc_param[RSZ_A].dscale_en) > + ret = calculate_normal_f_div_param( > + dev, > + ss_config->input. > + image_width, > + param->rsz_rsc_param > + [RSZ_A]. > + o_vsz + 1, > + ¶m->rsz_rsc_param > + [RSZ_A]); > + else > + ret = calculate_down_scale_f_div_param( > + dev, > + ss_config-> > + input.image_width, > + param->rsz_rsc_param > + [RSZ_A].o_vsz + 1, > + ¶m->rsz_rsc_param > + [RSZ_A]); > + if (ret) { > + mutex_unlock(&oper_state.lock); > + return -EINVAL; > + } > + } > + if (ss_config->input.frame_div_mode_en && > + param->rsz_en[RSZ_B]) { > + if (!param->rsz_rsc_param[RSZ_B].dscale_en) > + ret = calculate_normal_f_div_param( > + dev, > + ss_config->input. > + image_width, > + param->rsz_rsc_param > + [RSZ_B].o_vsz + 1, > + ¶m->rsz_rsc_param > + [RSZ_B]); > + else > + ret = calculate_down_scale_f_div_param( > + dev, > + ss_config->input. > + image_width, > + param->rsz_rsc_param > + [RSZ_B].o_vsz + 1, > + ¶m->rsz_rsc_param > + [RSZ_B]); > + if (ret) { > + mutex_unlock(&oper_state.lock); > + return -EINVAL; > + } > + } Are there differences between the two above ifs other than the resizer number? I don't think so and I don't think this is the only place. > + } > + if (ipipe_process_pix_fmts(ss_config->input.pix_fmt, > + ss_config->output.pix_fmt, > + param) < 0) { > + dev_err(dev, "error in input or output pix format\n"); > + mutex_unlock(&oper_state.lock); > + return -EINVAL; > + } > + param->ipipeif_param.hnum = ss_config->input.image_width; > + param->ipipeif_param.vnum = ss_config->input.image_height; > + param->ipipeif_param.glob_hor_size = ss_config->input.ppln; > + param->ipipeif_param.glob_ver_size = ss_config->input.lpfr; > + param->ipipeif_param.var.if_5_1.clk_div = ss_config->input.clk_div; > + param->ipipeif_param.var.if_5_1.pix_order = ss_config->input.pix_order; > + param->ipipeif_param.var.if_5_1.align_sync = > + ss_config->input.align_sync; > + param->ipipeif_param.var.if_5_1.rsz_start = ss_config->input.rsz_start; > + if (param->ipipeif_param.var.if_5_1.dpcm.en) { > + param->ipipeif_param.var.if_5_1.dpcm.pred = > + ss_config->input.pred; > + param->ipipeif_param.var.if_5_1.dpcm.type = > + IPIPEIF_DPCM_8BIT_12BIT; > + } > + param->ipipeif_param.var.if_5_1.data_shift = > + ss_config->input.data_shift; > + > + param->ipipe_hsz = ss_config->input.image_width - 1; > + if (ss_config->input.dec_en) { > + if ((ss_config->input.rsz < IPIPEIF_RSZ_MIN) || > + (ss_config->input.rsz > IPIPEIF_RSZ_MAX)) { > + dev_err(dev, "rsz range is %d to %d\n", > + IPIPEIF_RSZ_MIN, IPIPEIF_RSZ_MAX); > + mutex_unlock(&oper_state.lock); > + return -EINVAL; > + } > + param->ipipeif_param.decimation = IPIPEIF_DECIMATION_ON; > + param->ipipeif_param.rsz = ss_config->input.rsz; > + param->ipipeif_param.avg_filter = > + (enum ipipeif_avg_filter)ss_config->input.avg_filter_en; > + param->ipipe_hsz = > + (((ss_config->input.image_width * IPIPEIF_RSZ_CONST) / > + ss_config->input.rsz) - 1); > + } > + param->ipipeif_param.gain = ss_config->input.gain; > + param->ipipeif_param.var.if_5_1.clip = ss_config->input.clip; > + param->ipipeif_param.var.if_5_1.dpc = ss_config->input.dpc; > + param->ipipe_colpat_olop = ss_config->input.colp_olop; > + param->ipipe_colpat_olep = ss_config->input.colp_olep; > + param->ipipe_colpat_elop = ss_config->input.colp_elop; > + param->ipipe_colpat_elep = ss_config->input.colp_elep; > + param->ipipe_vps = ss_config->input.vst; > + param->ipipe_hps = ss_config->input.hst; > + param->ipipe_vsz = ss_config->input.image_height - 1; > + if (ss_config->input.pix_fmt == IPIPE_UYVY) > + param->ipipeif_param.source = IPIPEIF_SDRAM_YUV; > + else > + param->ipipeif_param.source = IPIPEIF_SDRAM_RAW; > + > + configure_common_rsz_in_params(dev, param, 1, oper_state.rsz_chained, > + &ss_config->input); > + > + param->rsz_common.passthrough = ss_config->bypass; > + /* update the resize parameters */ > + if (ss_config->bypass == IPIPE_BYPASS_ON || > + param->ipipe_dpaths_fmt == IPIPE_RAW2RAW) > + /* Bypass resizer */ > + configure_resize_passthru(param, 1); > + else { > + if (oper_state.rsz_chained) { > + if (param->rsz_en[RSZ_A]) { > + calculate_resize_ratios(param, RSZ_A); > + calculate_sdram_offsets(param, RSZ_A); > + } > + if (param->rsz_en[RSZ_B]) { > + calculate_resize_ratios(param, RSZ_B); > + calculate_sdram_offsets(param, RSZ_B); > + } > + } else { > + struct rsz_output_spec *output_specs = > + kmalloc(sizeof(struct rsz_output_spec), > + GFP_KERNEL); > + if (ISNULL(output_specs)) { > + dev_err(dev, "Memory Alloc failure\n"); > + mutex_unlock(&oper_state.lock); > + return -EINVAL; > + } > + /* Using resizer as pass through */ > + configure_resize_passthru(param, 0); > + memset((void *)output_specs, 0, > + sizeof(struct rsz_output_spec)); > + output_specs->enable = 1; > + output_specs->pix_fmt = IPIPE_UYVY; > + output_specs->width = ss_config->input.image_width; > + output_specs->height = ss_config->input.image_height; > + output_specs->vst_y = ss_config->input.vst; > + configure_resizer_out_params(param, RSZ_A, > + output_specs, 0, 0); > + calculate_sdram_offsets(param, RSZ_A); > + kfree(output_specs); > + } > + } > + mutex_unlock(&oper_state.lock); > + > + return 0; > +} > + > +static int ipipe_reconfig_resizer(struct device *dev, > + struct rsz_reconfig *reconfig, > + void *config) > +{ > + struct ipipe_params *param = (struct ipipe_params *)config; > + > + if (ISNULL(reconfig)) { > + dev_err(dev, "Null User ptr received for reconfig"); > + return -EINVAL; > + } > + > + if ((reconfig->pix_format != IMP_420SP_Y) && > + (reconfig->pix_format != IMP_420SP_C)) { > + dev_err(dev, "reconfig - pixel format incorrect"); > + return -EINVAL; > + } > + if (param->rsz_common.src_img_fmt != RSZ_IMG_420) { > + dev_err(dev, "reconfig - source format originally" > + "configured is not YUV420SP\n"); > + return -EINVAL; > + } > + if ((param->rsz_common.y_c) && (reconfig->pix_format == IMP_420SP_C)) { > + dev_err(dev, "reconfig - channel is already configured" > + "for YUV420SP - C data\n"); > + return -EINVAL; > + } > + if ((!param->rsz_common.y_c) && > + (reconfig->pix_format == IMP_420SP_Y)) { > + dev_err(dev, "reconfig - channel is already configured" > + "for YUV420SP - Y data\n"); > + return -EINVAL; > + } > + if (reconfig->pix_format == IMP_420SP_Y) > + param->rsz_common.y_c = 0; > + else > + param->rsz_common.y_c = 1; > + if (!en_serializer) > + rsz_set_in_pix_format(param->rsz_common.y_c); > + > + return 0; > +} > + > +static int ipipe_set_preview_config(struct device *dev, > + void *user_config, void *config) > +{ > + struct ipipe_params *param = (struct ipipe_params *)config; > + int ret; > + > + dev_err(dev, "ipipe_set_preview_config\n"); > + > + if ((ISNULL(user_config)) || (ISNULL(config))) { > + dev_err(dev, "Invalid user_config or config ptr\n"); > + return -EINVAL; > + } > + > + if (!oper_state.rsz_chained) { > + /* For chained resizer, defaults are set by resizer */ > + memcpy((void *)config, > + (void *)&dm365_ipipe_defs, > + sizeof(struct ipipe_params)); > + } > + > + /* continuous mode */ > + if (oper_mode == IMP_MODE_CONTINUOUS) > + return configure_previewer_in_cont_mode(dev, user_config, > + param); > + > + /* shared block */ > + /* previewer in standalone mode. In this mode if serializer > + * is enabled, we need to set config params for hw. > + */ > + ret = configure_previewer_in_ss_mode(dev, user_config, param); > + > + if ((!ret) && !en_serializer) > + ret = ipipe_hw_setup(config); > + > + return ret; > +} > + > +static int ipipe_set_input_win(struct imp_window *win) > +{ > + struct ipipe_params *param = oper_state.shared_config_param; > + int ret; > + > + ret = mutex_lock_interruptible(&oper_state.lock); > + if (ret) > + return ret; > + if (param->ipipeif_param.decimation) { > + param->ipipe_hsz = > + ((win->width * IPIPEIF_RSZ_CONST) / > + param->ipipeif_param.rsz) - 1; > + } else > + param->ipipe_hsz = win->width - 1; > + if (!oper_state.frame_format) { > + param->ipipe_vsz = (win->height >> 1) - 1; > + param->ipipe_vps = (win->vst >> 1); > + } else { > + param->ipipe_vsz = win->height - 1; > + param->ipipe_vps = win->vst; > + } > + param->ipipe_hps = win->hst; > + param->rsz_common.vsz = param->ipipe_vsz; > + param->rsz_common.hsz = param->ipipe_hsz; > + mutex_unlock(&oper_state.lock); > + > + return 0; > +} > +static int ipipe_get_input_win(struct imp_window *win) > +{ > + struct ipipe_params *param = oper_state.shared_config_param; > + int ret; > + > + ret = mutex_lock_interruptible(&oper_state.lock); > + if (ret) > + return ret; > + if (param->ipipeif_param.decimation) > + win->width = > + (((param->ipipe_hsz + 1) * param->ipipeif_param.rsz) >> 4); > + else > + win->width = param->ipipe_hsz + 1; > + if (!oper_state.frame_format) { > + win->height = (param->ipipe_vsz + 1) << 1; > + win->vst = (param->ipipe_vps << 1); > + } else { > + win->height = param->ipipe_vsz + 1; > + win->vst = param->ipipe_vps; > + } > + win->hst = param->ipipe_hps; > + mutex_unlock(&oper_state.lock); > + > + return 0; > +} > + > +static int ipipe_set_in_pixel_format(enum imp_pix_formats pix_fmt) > +{ > + struct ipipe_params *param = oper_state.shared_config_param; > + int ret; > + > + ret = mutex_lock_interruptible(&oper_state.lock); > + if (ret) > + return ret; > + oper_state.in_pixel_format = pix_fmt; > + param->rsz_common.src_img_fmt = RSZ_IMG_422; > + mutex_unlock(&oper_state.lock); > + > + return 0; > +} > + > +static int ipipe_set_out_pixel_format(enum imp_pix_formats pix_fmt) > +{ > + struct ipipe_params *param = oper_state.shared_config_param; > + int err; > + > + /* if image is RAW, preserve raw image format while flipping. > + * otherwise preserve, preserve ycbcr format while flipping > + */ > + if (pix_fmt == IMP_BAYER) > + param->rsz_common.raw_flip = 1; > + else > + param->rsz_common.raw_flip = 0; > + > + err = mutex_lock_interruptible(&oper_state.lock); > + if (err) > + return err; > + oper_state.out_pixel_format = pix_fmt; > + err = ipipe_process_pix_fmts(oper_state.in_pixel_format, > + oper_state.out_pixel_format, > + param); > + > + mutex_unlock(&oper_state.lock); > + > + return err; > +} > + > +static int ipipe_set_buftype(unsigned char buf_type) > +{ > + int ret; > + > + ret = mutex_lock_interruptible(&oper_state.lock); > + if (ret) > + return ret; > + oper_state.buffer_type = buf_type; > + mutex_unlock(&oper_state.lock); > + > + return 0; > +} > + > +static int ipipe_set_frame_format(unsigned char frm_fmt) > +{ > + int ret; > + > + ret = mutex_lock_interruptible(&oper_state.lock); > + if (ret) > + return ret; > + oper_state.frame_format = frm_fmt; > + mutex_unlock(&oper_state.lock); > + > + return 0; > +} > + > +static int ipipe_set_output_win(struct imp_window *win) > +{ > + struct ipipe_params *param = oper_state.shared_config_param; > + struct rsz_output_spec output_specs; > + int line_len_c; > + int line_len; > + int ret = -EINVAL; > + > + if (!param->rsz_en[0]) { > + printk(KERN_ERR "resizer output1 not enabled\n"); > + return ret; > + } > + output_specs.enable = 1; > + output_specs.width = win->width; > + /* Always set output height same as in height > + for de-interlacing > + */ > + output_specs.height = win->height; > + output_specs.vst_y = win->vst; > + if (oper_state.out_pixel_format == IPIPE_YUV420SP) > + output_specs.vst_c = win->vst; > + ret = mutex_lock_interruptible(&oper_state.lock); > + if (ret) > + return ret; > + configure_resizer_out_params(param, RSZ_A, &output_specs, 0, 0); > + calculate_line_length(oper_state.out_pixel_format, > + param->rsz_rsc_param[0].o_hsz + 1, > + param->rsz_rsc_param[0].o_vsz + 1, > + &line_len, > + &line_len_c); > + param->ext_mem_param[0].rsz_sdr_oft_y = line_len; > + param->ext_mem_param[0].rsz_sdr_oft_c = line_len_c; > + calculate_resize_ratios(param, RSZ_A); > + if (param->rsz_en[RSZ_B]) > + calculate_resize_ratios(param, RSZ_B); > + if (oper_state.out_pixel_format == IPIPE_YUV420SP) > + enable_422_420_conversion(param, RSZ_A, ENABLE); > + else > + enable_422_420_conversion(param, RSZ_A, DISABLE); > + > + ret = calculate_sdram_offsets(param, RSZ_A); > + if (param->rsz_en[RSZ_B]) > + ret = calculate_sdram_offsets(param, RSZ_B); > + > + if (ret) > + printk(KERN_ERR "error in calculating sdram offsets\n"); > + mutex_unlock(&oper_state.lock); > + > + return ret; > +} > +static int ipipe_get_output_state(unsigned char out_sel) > +{ > + struct ipipe_params *param = oper_state.shared_config_param; > + > + if ((out_sel != RSZ_A) && (out_sel != RSZ_B)) > + return 0; > + > + return param->rsz_en[out_sel]; > +} > + > +/* This should be called only after setting the output > + * window params. This also assumes the corresponding > + * output is configured prior to calling this. > + */ > +static int ipipe_get_line_length(unsigned char out_sel) > +{ > + struct ipipe_params *param = oper_state.shared_config_param; > + > + if ((out_sel != RSZ_A) && (out_sel != RSZ_B)) > + return -EINVAL; > + /* assume output is always UYVY. Change this if we > + * support RGB > + */ > + if (!param->rsz_en[out_sel]) > + return -EINVAL; > + > + return param->ext_mem_param[out_sel].rsz_sdr_oft_y; > +} > + > +static int ipipe_get_image_height(unsigned char out_sel) > +{ > + struct ipipe_params *param = oper_state.shared_config_param; > + > + if ((out_sel != RSZ_A) && (out_sel != RSZ_B)) > + return -EINVAL; > + if (!param->rsz_en[out_sel]) > + return -EINVAL; > + > + return param->rsz_rsc_param[out_sel].o_vsz + 1; > +} > + > +/* Assume valid param ptr */ > +static int ipipe_set_hw_if_param(struct vpfe_hw_if_param *if_param) > +{ > + struct ipipe_params *param = oper_state.shared_config_param; > + int ret; > + > + ret = mutex_lock_interruptible(&oper_state.lock); > + if (ret) > + return ret; > + param->ipipeif_param.var.if_5_1.isif_port = *if_param; > + mutex_unlock(&oper_state.lock); > + > + return 0; > +} > + > +static struct imp_hw_interface dm365_ipipe_interface = { > + .name = "DM365 IPIPE", > + .owner = THIS_MODULE, > + .prev_enum_modules = prev_enum_preview_cap, > + .set_oper_mode = ipipe_set_oper_mode, > + .reset_oper_mode = ipipe_reset_oper_mode, > + .get_oper_mode = prev_get_oper_mode, > + .get_hw_state = ipipe_get_oper_state, > + .set_hw_state = ipipe_set_oper_state, > + .resizer_chain = ipipe_rsz_chain_state, > + .lock_chain = ipipe_lock_chain, > + .unlock_chain = ipipe_unlock_chain, > + .serialize = ipipe_serialize, > + .alloc_config_block = ipipe_alloc_config_block, > + .dealloc_config_block = ipipe_dealloc_config_block, > + .alloc_user_config_block = ipipe_alloc_user_config_block, > + .dealloc_config_block = ipipe_dealloc_user_config_block, > + .set_user_config_defaults = ipipe_set_user_config_defaults, > + .set_preview_config = ipipe_set_preview_config, > + .set_resizer_config = ipipe_set_resize_config, > + .reconfig_resizer = ipipe_reconfig_resizer, > + .update_inbuf_address = ipipe_set_ipipe_if_address, > + .update_outbuf1_address = ipipe_update_outbuf1_address, > + .update_outbuf2_address = ipipe_update_outbuf2_address, > + .enable = ipipe_enable, > + .enable_resize = rsz_src_enable, > + .hw_setup = ipipe_do_hw_setup, > + .get_resizer_config_state = ipipe_get_rsz_config_state, > + .get_previewer_config_state = ipipe_get_prev_config_state, > + .set_input_win = ipipe_set_input_win, > + .get_input_win = ipipe_get_input_win, > + .set_hw_if_param = ipipe_set_hw_if_param, > + .set_in_pixel_format = ipipe_set_in_pixel_format, > + .set_out_pixel_format = ipipe_set_out_pixel_format, > + .set_buftype = ipipe_set_buftype, > + .set_frame_format = ipipe_set_frame_format, > + .set_output_win = ipipe_set_output_win, > + .get_output_state = ipipe_get_output_state, > + .get_line_length = ipipe_get_line_length, > + .get_image_height = ipipe_get_image_height, > + .get_image_height = ipipe_get_image_height, > + .get_max_output_width = ipipe_get_max_output_width, > + .get_max_output_height = ipipe_get_max_output_height, > + .enum_pix = ipipe_enum_pix, > +}; > + > +struct imp_hw_interface *imp_get_hw_if(void) > +{ > + return &dm365_ipipe_interface; > +} > + > +void enable_serializer(int val) > +{ > + en_serializer = val; > +} > + > +int ipipe_init(void) > +{ > + oper_state.shared_config_param = > + kmalloc(sizeof(struct ipipe_params), GFP_KERNEL); > + > + if (ISNULL(oper_state.shared_config_param)) { > + printk(KERN_ERR > + "dm365_ipipe_init: failed to allocate memory\n"); > + return -ENOMEM; > + } > + memcpy(&dm365_ipipe_defs.ipipeif_param.var.if_5_1, > + &ipipeif_5_1_defaults, > + sizeof(struct ipipeif_5_1)); > + lutdpc.table = ipipe_lutdpc_table; > + lut_3d.table = ipipe_3d_lut_table; > + gbce.table = ipipe_gbce_table; > + gamma.table_r = ipipe_gamma_table_r; > + gamma.table_b = ipipe_gamma_table_b; > + gamma.table_g = ipipe_gamma_table_g; > + yee.table = ipipe_yee_table; > + mutex_init(&oper_state.lock); > + oper_state.state = CHANNEL_FREE; > + oper_state.prev_config_state = STATE_NOT_CONFIGURED; > + oper_state.rsz_config_state = STATE_NOT_CONFIGURED; > + oper_state.frame_format = 1; > + oper_state.in_pixel_format = IMP_BAYER; > + oper_state.out_pixel_format = IMP_UYVY; > + > + return 0; > +} > + > +void ipipe_cleanup(void) > +{ > + kfree(oper_state.shared_config_param); > +} > diff --git a/drivers/media/video/davinci/dm365_ipipe.h b/drivers/media/video/davinci/dm365_ipipe.h > new file mode 100644 > index 0000000..9b5dfae > --- /dev/null > +++ b/drivers/media/video/davinci/dm365_ipipe.h > @@ -0,0 +1,300 @@ > +/* > +* Copyright (C) 2011 Texas Instruments Inc > +* > +* This program is free software; you can redistribute it and/or > +* modify it under the terms of the GNU General Public License as > +* published by the Free Software Foundation version 2. > +* > +* This program is distributed in the hope that it will be useful, > +* but WITHOUT ANY WARRANTY; without even the implied warranty of > +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > +* GNU General Public License for more details. > +* > +* You should have received a copy of the GNU General Public License > +* along with this program; if not, write to the Free Software > +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA > +* > +* Feature description > +* =================== > +* > +* VPFE hardware setup > +* > +* case 1: Capture to SDRAM with out IPIPE > +* **************************************** > +* > +* parallel > +* port > +* > +* Image sensor/ ________ > +* Yuv decoder ---->| CCDC |--> SDRAM > +* |______| > +* > +* case 2: Capture to SDRAM with IPIPE Preview modules in Continuous > +* (On the Fly mode) > +* > +* Image sensor/ ________ ____________________ > +* Yuv decoder ---->| CCDC |--> | Previewer modules |--> SDRAM > +* |______| |___________________| > +* > +* case 3: Capture to SDRAM with IPIPE Preview modules & Resizer > +* in continuous (On the Fly mode) > +* > +* Image sensor/ ________ _____________ ___________ > +* Yuv decoder ---->| CCDC |--> | Previewer |->| Resizer |-> SDRAM > +* |______| |____________| |__________| > +* > +* case 4: Capture to SDRAM with IPIPE Resizer > +* in continuous (On the Fly mode) > +* > +* Image sensor/ ________ ___________ > +* Yuv decoder ---->| CCDC |--> | Resizer |-> SDRAM > +* |______| |__________| > +* > +* case 5: Read from SDRAM and do preview and/or Resize > +* in Single shot mode > +* > +* _____________ ___________ > +* SDRAM ----> | Previewer |->| Resizer |-> SDRAM > +* |____________| |__________| > +* > +* > +* Previewer allows fine tuning of the input image using different > +* tuning modules in IPIPE. Some examples :- Noise filter, Defect > +* pixel correction etc. It essentially operate on Bayer Raw data > +* or YUV raw data. To do image tuning, application call, > +* PREV_QUERY_CAP, and then call PREV_SET_PARAM to set parameter > +* for a module. > +* > +* > +* Resizer allows upscaling or downscaling a image to a desired > +* resolution. There are 2 resizer modules. both operating on the > +* same input image, but can have different output resolution. > +*/ > + > +#ifndef DM365_IPIPE_H > +#define DM365_IPIPE_H > + > +#ifdef __KERNEL__ > +#include "imp_common.h" > +#include "dm3xx_ipipeif.h" > +#include > + > +/* Used for driver storage */ > +struct ipipe_otfdpc_2_0 { > + /* 0 - disable, 1 - enable */ > + unsigned char en; > + /* defect detection method */ > + enum ipipe_otfdpc_det_meth det_method; > + /* Algorith used. Applicable only when IPIPE_DPC_OTF_MIN_MAX2 is > + * used > + */ > + enum ipipe_otfdpc_alg alg; > + struct prev_otfdpc_2_0 otfdpc_2_0; > +}; > + > +struct ipipe_otfdpc_3_0 { > + /* 0 - disable, 1 - enable */ > + unsigned char en; > + /* defect detection method */ > + enum ipipe_otfdpc_det_meth det_method; > + /* Algorith used. Applicable only when IPIPE_DPC_OTF_MIN_MAX2 is > + * used > + */ > + enum ipipe_otfdpc_alg alg; > + struct prev_otfdpc_3_0 otfdpc_3_0; > +}; > + > +enum enable_disable_t { > + DISABLE, > + ENABLE > +}; Does that bring value over using e.g. boolean? > +#define CEIL(a, b) (((a) + (b-1)) / (b)) > +#define IPIPE_MAX_PASSES 2 > + > +struct f_div_pass { > + unsigned int o_hsz; > + unsigned int i_hps; > + unsigned int h_phs; > + unsigned int src_hps; > + unsigned int src_hsz; > +}; > + > +struct f_div_param { > + unsigned char en; > + unsigned int num_passes; > + struct f_div_pass pass[IPIPE_MAX_PASSES]; > +}; > + > +/* Resizer Rescale Parameters*/ > +struct ipipe_rsz_rescale_param { > + enum ipipe_oper_mode mode; > + enum enable_disable_t h_flip; > + enum enable_disable_t v_flip; > + enum enable_disable_t cen; > + enum enable_disable_t yen; > + unsigned short i_vps; > + unsigned short i_hps; > + unsigned short o_vsz; > + unsigned short o_hsz; > + unsigned short v_phs_y; > + unsigned short v_phs_c; > + unsigned short v_dif; > + /* resize method - Luminance */ > + enum rsz_intp_t v_typ_y; > + /* resize method - Chrominance */ > + enum rsz_intp_t v_typ_c; > + /* vertical lpf intensity - Luminance */ > + unsigned char v_lpf_int_y; > + /* vertical lpf intensity - Chrominance */ > + unsigned char v_lpf_int_c; > + unsigned short h_phs; > + unsigned short h_dif; > + /* resize method - Luminance */ > + enum rsz_intp_t h_typ_y; > + /* resize method - Chrominance */ > + enum rsz_intp_t h_typ_c; > + /* horizontal lpf intensity - Luminance */ > + unsigned char h_lpf_int_y; > + /* horizontal lpf intensity - Chrominance */ > + unsigned char h_lpf_int_c; > + enum enable_disable_t dscale_en; > + enum down_scale_ave_sz h_dscale_ave_sz; > + enum down_scale_ave_sz v_dscale_ave_sz; > + /* store the calculated frame division parameter */ > + struct f_div_param f_div; > +}; > + > +enum ipipe_rsz_rgb_t { > + OUTPUT_32BIT, > + OUTPUT_16BIT > +}; > + > +enum ipipe_rsz_rgb_msk_t { > + NOMASK, > + MASKLAST2 > +}; > + > +/* Resizer RGB Conversion Parameters */ > +struct ipipe_rsz_resize2rgb { > + enum enable_disable_t rgb_en; > + enum ipipe_rsz_rgb_t rgb_typ; > + enum ipipe_rsz_rgb_msk_t rgb_msk0; > + enum ipipe_rsz_rgb_msk_t rgb_msk1; > + unsigned int rgb_alpha_val; > +}; > + > +/* Resizer External Memory Parameters */ > +struct ipipe_ext_mem_param { > + unsigned int rsz_sdr_oft_y; > + unsigned int rsz_sdr_ptr_s_y; > + unsigned int rsz_sdr_ptr_e_y; > + unsigned int rsz_sdr_oft_c; > + unsigned int rsz_sdr_ptr_s_c; > + unsigned int rsz_sdr_ptr_e_c; > + /* offset to be added to buffer start when flipping for y/ycbcr */ > + unsigned int flip_ofst_y; > + /* offset to be added to buffer start when flipping for c */ > + unsigned int flip_ofst_c; > + /* c offset for YUV 420SP */ > + unsigned int c_offset; > + /* User Defined Y offset for YUV 420SP or YUV420ILE data */ > + unsigned int user_y_ofst; > + /* User Defined C offset for YUV 420SP data */ > + unsigned int user_c_ofst; > +}; > + > +enum rsz_data_source { > + IPIPE_DATA, > + IPIPEIF_DATA > +}; > + > +/* data paths */ > +enum ipipe_data_paths { > + IPIPE_RAW2YUV, > + /* Bayer RAW input to YCbCr output */ > + IPIPE_RAW2RAW, > + /* Bayer Raw to Bayer output */ > + IPIPE_RAW2BOX, > + /* Bayer Raw to Boxcar output */ > + IPIPE_YUV2YUV > + /* YUV Raw to YUV Raw output */ > +}; > + > +enum rsz_src_img_fmt { > + RSZ_IMG_422, > + RSZ_IMG_420 > +}; > + > +struct rsz_common_params { > + unsigned int vps; > + unsigned int vsz; > + unsigned int hps; > + unsigned int hsz; > + /* 420 or 422 */ > + enum rsz_src_img_fmt src_img_fmt; > + /* Y or C when src_fmt is 420, 0 - y, 1 - c */ > + unsigned char y_c; > + /* flip raw or ycbcr */ > + unsigned char raw_flip; > + /* IPIPE or IPIPEIF data */ > + enum rsz_data_source source; > + enum ipipe_dpaths_bypass_t passthrough; > + unsigned char yuv_y_min; > + unsigned char yuv_y_max; > + unsigned char yuv_c_min; > + unsigned char yuv_c_max; > + enum enable_disable_t rsz_seq_crv; > + enum ipipe_chr_pos out_chr_pos; > +}; > + > +struct ipipe_params { > + struct ipipeif ipipeif_param; > + enum ipipe_oper_mode ipipe_mode; > + /* input/output datapath through IPIPE */ > + enum ipipe_data_paths ipipe_dpaths_fmt; > + /* color pattern register */ > + enum ipipe_colpat_t ipipe_colpat_elep; > + enum ipipe_colpat_t ipipe_colpat_elop; > + enum ipipe_colpat_t ipipe_colpat_olep; > + enum ipipe_colpat_t ipipe_colpat_olop; > + /* horizontal/vertical start, horizontal/vertical size > + * for both IPIPE and RSZ input > + */ > + unsigned int ipipe_vps; > + unsigned int ipipe_vsz; > + unsigned int ipipe_hps; > + unsigned int ipipe_hsz; > + > + struct rsz_common_params rsz_common; > + struct ipipe_rsz_rescale_param rsz_rsc_param[2]; > + struct ipipe_rsz_resize2rgb rsz2rgb[2]; > + struct ipipe_ext_mem_param ext_mem_param[2]; > + enum enable_disable_t rsz_en[2]; > +}; > + > +void ipipe_set_d2f_regs(unsigned int id, struct prev_nf *noise_filter); > +void ipipe_set_rgb2rgb_regs(unsigned int id, struct prev_rgb2rgb *rgb); > +void rsz_set_output_address(struct ipipe_params *params, > + int resize_no, unsigned int address); > +void ipipe_set_yuv422_conv_regs(struct prev_yuv422_conv *conv); > +void ipipe_set_lum_adj_regs(struct prev_lum_adj *lum_adj); > +void ipipe_set_rgb2ycbcr_regs(struct prev_rgb2yuv *yuv); > +void ipipe_set_lutdpc_regs(struct prev_lutdpc *lutdpc); > +void ipipe_set_otfdpc_regs(struct prev_otfdpc *otfdpc); > +void ipipe_set_3d_lut_regs(struct prev_3d_lut *lut_3d); > +void ipipe_set_gamma_regs(struct prev_gamma *gamma); > +int ipipe_hw_setup(struct ipipe_params *config); > +void ipipe_set_gbce_regs(struct prev_gbce *gbce); > +void ipipe_set_gic_regs(struct prev_gic *gic); > +void ipipe_set_cfa_regs(struct prev_cfa *cfa); > +void ipipe_set_car_regs(struct prev_car *car); > +void ipipe_set_cgs_regs(struct prev_cgs *cgs); > +void rsz_set_in_pix_format(unsigned char y_c); > +void ipipe_set_ee_regs(struct prev_yee *ee); > +void ipipe_set_wb_regs(struct prev_wb *wb); > +int rsz_enable(int rsz_id, int enable); > +void rsz_src_enable(int enable); > + > +#endif > +#endif > diff --git a/drivers/media/video/davinci/imp_common.h b/drivers/media/video/davinci/imp_common.h > new file mode 100644 > index 0000000..25b2836 > --- /dev/null > +++ b/drivers/media/video/davinci/imp_common.h > @@ -0,0 +1,85 @@ > +/* > +* Copyright (C) 2011 Texas Instruments Inc > +* > +* This program is free software; you can redistribute it and/or > +* modify it under the terms of the GNU General Public License as > +* published by the Free Software Foundation version 2. > +* > +* This program is distributed in the hope that it will be useful, > +* but WITHOUT ANY WARRANTY; without even the implied warranty of > +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > +* GNU General Public License for more details. > +* > +* You should have received a copy of the GNU General Public License > +* along with this program; if not, write to the Free Software > +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA > +* > +* imp_common.h file > +*/ > +#ifndef _IMP_COMMON_H > +#define _IMP_COMMON_H > + > +#ifdef __KERNEL__ This is a kernel-only header file. No need to check for __KERNEL__. > +#include > +#include > +#include > +#include > +#define MAX_CHANNELS 2 > +#define MAX_BUFFERS 6 > +#define MAX_PRIORITY 5 > +#define MIN_PRIORITY 0 > +#define DEFAULT_PRIORITY 3 > +#define ENABLED 1 > +#define DISABLED 0 > +#define CHANNEL_BUSY 1 > +#define CHANNEL_FREE 0 > +#define ISNULL(val) ((val == NULL) ? 1 : 0) > + > +/* driver configured by application */ > +#define STATE_CONFIGURED 1 > +/* driver not configured by application */ > +#define STATE_NOT_CONFIGURED 0 > + > +enum imp_log_chan_t { > + IMP_PREVIEWER, > + IMP_RESIZER, > + IMP_HISTOGRAM, > + IMP_BOXCAR > +}; > + > +/* IMP channel structure */ > +struct imp_logical_channel { > + /* channel type */ > + enum imp_log_chan_t type; > + /* If this channel is chained with another channel, this is set */ > + char chained; > + /* Set if there is a primary user of this channel */ > + char primary_user; > + /* channel configuration for this logial channel */ > + void *config; > + /* Size of the user configuration block */ > + int user_config_size; > + /* Saves the user configuration */ > + void *user_config; > + /* configure State of the channel */ > + unsigned int config_state; > +}; > + > +/* Where hardware channel is shared, this is used for serialisation */ > +struct imp_serializer { > + /* channel config array for serialization */ > + struct imp_logical_channel *channel_config[MAX_CHANNELS]; > + /* number of elements in the array */ > + int array_count; > + /* Semaphore for above config array */ > + struct mutex array_sem; > + /* Completion semaphore when hw channel is common > + * Use device specific completion semaphore when request is serialized > + */ > + struct completion sem_isr; > +}; > + > + > + > +#endif > +#endif > diff --git a/drivers/media/video/davinci/imp_hw_if.h b/drivers/media/video/davinci/imp_hw_if.h > new file mode 100644 > index 0000000..20a2b7f > --- /dev/null > +++ b/drivers/media/video/davinci/imp_hw_if.h > @@ -0,0 +1,178 @@ > +/* > +* Copyright (C) 2011 Texas Instruments Inc > +* > +* This program is free software; you can redistribute it and/or > +* modify it under the terms of the GNU General Public License as > +* published by the Free Software Foundation version 2. > +* > +* This program is distributed in the hope that it will be useful, > +* but WITHOUT ANY WARRANTY; without even the implied warranty of > +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > +* GNU General Public License for more details. > +* > +* You should have received a copy of the GNU General Public License > +* along with this program; if not, write to the Free Software > +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA > +*/ > + > +#ifndef _IMP_HW_IF_H > +#define _IMP_HW_IF_H > + > +#ifdef __KERNEL__ Same here. > +#include > +#include "imp_common.h" > +#include > + > +struct prev_module_if { > + /* Version of the preview module */ > + char *version; > + /* Module IDs as defined above */ > + unsigned short module_id; > + /* Name of the module */ > + char *module_name; > + /* control allowed in continous mode ? 1 - allowed , 0 - not allowed */ > + char control; > + /* path in which module sits */ > + enum imp_data_paths path; > + int (*set)(struct device *dev, void *param, int len); > + int (*get)(struct device *dev, void *param, int len); > +}; > + > +struct imp_hw_interface { > + /* Name of the image processor hardware */ > + char *name; > + /* module owner */ > + struct module *owner; > + /* > + * enumerate preview modules. Return interface to the > + * the module > + */ > + struct prev_module_if *(*prev_enum_modules) (struct device *dev, > + int index); > + /* > + * set operating mode for IPIPE; 1-single shot, 0-continous > + */ > + int (*set_oper_mode) (unsigned int mode); > + /* > + * reset operating mode for IPIPE; > + */ > + void (*reset_oper_mode) (void); > + /* > + * get IPIPE operation mode > + */ > + unsigned int (*get_oper_mode) (void); > + /* check if hw is busy in continuous mode. > + * Used for checking if hw is used by ccdc driver in > + * continuous mode. If streaming is ON, this will be > + * set to busy > + */ > + unsigned int (*get_hw_state) (void); > + /* set hw state */ > + void (*set_hw_state) (unsigned int state); > + /* is resizer chained ? */ > + unsigned int (*resizer_chain) (void); > + /* this is used to lock shared resource */ > + void (*lock_chain) (void); > + /* this is used unlock shared resouce */ > + void (*unlock_chain) (void); > + /* Allocate a shared or exclusive config block for hardware > + * configuration > + */ > + void *(*alloc_config_block) (struct device *dev); > + /* hw serialization enabled ?? */ > + int (*serialize) (void); > + /* De-allocate the exclusive config block */ > + void (*dealloc_config_block) (struct device *dev, void *config); > + /* Allocate a user confguration block */ > + void *(*alloc_user_config_block) (struct device *dev, > + enum imp_log_chan_t chan_type, > + int *len); > + > + /* de-allocate user config block */ > + void (*dealloc_user_config_block) (struct device *dev, void *config); > + > + /* set default configuration in the config block */ > + void (*set_user_config_defaults) (struct device *dev, > + enum imp_log_chan_t chan_type, > + void *user_config); > + /* set user configuration for preview */ > + int (*set_preview_config) (struct device *dev, > + void *user_config, void *config); > + /* set user configuration for resize */ > + int (*set_resizer_config) (struct device *dev, > + int resizer_chained, > + void *user_config, void *config); > + > + int (*reconfig_resizer) (struct device *dev, > + struct rsz_reconfig *user_config, > + void *config); > + > + /* update output buffer address for a channel > + * if config is NULL, the shared config is assumed > + * this is used only in single shot mode > + */ > + int (*update_inbuf_address) (void *config, unsigned int address); > + /* update output buffer address for a channel > + * if config is NULL, the shared config is assumed > + */ > + void (*update_outbuf1_address) (void *config, unsigned int address); > + /* update output buffer address for a channel > + * if config is NULL, the shared config is assumed > + */ > + void (*update_outbuf2_address) (void *config, unsigned int address); > + /* enable or disable hw */ > + void (*enable) (unsigned char en, void *config); > + /* enable or disable resizer to allow frame by frame resize in > + * continuous mode > + */ > + void (*enable_resize) (int en); > + /* setup hardware for processing. if config is NULL, > + * shared channel is assumed > + */ > + int (*hw_setup) (struct device *dev, void *config); > + /* Get configuration state of resizer in continuous mode */ > + unsigned int (*get_resizer_config_state) (void); > + /* Get configuration state of previewer in continuous mode */ > + unsigned int (*get_previewer_config_state) (void); > + > + /* Below APIs assume we are using shared configuration since > + * oper mode is continuous > + */ > + /* Set the input crop window at the IMP interface and IMP */ > + int (*set_input_win) (struct imp_window *win); > + /* Get current input crop window param at the IMP */ > + int (*get_input_win) (struct imp_window *win); > + /* Set interface parameter at IPIPEIF. Only valid for DM360 */ > + int (*set_hw_if_param) (struct vpfe_hw_if_param *param); > + /* Set input pixel format */ > + int (*set_in_pixel_format) (enum imp_pix_formats pix_fmt); > + /* set output pixel format */ > + int (*set_out_pixel_format) (enum imp_pix_formats pix_fmt); > + /* 0 - interleaved, 1 - field seperated */ > + int (*set_buftype) (unsigned char buf_type); > + /* 0 - interlaced, 1 - progressive */ > + int (*set_frame_format) (unsigned char frm_fmt); > + /* Set the output window at the IMP, output selection > + * done by out_sel. 0 - output 1 and 1 - output 2 > + */ > + int (*set_output_win) (struct imp_window *win); > + /* Get output enable/disable status */ > + int (*get_output_state) (unsigned char out_sel); > + /* Get output line lenght */ > + int (*get_line_length) (unsigned char out_sel); > + /* Get the output image height */ > + int (*get_image_height) (unsigned char out_sel); > + /* Get current output window param at the IMP */ > + int (*get_output_win) (struct imp_window *win); > + /* get maximum output width of rsz-a or rsz_b*/ > + int (*get_max_output_width) (int rsz); > + /* get maximum output height of rsa-a or rsz-b */ > + int (*get_max_output_height) (int rsz); > + /* Enumerate pixel format for a given input format */ > + int (*enum_pix) (u32 *output_pix, int index); > +}; Are there real benefits from using the above struct? I'm not sure if this makes anything clearer. Is it being used elsewhere than in a single instance (dm365_ipipe_interface)? > +struct imp_hw_interface *imp_get_hw_if(void); > + > +#endif > +#endif Regards, -- Sakari Ailus sakari.ailus at iki.fi From manjunath.hadli at ti.com Wed Sep 28 07:01:42 2011 From: manjunath.hadli at ti.com (Hadli, Manjunath) Date: Wed, 28 Sep 2011 17:31:42 +0530 Subject: [PATCH RESEND 2/4] davinci vpbe: add dm365 VPBE display driver changes In-Reply-To: <201109261501.49077.hverkuil@xs4all.nl> References: <1316410529-14744-1-git-send-email-manjunath.hadli@ti.com> <1316410529-14744-3-git-send-email-manjunath.hadli@ti.com> <201109261501.49077.hverkuil@xs4all.nl> Message-ID: On Mon, Sep 26, 2011 at 18:31:48, Hans Verkuil wrote: > On Monday, September 19, 2011 07:35:27 Manjunath Hadli wrote: > > This patch implements the core additions to the display driver, mainly > > controlling the VENC and other encoders for dm365. > > This patch also includes addition of amplifier subdevice to the vpbe > > driver and interfacing with venc subdevice. > > > > Signed-off-by: Manjunath Hadli > > --- > > drivers/media/video/davinci/vpbe.c | 55 ++++++++++++++++++++++++++++++++++-- > > include/media/davinci/vpbe.h | 16 ++++++++++ > > 2 files changed, 68 insertions(+), 3 deletions(-) > > > > diff --git a/drivers/media/video/davinci/vpbe.c > > b/drivers/media/video/davinci/vpbe.c > > index d773d30..21a8645 100644 > > --- a/drivers/media/video/davinci/vpbe.c > > +++ b/drivers/media/video/davinci/vpbe.c > > @@ -141,11 +141,12 @@ static int vpbe_enum_outputs(struct vpbe_device *vpbe_dev, > > return 0; > > } > > > > -static int vpbe_get_mode_info(struct vpbe_device *vpbe_dev, char > > *mode) Hans, > > +static int vpbe_get_mode_info(struct vpbe_device *vpbe_dev, char *mode, > > + int output_index) > > { > > struct vpbe_config *cfg = vpbe_dev->cfg; > > struct vpbe_enc_mode_info var; > > - int curr_output = vpbe_dev->current_out_index; > > + int curr_output = output_index; > > int i; > > > > if (NULL == mode) > > @@ -245,6 +246,8 @@ static int vpbe_set_output(struct vpbe_device *vpbe_dev, int index) > > struct encoder_config_info *curr_enc_info = > > vpbe_current_encoder_info(vpbe_dev); > > struct vpbe_config *cfg = vpbe_dev->cfg; > > + struct venc_platform_data *venc_device = vpbe_dev->venc_device; > > + enum v4l2_mbus_pixelcode if_params; > > int enc_out_index; > > int sd_index; > > int ret = 0; > > @@ -274,6 +277,8 @@ static int vpbe_set_output(struct vpbe_device *vpbe_dev, int index) > > goto out; > > } > > > > + if_params = cfg->outputs[index].if_params; > > + venc_device->setup_if_config(if_params); > > if (ret) > > goto out; > > } > > @@ -293,7 +298,7 @@ static int vpbe_set_output(struct vpbe_device *vpbe_dev, int index) > > * encoder. > > */ > > ret = vpbe_get_mode_info(vpbe_dev, > > - cfg->outputs[index].default_mode); > > + cfg->outputs[index].default_mode, index); > > if (!ret) { > > struct osd_state *osd_device = vpbe_dev->osd_device; > > > > @@ -367,6 +372,11 @@ static int vpbe_s_dv_preset(struct vpbe_device > > *vpbe_dev, > > > > ret = v4l2_subdev_call(vpbe_dev->encoders[sd_index], video, > > s_dv_preset, dv_preset); > > + if (!ret && (vpbe_dev->amp != NULL)) { > > + /* Call amplifier subdevice */ > > + ret = v4l2_subdev_call(vpbe_dev->amp, video, > > + s_dv_preset, dv_preset); > > + } > > /* set the lcd controller output for the given mode */ > > if (!ret) { > > struct osd_state *osd_device = vpbe_dev->osd_device; @@ -566,6 > > +576,8 @@ static int platform_device_get(struct device *dev, void > > *data) > > > > if (strcmp("vpbe-osd", pdev->name) == 0) > > vpbe_dev->osd_device = platform_get_drvdata(pdev); > > + if (strcmp("vpbe-venc", pdev->name) == 0) > > + vpbe_dev->venc_device = dev_get_platdata(&pdev->dev); > > > > return 0; > > } > > @@ -584,6 +596,7 @@ static int platform_device_get(struct device *dev, > > void *data) static int vpbe_initialize(struct device *dev, struct > > vpbe_device *vpbe_dev) { > > struct encoder_config_info *enc_info; > > + struct amp_config_info *amp_info; > > struct v4l2_subdev **enc_subdev; > > struct osd_state *osd_device; > > struct i2c_adapter *i2c_adap; > > @@ -704,6 +717,39 @@ static int vpbe_initialize(struct device *dev, struct vpbe_device *vpbe_dev) > > v4l2_warn(&vpbe_dev->v4l2_dev, "non-i2c encoders" > > " currently not supported"); > > } > > + /* Add amplifier subdevice for dm365 */ > > + if ((strcmp(vpbe_dev->cfg->module_name, "dm365-vpbe-display") == 0) && > > + vpbe_dev->cfg->amp != NULL) { > > + vpbe_dev->amp = kmalloc(sizeof(struct v4l2_subdev *), > > + GFP_KERNEL); > > Huh? Why alloc a struct v4l2_subdev pointer here? > > > + if (vpbe_dev->amp == NULL) { > > + v4l2_err(&vpbe_dev->v4l2_dev, > > + "unable to allocate memory for sub device"); > > + ret = -ENOMEM; > > + goto vpbe_fail_v4l2_device; > > + } > > + amp_info = vpbe_dev->cfg->amp; > > + if (amp_info->is_i2c) { > > + vpbe_dev->amp = v4l2_i2c_new_subdev_board( > > + &vpbe_dev->v4l2_dev, i2c_adap, > > + &_info->board_info, NULL); > > Especially since it is overwritten here! And so causes a memory leak. > The kmalloc above (and the kfree below) feels like old code that should have been removed. Thank you Hans. It was old code to be removed. Good catch. This piece of code is now removed and tested. > > > + if (!vpbe_dev->amp) { > > + v4l2_err(&vpbe_dev->v4l2_dev, > > + "amplifier %s failed to register", > > + amp_info->module_name); > > + ret = -ENODEV; > > + goto vpbe_fail_amp_register; > > + } > > + v4l2_info(&vpbe_dev->v4l2_dev, > > + "v4l2 sub device %s registered\n", > > + amp_info->module_name); > > + } else { > > + vpbe_dev->amp = NULL; > > + v4l2_warn(&vpbe_dev->v4l2_dev, "non-i2c amplifiers" > > + " currently not supported"); > > + } > > + } else > > + vpbe_dev->amp = NULL; > > > > /* set the current encoder and output to that of venc by default */ > > vpbe_dev->current_sd_index = 0; > > @@ -731,6 +777,8 @@ static int vpbe_initialize(struct device *dev, struct vpbe_device *vpbe_dev) > > /* TBD handling of bootargs for default output and mode */ > > return 0; > > > > +vpbe_fail_amp_register: > > + kfree(vpbe_dev->amp); > > vpbe_fail_sd_register: > > kfree(vpbe_dev->encoders); > > vpbe_fail_v4l2_device: > > @@ -757,6 +805,7 @@ static void vpbe_deinitialize(struct device *dev, struct vpbe_device *vpbe_dev) > > if (strcmp(vpbe_dev->cfg->module_name, "dm644x-vpbe-display") != 0) > > clk_put(vpbe_dev->dac_clk); > > > > + kfree(vpbe_dev->amp); > > kfree(vpbe_dev->encoders); > > vpbe_dev->initialized = 0; > > /* disable vpss clocks */ > > diff --git a/include/media/davinci/vpbe.h > > b/include/media/davinci/vpbe.h index 8b11fb0..8bc1b3c 100644 > > --- a/include/media/davinci/vpbe.h > > +++ b/include/media/davinci/vpbe.h > > @@ -63,6 +63,7 @@ struct vpbe_output { > > * output basis. If per mode is needed, we may have to move this to > > * mode_info structure > > */ > > + enum v4l2_mbus_pixelcode if_params; > > }; > > > > /* encoder configuration info */ > > @@ -74,6 +75,15 @@ struct encoder_config_info { > > struct i2c_board_info board_info; > > }; > > > > +/*amplifier configuration info */ > > +struct amp_config_info { > > + char module_name[32]; > > + /* Is this an i2c device ? */ > > + unsigned int is_i2c:1; > > + /* i2c subdevice board info */ > > + struct i2c_board_info board_info; > > +}; > > + > > /* structure for defining vpbe display subsystem components */ > > struct vpbe_config { > > char module_name[32]; > > @@ -84,6 +94,8 @@ struct vpbe_config { > > /* external encoder information goes here */ > > int num_ext_encoders; > > struct encoder_config_info *ext_encoders; > > + /* amplifier information goes here */ > > + struct amp_config_info *amp; > > int num_outputs; > > /* Order is venc outputs followed by LCD and then external encoders */ > > struct vpbe_output *outputs; > > @@ -158,6 +170,8 @@ struct vpbe_device { > > struct v4l2_subdev **encoders; > > /* current encoder index */ > > int current_sd_index; > > + /* external amplifier v4l2 subdevice */ > > + struct v4l2_subdev *amp; > > struct mutex lock; > > /* device initialized */ > > int initialized; > > @@ -165,6 +179,8 @@ struct vpbe_device { > > struct clk *dac_clk; > > /* osd_device pointer */ > > struct osd_state *osd_device; > > + /* venc device pointer */ > > + struct venc_platform_data *venc_device; > > /* > > * fields below are accessed by users of vpbe_device. Not the > > * ones above > > > > Regards, > > Hans > Rgds, Manju From manjunath.hadli at ti.com Wed Sep 28 08:02:48 2011 From: manjunath.hadli at ti.com (Manjunath Hadli) Date: Wed, 28 Sep 2011 18:32:48 +0530 Subject: [GIT PULL] davinci vpbe: enable DM365 v4l2 display driver Message-ID: <1317214968-8679-1-git-send-email-manjunath.hadli@ti.com> Mauro, Please pull : git://linuxtv.org/mhadli/v4l-dvb-davinci_devices.git for_mauro The patchset adds incremental changes necessary to enable dm365 v4l2 display driver, which includes vpbe display driver changes, osd specific changes and venc changes. The changes are incremental in nature,addind a few HD modes, and taking care of register level changes. The patches are tested for both SD and HD modes. Manjunath Hadli (3): davinci vpbe: add dm365 VPBE display driver changes davinci vpbe: add dm365 and dm355 specific OSD changes davinci vpbe: add VENC block changes to enable dm365 and dm355 drivers/media/video/davinci/vpbe.c | 48 +++- drivers/media/video/davinci/vpbe_osd.c | 472 ++++++++++++++++++++++++++++--- drivers/media/video/davinci/vpbe_venc.c | 205 ++++++++++++-- include/media/davinci/vpbe.h | 16 + include/media/davinci/vpbe_venc.h | 4 + 5 files changed, 677 insertions(+), 68 deletions(-) From m-karicheri2 at ti.com Thu Sep 29 09:17:43 2011 From: m-karicheri2 at ti.com (Karicheri, Muralidharan) Date: Thu, 29 Sep 2011 14:17:43 +0000 Subject: kernel boot log timestamp all zeros - 3.0rcx based davinci tree In-Reply-To: References: <3E54258959B69E4282D79E01AB1F32B701A398@DLEE12.ent.ti.com> Message-ID: <3E54258959B69E4282D79E01AB1F32B703E0BD@DLEE12.ent.ti.com> Sudhakar, Could you check what revision of the clock timer IP used in your SoC? If it is greater than 1.5, then the timer code will not work as it tries to configure the two timers (event clock and free running clocks) independently. I.e. While one is active, configure and enable the other. As per the email that I got from the Simulator team, it seems the IP stopped supporting changing the timer configuration while the other timer is in active state. In this case, we are using the 64bit timer as two unchained independent timers and should have allowed to configure them independently. Not sure why IP team removed this capability in the later revisions of IP. I have currently added a work around to get this working on Simulator. Not sure if this limitation is available in the real IP. Could you confirm at your end? If your IP version is in fact the later version, then I need to take this up with the IP team. Murali Karicheri Software Design Engineer email: m-karicheri2 at ti.com Phone: (301) 407 9583 >> -----Original Message----- >> From: Rajashekhara, Sudhakar >> Sent: Monday, September 26, 2011 12:51 AM >> To: Karicheri, Muralidharan; davinci-linux-open- >> source at linux.davincidsp.com >> Subject: RE: kernel bootlog timestamp all zeros - 3.0rcx based davinci >> tree >> >> Hi Murali, >> >> On Mon, Aug 29, 2011 at 21:23:45, Karicheri, Muralidharan wrote: >> > Hi All, >> > >> > I have a port of the davinci tree for a new platform that I am working >> on. The time stamp of the boot log shows all zeros. I am using the master >> branch of davinci tree at http://gitorious.org/linux-davinci/linux-davinci >> > >> > My original port based on 2.6.37 has proper time stamps displayed. >> Anything changes related to this in recent kernel that I need to be aware >> causing this issue? Thanks in advance for your help. >> > >> >> I tried it from the same repository which had the below commit at the top >> and it worked absolutely fine. >> >> commit acc2ec87c22da0655bc75ef1d8eba89010bab00e >> Merge: 06baeca 6e22c04 >> Author: Sekhar Nori >> Date: Sat Sep 17 16:17:23 2011 +0530 >> >> rebuild linux-davinci from branches >> >> 5.241 0.011: Bytes transferred = 1815848 (1bb528 hex) >> 5.331 0.091: ## Booting kernel from Legacy Image at c0700000 ... >> 5.331 0.000: Image Name: Linux-3.1.0-rc6-07781-gacc2ec8 >> 5.340 0.009: Image Type: ARM Linux Kernel Image (uncompressed) >> 5.340 0.000: Data Size: 1815784 Bytes = 1.7 MB >> 5.340 0.000: Load Address: c0008000 >> 5.340 0.000: Entry Point: c0008000 >> 5.900 0.560: Verifying Checksum ... OK >> 6.500 0.600: Loading Kernel Image ... OK >> 6.500 0.000: OK >> 6.500 0.000: >> 6.500 0.000: Starting kernel ... >> 6.500 0.000: >> 7.880 1.380: Uncompressing Linux... done, booting the kernel. >> 9.830 1.950: Linux version 3.1.0-rc6-07781-gacc2ec8 (sudhakar at linux-psp- >> server.india.ext.ti.com) (gcc version 4.3.3 (Sourcery G++ Lite 2009q1-203) >> ) #1 PREEMPT Mon Sep 26 09:04:58 IST 2011 >> 9.843 0.013: CPU: ARM926EJ-S [41069265] revision 5 (ARMv5TEJ), cr=00053177 >> 9.843 0.000: CPU: VIVT data cache, VIVT instruction cache >> 9.843 0.000: Machine: DaVinci DA850/OMAP-L138/AM18x EVM >> 9.857 0.015: Memory policy: ECC disabled, Data cache writethrough >> 9.857 0.000: DaVinci da850/omap-l138 variant 0x0 >> >> Thanks, >> Sudhakar From bengardiner at nanometrics.ca Fri Sep 30 16:23:00 2011 From: bengardiner at nanometrics.ca (Ben Gardiner) Date: Fri, 30 Sep 2011 17:23:00 -0400 Subject: [RFC 0/3] ASoC: davinci- pcm and McASP error detection Message-ID: Both the EDMA3 and McASP have the ability to report error conditions. In both cases these errors are silently dropped on the floor. I would like very much to get HW errors up the stack to the aplay process using the harware. This is an RFC series demonstrating a first attempt. 1/3 isn't nearly as half-baked as the others. It proposes to return SNDRV_PCM_POS_XRUN from davinci-pcm's pointer() function like is currently done in fsl_dma. The problem I have observed in test is that the stream does not abort; several underruns are reported before aplay finally dies. I would prefer immeadiate death with a reason. 2/3 and 3/3 are a first-strike at registering 'health' callbacks provided by the CPU DAI so that error conditions can be reported back. The health callback is polled on calls to pointer(). This may be too often. Also the current method of registering these callbacks seems wrong -- please help me out here. If there is an established method of bubbling HW errors up to userspace that I completely missed: I am sorry for the noise and would be glad to hear about how to use it with davinci-pcm. Best Regards, Ben Gardiner Ben Gardiner (3): [RFC] ASoC: davinci-pcm: latch EDMA errors [RFC] ASoC: davinci-pcm: add cpu-dai health callbacks [RFC] ASoC: davinci-mcasp: add cpu dai health callback sound/soc/davinci/davinci-mcasp.c | 26 ++++++++++++++++++++++++++ sound/soc/davinci/davinci-pcm.c | 19 +++++++++++++++++-- sound/soc/davinci/davinci-pcm.h | 3 +++ 3 files changed, 46 insertions(+), 2 deletions(-) -- 1.7.4.1 From bengardiner at nanometrics.ca Fri Sep 30 16:23:01 2011 From: bengardiner at nanometrics.ca (Ben Gardiner) Date: Fri, 30 Sep 2011 17:23:01 -0400 Subject: [PATCH 1/3] ASoC: davinci-pcm: latch EDMA errors In-Reply-To: References: Message-ID: <647c53d57c6dc6b9780f7f1ad21f39106e702566.1317417232.git.bengardiner@nanometrics.ca> The davinci-pcm driver currently ignores all EDMA completion callbacks that could be indicating an error. Latch any edma error-status callbacks and report them as SNDDRV_PCM_POS_XRUN like is done in fsl_dma.c. Signed-off-by: Ben Gardiner --- In testing when an error occured early-on in playback the stream did not halt, but several underruns were reported until eventually the stream halted. Is there a better way to report HW errors up the stack? --- sound/soc/davinci/davinci-pcm.c | 13 +++++++++++-- 1 files changed, 11 insertions(+), 2 deletions(-) diff --git a/sound/soc/davinci/davinci-pcm.c b/sound/soc/davinci/davinci-pcm.c index d5fe08c..41a3b5b 100644 --- a/sound/soc/davinci/davinci-pcm.c +++ b/sound/soc/davinci/davinci-pcm.c @@ -155,6 +155,7 @@ struct davinci_runtime_data { int ram_link2; struct edmacc_param asp_params; struct edmacc_param ram_params; + unsigned error:1; }; static void davinci_pcm_period_elapsed(struct snd_pcm_substream *substream) @@ -245,8 +246,12 @@ static void davinci_pcm_dma_irq(unsigned link, u16 ch_status, void *data) print_buf_info(prtd->ram_channel, "i ram_channel"); pr_debug("davinci_pcm: link=%d, status=0x%x\n", link, ch_status); - if (unlikely(ch_status != DMA_COMPLETE)) + if (unlikely(ch_status != DMA_COMPLETE)) { + spin_lock(&prtd->lock); + prtd->error = 1; + spin_unlock(&prtd->lock); return; + } if (snd_pcm_running(substream)) { spin_lock(&prtd->lock); @@ -635,7 +640,7 @@ davinci_pcm_pointer(struct snd_pcm_substream *substream) struct snd_pcm_runtime *runtime = substream->runtime; struct davinci_runtime_data *prtd = runtime->private_data; unsigned int offset; - int asp_count; + int asp_count, error; unsigned int period_size = snd_pcm_lib_period_bytes(substream); /* @@ -647,8 +652,12 @@ davinci_pcm_pointer(struct snd_pcm_substream *substream) */ spin_lock(&prtd->lock); asp_count = prtd->period - 2; + error = prtd->error; spin_unlock(&prtd->lock); + if (error) + return SNDRV_PCM_POS_XRUN; + if (asp_count < 0) asp_count += runtime->periods; asp_count *= period_size; -- 1.7.4.1 From bengardiner at nanometrics.ca Fri Sep 30 16:23:02 2011 From: bengardiner at nanometrics.ca (Ben Gardiner) Date: Fri, 30 Sep 2011 17:23:02 -0400 Subject: [RFC 2/3] ASoC: davinci-pcm: add cpu-dai health callbacks In-Reply-To: References: Message-ID: The CPU DAIs available to the davinci-pcm driver have the capability of detecting and reporting errors. Add callbacks to the struct davinci_pcm_dma_params passed to davinci-pcm from the CPU DAI. This has several shortcomings: 1) It bubbles up to the user as underruns, not a fatal error -- some may prefer the former, I realize but the latter is more attractive to me. Same problem as with the previous patch in this series. 2) passing it in the dma_params struct seems like dual-purposing that structure 3) the device instance must be passed as drvdata since I did not know how to get back to the cpudai instance from a substream (sorry, please help!) [not ready yet, please comment] Not-Signed-off-by: Ben Gardiner --- sound/soc/davinci/davinci-pcm.c | 8 +++++++- sound/soc/davinci/davinci-pcm.h | 3 +++ 2 files changed, 10 insertions(+), 1 deletions(-) diff --git a/sound/soc/davinci/davinci-pcm.c b/sound/soc/davinci/davinci-pcm.c index 41a3b5b..cb0e296 100644 --- a/sound/soc/davinci/davinci-pcm.c +++ b/sound/soc/davinci/davinci-pcm.c @@ -156,6 +156,8 @@ struct davinci_runtime_data { struct edmacc_param asp_params; struct edmacc_param ram_params; unsigned error:1; + int (*cpudai_health)(struct snd_pcm_substream *, void *); + void *health_drvdata; }; static void davinci_pcm_period_elapsed(struct snd_pcm_substream *substream) @@ -655,7 +657,8 @@ davinci_pcm_pointer(struct snd_pcm_substream *substream) error = prtd->error; spin_unlock(&prtd->lock); - if (error) + if (error || (prtd->cpudai_health && + prtd->cpudai_health(substream, prtd->health_drvdata))) return SNDRV_PCM_POS_XRUN; if (asp_count < 0) @@ -706,6 +709,9 @@ static int davinci_pcm_open(struct snd_pcm_substream *substream) prtd->ram_link = -1; prtd->ram_link2 = -1; + prtd->cpudai_health = pa->health; + prtd->health_drvdata = pa->health_drvdata; + runtime->private_data = prtd; ret = davinci_pcm_dma_request(substream); diff --git a/sound/soc/davinci/davinci-pcm.h b/sound/soc/davinci/davinci-pcm.h index c0d6c9b..0474d97 100644 --- a/sound/soc/davinci/davinci-pcm.h +++ b/sound/soc/davinci/davinci-pcm.h @@ -26,6 +26,9 @@ struct davinci_pcm_dma_params { unsigned char data_type; /* xfer data type */ unsigned char convert_mono_stereo; unsigned int fifo_level; + + int (*health)(struct snd_pcm_substream *, void *drvdata); + void *health_drvdata; }; #endif -- 1.7.4.1 From bengardiner at nanometrics.ca Fri Sep 30 16:23:03 2011 From: bengardiner at nanometrics.ca (Ben Gardiner) Date: Fri, 30 Sep 2011 17:23:03 -0400 Subject: [RFC 3/3] ASoC: davinci-mcasp: add cpu dai health callback In-Reply-To: References: Message-ID: <8cf4a5e5fb678cf117803c9a11aaba82d6b5278e.1317417232.git.bengardiner@nanometrics.ca> The McASP has RERR and XERR bits in its RSTAT and XSTAT registers which report the OR'd state of several potential errors. Register a function to check the status of these bits and report HW errors back up the stack. [not ready yet, please comment] Not-Signed-off-by: Ben Gardiner --- sound/soc/davinci/davinci-mcasp.c | 26 ++++++++++++++++++++++++++ 1 files changed, 26 insertions(+), 0 deletions(-) diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c index 7173df2..ca4073f 100644 --- a/sound/soc/davinci/davinci-mcasp.c +++ b/sound/soc/davinci/davinci-mcasp.c @@ -273,6 +273,11 @@ #define MUTETXDMAERR BIT(12) /* + * DAVINCI_MCASP_RXSTAT_REG - Receiver Status Register bits + */ +#define RERR BIT(8) + +/* * DAVINCI_MCASP_REVTCTL_REG - Receiver DMA Event Control Register bits */ #define RXDATADMADIS BIT(0) @@ -283,6 +288,11 @@ #define TXDATADMADIS BIT(0) /* + * DAVINCI_MCASP_TXSTAT_REG - Transmitter Status Register bits + */ +#define XERR BIT(8) + +/* * DAVINCI_MCASP_W[R]FIFOCTL - Write/Read FIFO Control Register bits */ #define FIFO_ENABLE BIT(16) @@ -813,6 +823,19 @@ static int davinci_mcasp_startup(struct snd_pcm_substream *substream, return 0; } +static int davinci_mcasp_health(struct snd_pcm_substream *substream, + void *data) +{ + struct davinci_audio_dev *dev = data; + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + return mcasp_get_reg(dev->base + DAVINCI_MCASP_TXSTAT_REG) & + XERR; + else + return mcasp_get_reg(dev->base + DAVINCI_MCASP_RXSTAT_REG) & + RERR; +} + static struct snd_soc_dai_ops davinci_mcasp_dai_ops = { .startup = davinci_mcasp_startup, .trigger = davinci_mcasp_trigger, @@ -919,6 +942,9 @@ static int davinci_mcasp_probe(struct platform_device *pdev) dma_data->dma_addr = (dma_addr_t) (pdata->tx_dma_offset + mem->start); + dma_data->health = davinci_mcasp_health; + dma_data->health_drvdata = dev; + /* first TX, then RX */ res = platform_get_resource(pdev, IORESOURCE_DMA, 0); if (!res) { -- 1.7.4.1