diff mbox

[v3,03/16] media: coda: fix IRAM/AXI handling for i.MX53

Message ID 1346400670-16002-4-git-send-email-p.zabel@pengutronix.de (mailing list archive)
State New, archived
Headers show

Commit Message

Philipp Zabel Aug. 31, 2012, 8:10 a.m. UTC
This uses the ARCH_MXC specific iram_alloc API to allocate a work
buffer in the SoC's on-chip SRAM and sets up the AXI_SRAM_USE
register. In the future, the allocation will be converted to use
the genalloc API.

Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
---
 drivers/media/platform/Kconfig |    3 ++-
 drivers/media/platform/coda.c  |   51 ++++++++++++++++++++++++++++++++++++----
 drivers/media/platform/coda.h  |   21 +++++++++++++----
 3 files changed, 66 insertions(+), 9 deletions(-)

Comments

Javier Martin Sept. 3, 2012, 7:27 a.m. UTC | #1
Hi Philipp,

On 31 August 2012 10:10, Philipp Zabel <p.zabel@pengutronix.de> wrote:
> This uses the ARCH_MXC specific iram_alloc API to allocate a work
> buffer in the SoC's on-chip SRAM and sets up the AXI_SRAM_USE
> register. In the future, the allocation will be converted to use
> the genalloc API.
>
> Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
> ---
>  drivers/media/platform/Kconfig |    3 ++-
>  drivers/media/platform/coda.c  |   51 ++++++++++++++++++++++++++++++++++++----
>  drivers/media/platform/coda.h  |   21 +++++++++++++----
>  3 files changed, 66 insertions(+), 9 deletions(-)
>
> diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig
> index d4c034d..76f9a8f 100644
> --- a/drivers/media/platform/Kconfig
> +++ b/drivers/media/platform/Kconfig
> @@ -130,9 +130,10 @@ if V4L_MEM2MEM_DRIVERS
>
>  config VIDEO_CODA
>         tristate "Chips&Media Coda multi-standard codec IP"
> -       depends on VIDEO_DEV && VIDEO_V4L2
> +       depends on VIDEO_DEV && VIDEO_V4L2 && ARCH_MXC
>         select VIDEOBUF2_DMA_CONTIG
>         select V4L2_MEM2MEM_DEV
> +       select IRAM_ALLOC if SOC_IMX53
>         ---help---
>            Coda is a range of video codec IPs that supports
>            H.264, MPEG-4, and other video formats.
> diff --git a/drivers/media/platform/coda.c b/drivers/media/platform/coda.c
> index 8ec2ff4..5c06bc1 100644
> --- a/drivers/media/platform/coda.c
> +++ b/drivers/media/platform/coda.c
> @@ -24,6 +24,7 @@
>  #include <linux/videodev2.h>
>  #include <linux/of.h>
>
> +#include <mach/iram.h>
>  #include <media/v4l2-ctrls.h>
>  #include <media/v4l2-device.h>
>  #include <media/v4l2-ioctl.h>
> @@ -42,6 +43,7 @@
>  #define CODA7_WORK_BUF_SIZE    (512 * 1024 + CODA_FMO_BUF_SIZE * 8 * 1024)
>  #define CODA_PARA_BUF_SIZE     (10 * 1024)
>  #define CODA_ISRAM_SIZE        (2048 * 2)
> +#define CODA7_IRAM_SIZE                0x14000 /* 81920 bytes */
>
>  #define CODA_OUTPUT_BUFS       4
>  #define CODA_CAPTURE_BUFS      2
> @@ -127,6 +129,8 @@ struct coda_dev {
>
>         struct coda_aux_buf     codebuf;
>         struct coda_aux_buf     workbuf;
> +       long unsigned int       iram_vaddr;
> +       long unsigned int       iram_paddr;
>
>         spinlock_t              irqlock;
>         struct mutex            dev_mutex;
> @@ -710,6 +714,13 @@ static void coda_device_run(void *m2m_priv)
>         coda_write(dev, pic_stream_buffer_addr, CODA_CMD_ENC_PIC_BB_START);
>         coda_write(dev, pic_stream_buffer_size / 1024,
>                    CODA_CMD_ENC_PIC_BB_SIZE);
> +
> +       if (dev->devtype->product == CODA_7541) {
> +               coda_write(dev, CODA7_USE_BIT_ENABLE | CODA7_USE_HOST_BIT_ENABLE |
> +                               CODA7_USE_ME_ENABLE | CODA7_USE_HOST_ME_ENABLE,
> +                               CODA7_REG_BIT_AXI_SRAM_USE);
> +       }
> +
>         coda_command_async(ctx, CODA_COMMAND_PIC_RUN);
>  }
>
> @@ -941,8 +952,10 @@ static int coda_start_streaming(struct vb2_queue *q, unsigned int count)
>                         CODA7_STREAM_BUF_PIC_RESET, CODA_REG_BIT_STREAM_CTRL);
>         }
>
> -       /* Configure the coda */
> -       coda_write(dev, 0xffff4c00, CODA_REG_BIT_SEARCH_RAM_BASE_ADDR);
> +       if (dev->devtype->product == CODA_DX6) {
> +               /* Configure the coda */
> +               coda_write(dev, dev->iram_paddr, CODADX6_REG_BIT_SEARCH_RAM_BASE_ADDR);
> +       }
>
>         /* Could set rotation here if needed */
>         switch (dev->devtype->product) {
> @@ -1017,7 +1030,12 @@ static int coda_start_streaming(struct vb2_queue *q, unsigned int count)
>                 value  = (FMO_SLICE_SAVE_BUF_SIZE << 7);
>                 value |= (0 & CODA_FMOPARAM_TYPE_MASK) << CODA_FMOPARAM_TYPE_OFFSET;
>                 value |=  0 & CODA_FMOPARAM_SLICENUM_MASK;
> -               coda_write(dev, value, CODA_CMD_ENC_SEQ_FMO);
> +               if (dev->devtype->product == CODA_DX6) {
> +                       coda_write(dev, value, CODADX6_CMD_ENC_SEQ_FMO);
> +               } else {
> +                       coda_write(dev, dev->iram_paddr, CODA7_CMD_ENC_SEQ_SEARCH_BASE);
> +                       coda_write(dev, 48 * 1024, CODA7_CMD_ENC_SEQ_SEARCH_SIZE);
> +               }
>         }
>
>         if (coda_command_sync(ctx, CODA_COMMAND_SEQ_INIT)) {
> @@ -1047,7 +1065,15 @@ static int coda_start_streaming(struct vb2_queue *q, unsigned int count)
>         }
>
>         coda_write(dev, src_vq->num_buffers, CODA_CMD_SET_FRAME_BUF_NUM);
> -       coda_write(dev, q_data_src->width, CODA_CMD_SET_FRAME_BUF_STRIDE);
> +       coda_write(dev, round_up(q_data_src->width, 8), CODA_CMD_SET_FRAME_BUF_STRIDE);
> +       if (dev->devtype->product != CODA_DX6) {
> +               coda_write(dev, round_up(q_data_src->width, 8), CODA7_CMD_SET_FRAME_SOURCE_BUF_STRIDE);
> +               coda_write(dev, dev->iram_paddr + 48 * 1024, CODA7_CMD_SET_FRAME_AXI_DBKY_ADDR);
> +               coda_write(dev, dev->iram_paddr + 53 * 1024, CODA7_CMD_SET_FRAME_AXI_DBKC_ADDR);
> +               coda_write(dev, dev->iram_paddr + 58 * 1024, CODA7_CMD_SET_FRAME_AXI_BIT_ADDR);
> +               coda_write(dev, dev->iram_paddr + 68 * 1024, CODA7_CMD_SET_FRAME_AXI_IPACDC_ADDR);
> +               coda_write(dev, 0x0, CODA7_CMD_SET_FRAME_AXI_OVL_ADDR);
> +       }
>         if (coda_command_sync(ctx, CODA_COMMAND_SET_FRAME_BUF)) {
>                 v4l2_err(v4l2_dev, "CODA_COMMAND_SET_FRAME_BUF timeout\n");
>                 return -ETIMEDOUT;
> @@ -1580,6 +1606,10 @@ static int coda_hw_init(struct coda_dev *dev)
>                 coda_write(dev, CODA7_STREAM_BUF_PIC_FLUSH, CODA_REG_BIT_STREAM_CTRL);
>         }
>         coda_write(dev, 0, CODA_REG_BIT_FRAME_MEM_CTRL);
> +
> +       if (dev->devtype->product != CODA_DX6)
> +               coda_write(dev, 0, CODA7_REG_BIT_AXI_SRAM_USE);
> +
>         coda_write(dev, CODA_INT_INTERRUPT_ENABLE,
>                       CODA_REG_BIT_INT_ENABLE);
>
> @@ -1848,6 +1878,17 @@ static int __devinit coda_probe(struct platform_device *pdev)
>                 return -ENOMEM;
>         }
>
> +       if (dev->devtype->product == CODA_DX6) {
> +               dev->iram_paddr = 0xffff4c00;
> +       } else {
> +               dev->iram_vaddr = iram_alloc(CODA7_IRAM_SIZE,
> +                                            &dev->iram_paddr);

This leads to a warning at compile time:
  CC      drivers/media/platform/coda.o
drivers/media/platform/coda.c: In function 'coda_probe':
drivers/media/platform/coda.c:1884: warning: assignment makes integer
from pointer without a cast

Maybe you should add an explicit cast:
dev->iram_vaddr = (unsigned long int)iram_alloc(CODA7_IRAM_SIZE,
                                            &dev->iram_paddr);

> +               if (!dev->iram_vaddr) {
> +                       dev_err(&pdev->dev, "unable to alloc iram\n");
> +                       return -ENOMEM;
> +               }
> +       }
> +
>         platform_set_drvdata(pdev, dev);
>
>         return coda_firmware_request(dev);
> @@ -1863,6 +1904,8 @@ static int coda_remove(struct platform_device *pdev)
>         if (dev->alloc_ctx)
>                 vb2_dma_contig_cleanup_ctx(dev->alloc_ctx);
>         v4l2_device_unregister(&dev->v4l2_dev);
> +       if (dev->iram_vaddr)
> +               iram_free(dev->iram_vaddr, CODA7_IRAM_SIZE);
>         if (dev->codebuf.vaddr)
>                 dma_free_coherent(&pdev->dev, dev->codebuf.size,
>                                   &dev->codebuf.vaddr, dev->codebuf.paddr);
> diff --git a/drivers/media/platform/coda.h b/drivers/media/platform/coda.h
> index 3fbb315..3324010 100644
> --- a/drivers/media/platform/coda.h
> +++ b/drivers/media/platform/coda.h
> @@ -45,7 +45,12 @@
>  #define                CODA_IMAGE_ENDIAN_SELECT        (1 << 0)
>  #define CODA_REG_BIT_RD_PTR(x)                 (0x120 + 8 * (x))
>  #define CODA_REG_BIT_WR_PTR(x)                 (0x124 + 8 * (x))
> -#define CODA_REG_BIT_SEARCH_RAM_BASE_ADDR      0x140
> +#define CODADX6_REG_BIT_SEARCH_RAM_BASE_ADDR   0x140
> +#define CODA7_REG_BIT_AXI_SRAM_USE             0x140
> +#define                CODA7_USE_BIT_ENABLE            (1 << 0)
> +#define                CODA7_USE_HOST_BIT_ENABLE       (1 << 7)
> +#define                CODA7_USE_ME_ENABLE             (1 << 4)
> +#define                CODA7_USE_HOST_ME_ENABLE        (1 << 11)
>  #define CODA_REG_BIT_BUSY                      0x160
>  #define                CODA_REG_BIT_BUSY_FLAG          1
>  #define CODA_REG_BIT_RUN_COMMAND               0x164
> @@ -162,11 +167,13 @@
>  #define                CODA_RATECONTROL_ENABLE_MASK                    0x01
>  #define CODA_CMD_ENC_SEQ_RC_BUF_SIZE                           0x1b0
>  #define CODA_CMD_ENC_SEQ_INTRA_REFRESH                         0x1b4
> -#define CODA_CMD_ENC_SEQ_FMO                                   0x1b8
> +#define CODADX6_CMD_ENC_SEQ_FMO                                        0x1b8
>  #define                CODA_FMOPARAM_TYPE_OFFSET                       4
>  #define                CODA_FMOPARAM_TYPE_MASK                         1
>  #define                CODA_FMOPARAM_SLICENUM_OFFSET                   0
>  #define                CODA_FMOPARAM_SLICENUM_MASK                     0x0f
> +#define CODA7_CMD_ENC_SEQ_SEARCH_BASE                          0x1b8
> +#define CODA7_CMD_ENC_SEQ_SEARCH_SIZE                          0x1bc
>  #define CODA_CMD_ENC_SEQ_RC_QP_MAX                             0x1c8
>  #define                CODA_QPMAX_OFFSET                               0
>  #define                CODA_QPMAX_MASK                                 0x3f
> @@ -189,8 +196,14 @@
>  #define CODA_RET_ENC_PIC_FLAG          0x1d0
>
>  /* Set Frame Buffer */
> -#define CODA_CMD_SET_FRAME_BUF_NUM     0x180
> -#define CODA_CMD_SET_FRAME_BUF_STRIDE  0x184
> +#define CODA_CMD_SET_FRAME_BUF_NUM             0x180
> +#define CODA_CMD_SET_FRAME_BUF_STRIDE          0x184
> +#define CODA7_CMD_SET_FRAME_AXI_BIT_ADDR       0x190
> +#define CODA7_CMD_SET_FRAME_AXI_IPACDC_ADDR    0x194
> +#define CODA7_CMD_SET_FRAME_AXI_DBKY_ADDR      0x198
> +#define CODA7_CMD_SET_FRAME_AXI_DBKC_ADDR      0x19c
> +#define CODA7_CMD_SET_FRAME_AXI_OVL_ADDR       0x1a0
> +#define CODA7_CMD_SET_FRAME_SOURCE_BUF_STRIDE  0x1a8
>
>  /* Encoder Header */
>  #define CODA_CMD_ENC_HEADER_CODE       0x180
> --
> 1.7.10.4
>

