media: omap_vout: convert to vb2

Convert omap_vout to the vb2 framework. After this change
'v4l2-compliance -s' passes all tests.

As usual, this vb2 conversion is a 'big bang' patch and hard to read.

Tested on a Pandaboard and a Beagle XM board.

Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
This commit is contained in:
Hans Verkuil 2019-07-30 03:38:17 -03:00 committed by Mauro Carvalho Chehab
parent 839b9d2c59
commit 256acbebdc
5 changed files with 191 additions and 764 deletions

View File

@ -10,8 +10,7 @@ config VIDEO_OMAP2_VOUT
depends on FB_OMAP2 || (COMPILE_TEST && FB_OMAP2=n) depends on FB_OMAP2 || (COMPILE_TEST && FB_OMAP2=n)
depends on ARCH_OMAP2 || ARCH_OMAP3 || COMPILE_TEST depends on ARCH_OMAP2 || ARCH_OMAP3 || COMPILE_TEST
depends on VIDEO_V4L2 depends on VIDEO_V4L2
select VIDEOBUF_GEN select VIDEOBUF2_DMA_CONTIG
select VIDEOBUF_DMA_CONTIG
select OMAP2_VRFB if ARCH_OMAP2 || ARCH_OMAP3 select OMAP2_VRFB if ARCH_OMAP2 || ARCH_OMAP3
select FRAME_VECTOR select FRAME_VECTOR
help help

File diff suppressed because it is too large Load Diff

View File

@ -14,7 +14,6 @@
#include <linux/videodev2.h> #include <linux/videodev2.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <media/videobuf-dma-contig.h>
#include <media/v4l2-device.h> #include <media/v4l2-device.h>
#include <video/omapvrfb.h> #include <video/omapvrfb.h>
@ -40,7 +39,7 @@ static int omap_vout_allocate_vrfb_buffers(struct omap_vout_device *vout,
&vout->smsshado_phy_addr[i]); &vout->smsshado_phy_addr[i]);
} }
if (!vout->smsshado_virt_addr[i] && startindex != -1) { if (!vout->smsshado_virt_addr[i] && startindex != -1) {
if (V4L2_MEMORY_MMAP == vout->memory && i >= startindex) if (vout->vq.memory == V4L2_MEMORY_MMAP && i >= startindex)
break; break;
} }
if (!vout->smsshado_virt_addr[i]) { if (!vout->smsshado_virt_addr[i]) {
@ -109,8 +108,7 @@ int omap_vout_setup_vrfb_bufs(struct platform_device *pdev, int vid_num,
dev_info(&pdev->dev, ": VRFB allocation failed\n"); dev_info(&pdev->dev, ": VRFB allocation failed\n");
for (j = 0; j < i; j++) for (j = 0; j < i; j++)
omap_vrfb_release_ctx(&vout->vrfb_context[j]); omap_vrfb_release_ctx(&vout->vrfb_context[j]);
ret = -ENOMEM; return -ENOMEM;
goto free_buffers;
} }
} }
@ -155,8 +153,10 @@ int omap_vout_setup_vrfb_bufs(struct platform_device *pdev, int vid_num,
init_waitqueue_head(&vout->vrfb_dma_tx.wait); init_waitqueue_head(&vout->vrfb_dma_tx.wait);
/* statically allocated the VRFB buffer is done through /*
commands line aruments */ * statically allocated the VRFB buffer is done through
* command line arguments
*/
if (static_vrfb_allocation) { if (static_vrfb_allocation) {
if (omap_vout_allocate_vrfb_buffers(vout, &vrfb_num_bufs, -1)) { if (omap_vout_allocate_vrfb_buffers(vout, &vrfb_num_bufs, -1)) {
ret = -ENOMEM; ret = -ENOMEM;
@ -169,9 +169,6 @@ int omap_vout_setup_vrfb_bufs(struct platform_device *pdev, int vid_num,
release_vrfb_ctx: release_vrfb_ctx:
for (j = 0; j < VRFB_NUM_BUFS; j++) for (j = 0; j < VRFB_NUM_BUFS; j++)
omap_vrfb_release_ctx(&vout->vrfb_context[j]); omap_vrfb_release_ctx(&vout->vrfb_context[j]);
free_buffers:
omap_vout_free_buffers(vout);
return ret; return ret;
} }
@ -231,13 +228,14 @@ int omap_vout_vrfb_buffer_setup(struct omap_vout_device *vout,
} }
int omap_vout_prepare_vrfb(struct omap_vout_device *vout, int omap_vout_prepare_vrfb(struct omap_vout_device *vout,
struct videobuf_buffer *vb) struct vb2_buffer *vb)
{ {
struct dma_async_tx_descriptor *tx; struct dma_async_tx_descriptor *tx;
enum dma_ctrl_flags flags = DMA_PREP_INTERRUPT | DMA_CTRL_ACK; enum dma_ctrl_flags flags = DMA_PREP_INTERRUPT | DMA_CTRL_ACK;
struct dma_chan *chan = vout->vrfb_dma_tx.chan; struct dma_chan *chan = vout->vrfb_dma_tx.chan;
struct dma_interleaved_template *xt = vout->vrfb_dma_tx.xt; struct dma_interleaved_template *xt = vout->vrfb_dma_tx.xt;
dma_cookie_t cookie; dma_cookie_t cookie;
dma_addr_t buf_phy_addr = vb2_dma_contig_plane_dma_addr(vb, 0);
enum dma_status status; enum dma_status status;
enum dss_rotation rotation; enum dss_rotation rotation;
size_t dst_icg; size_t dst_icg;
@ -256,8 +254,8 @@ int omap_vout_prepare_vrfb(struct omap_vout_device *vout,
dst_icg = ((MAX_PIXELS_PER_LINE * pixsize) - dst_icg = ((MAX_PIXELS_PER_LINE * pixsize) -
(vout->pix.width * vout->bpp)) + 1; (vout->pix.width * vout->bpp)) + 1;
xt->src_start = vout->buf_phy_addr[vb->i]; xt->src_start = buf_phy_addr;
xt->dst_start = vout->vrfb_context[vb->i].paddr[0]; xt->dst_start = vout->vrfb_context[vb->index].paddr[0];
xt->numf = vout->pix.height; xt->numf = vout->pix.height;
xt->frame_size = 1; xt->frame_size = 1;
@ -308,8 +306,8 @@ int omap_vout_prepare_vrfb(struct omap_vout_device *vout,
/* Store buffers physical address into an array. Addresses /* Store buffers physical address into an array. Addresses
* from this array will be used to configure DSS */ * from this array will be used to configure DSS */
rotation = calc_rotation(vout); rotation = calc_rotation(vout);
vout->queued_buf_addr[vb->i] = (u8 *) vout->queued_buf_addr[vb->index] = (u8 *)
vout->vrfb_context[vb->i].paddr[rotation]; vout->vrfb_context[vb->index].paddr[rotation];
return 0; return 0;
} }

View File

@ -20,7 +20,7 @@ void omap_vout_release_vrfb(struct omap_vout_device *vout);
int omap_vout_vrfb_buffer_setup(struct omap_vout_device *vout, int omap_vout_vrfb_buffer_setup(struct omap_vout_device *vout,
unsigned int *count, unsigned int startindex); unsigned int *count, unsigned int startindex);
int omap_vout_prepare_vrfb(struct omap_vout_device *vout, int omap_vout_prepare_vrfb(struct omap_vout_device *vout,
struct videobuf_buffer *vb); struct vb2_buffer *vb);
void omap_vout_calculate_vrfb_offset(struct omap_vout_device *vout); void omap_vout_calculate_vrfb_offset(struct omap_vout_device *vout);
#else #else
static inline void omap_vout_free_vrfb_buffers(struct omap_vout_device *vout) { }; static inline void omap_vout_free_vrfb_buffers(struct omap_vout_device *vout) { };
@ -32,7 +32,7 @@ static inline int omap_vout_vrfb_buffer_setup(struct omap_vout_device *vout,
unsigned int *count, unsigned int startindex) unsigned int *count, unsigned int startindex)
{ return 0; }; { return 0; };
static inline int omap_vout_prepare_vrfb(struct omap_vout_device *vout, static inline int omap_vout_prepare_vrfb(struct omap_vout_device *vout,
struct videobuf_buffer *vb) struct vb2_buffer *vb)
{ return 0; }; { return 0; };
static inline void omap_vout_calculate_vrfb_offset(struct omap_vout_device *vout) { }; static inline void omap_vout_calculate_vrfb_offset(struct omap_vout_device *vout) { };
#endif #endif

View File

@ -11,6 +11,7 @@
#ifndef OMAP_VOUTDEF_H #ifndef OMAP_VOUTDEF_H
#define OMAP_VOUTDEF_H #define OMAP_VOUTDEF_H
#include <media/videobuf2-dma-contig.h>
#include <media/v4l2-ctrls.h> #include <media/v4l2-ctrls.h>
#include <video/omapfb_dss.h> #include <video/omapfb_dss.h>
#include <video/omapvrfb.h> #include <video/omapvrfb.h>
@ -113,6 +114,20 @@ struct omap2video_device {
struct omap_overlay_manager *managers[MAX_MANAGERS]; struct omap_overlay_manager *managers[MAX_MANAGERS];
}; };
/* buffer for one video frame */
struct omap_vout_buffer {
/* common v4l buffer stuff -- must be first */
struct vb2_v4l2_buffer vbuf;
struct list_head queue;
};
static inline struct omap_vout_buffer *vb2_to_omap_vout_buffer(struct vb2_buffer *vb)
{
struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
return container_of(vbuf, struct omap_vout_buffer, vbuf);
}
/* per-device data structure */ /* per-device data structure */
struct omap_vout_device { struct omap_vout_device {
@ -121,29 +136,12 @@ struct omap_vout_device {
struct omap2video_device *vid_dev; struct omap2video_device *vid_dev;
struct v4l2_ctrl_handler ctrl_handler; struct v4l2_ctrl_handler ctrl_handler;
int vid; int vid;
int opened;
/* we don't allow to change image fmt/size once buffer has
* been allocated
*/
int buffer_allocated;
/* allow to reuse previously allocated buffer which is big enough */ /* allow to reuse previously allocated buffer which is big enough */
int buffer_size; int buffer_size;
/* keep buffer info across opens */
unsigned long buf_virt_addr[VIDEO_MAX_FRAME];
unsigned long buf_phy_addr[VIDEO_MAX_FRAME];
enum omap_color_mode dss_mode; enum omap_color_mode dss_mode;
/* we don't allow to request new buffer when old buffers are u32 sequence;
* still mmapped
*/
int mmap_count;
spinlock_t vbq_lock; /* spinlock for videobuf queues */
unsigned long field_count; /* field counter for videobuf_buffer */
/* non-NULL means streaming is in progress. */
bool streaming;
struct v4l2_pix_format pix; struct v4l2_pix_format pix;
struct v4l2_rect crop; struct v4l2_rect crop;
@ -169,19 +167,14 @@ struct omap_vout_device {
unsigned char pos; unsigned char pos;
int ps, vr_ps, line_length, first_int, field_id; int ps, vr_ps, line_length, first_int, field_id;
enum v4l2_memory memory; struct omap_vout_buffer *cur_frm, *next_frm;
struct videobuf_buffer *cur_frm, *next_frm; spinlock_t vbq_lock; /* spinlock for dma_queue */
struct list_head dma_queue; struct list_head dma_queue;
u8 *queued_buf_addr[VIDEO_MAX_FRAME]; u8 *queued_buf_addr[VIDEO_MAX_FRAME];
u32 cropped_offset; u32 cropped_offset;
s32 tv_field1_offset; s32 tv_field1_offset;
void *isr_handle; void *isr_handle;
struct vb2_queue vq;
/* Buffer queue variables */
struct omap_vout_device *vout;
enum v4l2_buf_type type;
struct videobuf_queue vbq;
int io_allowed;
}; };