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 <twan...@marvell.com>
> Signed-off-by: Libin Yang <lby...@marvell.com>
> Acked-by: Jonathan Corbet <cor...@lwn.net>
> ---
>  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 majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to