Regards.
Richard Zhao Sept. 10, 2012, 8:20 a.m. UTC | #2
On Fri, Aug 31, 2012 at 10:10:57AM +0200, Philipp Zabel wrote:
> This uses the ARCH_MXC specific iram_alloc API to allocate a work
> buffer in the SoC's on-chip SRAM and sets up the AXI_SRAM_USE
> register. In the future, the allocation will be converted to use
> the genalloc API.
> 
> Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
> ---
>  drivers/media/platform/Kconfig |    3 ++-
>  drivers/media/platform/coda.c  |   51 ++++++++++++++++++++++++++++++++++++----
>  drivers/media/platform/coda.h  |   21 +++++++++++++----
>  3 files changed, 66 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig
> index d4c034d..76f9a8f 100644
> --- a/drivers/media/platform/Kconfig
> +++ b/drivers/media/platform/Kconfig
> @@ -130,9 +130,10 @@ if V4L_MEM2MEM_DRIVERS
>  
>  config VIDEO_CODA
>  	tristate "Chips&Media Coda multi-standard codec IP"
> -	depends on VIDEO_DEV && VIDEO_V4L2
> +	depends on VIDEO_DEV && VIDEO_V4L2 && ARCH_MXC
>  	select VIDEOBUF2_DMA_CONTIG
>  	select V4L2_MEM2MEM_DEV
> +	select IRAM_ALLOC if SOC_IMX53
>  	---help---
>  	   Coda is a range of video codec IPs that supports
>  	   H.264, MPEG-4, and other video formats.
> diff --git a/drivers/media/platform/coda.c b/drivers/media/platform/coda.c
> index 8ec2ff4..5c06bc1 100644
> --- a/drivers/media/platform/coda.c
> +++ b/drivers/media/platform/coda.c
> @@ -24,6 +24,7 @@
>  #include <linux/videodev2.h>
>  #include <linux/of.h>
>  
> +#include <mach/iram.h>
>  #include <media/v4l2-ctrls.h>
>  #include <media/v4l2-device.h>
>  #include <media/v4l2-ioctl.h>
> @@ -42,6 +43,7 @@
>  #define CODA7_WORK_BUF_SIZE	(512 * 1024 + CODA_FMO_BUF_SIZE * 8 * 1024)
>  #define CODA_PARA_BUF_SIZE	(10 * 1024)
>  #define CODA_ISRAM_SIZE	(2048 * 2)
> +#define CODA7_IRAM_SIZE		0x14000 /* 81920 bytes */
>  
>  #define CODA_OUTPUT_BUFS	4
>  #define CODA_CAPTURE_BUFS	2
> @@ -127,6 +129,8 @@ struct coda_dev {
>  
>  	struct coda_aux_buf	codebuf;
>  	struct coda_aux_buf	workbuf;
> +	long unsigned int	iram_vaddr;
should be void __iomem * ?
> +	long unsigned int	iram_paddr;
>  
>  	spinlock_t		irqlock;
>  	struct mutex		dev_mutex;
> @@ -710,6 +714,13 @@ static void coda_device_run(void *m2m_priv)
>  	coda_write(dev, pic_stream_buffer_addr, CODA_CMD_ENC_PIC_BB_START);
>  	coda_write(dev, pic_stream_buffer_size / 1024,
>  		   CODA_CMD_ENC_PIC_BB_SIZE);
> +
> +	if (dev->devtype->product == CODA_7541) {
> +		coda_write(dev, CODA7_USE_BIT_ENABLE | CODA7_USE_HOST_BIT_ENABLE |
> +				CODA7_USE_ME_ENABLE | CODA7_USE_HOST_ME_ENABLE,
> +				CODA7_REG_BIT_AXI_SRAM_USE);
> +	}
> +
>  	coda_command_async(ctx, CODA_COMMAND_PIC_RUN);
>  }
>  
> @@ -941,8 +952,10 @@ static int coda_start_streaming(struct vb2_queue *q, unsigned int count)
>  			CODA7_STREAM_BUF_PIC_RESET, CODA_REG_BIT_STREAM_CTRL);
>  	}
>  
> -	/* Configure the coda */
> -	coda_write(dev, 0xffff4c00, CODA_REG_BIT_SEARCH_RAM_BASE_ADDR);
> +	if (dev->devtype->product == CODA_DX6) {
> +		/* Configure the coda */
> +		coda_write(dev, dev->iram_paddr, CODADX6_REG_BIT_SEARCH_RAM_BASE_ADDR);
> +	}
>  
>  	/* Could set rotation here if needed */
>  	switch (dev->devtype->product) {
> @@ -1017,7 +1030,12 @@ static int coda_start_streaming(struct vb2_queue *q, unsigned int count)
>  		value  = (FMO_SLICE_SAVE_BUF_SIZE << 7);
>  		value |= (0 & CODA_FMOPARAM_TYPE_MASK) << CODA_FMOPARAM_TYPE_OFFSET;
>  		value |=  0 & CODA_FMOPARAM_SLICENUM_MASK;
> -		coda_write(dev, value, CODA_CMD_ENC_SEQ_FMO);
> +		if (dev->devtype->product == CODA_DX6) {
> +			coda_write(dev, value, CODADX6_CMD_ENC_SEQ_FMO);
> +		} else {
> +			coda_write(dev, dev->iram_paddr, CODA7_CMD_ENC_SEQ_SEARCH_BASE);
> +			coda_write(dev, 48 * 1024, CODA7_CMD_ENC_SEQ_SEARCH_SIZE);
> +		}
>  	}
>  
>  	if (coda_command_sync(ctx, CODA_COMMAND_SEQ_INIT)) {
> @@ -1047,7 +1065,15 @@ static int coda_start_streaming(struct vb2_queue *q, unsigned int count)
>  	}
>  
>  	coda_write(dev, src_vq->num_buffers, CODA_CMD_SET_FRAME_BUF_NUM);
> -	coda_write(dev, q_data_src->width, CODA_CMD_SET_FRAME_BUF_STRIDE);
> +	coda_write(dev, round_up(q_data_src->width, 8), CODA_CMD_SET_FRAME_BUF_STRIDE);
> +	if (dev->devtype->product != CODA_DX6) {
> +		coda_write(dev, round_up(q_data_src->width, 8), CODA7_CMD_SET_FRAME_SOURCE_BUF_STRIDE);
> +		coda_write(dev, dev->iram_paddr + 48 * 1024, CODA7_CMD_SET_FRAME_AXI_DBKY_ADDR);
> +		coda_write(dev, dev->iram_paddr + 53 * 1024, CODA7_CMD_SET_FRAME_AXI_DBKC_ADDR);
> +		coda_write(dev, dev->iram_paddr + 58 * 1024, CODA7_CMD_SET_FRAME_AXI_BIT_ADDR);
> +		coda_write(dev, dev->iram_paddr + 68 * 1024, CODA7_CMD_SET_FRAME_AXI_IPACDC_ADDR);
> +		coda_write(dev, 0x0, CODA7_CMD_SET_FRAME_AXI_OVL_ADDR);
> +	}
>  	if (coda_command_sync(ctx, CODA_COMMAND_SET_FRAME_BUF)) {
>  		v4l2_err(v4l2_dev, "CODA_COMMAND_SET_FRAME_BUF timeout\n");
>  		return -ETIMEDOUT;
> @@ -1580,6 +1606,10 @@ static int coda_hw_init(struct coda_dev *dev)
>  		coda_write(dev, CODA7_STREAM_BUF_PIC_FLUSH, CODA_REG_BIT_STREAM_CTRL);
>  	}
>  	coda_write(dev, 0, CODA_REG_BIT_FRAME_MEM_CTRL);
> +
> +	if (dev->devtype->product != CODA_DX6)
> +		coda_write(dev, 0, CODA7_REG_BIT_AXI_SRAM_USE);
> +
>  	coda_write(dev, CODA_INT_INTERRUPT_ENABLE,
>  		      CODA_REG_BIT_INT_ENABLE);
>  
> @@ -1848,6 +1878,17 @@ static int __devinit coda_probe(struct platform_device *pdev)
>  		return -ENOMEM;
>  	}
>  
> +	if (dev->devtype->product == CODA_DX6) {
> +		dev->iram_paddr = 0xffff4c00;
> +	} else {
> +		dev->iram_vaddr = iram_alloc(CODA7_IRAM_SIZE,
> +					     &dev->iram_paddr);
There will be no build warning if iram_vaddr is void __iomem *.
> +		if (!dev->iram_vaddr) {
> +			dev_err(&pdev->dev, "unable to alloc iram\n");
> +			return -ENOMEM;
> +		}
> +	}
> +
>  	platform_set_drvdata(pdev, dev);
>  
>  	return coda_firmware_request(dev);
> @@ -1863,6 +1904,8 @@ static int coda_remove(struct platform_device *pdev)
>  	if (dev->alloc_ctx)
>  		vb2_dma_contig_cleanup_ctx(dev->alloc_ctx);
>  	v4l2_device_unregister(&dev->v4l2_dev);
> +	if (dev->iram_vaddr)
> +		iram_free(dev->iram_vaddr, CODA7_IRAM_SIZE);
It should be freed by paddr.

