On Thu, 7 Feb 2013, Albert Wang wrote: > This patch adds support of 3 frame buffers in DMA-contiguous mode. > > In current DMA_CONTIG mode, only 2 frame buffers can be supported. > Actually, Marvell CCIC can support 2 or 3 frame buffers. > > Currently 3 frame buffers mode will be used by default. > To use 2 frame buffers mode, can do: > #define MAX_FRAME_BUFS 2 > in mcam-core.h. > > Signed-off-by: Albert Wang <twang13@xxxxxxxxxxx> > Signed-off-by: Libin Yang <lbyang@xxxxxxxxxxx> > Acked-by: Jonathan Corbet <corbet@xxxxxxx> > --- > drivers/media/platform/marvell-ccic/mcam-core.c | 59 +++++++++++++++++------ > drivers/media/platform/marvell-ccic/mcam-core.h | 13 +++++ > 2 files changed, 57 insertions(+), 15 deletions(-) > > diff --git a/drivers/media/platform/marvell-ccic/mcam-core.c b/drivers/media/platform/marvell-ccic/mcam-core.c > index f206e3c..33fce6c 100755 > --- a/drivers/media/platform/marvell-ccic/mcam-core.c > +++ b/drivers/media/platform/marvell-ccic/mcam-core.c > @@ -494,13 +494,32 @@ static void mcam_set_contig_buffer(struct mcam_camera *cam, unsigned int frame) > struct mcam_vb_buffer *buf; > struct v4l2_pix_format *fmt = &cam->pix_format; > > - /* > - * If there are no available buffers, go into single mode > - */ > if (list_empty(&cam->buffers)) { > - buf = cam->vb_bufs[frame ^ 0x1]; > - set_bit(CF_SINGLE_BUFFER, &cam->flags); > - cam->frame_state.singles++; > + /* > + * If there are no available buffers > + * go into single buffer mode > + * > + * If CCIC use Two Buffers mode > + * will use another remaining frame buffer > + * frame 0 -> buf 1 > + * frame 1 -> buf 0 > + * > + * If CCIC use Three Buffers mode > + * will use the 2rd remaining frame buffer > + * frame 0 -> buf 2 > + * frame 1 -> buf 0 > + * frame 2 -> buf 1 > + */ > + buf = cam->vb_bufs[(frame + (MAX_FRAME_BUFS - 1)) > + % MAX_FRAME_BUFS]; > + if (cam->frame_state.usebufs == 0) > + cam->frame_state.usebufs++; > + else { > + set_bit(CF_SINGLE_BUFFER, &cam->flags); > + cam->frame_state.singles++; > + if (cam->frame_state.usebufs < 2) > + cam->frame_state.usebufs++; What is this .usebufs actually supposed to do? AFAICS, it is only used to decide, whether it should be changed, I don't see it having any effect on anything else? > + } > } else { > /* > * OK, we have a buffer we can use. > @@ -509,15 +528,15 @@ static void mcam_set_contig_buffer(struct mcam_camera *cam, unsigned int frame) > queue); > list_del_init(&buf->queue); > clear_bit(CF_SINGLE_BUFFER, &cam->flags); > + if (cam->frame_state.usebufs != (3 - MAX_FRAME_BUFS)) > + cam->frame_state.usebufs--; > } > > cam->vb_bufs[frame] = buf; > - mcam_reg_write(cam, frame == 0 ? REG_Y0BAR : REG_Y1BAR, buf->yuv_p.y); > + mcam_reg_write(cam, REG_Y0BAR + (frame << 2), buf->yuv_p.y); > if (mcam_fmt_is_planar(fmt->pixelformat)) { > - mcam_reg_write(cam, frame == 0 ? > - REG_U0BAR : REG_U1BAR, buf->yuv_p.u); > - mcam_reg_write(cam, frame == 0 ? > - REG_V0BAR : REG_V1BAR, buf->yuv_p.v); > + mcam_reg_write(cam, REG_U0BAR + (frame << 2), buf->yuv_p.u); > + mcam_reg_write(cam, REG_V0BAR + (frame << 2), buf->yuv_p.v); > } > } > > @@ -526,10 +545,14 @@ static void mcam_set_contig_buffer(struct mcam_camera *cam, unsigned int frame) > */ > static void mcam_ctlr_dma_contig(struct mcam_camera *cam) > { > - mcam_reg_set_bit(cam, REG_CTRL1, C1_TWOBUFS); > - cam->nbufs = 2; > - mcam_set_contig_buffer(cam, 0); > - mcam_set_contig_buffer(cam, 1); > + unsigned int frame; > + > + cam->nbufs = MAX_FRAME_BUFS; > + for (frame = 0; frame < cam->nbufs; frame++) > + mcam_set_contig_buffer(cam, frame); > + > + if (cam->nbufs == 2) > + mcam_reg_set_bit(cam, REG_CTRL1, C1_TWOBUFS); > } > > /* > @@ -1068,6 +1091,12 @@ static int mcam_vb_start_streaming(struct vb2_queue *vq, unsigned int count) > for (frame = 0; frame < cam->nbufs; frame++) > clear_bit(CF_FRAME_SOF0 + frame, &cam->flags); > > + /* > + * If CCIC use Two Buffers mode, init usebufs == 1 > + * If CCIC use Three Buffers mode, init usebufs == 0 > + */ > + cam->frame_state.usebufs = 3 - MAX_FRAME_BUFS; > + > return mcam_read_setup(cam); > } > > diff --git a/drivers/media/platform/marvell-ccic/mcam-core.h b/drivers/media/platform/marvell-ccic/mcam-core.h > index 0accdbb..6fffa14 100755 > --- a/drivers/media/platform/marvell-ccic/mcam-core.h > +++ b/drivers/media/platform/marvell-ccic/mcam-core.h > @@ -44,6 +44,15 @@ enum mcam_state { > }; > #define MAX_DMA_BUFS 3 > > +#ifdef MCAM_MODE_DMA_CONTIG > +/* > + * CCIC can support at most 3 frame buffers in DMA_CONTIG buffer mode > + * 2 - Use Two Buffers mode > + * 3 - Use Three Buffers mode > + */ > +#define MAX_FRAME_BUFS 3 /* marvell-ccic used Three Buffers mode as default */ > +#endif > + > /* > * Different platforms work best with different buffer modes, so we > * let the platform pick. > @@ -82,6 +91,10 @@ struct mcam_frame_state { > unsigned int frames; > unsigned int singles; > unsigned int delivered; > + /* > + * Only usebufs == 2 can enter single buffer mode > + */ > + unsigned int usebufs; > }; > > #define NR_MCAM_CLK 3 > -- > 1.7.9.5 > Thanks Guennadi --- Guennadi Liakhovetski, Ph.D. Freelance Open-Source Software Developer http://www.open-technology.de/ -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html