Re: [REVIEW PATCH V4 12/12] [media] marvell-ccic: add 3 frame buffers support in DMA_CONTIG mode

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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


[Index of Archives]     [Linux Input]     [Video for Linux]     [Gstreamer Embedded]     [Mplayer Users]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]
  Powered by Linux