Thanks
Richard
>  	if (dev->codebuf.vaddr)
>  		dma_free_coherent(&pdev->dev, dev->codebuf.size,
>  				  &dev->codebuf.vaddr, dev->codebuf.paddr);
> diff --git a/drivers/media/platform/coda.h b/drivers/media/platform/coda.h
> index 3fbb315..3324010 100644
> --- a/drivers/media/platform/coda.h
> +++ b/drivers/media/platform/coda.h
> @@ -45,7 +45,12 @@
>  #define		CODA_IMAGE_ENDIAN_SELECT	(1 << 0)
>  #define CODA_REG_BIT_RD_PTR(x)			(0x120 + 8 * (x))
>  #define CODA_REG_BIT_WR_PTR(x)			(0x124 + 8 * (x))
> -#define CODA_REG_BIT_SEARCH_RAM_BASE_ADDR	0x140
> +#define CODADX6_REG_BIT_SEARCH_RAM_BASE_ADDR	0x140
> +#define CODA7_REG_BIT_AXI_SRAM_USE		0x140
> +#define		CODA7_USE_BIT_ENABLE		(1 << 0)
> +#define		CODA7_USE_HOST_BIT_ENABLE	(1 << 7)
> +#define		CODA7_USE_ME_ENABLE		(1 << 4)
> +#define		CODA7_USE_HOST_ME_ENABLE	(1 << 11)
>  #define CODA_REG_BIT_BUSY			0x160
>  #define		CODA_REG_BIT_BUSY_FLAG		1
>  #define CODA_REG_BIT_RUN_COMMAND		0x164
> @@ -162,11 +167,13 @@
>  #define		CODA_RATECONTROL_ENABLE_MASK			0x01
>  #define CODA_CMD_ENC_SEQ_RC_BUF_SIZE				0x1b0
>  #define CODA_CMD_ENC_SEQ_INTRA_REFRESH				0x1b4
> -#define CODA_CMD_ENC_SEQ_FMO					0x1b8
> +#define CODADX6_CMD_ENC_SEQ_FMO					0x1b8
>  #define		CODA_FMOPARAM_TYPE_OFFSET			4
>  #define		CODA_FMOPARAM_TYPE_MASK				1
>  #define		CODA_FMOPARAM_SLICENUM_OFFSET			0
>  #define		CODA_FMOPARAM_SLICENUM_MASK			0x0f
> +#define CODA7_CMD_ENC_SEQ_SEARCH_BASE				0x1b8
> +#define CODA7_CMD_ENC_SEQ_SEARCH_SIZE				0x1bc
>  #define CODA_CMD_ENC_SEQ_RC_QP_MAX				0x1c8
>  #define		CODA_QPMAX_OFFSET				0
>  #define		CODA_QPMAX_MASK					0x3f
> @@ -189,8 +196,14 @@
>  #define CODA_RET_ENC_PIC_FLAG		0x1d0
>  
>  /* Set Frame Buffer */
> -#define CODA_CMD_SET_FRAME_BUF_NUM	0x180
> -#define CODA_CMD_SET_FRAME_BUF_STRIDE	0x184
> +#define CODA_CMD_SET_FRAME_BUF_NUM		0x180
> +#define CODA_CMD_SET_FRAME_BUF_STRIDE		0x184
> +#define CODA7_CMD_SET_FRAME_AXI_BIT_ADDR	0x190
> +#define CODA7_CMD_SET_FRAME_AXI_IPACDC_ADDR	0x194
> +#define CODA7_CMD_SET_FRAME_AXI_DBKY_ADDR	0x198
> +#define CODA7_CMD_SET_FRAME_AXI_DBKC_ADDR	0x19c
> +#define CODA7_CMD_SET_FRAME_AXI_OVL_ADDR	0x1a0
> +#define CODA7_CMD_SET_FRAME_SOURCE_BUF_STRIDE	0x1a8
>  
>  /* Encoder Header */
>  #define CODA_CMD_ENC_HEADER_CODE	0x180
> -- 
> 1.7.10.4
> 
> 

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Philipp Zabel Sept. 10, 2012, 8:54 a.m. UTC | #3
Hi Richard,

thank you for your comments.

Am Montag, den 10.09.2012, 16:20 +0800 schrieb Richard Zhao:
> On Fri, Aug 31, 2012 at 10:10:57AM +0200, Philipp Zabel wrote:
> > This uses the ARCH_MXC specific iram_alloc API to allocate a work
> > buffer in the SoC's on-chip SRAM and sets up the AXI_SRAM_USE
> > register. In the future, the allocation will be converted to use
> > the genalloc API.
> > 
> > Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
> > ---
> >  drivers/media/platform/Kconfig |    3 ++-
> >  drivers/media/platform/coda.c  |   51 ++++++++++++++++++++++++++++++++++++----
> >  drivers/media/platform/coda.h  |   21 +++++++++++++----
> >  3 files changed, 66 insertions(+), 9 deletions(-)
> > 
> > diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig
> > index d4c034d..76f9a8f 100644
> > --- a/drivers/media/platform/Kconfig
> > +++ b/drivers/media/platform/Kconfig
> > @@ -130,9 +130,10 @@ if V4L_MEM2MEM_DRIVERS
> >  
> >  config VIDEO_CODA
> >  	tristate "Chips&Media Coda multi-standard codec IP"
> > -	depends on VIDEO_DEV && VIDEO_V4L2
> > +	depends on VIDEO_DEV && VIDEO_V4L2 && ARCH_MXC
> >  	select VIDEOBUF2_DMA_CONTIG
> >  	select V4L2_MEM2MEM_DEV
> > +	select IRAM_ALLOC if SOC_IMX53
> >  	---help---
> >  	   Coda is a range of video codec IPs that supports
> >  	   H.264, MPEG-4, and other video formats.
> > diff --git a/drivers/media/platform/coda.c b/drivers/media/platform/coda.c
> > index 8ec2ff4..5c06bc1 100644
> > --- a/drivers/media/platform/coda.c
> > +++ b/drivers/media/platform/coda.c
> > @@ -24,6 +24,7 @@
> >  #include <linux/videodev2.h>
> >  #include <linux/of.h>
> >  
> > +#include <mach/iram.h>
> >  #include <media/v4l2-ctrls.h>
> >  #include <media/v4l2-device.h>
> >  #include <media/v4l2-ioctl.h>
> > @@ -42,6 +43,7 @@
> >  #define CODA7_WORK_BUF_SIZE	(512 * 1024 + CODA_FMO_BUF_SIZE * 8 * 1024)
> >  #define CODA_PARA_BUF_SIZE	(10 * 1024)
> >  #define CODA_ISRAM_SIZE	(2048 * 2)
> > +#define CODA7_IRAM_SIZE		0x14000 /* 81920 bytes */
> >  
> >  #define CODA_OUTPUT_BUFS	4
> >  #define CODA_CAPTURE_BUFS	2
> > @@ -127,6 +129,8 @@ struct coda_dev {
> >  
> >  	struct coda_aux_buf	codebuf;
> >  	struct coda_aux_buf	workbuf;
> > +	long unsigned int	iram_vaddr;
> should be void __iomem * ?

I wrote this with the genalloc API in mind: gen_pool_alloc returns an
unsigned long. We are not accessing this memory from the CPU, so
iram_vaddr could just as well be an opaque token that only needs to be
remembered for gen_pool_free.
For the iram_alloc API in its current state, as you point out below,
keeping track of iram_vaddr is not needed.

> > +	long unsigned int	iram_paddr;
> >  
> >  	spinlock_t		irqlock;
> >  	struct mutex		dev_mutex;
> > @@ -710,6 +714,13 @@ static void coda_device_run(void *m2m_priv)
> >  	coda_write(dev, pic_stream_buffer_addr, CODA_CMD_ENC_PIC_BB_START);
> >  	coda_write(dev, pic_stream_buffer_size / 1024,
> >  		   CODA_CMD_ENC_PIC_BB_SIZE);
> > +
> > +	if (dev->devtype->product == CODA_7541) {
> > +		coda_write(dev, CODA7_USE_BIT_ENABLE | CODA7_USE_HOST_BIT_ENABLE |
> > +				CODA7_USE_ME_ENABLE | CODA7_USE_HOST_ME_ENABLE,
> > +				CODA7_REG_BIT_AXI_SRAM_USE);
> > +	}
> > +
> >  	coda_command_async(ctx, CODA_COMMAND_PIC_RUN);
> >  }
> >  
> > @@ -941,8 +952,10 @@ static int coda_start_streaming(struct vb2_queue *q, unsigned int count)
> >  			CODA7_STREAM_BUF_PIC_RESET, CODA_REG_BIT_STREAM_CTRL);
> >  	}
> >  
> > -	/* Configure the coda */
> > -	coda_write(dev, 0xffff4c00, CODA_REG_BIT_SEARCH_RAM_BASE_ADDR);
> > +	if (dev->devtype->product == CODA_DX6) {
> > +		/* Configure the coda */
> > +		coda_write(dev, dev->iram_paddr, CODADX6_REG_BIT_SEARCH_RAM_BASE_ADDR);
> > +	}
> >  
> >  	/* Could set rotation here if needed */
> >  	switch (dev->devtype->product) {
> > @@ -1017,7 +1030,12 @@ static int coda_start_streaming(struct vb2_queue *q, unsigned int count)
> >  		value  = (FMO_SLICE_SAVE_BUF_SIZE << 7);
> >  		value |= (0 & CODA_FMOPARAM_TYPE_MASK) << CODA_FMOPARAM_TYPE_OFFSET;
> >  		value |=  0 & CODA_FMOPARAM_SLICENUM_MASK;
> > -		coda_write(dev, value, CODA_CMD_ENC_SEQ_FMO);
> > +		if (dev->devtype->product == CODA_DX6) {
> > +			coda_write(dev, value, CODADX6_CMD_ENC_SEQ_FMO);
> > +		} else {
> > +			coda_write(dev, dev->iram_paddr, CODA7_CMD_ENC_SEQ_SEARCH_BASE);
> > +			coda_write(dev, 48 * 1024, CODA7_CMD_ENC_SEQ_SEARCH_SIZE);
> > +		}
> >  	}
> >  
> >  	if (coda_command_sync(ctx, CODA_COMMAND_SEQ_INIT)) {
> > @@ -1047,7 +1065,15 @@ static int coda_start_streaming(struct vb2_queue *q, unsigned int count)
> >  	}
> >  
> >  	coda_write(dev, src_vq->num_buffers, CODA_CMD_SET_FRAME_BUF_NUM);
> > -	coda_write(dev, q_data_src->width, CODA_CMD_SET_FRAME_BUF_STRIDE);
> > +	coda_write(dev, round_up(q_data_src->width, 8), CODA_CMD_SET_FRAME_BUF_STRIDE);
> > +	if (dev->devtype->product != CODA_DX6) {
> > +		coda_write(dev, round_up(q_data_src->width, 8), CODA7_CMD_SET_FRAME_SOURCE_BUF_STRIDE);
> > +		coda_write(dev, dev->iram_paddr + 48 * 1024, CODA7_CMD_SET_FRAME_AXI_DBKY_ADDR);
> > +		coda_write(dev, dev->iram_paddr + 53 * 1024, CODA7_CMD_SET_FRAME_AXI_DBKC_ADDR);
> > +		coda_write(dev, dev->iram_paddr + 58 * 1024, CODA7_CMD_SET_FRAME_AXI_BIT_ADDR);
> > +		coda_write(dev, dev->iram_paddr + 68 * 1024, CODA7_CMD_SET_FRAME_AXI_IPACDC_ADDR);
> > +		coda_write(dev, 0x0, CODA7_CMD_SET_FRAME_AXI_OVL_ADDR);
> > +	}
> >  	if (coda_command_sync(ctx, CODA_COMMAND_SET_FRAME_BUF)) {
> >  		v4l2_err(v4l2_dev, "CODA_COMMAND_SET_FRAME_BUF timeout\n");
> >  		return -ETIMEDOUT;
> > @@ -1580,6 +1606,10 @@ static int coda_hw_init(struct coda_dev *dev)
> >  		coda_write(dev, CODA7_STREAM_BUF_PIC_FLUSH, CODA_REG_BIT_STREAM_CTRL);
> >  	}
> >  	coda_write(dev, 0, CODA_REG_BIT_FRAME_MEM_CTRL);
> > +
> > +	if (dev->devtype->product != CODA_DX6)
> > +		coda_write(dev, 0, CODA7_REG_BIT_AXI_SRAM_USE);
> > +
> >  	coda_write(dev, CODA_INT_INTERRUPT_ENABLE,
> >  		      CODA_REG_BIT_INT_ENABLE);
> >  
> > @@ -1848,6 +1878,17 @@ static int __devinit coda_probe(struct platform_device *pdev)
> >  		return -ENOMEM;
> >  	}
> >  
> > +	if (dev->devtype->product == CODA_DX6) {
> > +		dev->iram_paddr = 0xffff4c00;
> > +	} else {
> > +		dev->iram_vaddr = iram_alloc(CODA7_IRAM_SIZE,
> > +					     &dev->iram_paddr);
> There will be no build warning if iram_vaddr is void __iomem *.

Ok, and I'll use a temporary variable for vaddr here.

> > +		if (!dev->iram_vaddr) {
> > +			dev_err(&pdev->dev, "unable to alloc iram\n");
> > +			return -ENOMEM;
> > +		}
> > +	}
> > +
> >  	platform_set_drvdata(pdev, dev);
> >  
> >  	return coda_firmware_request(dev);
> > @@ -1863,6 +1904,8 @@ static int coda_remove(struct platform_device *pdev)
> >  	if (dev->alloc_ctx)
> >  		vb2_dma_contig_cleanup_ctx(dev->alloc_ctx);
> >  	v4l2_device_unregister(&dev->v4l2_dev);
> > +	if (dev->iram_vaddr)
> > +		iram_free(dev->iram_vaddr, CODA7_IRAM_SIZE);
> It should be freed by paddr.

Yes. I had a patch to make iram_free take the vaddr, but Shawn suggested
to drop it and just go for genalloc support.
(see https://lkml.org/lkml/2012/9/7/281 for the last round of patches)

regards
Philipp


--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig
index d4c034d..76f9a8f 100644
--- a/drivers/media/platform/Kconfig
+++ b/drivers/media/platform/Kconfig
@@ -130,9 +130,10 @@  if V4L_MEM2MEM_DRIVERS
 
 config VIDEO_CODA
 	tristate "Chips&Media Coda multi-standard codec IP"
-	depends on VIDEO_DEV && VIDEO_V4L2
+	depends on VIDEO_DEV && VIDEO_V4L2 && ARCH_MXC
 	select VIDEOBUF2_DMA_CONTIG
 	select V4L2_MEM2MEM_DEV
+	select IRAM_ALLOC if SOC_IMX53
 	---help---
 	   Coda is a range of video codec IPs that supports
 	   H.264, MPEG-4, and other video formats.
diff --git a/drivers/media/platform/coda.c b/drivers/media/platform/coda.c
index 8ec2ff4..5c06bc1 100644
--- a/drivers/media/platform/coda.c
+++ b/drivers/media/platform/coda.c
@@ -24,6 +24,7 @@ 
 #include <linux/videodev2.h>
 #include <linux/of.h>
 
+#include <mach/iram.h>
 #include <media/v4l2-ctrls.h>
 #include <media/v4l2-device.h>
 #include <media/v4l2-ioctl.h>
@@ -42,6 +43,7 @@ 
 #define CODA7_WORK_BUF_SIZE	(512 * 1024 + CODA_FMO_BUF_SIZE * 8 * 1024)
 #define CODA_PARA_BUF_SIZE	(10 * 1024)
 #define CODA_ISRAM_SIZE	(2048 * 2)
+#define CODA7_IRAM_SIZE		0x14000 /* 81920 bytes */
 
 #define CODA_OUTPUT_BUFS	4
 #define CODA_CAPTURE_BUFS	2
@@ -127,6 +129,8 @@  struct coda_dev {
 
 	struct coda_aux_buf	codebuf;
 	struct coda_aux_buf	workbuf;
+	long unsigned int	iram_vaddr;
+	long unsigned int	iram_paddr;
 
 	spinlock_t		irqlock;
 	struct mutex		dev_mutex;
@@ -710,6 +714,13 @@  static void coda_device_run(void *m2m_priv)
 	coda_write(dev, pic_stream_buffer_addr, CODA_CMD_ENC_PIC_BB_START);
 	coda_write(dev, pic_stream_buffer_size / 1024,
 		   CODA_CMD_ENC_PIC_BB_SIZE);
+
+	if (dev->devtype->product == CODA_7541) {
+		coda_write(dev, CODA7_USE_BIT_ENABLE | CODA7_USE_HOST_BIT_ENABLE |
+				CODA7_USE_ME_ENABLE | CODA7_USE_HOST_ME_ENABLE,
+				CODA7_REG_BIT_AXI_SRAM_USE);
+	}
+
 	coda_command_async(ctx, CODA_COMMAND_PIC_RUN);
 }
 
@@ -941,8 +952,10 @@  static int coda_start_streaming(struct vb2_queue *q, unsigned int count)
 			CODA7_STREAM_BUF_PIC_RESET, CODA_REG_BIT_STREAM_CTRL);
 	}
 
-	/* Configure the coda */
-	coda_write(dev, 0xffff4c00, CODA_REG_BIT_SEARCH_RAM_BASE_ADDR);
+	if (dev->devtype->product == CODA_DX6) {
+		/* Configure the coda */
+		coda_write(dev, dev->iram_paddr, CODADX6_REG_BIT_SEARCH_RAM_BASE_ADDR);
+	}
 
 	/* Could set rotation here if needed */
 	switch (dev->devtype->product) {
@@ -1017,7 +1030,12 @@  static int coda_start_streaming(struct vb2_queue *q, unsigned int count)
 		value  = (FMO_SLICE_SAVE_BUF_SIZE << 7);
 		value |= (0 & CODA_FMOPARAM_TYPE_MASK) << CODA_FMOPARAM_TYPE_OFFSET;
 		value |=  0 & CODA_FMOPARAM_SLICENUM_MASK;
-		coda_write(dev, value, CODA_CMD_ENC_SEQ_FMO);
+		if (dev->devtype->product == CODA_DX6) {
+			coda_write(dev, value, CODADX6_CMD_ENC_SEQ_FMO);
+		} else {
+			coda_write(dev, dev->iram_paddr, CODA7_CMD_ENC_SEQ_SEARCH_BASE);
+			coda_write(dev, 48 * 1024, CODA7_CMD_ENC_SEQ_SEARCH_SIZE);
+		}
 	}
 
 	if (coda_command_sync(ctx, CODA_COMMAND_SEQ_INIT)) {
@@ -1047,7 +1065,15 @@  static int coda_start_streaming(struct vb2_queue *q, unsigned int count)
 	}
 
 	coda_write(dev, src_vq->num_buffers, CODA_CMD_SET_FRAME_BUF_NUM);
