|
@@ -135,9 +135,7 @@ struct coda_dev {
|
|
|
struct coda_aux_buf tempbuf;
|
|
|
struct coda_aux_buf workbuf;
|
|
|
struct gen_pool *iram_pool;
|
|
|
- long unsigned int iram_vaddr;
|
|
|
- long unsigned int iram_paddr;
|
|
|
- unsigned long iram_size;
|
|
|
+ struct coda_aux_buf iram;
|
|
|
|
|
|
spinlock_t irqlock;
|
|
|
struct mutex dev_mutex;
|
|
@@ -175,6 +173,8 @@ struct coda_iram_info {
|
|
|
phys_addr_t buf_btp_use;
|
|
|
phys_addr_t search_ram_paddr;
|
|
|
int search_ram_size;
|
|
|
+ int remaining;
|
|
|
+ phys_addr_t next_paddr;
|
|
|
};
|
|
|
|
|
|
struct coda_ctx {
|
|
@@ -1578,23 +1578,43 @@ static int coda_h264_padding(int size, char *p)
|
|
|
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)
|
|
|
{
|
|
|
struct coda_iram_info *iram_info = &ctx->iram_info;
|
|
|
struct coda_dev *dev = ctx->dev;
|
|
|
- int ipacdc_size;
|
|
|
- int bitram_size;
|
|
|
- int dbk_size;
|
|
|
- int ovl_size;
|
|
|
int mb_width;
|
|
|
- int me_size;
|
|
|
- int size;
|
|
|
+ int dbk_bits;
|
|
|
+ int bit_bits;
|
|
|
+ int ip_bits;
|
|
|
|
|
|
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;
|
|
|
+ }
|
|
|
|
|
|
if (ctx->inst_type == CODA_INST_ENCODER) {
|
|
|
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);
|
|
|
|
|
|
/* Prioritize in case IRAM is too small for everything */
|
|
|
- me_size = round_up(round_up(q_data_src->width, 16) * 36 + 2048,
|
|
|
- 1024);
|
|
|
- iram_info->search_ram_size = me_size;
|
|
|
- if (size >= iram_info->search_ram_size) {
|
|
|
- if (dev->devtype->product == CODA_7541)
|
|
|
- iram_info->axi_sram_use |= CODA7_USE_HOST_ME_ENABLE;
|
|
|
- iram_info->search_ram_paddr = dev->iram_paddr;
|
|
|
- size -= iram_info->search_ram_size;
|
|
|
- } else {
|
|
|
- pr_err("IRAM is smaller than the search ram size\n");
|
|
|
- goto out;
|
|
|
+ if (dev->devtype->product == CODA_7541) {
|
|
|
+ iram_info->search_ram_size = round_up(mb_width * 16 *
|
|
|
+ 36 + 2048, 1024);
|
|
|
+ iram_info->search_ram_paddr = coda_iram_alloc(iram_info,
|
|
|
+ iram_info->search_ram_size);
|
|
|
+ if (!iram_info->search_ram_paddr) {
|
|
|
+ pr_err("IRAM is smaller than the search ram size\n");
|
|
|
+ goto out;
|
|
|
+ }
|
|
|
+ iram_info->axi_sram_use |= CODA7_USE_HOST_ME_ENABLE |
|
|
|
+ CODA7_USE_ME_ENABLE;
|
|
|
}
|
|
|
|
|
|
/* Only H.264BP and H.263P3 are considered */
|
|
|
- dbk_size = round_up(128 * mb_width, 1024);
|
|
|
- if (size >= dbk_size) {
|
|
|
- iram_info->axi_sram_use |= CODA7_USE_HOST_DBK_ENABLE;
|
|
|
- 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 {
|
|
|
+ iram_info->buf_dbk_y_use = coda_iram_alloc(iram_info, 64 * mb_width);
|
|
|
+ iram_info->buf_dbk_c_use = coda_iram_alloc(iram_info, 64 * mb_width);
|
|
|
+ if (!iram_info->buf_dbk_c_use)
|
|
|
goto out;
|
|
|
- }
|
|
|
+ iram_info->axi_sram_use |= dbk_bits;
|
|
|
|
|
|
- bitram_size = round_up(128 * mb_width, 1024);
|
|
|
- if (size >= bitram_size) {
|
|
|
- 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 {
|
|
|
+ iram_info->buf_bit_use = coda_iram_alloc(iram_info, 128 * mb_width);
|
|
|
+ if (!iram_info->buf_bit_use)
|
|
|
goto out;
|
|
|
- }
|
|
|
+ iram_info->axi_sram_use |= bit_bits;
|
|
|
|
|
|
- ipacdc_size = round_up(128 * mb_width, 1024);
|
|
|
- if (size >= ipacdc_size) {
|
|
|
- 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;
|
|
|
- }
|
|
|
+ iram_info->buf_ip_ac_dc_use = coda_iram_alloc(iram_info, 128 * mb_width);
|
|
|
+ if (!iram_info->buf_ip_ac_dc_use)
|
|
|
+ goto out;
|
|
|
+ iram_info->axi_sram_use |= ip_bits;
|
|
|
|
|
|
/* OVL and BTP disabled for encoder */
|
|
|
} else if (ctx->inst_type == CODA_INST_DECODER) {
|
|
|
struct coda_q_data *q_data_dst;
|
|
|
- int mb_height;
|
|
|
|
|
|
q_data_dst = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
|
|
|
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);
|
|
|
- if (size >= dbk_size) {
|
|
|
- iram_info->axi_sram_use |= CODA7_USE_HOST_DBK_ENABLE;
|
|
|
- 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 {
|
|
|
+
|
|
|
+ iram_info->buf_dbk_y_use = coda_iram_alloc(iram_info, 128 * mb_width);
|
|
|
+ iram_info->buf_dbk_c_use = coda_iram_alloc(iram_info, 128 * mb_width);
|
|
|
+ if (!iram_info->buf_dbk_c_use)
|
|
|
goto out;
|
|
|
- }
|
|
|
+ iram_info->axi_sram_use |= dbk_bits;
|
|
|
|
|
|
- bitram_size = round_up(128 * mb_width, 1024);
|
|
|
- if (size >= bitram_size) {
|
|
|
- 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 {
|
|
|
+ iram_info->buf_bit_use = coda_iram_alloc(iram_info, 128 * mb_width);
|
|
|
+ if (!iram_info->buf_bit_use)
|
|
|
goto out;
|
|
|
- }
|
|
|
+ iram_info->axi_sram_use |= bit_bits;
|
|
|
|
|
|
- ipacdc_size = round_up(128 * mb_width, 1024);
|
|
|
- if (size >= ipacdc_size) {
|
|
|
- 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 {
|
|
|
+ iram_info->buf_ip_ac_dc_use = coda_iram_alloc(iram_info, 128 * mb_width);
|
|
|
+ if (!iram_info->buf_ip_ac_dc_use)
|
|
|
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:
|
|
|
- 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))
|
|
|
v4l2_dbg(1, coda_debug, &ctx->dev->v4l2_dev,
|
|
|
"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) {
|
|
|
/* 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 */
|
|
@@ -3296,15 +3268,15 @@ static int coda_probe(struct platform_device *pdev)
|
|
|
|
|
|
switch (dev->devtype->product) {
|
|
|
case CODA_DX6:
|
|
|
- dev->iram_size = CODADX6_IRAM_SIZE;
|
|
|
+ dev->iram.size = CODADX6_IRAM_SIZE;
|
|
|
break;
|
|
|
case CODA_7541:
|
|
|
- dev->iram_size = CODA7_IRAM_SIZE;
|
|
|
+ dev->iram.size = CODA7_IRAM_SIZE;
|
|
|
break;
|
|
|
}
|
|
|
- dev->iram_vaddr = (unsigned long)gen_pool_dma_alloc(dev->iram_pool,
|
|
|
- dev->iram_size, (dma_addr_t *)&dev->iram_paddr);
|
|
|
- if (!dev->iram_vaddr) {
|
|
|
+ dev->iram.vaddr = gen_pool_dma_alloc(dev->iram_pool, dev->iram.size,
|
|
|
+ &dev->iram.paddr);
|
|
|
+ if (!dev->iram.vaddr) {
|
|
|
dev_err(&pdev->dev, "unable to alloc iram\n");
|
|
|
return -ENOMEM;
|
|
|
}
|
|
@@ -3324,8 +3296,9 @@ 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)
|
|
|
- gen_pool_free(dev->iram_pool, dev->iram_vaddr, dev->iram_size);
|
|
|
+ if (dev->iram.vaddr)
|
|
|
+ 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->tempbuf);
|
|
|
coda_free_aux_buf(dev, &dev->workbuf);
|