[media] coda: simplify IRAM setup

OVL and BTP IRAM buffers are never used, setup the bits for
for DBK/BIT/IP usage depending on CODA version in one place.
Also, use a simple allocator function and group IRAM addresses
and size in a coda_aux_buf structure.
This is done in preparation for CODA960 support.

Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
Signed-off-by: Kamil Debski <k.debski@samsung.com>
Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
This commit is contained in:
Philipp Zabel 2014-07-11 06:36:16 -03:00 committed by Mauro Carvalho Chehab
parent aed14b0a62
commit b313bcc9a4

View file

@ -135,9 +135,7 @@ struct coda_dev {
struct coda_aux_buf tempbuf; struct coda_aux_buf tempbuf;
struct coda_aux_buf workbuf; struct coda_aux_buf workbuf;
struct gen_pool *iram_pool; struct gen_pool *iram_pool;
long unsigned int iram_vaddr; struct coda_aux_buf iram;
long unsigned int iram_paddr;
unsigned long iram_size;
spinlock_t irqlock; spinlock_t irqlock;
struct mutex dev_mutex; struct mutex dev_mutex;
@ -175,6 +173,8 @@ struct coda_iram_info {
phys_addr_t buf_btp_use; phys_addr_t buf_btp_use;
phys_addr_t search_ram_paddr; phys_addr_t search_ram_paddr;
int search_ram_size; int search_ram_size;
int remaining;
phys_addr_t next_paddr;
}; };
struct coda_ctx { struct coda_ctx {
@ -1578,23 +1578,43 @@ static int coda_h264_padding(int size, char *p)
return nal_size; return nal_size;
} }
static phys_addr_t coda_iram_alloc(struct coda_iram_info *iram, size_t size)
{
phys_addr_t ret;
size = round_up(size, 1024);
if (size > iram->remaining)
return 0;
iram->remaining -= size;
ret = iram->next_paddr;
iram->next_paddr += size;
return ret;
}
static void coda_setup_iram(struct coda_ctx *ctx) static void coda_setup_iram(struct coda_ctx *ctx)
{ {
struct coda_iram_info *iram_info = &ctx->iram_info; struct coda_iram_info *iram_info = &ctx->iram_info;
struct coda_dev *dev = ctx->dev; struct coda_dev *dev = ctx->dev;
int ipacdc_size;
int bitram_size;
int dbk_size;
int ovl_size;
int mb_width; int mb_width;
int me_size; int dbk_bits;
int size; int bit_bits;
int ip_bits;
memset(iram_info, 0, sizeof(*iram_info)); memset(iram_info, 0, sizeof(*iram_info));
size = dev->iram_size; iram_info->next_paddr = dev->iram.paddr;
iram_info->remaining = dev->iram.size;
if (dev->devtype->product == CODA_DX6) switch (dev->devtype->product) {
case CODA_7541:
dbk_bits = CODA7_USE_HOST_DBK_ENABLE | CODA7_USE_DBK_ENABLE;
bit_bits = CODA7_USE_HOST_BIT_ENABLE | CODA7_USE_BIT_ENABLE;
ip_bits = CODA7_USE_HOST_IP_ENABLE | CODA7_USE_IP_ENABLE;
break;
default: /* CODA_DX6 */
return; return;
}
if (ctx->inst_type == CODA_INST_ENCODER) { if (ctx->inst_type == CODA_INST_ENCODER) {
struct coda_q_data *q_data_src; struct coda_q_data *q_data_src;
@ -1603,111 +1623,63 @@ static void coda_setup_iram(struct coda_ctx *ctx)
mb_width = DIV_ROUND_UP(q_data_src->width, 16); mb_width = DIV_ROUND_UP(q_data_src->width, 16);
/* Prioritize in case IRAM is too small for everything */ /* Prioritize in case IRAM is too small for everything */
me_size = round_up(round_up(q_data_src->width, 16) * 36 + 2048, if (dev->devtype->product == CODA_7541) {
1024); iram_info->search_ram_size = round_up(mb_width * 16 *
iram_info->search_ram_size = me_size; 36 + 2048, 1024);
if (size >= iram_info->search_ram_size) { iram_info->search_ram_paddr = coda_iram_alloc(iram_info,
if (dev->devtype->product == CODA_7541) iram_info->search_ram_size);
iram_info->axi_sram_use |= CODA7_USE_HOST_ME_ENABLE; if (!iram_info->search_ram_paddr) {
iram_info->search_ram_paddr = dev->iram_paddr; pr_err("IRAM is smaller than the search ram size\n");
size -= iram_info->search_ram_size; goto out;
} else { }
pr_err("IRAM is smaller than the search ram size\n"); iram_info->axi_sram_use |= CODA7_USE_HOST_ME_ENABLE |
goto out; CODA7_USE_ME_ENABLE;
} }
/* Only H.264BP and H.263P3 are considered */ /* Only H.264BP and H.263P3 are considered */
dbk_size = round_up(128 * mb_width, 1024); iram_info->buf_dbk_y_use = coda_iram_alloc(iram_info, 64 * mb_width);
if (size >= dbk_size) { iram_info->buf_dbk_c_use = coda_iram_alloc(iram_info, 64 * mb_width);
iram_info->axi_sram_use |= CODA7_USE_HOST_DBK_ENABLE; if (!iram_info->buf_dbk_c_use)
iram_info->buf_dbk_y_use = dev->iram_paddr +
iram_info->search_ram_size;
iram_info->buf_dbk_c_use = iram_info->buf_dbk_y_use +
dbk_size / 2;
size -= dbk_size;
} else {
goto out; goto out;
} iram_info->axi_sram_use |= dbk_bits;
bitram_size = round_up(128 * mb_width, 1024); iram_info->buf_bit_use = coda_iram_alloc(iram_info, 128 * mb_width);
if (size >= bitram_size) { if (!iram_info->buf_bit_use)
iram_info->axi_sram_use |= CODA7_USE_HOST_BIT_ENABLE;
iram_info->buf_bit_use = iram_info->buf_dbk_c_use +
dbk_size / 2;
size -= bitram_size;
} else {
goto out; goto out;
} iram_info->axi_sram_use |= bit_bits;
ipacdc_size = round_up(128 * mb_width, 1024); iram_info->buf_ip_ac_dc_use = coda_iram_alloc(iram_info, 128 * mb_width);
if (size >= ipacdc_size) { if (!iram_info->buf_ip_ac_dc_use)
iram_info->axi_sram_use |= CODA7_USE_HOST_IP_ENABLE; goto out;
iram_info->buf_ip_ac_dc_use = iram_info->buf_bit_use + iram_info->axi_sram_use |= ip_bits;
bitram_size;
size -= ipacdc_size;
}
/* OVL and BTP disabled for encoder */ /* OVL and BTP disabled for encoder */
} else if (ctx->inst_type == CODA_INST_DECODER) { } else if (ctx->inst_type == CODA_INST_DECODER) {
struct coda_q_data *q_data_dst; struct coda_q_data *q_data_dst;
int mb_height;
q_data_dst = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE); q_data_dst = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
mb_width = DIV_ROUND_UP(q_data_dst->width, 16); mb_width = DIV_ROUND_UP(q_data_dst->width, 16);
mb_height = DIV_ROUND_UP(q_data_dst->height, 16);
dbk_size = round_up(256 * mb_width, 1024); iram_info->buf_dbk_y_use = coda_iram_alloc(iram_info, 128 * mb_width);
if (size >= dbk_size) { iram_info->buf_dbk_c_use = coda_iram_alloc(iram_info, 128 * mb_width);
iram_info->axi_sram_use |= CODA7_USE_HOST_DBK_ENABLE; if (!iram_info->buf_dbk_c_use)
iram_info->buf_dbk_y_use = dev->iram_paddr;
iram_info->buf_dbk_c_use = dev->iram_paddr +
dbk_size / 2;
size -= dbk_size;
} else {
goto out; goto out;
} iram_info->axi_sram_use |= dbk_bits;
bitram_size = round_up(128 * mb_width, 1024); iram_info->buf_bit_use = coda_iram_alloc(iram_info, 128 * mb_width);
if (size >= bitram_size) { if (!iram_info->buf_bit_use)
iram_info->axi_sram_use |= CODA7_USE_HOST_BIT_ENABLE;
iram_info->buf_bit_use = iram_info->buf_dbk_c_use +
dbk_size / 2;
size -= bitram_size;
} else {
goto out; goto out;
} iram_info->axi_sram_use |= bit_bits;
ipacdc_size = round_up(128 * mb_width, 1024); iram_info->buf_ip_ac_dc_use = coda_iram_alloc(iram_info, 128 * mb_width);
if (size >= ipacdc_size) { if (!iram_info->buf_ip_ac_dc_use)
iram_info->axi_sram_use |= CODA7_USE_HOST_IP_ENABLE;
iram_info->buf_ip_ac_dc_use = iram_info->buf_bit_use +
bitram_size;
size -= ipacdc_size;
} else {
goto out; goto out;
} iram_info->axi_sram_use |= ip_bits;
ovl_size = round_up(80 * mb_width, 1024); /* OVL and BTP unused as there is no VC1 support yet */
} }
out: out:
switch (dev->devtype->product) {
case CODA_DX6:
break;
case CODA_7541:
/* i.MX53 uses secondary AXI for IRAM access */
if (iram_info->axi_sram_use & CODA7_USE_HOST_BIT_ENABLE)
iram_info->axi_sram_use |= CODA7_USE_BIT_ENABLE;
if (iram_info->axi_sram_use & CODA7_USE_HOST_IP_ENABLE)
iram_info->axi_sram_use |= CODA7_USE_IP_ENABLE;
if (iram_info->axi_sram_use & CODA7_USE_HOST_DBK_ENABLE)
iram_info->axi_sram_use |= CODA7_USE_DBK_ENABLE;
if (iram_info->axi_sram_use & CODA7_USE_HOST_OVL_ENABLE)
iram_info->axi_sram_use |= CODA7_USE_OVL_ENABLE;
if (iram_info->axi_sram_use & CODA7_USE_HOST_ME_ENABLE)
iram_info->axi_sram_use |= CODA7_USE_ME_ENABLE;
}
if (!(iram_info->axi_sram_use & CODA7_USE_HOST_IP_ENABLE)) if (!(iram_info->axi_sram_use & CODA7_USE_HOST_IP_ENABLE))
v4l2_dbg(1, coda_debug, &ctx->dev->v4l2_dev, v4l2_dbg(1, coda_debug, &ctx->dev->v4l2_dev,
"IRAM smaller than needed\n"); "IRAM smaller than needed\n");
@ -2063,7 +2035,7 @@ static int coda_start_streaming(struct vb2_queue *q, unsigned int count)
if (dev->devtype->product == CODA_DX6) { if (dev->devtype->product == CODA_DX6) {
/* Configure the coda */ /* Configure the coda */
coda_write(dev, dev->iram_paddr, CODADX6_REG_BIT_SEARCH_RAM_BASE_ADDR); coda_write(dev, dev->iram.paddr, CODADX6_REG_BIT_SEARCH_RAM_BASE_ADDR);
} }
/* Could set rotation here if needed */ /* Could set rotation here if needed */
@ -3296,15 +3268,15 @@ static int coda_probe(struct platform_device *pdev)
switch (dev->devtype->product) { switch (dev->devtype->product) {
case CODA_DX6: case CODA_DX6:
dev->iram_size = CODADX6_IRAM_SIZE; dev->iram.size = CODADX6_IRAM_SIZE;
break; break;
case CODA_7541: case CODA_7541:
dev->iram_size = CODA7_IRAM_SIZE; dev->iram.size = CODA7_IRAM_SIZE;
break; break;
} }
dev->iram_vaddr = (unsigned long)gen_pool_dma_alloc(dev->iram_pool, dev->iram.vaddr = gen_pool_dma_alloc(dev->iram_pool, dev->iram.size,
dev->iram_size, (dma_addr_t *)&dev->iram_paddr); &dev->iram.paddr);
if (!dev->iram_vaddr) { if (!dev->iram.vaddr) {
dev_err(&pdev->dev, "unable to alloc iram\n"); dev_err(&pdev->dev, "unable to alloc iram\n");
return -ENOMEM; return -ENOMEM;
} }
@ -3324,8 +3296,9 @@ static int coda_remove(struct platform_device *pdev)
if (dev->alloc_ctx) if (dev->alloc_ctx)
vb2_dma_contig_cleanup_ctx(dev->alloc_ctx); vb2_dma_contig_cleanup_ctx(dev->alloc_ctx);
v4l2_device_unregister(&dev->v4l2_dev); v4l2_device_unregister(&dev->v4l2_dev);
if (dev->iram_vaddr) if (dev->iram.vaddr)
gen_pool_free(dev->iram_pool, dev->iram_vaddr, dev->iram_size); gen_pool_free(dev->iram_pool, (unsigned long)dev->iram.vaddr,
dev->iram.size);
coda_free_aux_buf(dev, &dev->codebuf); coda_free_aux_buf(dev, &dev->codebuf);
coda_free_aux_buf(dev, &dev->tempbuf); coda_free_aux_buf(dev, &dev->tempbuf);
coda_free_aux_buf(dev, &dev->workbuf); coda_free_aux_buf(dev, &dev->workbuf);