-	coda_write(dev, q_data_src->width, CODA_CMD_SET_FRAME_BUF_STRIDE);
+	coda_write(dev, round_up(q_data_src->width, 8), CODA_CMD_SET_FRAME_BUF_STRIDE);
+	if (dev->devtype->product != CODA_DX6) {
+		coda_write(dev, round_up(q_data_src->width, 8), CODA7_CMD_SET_FRAME_SOURCE_BUF_STRIDE);
+		coda_write(dev, dev->iram_paddr + 48 * 1024, CODA7_CMD_SET_FRAME_AXI_DBKY_ADDR);
+		coda_write(dev, dev->iram_paddr + 53 * 1024, CODA7_CMD_SET_FRAME_AXI_DBKC_ADDR);
+		coda_write(dev, dev->iram_paddr + 58 * 1024, CODA7_CMD_SET_FRAME_AXI_BIT_ADDR);
+		coda_write(dev, dev->iram_paddr + 68 * 1024, CODA7_CMD_SET_FRAME_AXI_IPACDC_ADDR);
+		coda_write(dev, 0x0, CODA7_CMD_SET_FRAME_AXI_OVL_ADDR);
+	}
 	if (coda_command_sync(ctx, CODA_COMMAND_SET_FRAME_BUF)) {
 		v4l2_err(v4l2_dev, "CODA_COMMAND_SET_FRAME_BUF timeout\n");
 		return -ETIMEDOUT;
@@ -1580,6 +1606,10 @@  static int coda_hw_init(struct coda_dev *dev)
 		coda_write(dev, CODA7_STREAM_BUF_PIC_FLUSH, CODA_REG_BIT_STREAM_CTRL);
 	}
 	coda_write(dev, 0, CODA_REG_BIT_FRAME_MEM_CTRL);
