V4L/DVB: OMAP_VOUT: Allow omap_vout to build without VRFB
v2 cover V4L/DVB: OMAP_VOUT: Allow omap_vout to build without VRFB
This lets omap_vout driver build and run without VRFB. It works along the lines of the following patch series:
OMAP: DSS2: OMAPFB: Allow FB_OMAP2 to build without VRFB
https://patchwork.kernel.org/patch/105371/
Since VRFB is tightly coupled with the omap_vout driver, a handful of vrfb specific functions have been defined and placed in omap_vout_vrfb.c
A variable rotation_type is introduced in omapvideo_info like the way in omapfb_info, this allows to call vrfb specific functions only if the rotation type is vrfb. When the rotation_type is set to SDMA, the S_CTRL ioctl prevents the user setting a non zero rotation value.
Archit Taneja (2):
V4L/DVB: OMAP_VOUT: Create a seperate vrfb functions library V4L/DVB: OMAP_VOUT: Use rotation_type to choose between vrfb and
sdram buffers
drivers/media/video/omap/Kconfig | 1 - drivers/media/video/omap/Makefile | 1 + drivers/media/video/omap/omap_vout.c | 480 ++++++----------------------- drivers/media/video/omap/omap_vout_vrfb.c | 417 +++++++++++++++++++++++++ drivers/media/video/omap/omap_vout_vrfb.h | 40 +++ drivers/media/video/omap/omap_voutdef.h | 26 ++ 6 files changed, 571 insertions(+), 394 deletions(-) create mode 100644 drivers/media/video/omap/omap_vout_vrfb.c create mode 100644 drivers/media/video/omap/omap_vout_vrfb.h
--
Version 2:
- Don't try to enable SDRAM rotation , return an error if non zero rotation is attempted when rotation_type is set to SDMA rotation.
Version 1:
http://www.mail-archive.com/[email protected]/msg21937.html
PATCH v2 1/2 V4L/DVB: OMAP_VOUT: Create a seperate vrfb functions library
Create omap_vout_vrfb.c and omap_vout_vrfb.h, these contain functions which omap_vout will call if the rotation type is set to VRFB rotation. It is essentialy the code in omap_vout which is used for vrfb specific tasks.
Apart from this, some functions and preprocessor defines needed by the new vrfb function's have been moved around.
--- drivers/media/video/omap/omap_vout.c | 32 +-- drivers/media/video/omap/omap_vout_vrfb.c | 417 +++++++++++++++++++++++++++++ drivers/media/video/omap/omap_vout_vrfb.h | 40 +++ drivers/media/video/omap/omap_voutdef.h | 25 ++ 4 files changed, 490 insertions(+), 24 deletions(-) create mode 100644 drivers/media/video/omap/omap_vout_vrfb.c create mode 100644 drivers/media/video/omap/omap_vout_vrfb.h
drivers/media/video/omap/omap_vout.c +8 -24
@@ -56,7 +56,6 @@ MODULE_AUTHOR("Texas Instruments");MODULE_DESCRIPTION ("OMAP Video for Linux Video out driver" );MODULE_LICENSE ("GPL" ); -/* Driver Configuration macros */ #define VOUT_NAME "omap_vout"
@@ -65,28 +64,13 @@ enum omap_vout_channels { OMAP_VIDEO2, }; -enum dma_channel_state { -DMA_CHAN_NOT_ALLOTED , -DMA_CHAN_ALLOTED , -}; -#define QQVGA_WIDTH 160#define QQVGA_HEIGHT 120 -/* Max Resolution supported by the driver */ -#define VID_MAX_WIDTH 1280/* Largest width */ -#define VID_MAX_HEIGHT 720/* Largest height */ -/* Mimimum requirement is 2x2 for DSS */ #define VID_MIN_WIDTH 2#define VID_MIN_HEIGHT 2 -/* 2048 x 2048 is max res supported by OMAP display controller */ -#define MAX_PIXELS_PER_LINE 2048 - -#define VRFB_TX_TIMEOUT 1000 -#define VRFB_NUM_BUFS 4 -/* Max buffer size tobe allocated during init */ #define OMAP_VOUT_MAX_BUF_SIZE (VID_MAX_WIDTH*VID_MAX_HEIGHT*4)
@@ -96,8 +80,8 @@ static u32 video1_numbuffers = 3;static u32 video2_numbuffers =3 ;static u32 video1_bufsize =OMAP_VOUT_MAX_BUF_SIZE ;static u32 video2_bufsize =OMAP_VOUT_MAX_BUF_SIZE ; -static u32 vid1_static_vrfb_alloc; -static u32 vid2_static_vrfb_alloc; +u32 vid1_static_vrfb_alloc; +u32 vid2_static_vrfb_alloc;static int debug;/* Module parameters */
@@ -174,7 +158,7 @@ const static struct v4l2_fmtdesc omap_formats[] = {/* * Allocate buffers */ -static unsigned long omap_vout_alloc_buffer (u32 buf_size,u32 *phys_addr) +unsigned long omap_vout_alloc_buffer (u32 buf_size,u32 *phys_addr) {u32 order, size;unsigned long virt_addr, addr;
@@ -198,7 +182,7 @@ static unsigned long omap_vout_alloc_buffer(u32 buf_size, u32 *phys_addr)/* * Free buffers */ -static void omap_vout_free_buffer (unsigned long virtaddr,u32 buf_size) +void omap_vout_free_buffer (unsigned long virtaddr,u32 buf_size) {u32 order, size;unsigned long addr = virtaddr;
@@ -371,7 +355,7 @@ static void omap_vout_release_vrfb(struct omap_vout_device *vout)/* * Return true if rotation is 90 or 270 */ -static inline int rotate_90_or_270 (const struct omap_vout_device *vout) +int rotate_90_or_270 (const struct omap_vout_device *vout) {return (vout->rotation == dss_rotation_90_degree || vout->rotation == dss_rotation_270_degree);
@@ -380,7 +364,7 @@ static inline int rotate_90_or_270(const struct omap_vout_device *vout)/* * Return true if rotation is enabled */ -static inline int rotation_enabled (const struct omap_vout_device *vout) +int rotation_enabled (const struct omap_vout_device *vout) {return vout->rotation || vout->mirror; }
@@ -388,7 +372,7 @@ static inline int rotation_enabled(const struct omap_vout_device *vout)/* * Reverse the rotation degree if mirroring is enabled */ -static inline int calc_rotation (const struct omap_vout_device *vout) +int calc_rotation (const struct omap_vout_device *vout) {if (!vout->mirror)return vout->rotation;
@@ -408,7 +392,7 @@ static inline int calc_rotation(const struct omap_vout_device *vout)/* * Free the V4L2 buffers */ -static void omap_vout_free_buffers (struct omap_vout_device *vout) +void omap_vout_free_buffers (struct omap_vout_device *vout) {int i, numbuffers;
drivers/media/video/omap/omap_vout_vrfb.c new file +417 -0
417 lines not on this page · raw message
drivers/media/video/omap/omap_vout_vrfb.h new file +40 -0
@@ -0,0 +1,40 @@ +/* +* omap_vout_vrfb.h +* +* Copyright (C) 2010 Texas Instruments. +* +* This file is licensed under the terms of the GNU General Public License +* version 2. This program is licensed "as is" without any warranty of any +* kind, whether express or implied. +* +*/ + +#ifndef OMAP_VOUT_VRFB_H +#define OMAP_VOUT_VRFB_H + +#ifdef CONFIG_OMAP2_VRFB +void omap_vout_free_vrfb_buffers (struct omap_vout_device *vout); +void omap_vout_free_extra_vrfb_buffers (struct omap_vout_device *vout); +int omap_vout_setup_vrfb_bufs (struct platform_device *pdev,int vid_num); +void omap_vout_release_vrfb (struct omap_vout_device *vout); +int omap_vout_vrfb_buffer_setup (struct omap_vout_device *vout, +unsigned int *count,unsigned int startindex); +int omap_vout_prepare_vrfb (struct omap_vout_device *vout, +struct videobuf_buffer *vb); +void omap_vout_calculate_vrfb_offset (struct omap_vout_device *vout); +#else +void omap_vout_free_vrfb_buffers (struct omap_vout_device *vout) { } +void omap_vout_free_extra_vrfb_buffers (struct omap_vout_device *vout) { } +int omap_vout_setup_vrfb_bufs (struct platform_device *pdev,int vid_num) + {return 0 ; } +void omap_vout_release_vrfb (struct omap_vout_device *vout) { } +int omap_vout_vrfb_buffer_setup (struct omap_vout_device *vout, +unsigned int *count,unsigned int startindex) + {return 0 ; } +int omap_vout_prepare_vrfb (struct omap_vout_device *vout, +struct videobuf_buffer *vb) + {return 0 ; } +void omap_vout_calculate_vrfb_offset (struct omap_vout_device *vout) { } +#endif + +#endif
drivers/media/video/omap/omap_voutdef.h +25 -0
@@ -27,6 +27,24 @@#define MAX_DISPLAYS 3#define MAX_MANAGERS 3 +/* Max Resolution supported by the driver */ +#define VID_MAX_WIDTH 1280/* Largest width */ +#define VID_MAX_HEIGHT 720/* Largest height */ + +/* 2048 x 2048 is max res supported by OMAP display controller */ +#define MAX_PIXELS_PER_LINE 2048 + +#define VRFB_TX_TIMEOUT 1000 +#define VRFB_NUM_BUFS 4 + +extern u32 vid1_static_vrfb_alloc; +extern u32 vid2_static_vrfb_alloc; + +enum dma_channel_state { +DMA_CHAN_NOT_ALLOTED , +DMA_CHAN_ALLOTED , +}; +/* Enum for Rotation * DSS understands rotation in 0, 1, 2, 3 context * while V4L2 driver understands it as 0, 90, 180, 270
@@ -144,4 +162,11 @@ struct omap_vout_device { int io_allowed; }; + +unsigned long omap_vout_alloc_buffer (u32 buf_size,u32 *phys_addr); +void omap_vout_free_buffer (unsigned long virtaddr,u32 buf_size); +void omap_vout_free_buffers (struct omap_vout_device *vout); +int rotate_90_or_270 (const struct omap_vout_device *vout); +int rotation_enabled (const struct omap_vout_device *vout); +int calc_rotation (const struct omap_vout_device *vout);#endif /* ifndef OMAP_VOUTDEF_H */
Signature · 1 line
1.7.0.4
RE: [PATCH v2 1/2] V4L/DVB: OMAP_VOUT: Create a seperate vrfb functions library
Quoted 47 lines
-----Original Message-----
From: Taneja, Archit
Sent: Monday, September 27, 2010 12:47 PM
To: Hiremath, Vaibhav
Cc: [email protected]; [email protected]; Taneja, Archit
Subject: [PATCH v2 1/2] V4L/DVB:OMAP_VOUT: Create a seperate vrfb functions libraryCreate
omap_vout_vrfb.candomap_vout_vrfb.h, these contain functions whichomap_voutwill call if the rotation type is set to VRFB rotation. It is essentialy the code inomap_voutwhich is used for vrfb specific tasks.Apart from this, some functions and preprocessor defines needed by the new vrfb function's have been moved around.
Signed-off-by Archit Taneja <[email protected]>--- drivers/media/video/omap/omap_vout.c | 32 +-- drivers/media/video/omap/omap_vout_vrfb.c | 417 +++++++++++++++++++++++++++++ drivers/media/video/omap/omap_vout_vrfb.h | 40 +++ drivers/media/video/omap/omap_voutdef.h | 25 ++ 4 files changed, 490 insertions(+), 24 deletions(-) create mode 100644 drivers/media/video/omap/omap_vout_vrfb.c create mode 100644 drivers/media/video/omap/omap_vout_vrfb.hdrivers/media/video/omap/omap_vout.c +0
-3@@ -56,7 +56,6 @@ MODULE_AUTHOR("Texas Instruments");MODULE_DESCRIPTION ("OMAP Video for Linux Video out driver" );MODULE_LICENSE ("GPL" ); -/* Driver Configuration macros */ #define VOUT_NAME "omap_vout"@@ -65,28 +64,13 @@ enum omap_vout_channels { OMAP_VIDEO2, }; -enum dma_channel_state { -DMA_CHAN_NOT_ALLOTED ,
drivers/media/video/omap/omap_vout.c enum omap_vout_channels { · line 79
Quoted 10 lines
drivers/media/video/omap/omap_vout.c +0
-7- DMA_CHAN_ALLOTED, -}; -#define QQVGA_WIDTH 160#define QQVGA_HEIGHT 120 -/* Max Resolution supported by the driver */ -#define VID_MAX_WIDTH 1280/* Largest width */ -#define VID_MAX_HEIGHT 720/* Largest height */ -
[Hiremath, Vaibhav] I wanted to get rid of this sometime, but as of now we can live with this.
I would suggest to move QQVGA_xxx macros to header file to keep consistency.
Quoted 14 lines
drivers/media/video/omap/omap_vout.c +0
-6/* Mimimum requirement is 2x2 for DSS */ #define VID_MIN_WIDTH 2#define VID_MIN_HEIGHT 2 -/* 2048 x 2048 is max res supported by OMAP display controller */ -#define MAX_PIXELS_PER_LINE 2048 - -#define VRFB_TX_TIMEOUT 1000 -#define VRFB_NUM_BUFS 4 -/* Max buffer size tobe allocated during init */ #define OMAP_VOUT_MAX_BUF_SIZE (VID_MAX_WIDTH*VID_MAX_HEIGHT*4)
drivers/media/video/omap/omap_vout.c static u32 video1_numbuffers = 3; · line 84
Quoted 7 lines
drivers/media/video/omap/omap_vout.c +2
-2@@ -96,8 +80,8 @@ static u32 video1_numbuffers = 3;static u32 video2_numbuffers =3 ;static u32 video1_bufsize =OMAP_VOUT_MAX_BUF_SIZE ;static u32 video2_bufsize =OMAP_VOUT_MAX_BUF_SIZE ; -static u32 vid1_static_vrfb_alloc; -static u32 vid2_static_vrfb_alloc; +u32 vid1_static_vrfb_alloc; +u32 vid2_static_vrfb_alloc;
[Hiremath, Vaibhav] Don't make this variable "extern"; I think these variables are being used during init time only so you can pass it as function argument.
drivers/media/video/omap/omap_vout.c const static struct v4l2_fmtdesc omap_formats[] = { · line 161
Quoted 9 lines
drivers/media/video/omap/omap_vout.c +1
-1static int debug;/* Module parameters */ @@ -174,7 +158,7 @@ const static struct v4l2_fmtdesc omap_formats[] = {/* * Allocate buffers */ -static unsigned long omap_vout_alloc_buffer (u32 buf_size,u32 *phys_addr) +unsigned long omap_vout_alloc_buffer (u32 buf_size,u32 *phys_addr)
[Hiremath, Vaibhav] This function can be moved to omap_voutlib.c file since it is something generic and independent.
drivers/media/video/omap/omap_vout.c static unsigned long omap_vout_alloc_buffer(u32 · line 187
Quoted 11 lines
drivers/media/video/omap/omap_vout.c +1
-1{u32 order, size;unsigned long virt_addr, addr;@@ -198,7 +182,7 @@ static unsigned long omap_vout_alloc_buffer(u32 buf_size, u32 *phys_addr)/* * Free buffers */ -static void omap_vout_free_buffer (unsigned long virtaddr,u32 buf_size) +void omap_vout_free_buffer (unsigned long virtaddr,u32 buf_size) {
[Hiremath, Vaibhav] same here.
drivers/media/video/omap/omap_vout.c static void omap_vout_release_vrfb(struct · line 360
Quoted 10 lines
drivers/media/video/omap/omap_vout.c +0
-0u32 order, size;unsigned long addr = virtaddr;drivers/media/video/omap/omap_vout.c +1
-1@@ -371,7 +355,7 @@ static void omap_vout_release_vrfb(struct omap_vout_device *vout)/* * Return true if rotation is 90 or 270 */ -static inline int rotate_90_or_270 (const struct omap_vout_device *vout) +int rotate_90_or_270 (const struct omap_vout_device *vout) {
[Hiremath, Vaibhav] You can move this to header file keeping it inline.
drivers/media/video/omap/omap_vout.c static inline int rotate_90_or_270(const struct · line 368
Quoted 9 lines
drivers/media/video/omap/omap_vout.c +0
-0return (vout->rotation == dss_rotation_90_degree ||vout->rotation == dss_rotation_270_degree);drivers/media/video/omap/omap_vout.c +1
-1@@ -380,7 +364,7 @@ static inline int rotate_90_or_270(const struct omap_vout_device *vout)/* * Return true if rotation is enabled */ -static inline int rotation_enabled (const struct omap_vout_device *vout) +int rotation_enabled (const struct omap_vout_device *vout)
[Hiremath, Vaibhav] ditto here.
Quoted 42 lines
drivers/media/video/omap/omap_vout.c +0
-0{return vout->rotation || vout->mirror;}
drivers/media/video/omap/omap_vout.c +1
-1@@ -388,7 +372,7 @@ static inline int rotation_enabled(const struct omap_vout_device *vout)/* * Reverse the rotation degree if mirroring is enabled */ -static inline int calc_rotation (const struct omap_vout_device *vout) +int calc_rotation (const struct omap_vout_device *vout) {if (!vout->mirror)return vout->rotation;drivers/media/video/omap/omap_vout.c +1
-1@@ -408,7 +392,7 @@ static inline int calc_rotation(const struct omap_vout_device *vout)/* * Free the V4L2 buffers */ -static void omap_vout_free_buffers (struct omap_vout_device *vout) +void omap_vout_free_buffers (struct omap_vout_device *vout) {int i, numbuffers;drivers/media/video/omap/omap_vout_vrfb.c new file +6
-0@@ -0,0 +1,417 @@ +/* +* omap_vout_vrfb.c +* +* Copyright (C) 2010 Texas Instruments. +* +* This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ *
+ */
drivers/media/video/omap/omap_vout_vrfb.c line 15
Quoted 5 lines
drivers/media/video/omap/omap_vout_vrfb.c new file +5
-0+ +#include <linux/module.h> +#include <linux/types.h> +#include <linux/sched.h> +#include <linux/platform_device.h>
[Hiremath, Vaibhav] Do you need all of these header files?
Quoted 426 lines
drivers/media/video/omap/omap_vout_vrfb.c new file +49
-0+#include <linux/dma-mapping.h> +#include <linux/videodev2.h> + +#include <media/videobuf-dma-contig.h> +#include <media/v4l2-device.h> + +#include <plat/dma.h> +#include <plat/vrfb.h> +#include <plat/display.h> + +#include "omap_voutdef.h" + +/* +* Function for allocating video buffers +*/ +static int omap_vout_allocate_vrfb_buffers (struct omap_vout_device *vout, +unsigned int *count,int startindex) +{ +int i, j; + +for (i =0 ; i < *count; i++) { +if (!vout->smsshado_virt_addr[i]) { + vout->smsshado_virt_addr[i] = +omap_vout_alloc_buffer (vout->smsshado_size, + &vout->smsshado_phy_addr[i]); + } +if (!vout->smsshado_virt_addr[i] && startindex !=-1 ) { +if (V4L2_MEMORY_MMAP == vout->memory && i >= startindex) +break ; + } +if (!vout->smsshado_virt_addr[i]) { +for (j =0 ; j < i; j++) { +omap_vout_free_buffer ( + vout->smsshado_virt_addr[j], + vout->smsshado_size); + vout->smsshado_virt_addr[j] =0 ; + vout->smsshado_phy_addr[j] =0 ; + } + *count =0 ; +return -ENOMEM ; + } +memset ((void *) vout->smsshado_virt_addr[i],0 , + vout->smsshado_size); + } +return 0 ; +} + +/* +* Wakes up the application once the DMA transfer to VRFB space is completed.
+ */
+static voidomap_vout_vrfb_dma_tx_callback(int lch, u16 ch_status, void *data)drivers/media/video/omap/omap_vout_vrfb.c new file +81
-0+{ +struct vid_vrfb_dma *t = (struct vid_vrfb_dma *) data; + + t->tx_status =1 ; +wake_up_interruptible (&t->wait); +} + +/* +* Free VRFB buffers +*/ +void omap_vout_free_vrfb_buffers (struct omap_vout_device *vout) +{ +int j; + +for (j =0 ; j <VRFB_NUM_BUFS ; j++) { +omap_vout_free_buffer (vout->smsshado_virt_addr[j], + vout->smsshado_size); + vout->smsshado_virt_addr[j] =0 ; + vout->smsshado_phy_addr[j] =0 ; + } +} + +/* Free the VRFB buffers only if they are allocated +* during reqbufs. Don't free if init time allocated +*/ +void omap_vout_free_extra_vrfb_buffers (struct omap_vout_device *vout) +{ + +int i =0 ; + +if (!vout->vrfb_static_allocation) { +for (i =0 ; i <VRFB_NUM_BUFS ; i++) { +if (vout->smsshado_virt_addr[i]) { +omap_vout_free_buffer ( + vout->smsshado_virt_addr[i], + vout->smsshado_size); + vout->smsshado_virt_addr[i] =0 ; + vout->smsshado_phy_addr[i] =0 ; + } + } + } +} + +int omap_vout_setup_vrfb_bufs (struct platform_device *pdev,int vid_num) +{ +int ret =0 , i, j; +struct omap_vout_device *vout; +struct video_device *vfd; +int image_width, image_height; +int static_vrfb_allocation =0 , vrfb_num_bufs =VRFB_NUM_BUFS ; +struct v4l2_device *v4l2_dev =platform_get_drvdata (pdev); +struct omap2video_device *vid_dev = + container_of(v4l2_dev, struct omap2video_device, v4l2_dev); + + vout = vid_dev->vouts[vid_num]; + vfd = vout->vfd; + +for (i =0 ; i <VRFB_NUM_BUFS ; i++) { +if (omap_vrfb_request_ctx (&vout->vrfb_context[i])) { +dev_info (&pdev->dev,": VRFB allocation failed\n" ); +for (j =0 ; j < i; j++) +omap_vrfb_release_ctx (&vout->vrfb_context[j]); + ret = -ENOMEM ; + goto free_buffers; + } + } + +/* Calculate VRFB memory size */ +/* allocate for worst case size */ + image_width =VID_MAX_WIDTH /TILE_SIZE ; +if (VID_MAX_WIDTH %TILE_SIZE ) + image_width++; + + image_width = image_width *TILE_SIZE ; + image_height =VID_MAX_HEIGHT /TILE_SIZE ; + +if (VID_MAX_HEIGHT %TILE_SIZE ) + image_height++; + + image_height = image_height *TILE_SIZE ; + vout->smsshado_size = PAGE_ALIGN(image_width * image_height * 2 *2);
drivers/media/video/omap/omap_vout_vrfb.c new file +25
-0+ +/* +* Request and Initialize DMA, for DMA based VRFB transfer +*/ + vout->vrfb_dma_tx.dev_id =OMAP_DMA_NO_DEVICE ; + vout->vrfb_dma_tx.dma_ch =-1 ; + vout->vrfb_dma_tx.req_status =DMA_CHAN_ALLOTED ; + ret =omap_request_dma (vout->vrfb_dma_tx.dev_id,"VRFB DMA TX" , + omap_vout_vrfb_dma_tx_callback, + (void *) &vout->vrfb_dma_tx, &vout->vrfb_dma_tx.dma_ch); +if (ret <0 ) { + vout->vrfb_dma_tx.req_status =DMA_CHAN_NOT_ALLOTED ; +dev_info (&pdev->dev,": failed to allocate DMA Channel for" +" video%d\n" , vfd->minor); + } +init_waitqueue_head (&vout->vrfb_dma_tx.wait); + +/* Allocate VRFB buffers if selected through bootargs */ + static_vrfb_allocation = (vid_num ==0 ) ? + vid1_static_vrfb_alloc : vid2_static_vrfb_alloc; + +/* statically allocated the VRFB buffer is done through +commands line aruments */ +if (static_vrfb_allocation) { +if (omap_vout_allocate_vrfb_buffers (vout, &vrfb_num_bufs,-1 )){
drivers/media/video/omap/omap_vout_vrfb.c new file +201
-0+ ret = -ENOMEM ; + goto release_vrfb_ctx; + } + vout->vrfb_static_allocation =1 ; + } +return 0 ; + +release_vrfb_ctx: +for (j =0 ; j <VRFB_NUM_BUFS ; j++) +omap_vrfb_release_ctx (&vout->vrfb_context[j]); +free_buffers: +omap_vout_free_buffers (vout); + +return ret; +} + +/* +* Release the VRFB context once the module exits +*/ +void omap_vout_release_vrfb (struct omap_vout_device *vout) +{ +int i; + +for (i =0 ; i <VRFB_NUM_BUFS ; i++) +omap_vrfb_release_ctx (&vout->vrfb_context[i]); + +if (vout->vrfb_dma_tx.req_status ==DMA_CHAN_ALLOTED ) { + vout->vrfb_dma_tx.req_status =DMA_CHAN_NOT_ALLOTED ; +omap_free_dma (vout->vrfb_dma_tx.dma_ch); + } +} + +/* +* Allocate the buffers for the VRFB space. Data is copied from V4L2 +* buffers to the VRFB buffers using the DMA engine. +*/ +int omap_vout_vrfb_buffer_setup (struct omap_vout_device *vout, +unsigned int *count,unsigned int startindex) +{ +int i; +bool yuv_mode; + +if (!rotation_enabled (vout)) +return 0 ; + +/* If rotation is enabled, allocate memory for VRFB space also */ + *count = *count >VRFB_NUM_BUFS ?VRFB_NUM_BUFS : *count; + +/* Allocate the VRFB buffers only if the buffers are not +* allocated during init time. +*/ +if (!vout->vrfb_static_allocation) +if (omap_vout_allocate_vrfb_buffers (vout, count, startindex)) +return -ENOMEM ; + +if (vout->dss_mode ==OMAP_DSS_COLOR_YUV2 || + vout->dss_mode ==OMAP_DSS_COLOR_UYVY ) + yuv_mode = true; +else + yuv_mode = false; + +for (i =0 ; i < *count; i++) +omap_vrfb_setup (&vout->vrfb_context[i], + vout->smsshado_phy_addr[i], vout->pix.width, + vout->pix.height, vout->bpp, yuv_mode); + +return 0 ; +} + +int omap_vout_prepare_vrfb (struct omap_vout_device *vout, +struct videobuf_buffer *vb) +{ +dma_addr_t dmabuf; +struct vid_vrfb_dma *tx; +enum dss_rotation rotation; +u32 dest_frame_index =0 , src_element_index =0 ; +u32 dest_element_index =0 , src_frame_index =0 ; +u32 elem_count =0 , frame_count =0 , pixsize =2 ; + +if (!rotation_enabled (vout)) +return 0 ; + + dmabuf = vout->buf_phy_addr[vb->i]; +/* If rotation is enabled, copy input buffer into VRFB +* memory space using DMA. We are copying input buffer +* into VRFB memory space of desired angle and DSS will +* read image VRFB memory for 0 degree angle +*/ + pixsize = vout->bpp * vout->vrfb_bpp; +/* +* DMA transfer in double index mode +*/ + +/* Frame index */ + dest_frame_index = ((MAX_PIXELS_PER_LINE * pixsize) - + (vout->pix.width * vout->bpp)) +1 ; + +/* Source and destination parameters */ + src_element_index =0 ; + src_frame_index =0 ; + dest_element_index =1 ; +/* Number of elements per frame */ + elem_count = vout->pix.width * vout->bpp; + frame_count = vout->pix.height; + tx = &vout->vrfb_dma_tx; + tx->tx_status =0 ; +omap_set_dma_transfer_params (tx->dma_ch,OMAP_DMA_DATA_TYPE_S32 , + (elem_count /4 ), frame_count,OMAP_DMA_SYNC_ELEMENT , + tx->dev_id,0x0 ); +/* src_port required only for OMAP1 */ +omap_set_dma_src_params (tx->dma_ch,0 ,OMAP_DMA_AMODE_POST_INC , + dmabuf, src_element_index, src_frame_index); +/*set dma source burst mode for VRFB */ +omap_set_dma_src_burst_mode (tx->dma_ch,OMAP_DMA_DATA_BURST_16 ); + rotation =calc_rotation (vout); + +/* dest_port required only for OMAP1 */ +omap_set_dma_dest_params (tx->dma_ch,0 ,OMAP_DMA_AMODE_DOUBLE_IDX , + vout->vrfb_context[vb->i].paddr[0 ], dest_element_index, + dest_frame_index); +/*set dma dest burst mode for VRFB */ +omap_set_dma_dest_burst_mode (tx->dma_ch,OMAP_DMA_DATA_BURST_16 ); +omap_dma_set_global_params (DMA_DEFAULT_ARB_RATE ,0x20 ,0 ); + +omap_start_dma (tx->dma_ch); +interruptible_sleep_on_timeout (&tx->wait,VRFB_TX_TIMEOUT ); + +if (tx->tx_status ==0 ) { +omap_stop_dma (tx->dma_ch); +return -EINVAL ; + } +/* Store buffers physical address into an array. Addresses +* from this array will be used to configure DSS */ + vout->queued_buf_addr[vb->i] = (u8 *) + vout->vrfb_context[vb->i].paddr[rotation]; +return 0 ; +} + +/* +* Calculate the buffer offsets from which the streaming should +* start. This offset calculation is mainly required because of +* the VRFB 32 pixels alignment with rotation. +*/ +void omap_vout_calculate_vrfb_offset (struct omap_vout_device *vout) +{ +enum dss_rotation rotation; +bool mirroring = vout->mirror; +struct v4l2_rect *crop = &vout->crop; +struct v4l2_pix_format *pix = &vout->pix; +int *cropped_offset = &vout->cropped_offset; +int vr_ps =1 , ps =2 , temp_ps =2 ; +int offset =0 , ctop =0 , cleft =0 , line_length =0 ; + + rotation =calc_rotation (vout); + +if (V4L2_PIX_FMT_YUYV == pix->pixelformat || +V4L2_PIX_FMT_UYVY == pix->pixelformat) { +if (rotation_enabled (vout)) { +/* +* ps - Actual pixel size for YUYV/UYVY for +* VRFB/Mirroring is 4 bytes +* vr_ps - Virtually pixel size for YUYV/UYVY is +* 2 bytes +*/ + ps =4 ; + vr_ps =2 ; + }else { + ps =2 ;/* otherwise the pixel size is 2 byte */ + } + }else if (V4L2_PIX_FMT_RGB32 == pix->pixelformat) { + ps =4 ; + }else if (V4L2_PIX_FMT_RGB24 == pix->pixelformat) { + ps =3 ; + } + vout->ps = ps; + vout->vr_ps = vr_ps; + +if (rotation_enabled (vout)) { + line_length =MAX_PIXELS_PER_LINE ; + ctop = (pix->height - crop->height) - crop->top; + cleft = (pix->width - crop->width) - crop->left; + }else { + line_length = pix->width; + } + vout->line_length = line_length; +switch (rotation) { +case dss_rotation_90_degree: + offset = vout->vrfb_context[0 ].yoffset * + vout->vrfb_context[0 ].bytespp; + temp_ps = ps / vr_ps; +if (mirroring ==0 ) { + *cropped_offset = offset + line_length * + temp_ps * cleft + crop->top * temp_ps; + }else { + *cropped_offset = offset + line_length * temp_ps * + cleft + crop->top * temp_ps + (line_length * + ((crop->width / (vr_ps)) -1 ) * ps); + } +break ; +case dss_rotation_180_degree: + offset = ((MAX_PIXELS_PER_LINE * vout->vrfb_context[0].yoffset*
drivers/media/video/omap/omap_vout_vrfb.c new file +44
-0+ vout->vrfb_context[0].bytespp) + + (vout->vrfb_context[0 ].xoffset * + vout->vrfb_context[0].bytespp)); +if (mirroring ==0 ) { + *cropped_offset = offset + (line_length * ps * ctop) + + (cleft / vr_ps) * ps; + + }else { + *cropped_offset = offset + (line_length * ps * ctop) + + (cleft / vr_ps) * ps + (line_length * + (crop->height -1 ) * ps); + } +break ; +case dss_rotation_270_degree: + offset =MAX_PIXELS_PER_LINE * vout->vrfb_context[0 ].xoffset * + vout->vrfb_context[0 ].bytespp; + temp_ps = ps / vr_ps; +if (mirroring ==0 ) { + *cropped_offset = offset + line_length * + temp_ps * crop->left + ctop * ps; + }else { + *cropped_offset = offset + line_length * + temp_ps * crop->left + ctop * ps + + (line_length * ((crop->width / vr_ps) -1 ) * + ps); + } +break ; +case dss_rotation_0_degree: +if (mirroring ==0 ) { + *cropped_offset = (line_length * ps) * + crop->top + (crop->left / vr_ps) * ps; + }else { + *cropped_offset = (line_length * ps) * + crop->top + (crop->left / vr_ps) * ps + + (line_length * (crop->height -1 ) * ps); + } +break ; +default : + *cropped_offset = (line_length * ps * crop->top) / + vr_ps + (crop->left * ps) / vr_ps + + ((crop->width / vr_ps) -1 ) * ps; +break ; + } +}drivers/media/video/omap/omap_vout_vrfb.h new file +6
-0@@ -0,0 +1,40 @@ +/* +* omap_vout_vrfb.h +* +* Copyright (C) 2010 Texas Instruments. +* +* This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ *
+ */
drivers/media/video/omap/omap_vout_vrfb.h line 15
Quoted 5 lines
drivers/media/video/omap/omap_vout_vrfb.h new file +5
-0+ +#ifndef OMAP_VOUT_VRFB_H +#define OMAP_VOUT_VRFB_H + +#ifdef CONFIG_OMAP2_VRFB
[Hiremath, Vaibhav] you don't have to do this, since VRFB is automatically gets enabled when you select OMAP_VOUT.
Thanks,
Vaibhav
Quoted 69 lines
drivers/media/video/omap/omap_vout_vrfb.h new file +25
-0+void omap_vout_free_vrfb_buffers (struct omap_vout_device *vout); +void omap_vout_free_extra_vrfb_buffers (struct omap_vout_device *vout); +int omap_vout_setup_vrfb_bufs (struct platform_device *pdev,int vid_num); +void omap_vout_release_vrfb (struct omap_vout_device *vout); +int omap_vout_vrfb_buffer_setup (struct omap_vout_device *vout, +unsigned int *count,unsigned int startindex); +int omap_vout_prepare_vrfb (struct omap_vout_device *vout, +struct videobuf_buffer *vb); +void omap_vout_calculate_vrfb_offset (struct omap_vout_device *vout); +#else +void omap_vout_free_vrfb_buffers (struct omap_vout_device *vout) { } +void omap_vout_free_extra_vrfb_buffers (struct omap_vout_device *vout) { } +int omap_vout_setup_vrfb_bufs (struct platform_device *pdev,int vid_num) + {return 0 ; } +void omap_vout_release_vrfb (struct omap_vout_device *vout) { } +int omap_vout_vrfb_buffer_setup (struct omap_vout_device *vout, +unsigned int *count,unsigned int startindex) + {return 0 ; } +int omap_vout_prepare_vrfb (struct omap_vout_device *vout, +struct videobuf_buffer *vb) + {return 0 ; } +void omap_vout_calculate_vrfb_offset (struct omap_vout_device *vout) { } +#endif + +#endif drivers/media/video/omap/omap_voutdef.h +25
-1@@ -27,6 +27,24 @@#define MAX_DISPLAYS 3#define MAX_MANAGERS 3 +/* Max Resolution supported by the driver */ +#define VID_MAX_WIDTH 1280/* Largest width */ +#define VID_MAX_HEIGHT 720/* Largest height */ + +/* 2048 x 2048 is max res supported by OMAP display controller */ +#define MAX_PIXELS_PER_LINE 2048 + +#define VRFB_TX_TIMEOUT 1000 +#define VRFB_NUM_BUFS 4 + +extern u32 vid1_static_vrfb_alloc; +extern u32 vid2_static_vrfb_alloc; + +enum dma_channel_state { +DMA_CHAN_NOT_ALLOTED , +DMA_CHAN_ALLOTED , +}; +/* Enum for Rotation * DSS understands rotation in 0, 1, 2, 3 context * while V4L2 driver understands it as 0, 90, 180, 270 @@ -144,4 +162,11 @@ struct omap_vout_device { int io_allowed; }; + +unsigned long omap_vout_alloc_buffer (u32 buf_size,u32 *phys_addr); +void omap_vout_free_buffer (unsigned long virtaddr,u32 buf_size); +void omap_vout_free_buffers (struct omap_vout_device *vout); +int rotate_90_or_270 (const struct omap_vout_device *vout); +int rotation_enabled (const struct omap_vout_device *vout); +int calc_rotation (const struct omap_vout_device *vout);#endif /* ifndef OMAP_VOUTDEF_H */ --1.7.0.4
PATCH v2 2/2 V4L/DVB: OMAP_VOUT: Use rotation_type to choose between vrfb and sdram buffers
In reply to Archit TanejaAdd "rotation_type" member to omapvideo_info, this is initialized based on the value "def_vrfb" bootarg parameter, vrfb rotation is chosen by default. The rotation_type var is now used to choose between vrfb and non-vrfb calls.
vrfb specific code in omap_vout has been removed and is present in omap_vout_vrfb.c
--- drivers/media/video/omap/Kconfig | 1 - drivers/media/video/omap/Makefile | 1 + drivers/media/video/omap/omap_vout.c | 448 ++++++------------------------- drivers/media/video/omap/omap_voutdef.h | 1 + 4 files changed, 81 insertions(+), 370 deletions(-)
drivers/media/video/omap/Kconfig +0 -1
@@ -5,7 +5,6 @@ config VIDEO_OMAP2_VOUT select VIDEOBUF_DMA_CONTIG select OMAP2_DSS select OMAP2_VRAM - select OMAP2_VRFB default n ---help--- V4L2 Display driver support for OMAP2/3 based boards.
drivers/media/video/omap/Makefile +1 -0
@@ -5,3 +5,4 @@ # OMAP2/3 Display driver omap-vout-y := omap_vout.o omap_voutlib.o obj-$(CONFIG_VIDEO_OMAP2_VOUT) += omap-vout.o +obj-$(CONFIG_OMAP2_VRFB) += omap_vout_vrfb.o
drivers/media/video/omap/omap_vout.c +79 -369
639 lines not on this page · raw message
drivers/media/video/omap/omap_voutdef.h +1 -0
@@ -71,6 +71,7 @@ struct omapvideo_info {int id;int num_overlays;struct omap_overlay *overlays[MAX_OVLS ]; +enum omap_dss_rotation_type rotation_type; };struct omap2video_device {
Signature · 1 line
1.7.0.4
RE: [PATCH v2 2/2] V4L/DVB: OMAP_VOUT: Use rotation_type to choose between vrfb and sdram buffers
Quoted 34 lines
-----Original Message-----
From: Taneja, Archit
Sent: Monday, September 27, 2010 12:47 PM
To: Hiremath, Vaibhav
Cc: [email protected]; [email protected]; Taneja, Archit
Subject: [PATCH v2 2/2] V4L/DVB:OMAP_VOUT: Userotation_typeto choose between vrfb and sdram buffersAdd "
rotation_type" member toomapvideo_info, this is initialized based on the value "def_vrfb" bootarg parameter, vrfb rotation is chosen by default.
Therotation_typevar is now used to choose between vrfb and non-vrfb calls.vrfb specific code in
omap_vouthas been removed and is present inomap_vout_vrfb.cSigned-off-by Archit Taneja <[email protected]>--- drivers/media/video/omap/Kconfig | 1 - drivers/media/video/omap/Makefile | 1 + drivers/media/video/omap/omap_vout.c | 448 ++++++-------------------- ----- drivers/media/video/omap/omap_voutdef.h | 1 + 4 files changed, 81 insertions(+), 370 deletions(-)drivers/media/video/omap/Kconfig +0
-0
drivers/media/video/omap/Kconfig config VIDEO_OMAP2_VOUT · line 8
Quoted 4 lines
drivers/media/video/omap/Kconfig +0
-1@@ -5,7 +5,6 @@ config VIDEO_OMAP2_VOUT select VIDEOBUF_DMA_CONTIG select OMAP2_DSS select OMAP2_VRAM - select OMAP2_VRFB
[Hiremath, Vaibhav] Don't remove it, select for OMAP3 family of devices.
Quoted 35 lines
drivers/media/video/omap/Kconfig +0
-0default n ---help--- V4L2 Display driver support for OMAP2/3 based boards.drivers/media/video/omap/Makefile +1
-0@@ -5,3 +5,4 @@ # OMAP2/3 Display driver omap-vout-y := omap_vout.o omap_voutlib.o obj-$(CONFIG_VIDEO_OMAP2_VOUT) += omap-vout.o +obj-$(CONFIG_OMAP2_VRFB) += omap_vout_vrfb.odrivers/media/video/omap/omap_vout.c +2
-0@@ -51,6 +51,7 @@#include "omap_voutlib.h" #include "omap_voutdef.h" +#include "omap_vout_vrfb.h" MODULE_AUTHOR ("Texas Instruments" );MODULE_DESCRIPTION ("OMAP Video for Linux Video out driver" );@@ -82,6 +83,7 @@ static u32 video1_bufsize = OMAP_VOUT_MAX_BUF_SIZE;static u32 video2_bufsize =OMAP_VOUT_MAX_BUF_SIZE ;u32 vid1_static_vrfb_alloc;u32 vid2_static_vrfb_alloc; +static int def_vrfb =1 ;static int debug;/* Module parameters */
drivers/media/video/omap/omap_vout.c module_param(vid2_static_vrfb_alloc, bool, S_IRUGO); · line 114
Quoted 4 lines
drivers/media/video/omap/omap_vout.c +1
-0@@ -109,6 +111,10 @@ module_param(vid2_static_vrfb_alloc, bool, S_IRUGO);MODULE_PARM_DESC (vid2_static_vrfb_alloc,"Static allocation of the VRFB buffer for video2 device" ); +module_param (def_vrfb, bool,S_IRUGO );
[Hiremath, Vaibhav] Till the time we don't come up with Tiler (for that matter any other way of rotating image) based rotation mechanism, I wouldn't want to change/introduce any new interface.
Quoted 683 lines
drivers/media/video/omap/omap_vout.c +3
-35+MODULE_PARM_DESC (def_vrfb, +"decide if vrfb is used for rotation" ); +module_param (debug, bool,S_IRUGO );MODULE_PARM_DESC (debug,"Debug level (0-1)" );@@ -199,41 +205,6 @@ void omap_vout_free_buffer(unsigned long virtaddr, u32 buf_size) }/* -* Function for allocating video buffers -*/ -static int omap_vout_allocate_vrfb_buffers (struct omap_vout_device *vout, -unsigned int *count,int startindex) -{ -int i, j; - -for (i =0 ; i < *count; i++) { -if (!vout->smsshado_virt_addr[i]) { - vout->smsshado_virt_addr[i] = -omap_vout_alloc_buffer (vout->smsshado_size, - &vout->smsshado_phy_addr[i]); - } -if (!vout->smsshado_virt_addr[i] && startindex !=-1 ) { -if (V4L2_MEMORY_MMAP == vout->memory && i >= startindex) -break ; - } -if (!vout->smsshado_virt_addr[i]) { -for (j =0 ; j < i; j++) { -omap_vout_free_buffer ( - vout->smsshado_virt_addr[j], - vout->smsshado_size); - vout->smsshado_virt_addr[j] =0 ; - vout->smsshado_phy_addr[j] =0 ; - } - *count =0 ; -return -ENOMEM ; - } -memset ((void *) vout->smsshado_virt_addr[i],0 , - vout->smsshado_size); - } -return 0 ; -} - -/* * Try format */ static int
omap_vout_try_format(struct v4l2_pix_format *pix)drivers/media/video/omap/omap_vout.c +0
-1@@ -326,33 +297,6 @@ static u32 omap_vout_uservirt_to_phys(u32 virtp) }/* -* Wakes up the application once the DMA transfer to VRFB space is completed.
- */
-static voidomap_vout_vrfb_dma_tx_callback(int lch, u16 ch_status, void *data)drivers/media/video/omap/omap_vout.c +0
-70-{ -struct vid_vrfb_dma *t = (struct vid_vrfb_dma *) data; - - t->tx_status =1 ; -wake_up_interruptible (&t->wait); -} - -/* -* Release the VRFB context once the module exits -*/ -static void omap_vout_release_vrfb (struct omap_vout_device *vout) -{ -int i; - -for (i =0 ; i <VRFB_NUM_BUFS ; i++) -omap_vrfb_release_ctx (&vout->vrfb_context[i]); - -if (vout->vrfb_dma_tx.req_status ==DMA_CHAN_ALLOTED ) { - vout->vrfb_dma_tx.req_status =DMA_CHAN_NOT_ALLOTED ; -omap_free_dma (vout->vrfb_dma_tx.dma_ch); - } -} - -/* * Return true if rotation is 90 or 270 */ int rotate_90_or_270 (const struct omap_vout_device *vout)@@ -409,52 +353,6 @@ void omap_vout_free_buffers(struct omap_vout_device *vout) }/* -* Free VRFB buffers -*/ -static void omap_vout_free_vrfb_buffers (struct omap_vout_device *vout) -{ -int j; - -for (j =0 ; j <VRFB_NUM_BUFS ; j++) { -omap_vout_free_buffer (vout->smsshado_virt_addr[j], - vout->smsshado_size); - vout->smsshado_virt_addr[j] =0 ; - vout->smsshado_phy_addr[j] =0 ; - } -} - -/* -* Allocate the buffers for the VRFB space. Data is copied from V4L2 -* buffers to the VRFB buffers using the DMA engine. -*/ -static int omap_vout_vrfb_buffer_setup (struct omap_vout_device *vout, -unsigned int *count,unsigned int startindex) -{ -int i; -bool yuv_mode; - -/* Allocate the VRFB buffers only if the buffers are not -* allocated during init time. -*/ -if ((rotation_enabled (vout)) && !vout->vrfb_static_allocation) -if (omap_vout_allocate_vrfb_buffers (vout, count, startindex)) -return -ENOMEM ; - -if (vout->dss_mode ==OMAP_DSS_COLOR_YUV2 || - vout->dss_mode ==OMAP_DSS_COLOR_UYVY ) - yuv_mode = true; -else - yuv_mode = false; - -for (i =0 ; i < *count; i++) -omap_vrfb_setup (&vout->vrfb_context[i], - vout->smsshado_phy_addr[i], vout->pix.width, - vout->pix.height, vout->bpp, yuv_mode); - -return 0 ; -} - -/* * Convert V4L2 rotation to DSS rotation * V4L2 understand 0, 90, 180, 270. * Convert to 0, 1, 2 and 3 repsectively for DSS
drivers/media/video/omap/omap_vout.c +19
-104@@ -483,124 +381,38 @@ static int v4l2_rot_to_dss_rot(int v4l2_rotation,return ret; } -/* -* Calculate the buffer offsets from which the streaming should -* start. This offset calculation is mainly required because of -* the VRFB 32 pixels alignment with rotation. -*/ static int omap_vout_calculate_offset (struct omap_vout_device *vout) { -struct omap_overlay *ovl; -enum dss_rotation rotation;struct omapvideo_info *ovid; -bool mirroring = vout->mirror; -struct omap_dss_device *cur_display;struct v4l2_rect *crop = &vout->crop;struct v4l2_pix_format *pix = &vout->pix;int *cropped_offset = &vout->cropped_offset; -int vr_ps =1 , ps =2 , temp_ps =2 ; -int offset =0 , ctop =0 , cleft =0 , line_length =0 ; +int ps =2 , line_length =0 ; ovid = &vout->vid_info; - ovl = ovid->overlays[0 ]; -/* get the display device attached to the overlay */ -if (!ovl->manager || !ovl->manager->device) -return -1 ; - cur_display = ovl->manager->device; - rotation =calc_rotation (vout); +if (ovid->rotation_type ==OMAP_DSS_ROT_VRFB ) { +omap_vout_calculate_vrfb_offset (vout); + }else { + vout->line_length = line_length = pix->width; -if (V4L2_PIX_FMT_YUYV == pix->pixelformat || -V4L2_PIX_FMT_UYVY == pix->pixelformat) { -if (rotation_enabled (vout)) { -/* -* ps - Actual pixel size for YUYV/UYVY for -* VRFB/Mirroring is 4 bytes -* vr_ps - Virtually pixel size for YUYV/UYVY is -* 2 bytes -*/ +if (V4L2_PIX_FMT_YUYV == pix->pixelformat || +V4L2_PIX_FMT_UYVY == pix->pixelformat) + ps =2 ; +else if (V4L2_PIX_FMT_RGB32 == pix->pixelformat) ps =4 ; - vr_ps =2 ; - }else { - ps =2 ;/* otherwise the pixel size is 2 byte */ - } - }else if (V4L2_PIX_FMT_RGB32 == pix->pixelformat) { - ps =4 ; - }else if (V4L2_PIX_FMT_RGB24 == pix->pixelformat) { - ps =3 ; - } - vout->ps = ps; - vout->vr_ps = vr_ps; - -if (rotation_enabled (vout)) { - line_length =MAX_PIXELS_PER_LINE ; - ctop = (pix->height - crop->height) - crop->top; - cleft = (pix->width - crop->width) - crop->left; - }else { - line_length = pix->width; - } - vout->line_length = line_length; -switch (rotation) { -case dss_rotation_90_degree: - offset = vout->vrfb_context[0 ].yoffset * - vout->vrfb_context[0 ].bytespp; - temp_ps = ps / vr_ps; -if (mirroring ==0 ) { - *cropped_offset = offset + line_length * - temp_ps * cleft + crop->top * temp_ps; - }else { - *cropped_offset = offset + line_length * temp_ps * - cleft + crop->top * temp_ps + (line_length * - ((crop->width / (vr_ps)) -1 ) * ps); - } -break ; -case dss_rotation_180_degree: - offset = ((MAX_PIXELS_PER_LINE * vout->vrfb_context[0 ].yoffset * - vout->vrfb_context[0 ].bytespp) + - (vout->vrfb_context[0 ].xoffset * - vout->vrfb_context[0 ].bytespp)); -if (mirroring ==0 ) { - *cropped_offset = offset + (line_length * ps * ctop) + - (cleft / vr_ps) * ps; + else if (V4L2_PIX_FMT_RGB24 == pix->pixelformat) + ps =3 ; - }else { - *cropped_offset = offset + (line_length * ps * ctop) + - (cleft / vr_ps) * ps + (line_length * - (crop->height -1 ) * ps); - } -break ; -case dss_rotation_270_degree: - offset =MAX_PIXELS_PER_LINE * vout->vrfb_context[0 ].xoffset * - vout->vrfb_context[0 ].bytespp; - temp_ps = ps / vr_ps; -if (mirroring ==0 ) { - *cropped_offset = offset + line_length * - temp_ps * crop->left + ctop * ps; - }else { - *cropped_offset = offset + line_length * - temp_ps * crop->left + ctop * ps + - (line_length * ((crop->width / vr_ps) -1 ) * - ps); - } -break ; -case dss_rotation_0_degree: -if (mirroring ==0 ) { - *cropped_offset = (line_length * ps) * - crop->top + (crop->left / vr_ps) * ps; - }else { - *cropped_offset = (line_length * ps) * - crop->top + (crop->left / vr_ps) * ps + - (line_length * (crop->height -1 ) * ps); - } -break ; -default : - *cropped_offset = (line_length * ps * crop->top) / - vr_ps + (crop->left * ps) / vr_ps + - ((crop->width / vr_ps) -1 ) * ps; -break ; + vout->ps = ps; + + *cropped_offset = (line_length * ps) * + crop->top + crop->left * ps; } +v4l2_dbg (1 , debug, &vout->vid_dev->v4l2_dev,"%s Offset:%x\n" , - __func__, *cropped_offset); + __func__, vout->cropped_offset); +return 0 ; }@@ -938,6 +750,7 @@ static int omap_vout_buffer_setup(struct videobuf_queue *q, unsigned int *count, int startindex = 0, i, j;u32 phy_addr =0 , virt_addr =0 ;struct omap_vout_device *vout = q->priv_data; +struct omapvideo_info *ovid = &vout->vid_info;if (!vout)return -EINVAL;drivers/media/video/omap/omap_vout.c +2
-5@@ -950,13 +763,10 @@ static int omap_vout_buffer_setup(struct videobuf_queue *q, unsigned int *count, if (V4L2_MEMORY_MMAP == vout->memory && *count < startindex) *count = startindex; -if ((rotation_enabled (vout )) && *count >VRFB_NUM_BUFS ) - *count =VRFB_NUM_BUFS ; - -/* If rotation is enabled, allocate memory for VRFB space also */ -if (rotation_enabled (vout)) +if (ovid->rotation_type ==OMAP_DSS_ROT_VRFB ) {if (omap_vout_vrfb_buffer_setup (vout, count, startindex))return -ENOMEM ; + }if (V4L2_MEMORY_MMAP != vout->memory)return 0;drivers/media/video/omap/omap_vout.c +4
-1@@ -972,8 +782,11 @@ static int omap_vout_buffer_setup(struct videobuf_queue *q, unsigned int *count, virt_addr =omap_vout_alloc_buffer (vout->buffer_size, &phy_addr);if (!virt_addr) { -if (!rotation_enabled (vout)) +if (ovid->rotation_type ==OMAP_DSS_ROT_DMA ) {break ; + }else { +if (!rotation_enabled (vout)) +break ;/* Free the VRFB buffers if no space for V4L2 buffers */ for (j = i; j < *count; j++) {omap_vout_free_buffer(drivers/media/video/omap/omap_vout.c +1
-0@@ -981,6 +794,7 @@ static int omap_vout_buffer_setup(struct videobuf_queue *q, unsigned int *count, vout->smsshado_size); vout->smsshado_virt_addr[j] =0 ; vout->smsshado_phy_addr[j] =0 ; + } } }vout->buf_virt_addr[i] = virt_addr;drivers/media/video/omap/omap_vout.c +5
-24@@ -993,9 +807,9 @@ static int omap_vout_buffer_setup(struct videobuf_queue *q, unsigned int *count,/* * Free the V4L2 buffers additionally allocated than default -* number of buffers and free all the VRFB buffers +* number of buffers */ -static void omap_vout_free_allbuffers(struct omap_vout_device *vout) +static void omap_vout_free_extra_buffers(struct omap_vout_device *vout) { int num_buffers = 0, i;@@ -1010,20 +824,6 @@ static void omap_vout_free_allbuffers(struct omap_vout_device *vout) vout->buf_virt_addr[i] = 0; vout->buf_phy_addr[i] =0 ; } -/* Free the VRFB buffers only if they are allocated -* during reqbufs. Don't free if init time allocated -*/ -if (!vout->vrfb_static_allocation) { -for (i =0 ; i <VRFB_NUM_BUFS ; i++) { -if (vout->smsshado_virt_addr[i]) { -omap_vout_free_buffer ( - vout->smsshado_virt_addr[i], - vout->smsshado_size); - vout->smsshado_virt_addr[i] =0 ; - vout->smsshado_phy_addr[i] =0 ; - } - } - } vout->buffer_allocated = num_buffers; }@@ -1035,16 +835,11 @@ static void omap_vout_free_allbuffers(structomap_vout_device *vout) * buffer into VRFB memory space before giving it to the DSS. */ static int omap_vout_buffer_prepare (struct videobuf_queue *q, -struct videobuf_buffer *vb, -enum v4l2_field field) +struct videobuf_buffer *vb, +enum v4l2_field field) { -dma_addr_t dmabuf; -struct vid_vrfb_dma *tx; -enum dss_rotation rotation;struct omap_vout_device *vout = q->priv_data; -u32 dest_frame_index =0 , src_element_index =0 ; -u32 dest_element_index =0 , src_frame_index =0 ; -u32 elem_count =0 , frame_count =0 , pixsize =2 ; +struct omapvideo_info *ovid = &vout->vid_info;if (VIDEOBUF_NEEDS_INIT == vb->state) {vb->width = vout->pix.width;drivers/media/video/omap/omap_vout.c +3
-56@@ -1066,63 +861,10 @@ static int omap_vout_buffer_prepare(struct videobuf_queue *q, vout->queued_buf_addr[vb->i] = (u8 *)vout->buf_phy_addr[vb- >i]; } -if (!rotation_enabled (vout)) +if (ovid->rotation_type ==OMAP_DSS_ROT_VRFB ) +return omap_vout_prepare_vrfb (vout, vb); +else return 0 ; - - dmabuf = vout->buf_phy_addr[vb->i]; -/* If rotation is enabled, copy input buffer into VRFB -* memory space using DMA. We are copying input buffer -* into VRFB memory space of desired angle and DSS will -* read image VRFB memory for 0 degree angle -*/ - pixsize = vout->bpp * vout->vrfb_bpp; -/* -* DMA transfer in double index mode -*/ - -/* Frame index */ - dest_frame_index = ((MAX_PIXELS_PER_LINE * pixsize) - - (vout->pix.width * vout->bpp)) +1 ; - -/* Source and destination parameters */ - src_element_index =0 ; - src_frame_index =0 ; - dest_element_index =1 ; -/* Number of elements per frame */ - elem_count = vout->pix.width * vout->bpp; - frame_count = vout->pix.height; - tx = &vout->vrfb_dma_tx; - tx->tx_status =0 ; -omap_set_dma_transfer_params (tx->dma_ch,OMAP_DMA_DATA_TYPE_S32 , - (elem_count /4 ), frame_count,OMAP_DMA_SYNC_ELEMENT , - tx->dev_id,0x0 ); -/* src_port required only for OMAP1 */ -omap_set_dma_src_params (tx->dma_ch,0 ,OMAP_DMA_AMODE_POST_INC , - dmabuf, src_element_index, src_frame_index); -/*set dma source burst mode for VRFB */ -omap_set_dma_src_burst_mode (tx->dma_ch,OMAP_DMA_DATA_BURST_16 ); - rotation =calc_rotation (vout); - -/* dest_port required only for OMAP1 */ -omap_set_dma_dest_params (tx->dma_ch,0 ,OMAP_DMA_AMODE_DOUBLE_IDX , - vout->vrfb_context[vb->i].paddr[0 ], dest_element_index, - dest_frame_index); -/*set dma dest burst mode for VRFB */ -omap_set_dma_dest_burst_mode (tx->dma_ch,OMAP_DMA_DATA_BURST_16 ); -omap_dma_set_global_params (DMA_DEFAULT_ARB_RATE ,0x20 ,0 ); - -omap_start_dma (tx->dma_ch); -interruptible_sleep_on_timeout (&tx->wait,VRFB_TX_TIMEOUT ); - -if (tx->tx_status ==0 ) { -omap_stop_dma (tx->dma_ch); -return -EINVAL ; - } -/* Store buffers physical address into an array. Addresses -* from this array will be used to configure DSS */ - vout->queued_buf_addr[vb->i] = (u8 *) - vout->vrfb_context[vb->i].paddr[rotation]; -return 0 ; }/*
drivers/media/video/omap/omap_vout.c +12
-1@@ -1266,7 +1008,9 @@ static int omap_vout_release(struct file *file) "Unable to apply changes\n");/* Free all buffers */ -omap_vout_free_allbuffers (vout); +omap_vout_free_extra_buffers (vout); +if (ovid->rotation_type ==OMAP_DSS_ROT_VRFB ) +omap_vout_free_extra_vrfb_buffers (vout);videobuf_mmap_free (q);/* Even if apply changes fails we should continue @@ -1693,9 +1437,18 @@ static int vidioc_s_ctrl(struct file *file, void *fh, struct v4l2_control *a)switch (a->id) {case V4L2_CID_ROTATE : { +struct omapvideo_info *ovid;int rotation = a->value; + ovid = &vout->vid_info; +mutex_lock (&vout->lock); +if (rotation && ovid->rotation_type ==OMAP_DSS_ROT_DMA ) { +/* Don't support rotation for SDMA rotation_type */ +mutex_unlock (&vout->lock); + ret = -ERANGE ; +break ; + }if (rotation && vout->pix.pixelformat ==V4L2_PIX_FMT_RGB24 ) {mutex_unlock(&vout->lock);drivers/media/video/omap/omap_vout.c +2
-1@@ -2196,7 +1949,8 @@ static int __init omap_vout_setup_video_data(struct omap_vout_device *vout) vout->mirror = 0; vout->control[2 ].id =V4L2_CID_HFLIP ; vout->control[2 ].value =0 ; - vout->vrfb_bpp =2 ; +if (vout->vid_info.rotation_type ==OMAP_DSS_ROT_VRFB ) + vout->vrfb_bpp =2 ; control[1 ].id =V4L2_CID_BG_COLOR ;control[1].value = 0;drivers/media/video/omap/omap_vout.c +3
-5@@ -2229,17 +1983,15 @@ static int __init omap_vout_setup_video_bufs(struct platform_device *pdev, int vid_num) {u32 numbuffers; -int ret =0 , i, j; -int image_width, image_height; -struct video_device *vfd; +int ret =0 , i; +struct omapvideo_info *ovid;struct omap_vout_device *vout; -int static_vrfb_allocation =0 , vrfb_num_bufs =VRFB_NUM_BUFS ;struct v4l2_device *v4l2_dev =platform_get_drvdata (pdev);struct omap2video_device *vid_dev = container_of(v4l2_dev, struct omap2video_device, v4l2_dev); vout = vid_dev->vouts[vid_num]; - vfd = vout->vfd; + ovid = &vout->vid_info; numbuffers = (vid_num ==0 ) ? video1_numbuffers : video2_numbuffers;vout->buffer_size = (vid_num == 0) ? video1_bufsize :
video2_bufsize;drivers/media/video/omap/omap_vout.c +2
-56@@ -2256,67 +2008,13 @@ static int __init omap_vout_setup_video_bufs(struct platform_device *pdev, } } -for (i =0 ; i <VRFB_NUM_BUFS ; i++) { -if (omap_vrfb_request_ctx (&vout->vrfb_context[i])) { -dev_info (&pdev->dev,": VRFB allocation failed\n" ); -for (j =0 ; j < i; j++) -omap_vrfb_release_ctx (&vout->vrfb_context[j]); - ret = -ENOMEM ; - goto free_buffers; - } - } vout->cropped_offset =0 ; -/* Calculate VRFB memory size */ -/* allocate for worst case size */ - image_width =VID_MAX_WIDTH /TILE_SIZE ; -if (VID_MAX_WIDTH %TILE_SIZE ) - image_width++; +if (ovid->rotation_type ==OMAP_DSS_ROT_VRFB ) +return omap_vout_setup_vrfb_bufs (pdev, vid_num); - image_width = image_width *TILE_SIZE ; - image_height =VID_MAX_HEIGHT /TILE_SIZE ; - -if (VID_MAX_HEIGHT %TILE_SIZE ) - image_height++; - - image_height = image_height *TILE_SIZE ; - vout->smsshado_size =PAGE_ALIGN (image_width * image_height *2 * 2); - -/* -* Request and Initialize DMA, for DMA based VRFB transfer -*/ - vout->vrfb_dma_tx.dev_id =OMAP_DMA_NO_DEVICE ; - vout->vrfb_dma_tx.dma_ch =-1 ; - vout->vrfb_dma_tx.req_status =DMA_CHAN_ALLOTED ; - ret =omap_request_dma (vout->vrfb_dma_tx.dev_id,"VRFB DMA TX" , - omap_vout_vrfb_dma_tx_callback, - (void *) &vout->vrfb_dma_tx, &vout->vrfb_dma_tx.dma_ch); -if (ret <0 ) { - vout->vrfb_dma_tx.req_status =DMA_CHAN_NOT_ALLOTED ; -dev_info (&pdev->dev,": failed to allocate DMA Channel for" -" video%d\n" , vfd->minor); - } -init_waitqueue_head (&vout->vrfb_dma_tx.wait); - -/* Allocate VRFB buffers if selected through bootargs */ - static_vrfb_allocation = (vid_num ==0 ) ? - vid1_static_vrfb_alloc : vid2_static_vrfb_alloc; - -/* statically allocated the VRFB buffer is done through -commands line aruments */ -if (static_vrfb_allocation) { -if (omap_vout_allocate_vrfb_buffers (vout, &vrfb_num_bufs,-1 )) { - ret = -ENOMEM ; - goto release_vrfb_ctx; - } - vout->vrfb_static_allocation =1 ; - }return 0 ; -release_vrfb_ctx: -for (j =0 ; j <VRFB_NUM_BUFS ; j++) -omap_vrfb_release_ctx (&vout->vrfb_context[j]); -
free_buffers:for (i = 0; i < numbuffers; i++) { omap_vout_free_buffer(vout->buf_virt_addr[i],drivers/media/video/omap/omap_vout.c +2
-0@@ -2357,6 +2055,8 @@ static int __init omap_vout_create_video_devices(struct platform_device *pdev) vout->vid_info.overlays[0] = vid_dev->overlays[k + 1]; vout->vid_info.num_overlays =1 ; vout->vid_info.id = k +1 ; + vout->vid_info.rotation_type = def_vrfb ?OMAP_DSS_ROT_VRFB : +OMAP_DSS_ROT_DMA ;/* Setup the default configuration for the video devices */drivers/media/video/omap/omap_vout.c +2
-1@@ -2391,7 +2091,8 @@ static int __init omap_vout_create_video_devices(struct platform_device *pdev) goto success; error2: -omap_vout_release_vrfb (vout); +if (vout->vid_info.rotation_type ==OMAP_DSS_ROT_VRFB ) +omap_vout_release_vrfb (vout);omap_vout_free_buffers (vout); error1:video_device_release(vfd);drivers/media/video/omap/omap_vout.c +10
-7@@ -2412,11 +2113,13 @@ success:static void omap_vout_cleanup_device (struct omap_vout_device *vout) {struct video_device *vfd; +struct omapvideo_info *ovid;if (!vout)return ; vfd = vout->vfd; + ovid = &vout->vid_info;if (vfd) {if (!video_is_registered (vfd)) {/* @@ -2432,14 +2135,15 @@ static void omap_vout_cleanup_device(struct omap_vout_device *vout)video_unregister_device (vfd ); } } - -omap_vout_release_vrfb (vout); +if (ovid->rotation_type ==OMAP_DSS_ROT_VRFB ) { +omap_vout_release_vrfb (vout); +/* Free the VRFB buffer if allocated +* init time +*/ +if (vout->vrfb_static_allocation) +omap_vout_free_vrfb_buffers (vout); + }omap_vout_free_buffers (vout); -/* Free the VRFB buffer if allocated -* init time -*/ -if (vout->vrfb_static_allocation) -omap_vout_free_vrfb_buffers (vout);kfree (vout);}
drivers/media/video/omap/omap_vout.c +6
-0@@ -2478,6 +2182,12 @@ static int __init omap_vout_probe(struct platform_device *pdev)return -ENODEV ; } +if (def_vrfb && (!cpu_is_omap24xx ()) && (!cpu_is_omap34xx ())) { + def_vrfb =0 ; +dev_warn (&pdev->dev,"VRFB is not in this device," +"setting DMA as rotation_type\n" ); + } + vid_dev =kzalloc (sizeof (struct omap2video_device ),GFP_KERNEL );if (vid_dev ==NULL )return -ENOMEM;drivers/media/video/omap/omap_voutdef.h +1
-1@@ -71,6 +71,7 @@ struct omapvideo_info {int id;int num_overlays;struct omap_overlay *overlays[MAX_OVLS ]; +enum omap_dss_rotation_type rotation_type; };struct omap2video_device { --1.7.0.4
Quoted 18 lines
-----Original Message-----
From: Taneja, Archit
Sent: Monday, September 27, 2010 12:47 PM
To: Hiremath, Vaibhav
Cc: [email protected]; [email protected]; Taneja, Archit
Subject: [PATCH v2 0/2] V4L/DVB:OMAP_VOUT: Allowomap_voutto build without VRFBThis lets
omap_voutdriver build and run without VRFB. It works along the lines of the following patch series:OMAP: DSS2: OMAPFB: Allow
FB_OMAP2to build without VRFB
https://patchwork.kernel.org/patch/105371/Since VRFB is tightly coupled with the
omap_voutdriver, a handful of vrfb specific functions have been defined and placed inomap_vout_vrfb.c
Quoted 7 lines
A variable
rotation_typeis introduced inomapvideo_infolike the way inomapfb_info, this allows to call vrfb specific functions only if the rotation
type is vrfb. When therotation_typeis set to SDMA, theS_CTRLioctl prevents
the user setting a non zero rotation value.
[Hiremath, Vaibhav] Lets make one stand here,
I think this series still doesn't support DMA based rotation, unlike Fbdev driver so I would say lets clearly state that we are not supporting sDMA based rotation here. So I don't see any reason why we need
Quoted 23 lines
Archit Taneja (2):
V4L/DVB:OMAP_VOUT: Create a seperate vrfb functions library V4L/DVB:OMAP_VOUT: Userotation_typeto choose between vrfb and
sdram buffersdrivers/media/video/omap/Kconfig | 1 - drivers/media/video/omap/Makefile | 1 + drivers/media/video/omap/omap_vout.c | 480 ++++++------------------ ----- drivers/media/video/omap/omap_vout_vrfb.c | 417 +++++++++++++++++++++++++ drivers/media/video/omap/omap_vout_vrfb.h | 40 +++ drivers/media/video/omap/omap_voutdef.h | 26 ++ 6 files changed, 571 insertions(+), 394 deletions(-) create mode 100644 drivers/media/video/omap/omap_vout_vrfb.c create mode 100644 drivers/media/video/omap/omap_vout_vrfb.h--
Version 2:
- Don't try to enable SDRAM rotation , return an error if non zero
rotation
is attempted whenrotation_typeis set to SDMA rotation.
Version 1:http://www.mail-archive.com/[email protected]/msg21937.html
Hi,
Quoted 24 lines · Vaibhav
Quoted 5 lines
-----Original Message-----
From: Taneja, Archit
Sent: Monday, September 27, 2010 12:47 PM
To: Hiremath, Vaibhav
Cc: [email protected];[email protected]; Taneja,
Quoted 11 lines
Archit
Subject: [PATCH v2 0/2] V4L/DVB:OMAP_VOUT: Allowomap_voutto build without VRFBThis lets
omap_voutdriver build and run without VRFB. It works along the lines of the following patch series:OMAP: DSS2: OMAPFB: Allow
FB_OMAP2to build without VRFB
https://patchwork.kernel.org/patch/105371/Since VRFB is tightly coupled with the
omap_voutdriver, a handful ofvrfb specific functions have been defined and placed in
omap_vout_vrfb.cQuoted 6 lines
A variable
rotation_typeis introduced inomapvideo_infolike the way inomapfb_info, this allows to call vrfb specific functions only if the rotation type is vrfb. When therotation_typeis set to SDMA, theS_CTRLioctl prevents the user setting a non zero rotation value.
Quoted 6 lines
[Hiremath, Vaibhav] Lets make one stand here,
I think this series still doesn't support DMA based rotation, unlike Fbdev driver so I would say lets clearly state that we
are not supporting sDMA based rotation here. So I don't see any reason why we need
Yes, we aren't supporting sDMA rotation. I use the rotation_type to differentiate between using vrfb and not using vrfb. I agree it becomes misleading as it looks as if we support sDMA rotation, but im not sure how to differentiate between choosing vrfb and non-vrfb modes without using the enum "omap_dss_rotation_type".
Should we add something like "OMAP_DSS_ROT_NONE" to the enum to show we won't do rotation, or should we add a new enum like omap_dss_buffer_type?
The approach of patch is to allow us to set both types of rotation..but return an error if we try to set the rotation when the rotation type selected is sDMA.
Can you suggest a cleaner way to choose between vrfb and non vrfb?
Quoted 22 lines
Quoted 16 lines
Archit Taneja (2):
V4L/DVB:OMAP_VOUT: Create a seperate vrfb functions library
V4L/DVB:OMAP_VOUT: Userotation_typeto choose between vrfb and sdram
buffersdrivers/media/video/omap/Kconfig | 1 - drivers/media/video/omap/Makefile | 1 + drivers/media/video/omap/omap_vout.c | 480 ++++++------------------ ----- drivers/media/video/omap/omap_vout_vrfb.c | 417 +++++++++++++++++++++++++ drivers/media/video/omap/omap_vout_vrfb.h | 40 +++ drivers/media/video/omap/omap_voutdef.h | 26 ++ 6 files changed, 571 insertions(+), 394 deletions(-) create mode 100644 drivers/media/video/omap/omap_vout_vrfb.c create mode 100644 drivers/media/video/omap/omap_vout_vrfb.h --Quoted 5 lines
Version 2:
- Don't try to enable SDRAM rotation , return an error if non zero rotation is attempted whenrotation_typeis set to SDMA rotation. Version 1: