RE: [RFC/PATCH v7 3/5] MFC: Add MFC 5.1 V4L2 driver

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

 



Hi, Kamil

I found some mal-functional points.

> -----Original Message-----
> From: linux-media-owner@xxxxxxxxxxxxxxx [mailto:linux-media-
> owner@xxxxxxxxxxxxxxx] On Behalf Of Kamil Debski
> Sent: Friday, March 04, 2011 8:26 PM
> To: linux-media@xxxxxxxxxxxxxxx; linux-samsung-soc@xxxxxxxxxxxxxxx
> Cc: m.szyprowski@xxxxxxxxxxx; kyungmin.park@xxxxxxxxxxx;
> k.debski@xxxxxxxxxxx; jaeryul.oh@xxxxxxxxxxx; kgene.kim@xxxxxxxxxxx
> Subject: [RFC/PATCH v7 3/5] MFC: Add MFC 5.1 V4L2 driver
> 
> Multi Format Codec 5.1 is capable of handling a range of video codecs
> and this driver provides V4L2 interface for video decoding.
> 
> Signed-off-by: Kamil Debski <k.debski@xxxxxxxxxxx>
> Signed-off-by: Kyungmin Park <kyungmin.park@xxxxxxxxxxx>
> ---
>  drivers/media/video/Kconfig                  |    8 +
>  drivers/media/video/Makefile                 |    1 +
>  drivers/media/video/s5p-mfc/Makefile         |    3 +
>  drivers/media/video/s5p-mfc/regs-mfc5.h      |  346 ++++
>  drivers/media/video/s5p-mfc/s5p_mfc.c        | 2253
> ++++++++++++++++++++++++++
>  drivers/media/video/s5p-mfc/s5p_mfc_common.h |  240 +++
>  drivers/media/video/s5p-mfc/s5p_mfc_ctrls.h  |  182 +++
>  drivers/media/video/s5p-mfc/s5p_mfc_debug.h  |   47 +
>  drivers/media/video/s5p-mfc/s5p_mfc_intr.c   |   92 ++
>  drivers/media/video/s5p-mfc/s5p_mfc_intr.h   |   26 +
>  drivers/media/video/s5p-mfc/s5p_mfc_memory.h |   43 +
>  drivers/media/video/s5p-mfc/s5p_mfc_opr.c    |  913 +++++++++++
>  drivers/media/video/s5p-mfc/s5p_mfc_opr.h    |  142 ++
>  13 files changed, 4296 insertions(+), 0 deletions(-)
>  create mode 100644 drivers/media/video/s5p-mfc/Makefile
>  create mode 100644 drivers/media/video/s5p-mfc/regs-mfc5.h
>  create mode 100644 drivers/media/video/s5p-mfc/s5p_mfc.c
>  create mode 100644 drivers/media/video/s5p-mfc/s5p_mfc_common.h
>  create mode 100644 drivers/media/video/s5p-mfc/s5p_mfc_ctrls.h
>  create mode 100644 drivers/media/video/s5p-mfc/s5p_mfc_debug.h
>  create mode 100644 drivers/media/video/s5p-mfc/s5p_mfc_intr.c
>  create mode 100644 drivers/media/video/s5p-mfc/s5p_mfc_intr.h
>  create mode 100644 drivers/media/video/s5p-mfc/s5p_mfc_memory.h
>  create mode 100644 drivers/media/video/s5p-mfc/s5p_mfc_opr.c
>  create mode 100644 drivers/media/video/s5p-mfc/s5p_mfc_opr.h
> 
> diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig
> index 12fb325..0bdc64d 100644
> --- a/drivers/media/video/Kconfig
> +++ b/drivers/media/video/Kconfig
> @@ -1025,4 +1025,12 @@ config  VIDEO_SAMSUNG_S5P_FIMC
>  	  This is a v4l2 driver for the S5P camera interface
>  	  (video postprocessor)
> 
> +config VIDEO_SAMSUNG_S5P_MFC
> +	tristate "Samsung S5P MFC 5.1 Video Codec"
> +	depends on VIDEO_V4L2
> +	select VIDEOBUF2_S5P_IOMMU
> +	default n
> +	help
> +	    MFC 5.1 driver for V4L2.
> +
>  endif # V4L_MEM2MEM_DRIVERS
> diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile
> index fd9488d..4b09ddb 100644
> --- a/drivers/media/video/Makefile
> +++ b/drivers/media/video/Makefile
> @@ -164,6 +164,7 @@ obj-$(CONFIG_VIDEO_SH_MOBILE_CSI2)	+=
> sh_mobile_csi2.o
>  obj-$(CONFIG_VIDEO_SH_MOBILE_CEU)	+= sh_mobile_ceu_camera.o
>  obj-$(CONFIG_VIDEO_OMAP1)		+= omap1_camera.o
>  obj-$(CONFIG_VIDEO_SAMSUNG_S5P_FIMC) 	+= s5p-fimc/
> +obj-$(CONFIG_VIDEO_SAMSUNG_S5P_MFC)	+= s5p-mfc/
> 
>  obj-$(CONFIG_ARCH_DAVINCI)		+= davinci/
> 
> diff --git a/drivers/media/video/s5p-mfc/Makefile
> b/drivers/media/video/s5p-mfc/Makefile
> new file mode 100644
> index 0000000..69b6294
> --- /dev/null
> +++ b/drivers/media/video/s5p-mfc/Makefile
> @@ -0,0 +1,3 @@
> +obj-$(CONFIG_VIDEO_SAMSUNG_S5P_MFC) := s5p-mfc.o
> +s5p-mfc-y := s5p_mfc.o s5p_mfc_intr.o  s5p_mfc_opr.o
> +
> diff --git a/drivers/media/video/s5p-mfc/regs-mfc5.h
> b/drivers/media/video/s5p-mfc/regs-mfc5.h
> new file mode 100644
> index 0000000..eeb6e2e
> --- /dev/null
> +++ b/drivers/media/video/s5p-mfc/regs-mfc5.h
> @@ -0,0 +1,346 @@

snipping

> +}
> +
> +static inline void s5p_mfc_run_res_change(struct s5p_mfc_ctx *ctx)
> +{
> +	struct s5p_mfc_dev *dev = ctx->dev;
> +
> +	s5p_mfc_set_dec_stream_buffer(ctx, 0, 0, 0);
> +	dev->curr_ctx = ctx->num;
> +	s5p_mfc_clean_ctx_int_flags(ctx);
> +	s5p_mfc_decode_one_frame(ctx, MFC_DEC_RES_CHANGE);
> +}
> +
> +static inline void s5p_mfc_run_dec_last_frames(struct s5p_mfc_ctx *ctx)
> +{
> +	struct s5p_mfc_dev *dev = ctx->dev;
> +
> +	s5p_mfc_set_dec_stream_buffer(ctx, 0, 0, 0);
> +	dev->curr_ctx = ctx->num;
> +	s5p_mfc_clean_ctx_int_flags(ctx);
> +	s5p_mfc_decode_one_frame(ctx, MFC_DEC_LAST_FRAME);
> +}
> +

You used '0' as a second param.(= buf_addr) in
s5p_mfc_set_dec_stream_buffer(ctx, 0, 0, 0)
This must be a problem, 'cause OFFSETA(buf_addr) is calculated wrongly.
And I propose that 
why don't you try to check addr condition(necessary cond. of MFC, it should
be located at 
rear region from base_addr) 

> +static inline int s5p_mfc_run_dec_frame(struct s5p_mfc_ctx *ctx)
> +{
> +	struct s5p_mfc_dev *dev = ctx->dev;
> +	struct s5p_mfc_buf *temp_vb;
> +	unsigned long flags;
> +	int dec_arg = MFC_DEC_FRAME;
> +
> +	spin_lock_irqsave(&dev->irqlock, flags);
> +
> +	/* Frames are being decoded */
> +	if (list_empty(&ctx->src_queue)) {
> +		mfc_debug("No src buffers.\n");
> +		spin_unlock_irqrestore(&dev->irqlock, flags);
> +		return -EAGAIN;
> +	}
> +	/* Get the next source buffer */
> +	temp_vb = list_entry(ctx->src_queue.next, struct s5p_mfc_buf, list);
> +	mfc_debug("Temp vb: %p\n", temp_vb);
> +	mfc_debug("Src Addr: %08x\n", s5p_mfc_plane_addr(temp_vb->b, 0));
> +	s5p_mfc_set_dec_stream_buffer(ctx, s5p_mfc_plane_addr(temp_vb->b,
> 0),
> +				ctx->consumed_stream, temp_vb->b-
> >v4l2_planes[0].bytesused);
> +	spin_unlock_irqrestore(&dev->irqlock, flags);
> +	dev->curr_ctx = ctx->num;
> +	s5p_mfc_clean_ctx_int_flags(ctx);
> +	if (temp_vb->b->v4l2_planes[0].bytesused == 0) {
> +	        mfc_debug("Setting ctx->state to FINISHING\n");
> +	        ctx->state = MFCINST_DEC_FINISHING;
> +		dec_arg = MFC_DEC_LAST_FRAME;
> +	}
> +	s5p_mfc_decode_one_frame(ctx,
> +				dec_arg);
> +
> +	return 0;
> +}
> +
> +static inline int s5p_mfc_run_get_inst_no(struct s5p_mfc_ctx *ctx)
> +{
> +	struct s5p_mfc_dev *dev = ctx->dev;
> +	int ret;
> +
> +	/* Preparing decoding - getting instance number */
> +	mfc_debug("Getting instance number\n");
> +	dev->curr_ctx = ctx->num;
> +	s5p_mfc_clean_ctx_int_flags(ctx);
> +	ret = s5p_mfc_open_inst(ctx);
> +	if (ret) {
> +		mfc_err("Failed to create a new instance.\n");
> +		ctx->state = MFCINST_DEC_ERROR;
> +	}
> +	return ret;
> +}
> +
> +static inline int s5p_mfc_run_return_inst(struct s5p_mfc_ctx *ctx)
> +{
> +	struct s5p_mfc_dev *dev = ctx->dev;
> +	int ret;
> +
> +	/* Closing decoding instance  */
> +	mfc_debug("Returning instance number\n");
> +	dev->curr_ctx = ctx->num;
> +	s5p_mfc_clean_ctx_int_flags(ctx);
> +	ret = s5p_mfc_return_inst_no(ctx);
> +	if (ret) {
> +		mfc_err("Failed to return an instance.\n");
> +		ctx->state = MFCINST_DEC_ERROR;
> +		return ret;
> +	}
> +	return ret;
> +}
> +
> +static inline void s5p_mfc_run_init_dec(struct s5p_mfc_ctx *ctx)
> +{
> +	struct s5p_mfc_dev *dev = ctx->dev;
> +	unsigned long flags;
> +	struct s5p_mfc_buf *temp_vb;
> +
> +	/* Initializing decoding - parsing header */
> +	spin_lock_irqsave(&dev->irqlock, flags);
> +	mfc_debug("Preparing to init decoding.\n");
> +	temp_vb = list_entry(ctx->src_queue.next, struct s5p_mfc_buf, list);
> +	s5p_mfc_set_dec_desc_buffer(ctx);
> +	mfc_debug("Header size: %d\n", temp_vb->b-
> >v4l2_planes[0].bytesused);
> +	s5p_mfc_set_dec_stream_buffer(ctx, s5p_mfc_plane_addr(temp_vb->b,
> 0),
> +				0, temp_vb->b->v4l2_planes[0].bytesused);
> +	spin_unlock_irqrestore(&dev->irqlock, flags);
> +	dev->curr_ctx = ctx->num;
> +	mfc_debug("paddr: %08x\n",
> +			(int)phys_to_virt(s5p_mfc_plane_addr(temp_vb->b,
0)));
> +	s5p_mfc_clean_ctx_int_flags(ctx);
> +	s5p_mfc_init_decode(ctx);
> +}
> +
> +static inline int s5p_mfc_run_init_dec_buffers(struct s5p_mfc_ctx *ctx)
> +{
> +	struct s5p_mfc_dev *dev = ctx->dev;
> +	unsigned long flags;
> +	struct s5p_mfc_buf *temp_vb;
> +	int ret;
> +	/* Header was parsed now starting processing
> +	 * First set the output frame buffers
> +	 * s5p_mfc_alloc_dec_buffers(ctx); */
> +
> +	if (ctx->capture_state != QUEUE_BUFS_MMAPED) {
> +		mfc_err("It seems that not all destionation buffers were "
> +			"mmaped.\nMFC requires that all destination are
mmaped
> "
> +			"before starting processing.\n");
> +		return -EAGAIN;
> +	}
> +
> +	spin_lock_irqsave(&dev->irqlock, flags);
> +
> +	if (list_empty(&ctx->src_queue)) {
> +		mfc_err("Header has been deallocated in the middle of "
>
+							"initialization.\n")
;
> +		spin_unlock_irqrestore(&dev->irqlock, flags);
> +		return -EIO;
> +	}
> +
> +	temp_vb = list_entry(ctx->src_queue.next, struct s5p_mfc_buf, list);
> +	mfc_debug("Header size: %d\n", temp_vb->b-
> >v4l2_planes[0].bytesused);
> +	s5p_mfc_set_dec_stream_buffer(ctx, s5p_mfc_plane_addr(temp_vb->b,
> 0),
> +				0, temp_vb->b->v4l2_planes[0].bytesused);
> +	spin_unlock_irqrestore(&dev->irqlock, flags);
> +	dev->curr_ctx = ctx->num;
> +	s5p_mfc_clean_ctx_int_flags(ctx);
> +	ret = s5p_mfc_set_dec_frame_buffer(ctx);
> +	if (ret) {
> +		mfc_err("Failed to alloc frame mem.\n");
> +		ctx->state = MFCINST_DEC_ERROR;
> +	}
> +	return ret;
> +}

snipping

> +/* Set registers for decoding stream buffer */
> +int s5p_mfc_set_dec_stream_buffer(struct s5p_mfc_ctx *ctx, int buf_addr,
> +		  unsigned int start_num_byte, unsigned int buf_size)
> +{
> +	struct s5p_mfc_dev *dev = ctx->dev;
> +
> +	mfc_debug_enter();
> +	mfc_debug("inst_no: %d, buf_addr: 0x%08x, buf_size: 0x"
> +		"%08x (%d)\n",  ctx->inst_no, buf_addr, buf_size, buf_size);
> +	WRITEL(OFFSETA(buf_addr), S5P_FIMV_SI_CH0_SB_ST_ADR);
> +	WRITEL(CPB_BUF_SIZE, S5P_FIMV_SI_CH0_CPB_SIZE);
> +	WRITEL(buf_size, S5P_FIMV_SI_CH0_SB_FRM_SIZE);
> +	mfc_debug("Shared_virt: %p (start offset: %d)\n",
> +					ctx->shared_virt, start_num_byte);
> +	s5p_mfc_set_start_num(ctx, start_num_byte);
> +	mfc_debug_leave();
> +	return 0;
> +}
> +
> 
Snipping

> --
> 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

--
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