+
+	if (dev->devtype->product != CODA_DX6)
+		coda_write(dev, 0, CODA7_REG_BIT_AXI_SRAM_USE);
+
 	coda_write(dev, CODA_INT_INTERRUPT_ENABLE,
 		      CODA_REG_BIT_INT_ENABLE);
 
@@ -1848,6 +1878,17 @@  static int __devinit coda_probe(struct platform_device *pdev)
 		return -ENOMEM;
 	}
 
+	if (dev->devtype->product == CODA_DX6) {
+		dev->iram_paddr = 0xffff4c00;
+	} else {
+		dev->iram_vaddr = iram_alloc(CODA7_IRAM_SIZE,
+					     &dev->iram_paddr);
+		if (!dev->iram_vaddr) {
+			dev_err(&pdev->dev, "unable to alloc iram\n");
+			return -ENOMEM;
+		}
+	}
+
 	platform_set_drvdata(pdev, dev);
 
 	return coda_firmware_request(dev);
@@ -1863,6 +1904,8 @@  static int coda_remove(struct platform_device *pdev)
 	if (dev->alloc_ctx)
 		vb2_dma_contig_cleanup_ctx(dev->alloc_ctx);
 	v4l2_device_unregister(&dev->v4l2_dev);
+	if (dev->iram_vaddr)
+		iram_free(dev->iram_vaddr, CODA7_IRAM_SIZE);
 	if (dev->codebuf.vaddr)
 		dma_free_coherent(&pdev->dev, dev->codebuf.size,
 				  &dev->codebuf.vaddr, dev->codebuf.paddr);
diff --git a/drivers/media/platform/coda.h b/drivers/media/platform/coda.h
index 3fbb315..3324010 100644
--- a/drivers/media/platform/coda.h
+++ b/drivers/media/platform/coda.h
@@ -45,7 +45,12 @@ 
 #define		CODA_IMAGE_ENDIAN_SELECT	(1 << 0)
 #define CODA_REG_BIT_RD_PTR(x)			(0x120 + 8 * (x))
 #define CODA_REG_BIT_WR_PTR(x)			(0x124 + 8 * (x))
-#define CODA_REG_BIT_SEARCH_RAM_BASE_ADDR	0x140
+#define CODADX6_REG_BIT_SEARCH_RAM_BASE_ADDR	0x140
+#define CODA7_REG_BIT_AXI_SRAM_USE		0x140
+#define		CODA7_USE_BIT_ENABLE		(1 << 0)
+#define		CODA7_USE_HOST_BIT_ENABLE	(1 << 7)
+#define		CODA7_USE_ME_ENABLE		(1 << 4)
+#define		CODA7_USE_HOST_ME_ENABLE	(1 << 11)
 #define CODA_REG_BIT_BUSY			0x160
 #define		CODA_REG_BIT_BUSY_FLAG		1
 #define CODA_REG_BIT_RUN_COMMAND		0x164
@@ -162,11 +167,13 @@ 
 #define		CODA_RATECONTROL_ENABLE_MASK			0x01
 #define CODA_CMD_ENC_SEQ_RC_BUF_SIZE				0x1b0
 #define CODA_CMD_ENC_SEQ_INTRA_REFRESH				0x1b4
-#define CODA_CMD_ENC_SEQ_FMO					0x1b8
+#define CODADX6_CMD_ENC_SEQ_FMO					0x1b8
 #define		CODA_FMOPARAM_TYPE_OFFSET			4
 #define		CODA_FMOPARAM_TYPE_MASK				1
 #define		CODA_FMOPARAM_SLICENUM_OFFSET			0
 #define		CODA_FMOPARAM_SLICENUM_MASK			0x0f
+#define CODA7_CMD_ENC_SEQ_SEARCH_BASE				0x1b8
+#define CODA7_CMD_ENC_SEQ_SEARCH_SIZE				0x1bc
 #define CODA_CMD_ENC_SEQ_RC_QP_MAX				0x1c8
 #define		CODA_QPMAX_OFFSET				0
 #define		CODA_QPMAX_MASK					0x3f
@@ -189,8 +196,14 @@ 
 #define CODA_RET_ENC_PIC_FLAG		0x1d0
 
 /* Set Frame Buffer */
-#define CODA_CMD_SET_FRAME_BUF_NUM	0x180
-#define CODA_CMD_SET_FRAME_BUF_STRIDE	0x184
+#define CODA_CMD_SET_FRAME_BUF_NUM		0x180
+#define CODA_CMD_SET_FRAME_BUF_STRIDE		0x184
+#define CODA7_CMD_SET_FRAME_AXI_BIT_ADDR	0x190
+#define CODA7_CMD_SET_FRAME_AXI_IPACDC_ADDR	0x194
+#define CODA7_CMD_SET_FRAME_AXI_DBKY_ADDR	0x198
+#define CODA7_CMD_SET_FRAME_AXI_DBKC_ADDR	0x19c
+#define CODA7_CMD_SET_FRAME_AXI_OVL_ADDR	0x1a0
+#define CODA7_CMD_SET_FRAME_SOURCE_BUF_STRIDE	0x1a8
 
 /* Encoder Header */
 #define CODA_CMD_ENC_HEADER_CODE	0x180