|
@@ -160,6 +160,18 @@ struct coda_params {
|
|
|
u32 slice_max_mb;
|
|
|
};
|
|
|
|
|
|
+struct coda_iram_info {
|
|
|
+ u32 axi_sram_use;
|
|
|
+ phys_addr_t buf_bit_use;
|
|
|
+ phys_addr_t buf_ip_ac_dc_use;
|
|
|
+ phys_addr_t buf_dbk_y_use;
|
|
|
+ phys_addr_t buf_dbk_c_use;
|
|
|
+ phys_addr_t buf_ovl_use;
|
|
|
+ phys_addr_t buf_btp_use;
|
|
|
+ phys_addr_t search_ram_paddr;
|
|
|
+ int search_ram_size;
|
|
|
+};
|
|
|
+
|
|
|
struct coda_ctx {
|
|
|
struct coda_dev *dev;
|
|
|
struct list_head list;
|
|
@@ -182,6 +194,7 @@ struct coda_ctx {
|
|
|
struct coda_aux_buf internal_frames[CODA_MAX_FRAMEBUFFERS];
|
|
|
int num_internal_frames;
|
|
|
int idx;
|
|
|
+ struct coda_iram_info iram_info;
|
|
|
};
|
|
|
|
|
|
static const u8 coda_filler_nal[14] = { 0x00, 0x00, 0x00, 0x01, 0x0c, 0xff,
|
|
@@ -800,6 +813,10 @@ static void coda_device_run(void *m2m_priv)
|
|
|
CODA7_REG_BIT_AXI_SRAM_USE);
|
|
|
}
|
|
|
|
|
|
+ if (dev->devtype->product != CODA_DX6)
|
|
|
+ coda_write(dev, ctx->iram_info.axi_sram_use,
|
|
|
+ CODA7_REG_BIT_AXI_SRAM_USE);
|
|
|
+
|
|
|
/* 1 second timeout in case CODA locks up */
|
|
|
schedule_delayed_work(&dev->timeout, HZ);
|
|
|
|
|
@@ -1035,6 +1052,110 @@ static int coda_h264_padding(int size, char *p)
|
|
|
return nal_size;
|
|
|
}
|
|
|
|
|
|
+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 mb_width;
|
|
|
+ int me_size;
|
|
|
+ int size;
|
|
|
+
|
|
|
+ memset(iram_info, 0, sizeof(*iram_info));
|
|
|
+ size = dev->iram_size;
|
|
|
+
|
|
|
+ if (dev->devtype->product == CODA_DX6)
|
|
|
+ return;
|
|
|
+
|
|
|
+ if (ctx->inst_type == CODA_INST_ENCODER) {
|
|
|
+ struct coda_q_data *q_data_src;
|
|
|
+
|
|
|
+ q_data_src = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT);
|
|
|
+ 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;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* 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 {
|
|
|
+ goto out;
|
|
|
+ }
|
|
|
+
|
|
|
+ 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 {
|
|
|
+ goto out;
|
|
|
+ }
|
|
|
+
|
|
|
+ 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;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* OVL disabled for encoder */
|
|
|
+ }
|
|
|
+
|
|
|
+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");
|
|
|
+
|
|
|
+ if (dev->devtype->product == CODA_7541) {
|
|
|
+ /* TODO - Enabling these causes picture errors on CODA7541 */
|
|
|
+ if (ctx->inst_type == CODA_INST_ENCODER) {
|
|
|
+ iram_info->axi_sram_use &= ~(CODA7_USE_HOST_IP_ENABLE |
|
|
|
+ CODA7_USE_HOST_DBK_ENABLE |
|
|
|
+ CODA7_USE_IP_ENABLE |
|
|
|
+ CODA7_USE_DBK_ENABLE);
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
static int coda_encode_header(struct coda_ctx *ctx, struct vb2_buffer *buf,
|
|
|
int header_code, u8 *header, int *size)
|
|
|
{
|
|
@@ -1207,6 +1328,8 @@ static int coda_start_streaming(struct vb2_queue *q, unsigned int count)
|
|
|
}
|
|
|
coda_write(dev, value, CODA_CMD_ENC_SEQ_OPTION);
|
|
|
|
|
|
+ coda_setup_iram(ctx);
|
|
|
+
|
|
|
if (dst_fourcc == V4L2_PIX_FMT_H264) {
|
|
|
value = (FMO_SLICE_SAVE_BUF_SIZE << 7);
|
|
|
value |= (0 & CODA_FMOPARAM_TYPE_MASK) << CODA_FMOPARAM_TYPE_OFFSET;
|
|
@@ -1214,8 +1337,10 @@ static int coda_start_streaming(struct vb2_queue *q, unsigned int count)
|
|
|
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);
|
|
|
+ coda_write(dev, ctx->iram_info.search_ram_paddr,
|
|
|
+ CODA7_CMD_ENC_SEQ_SEARCH_BASE);
|
|
|
+ coda_write(dev, ctx->iram_info.search_ram_size,
|
|
|
+ CODA7_CMD_ENC_SEQ_SEARCH_SIZE);
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -1240,12 +1365,16 @@ static int coda_start_streaming(struct vb2_queue *q, unsigned int count)
|
|
|
coda_write(dev, ctx->num_internal_frames, CODA_CMD_SET_FRAME_BUF_NUM);
|
|
|
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);
|
|
|
+ coda_write(dev, ctx->iram_info.buf_bit_use,
|
|
|
+ CODA7_CMD_SET_FRAME_AXI_BIT_ADDR);
|
|
|
+ coda_write(dev, ctx->iram_info.buf_ip_ac_dc_use,
|
|
|
+ CODA7_CMD_SET_FRAME_AXI_IPACDC_ADDR);
|
|
|
+ coda_write(dev, ctx->iram_info.buf_dbk_y_use,
|
|
|
+ CODA7_CMD_SET_FRAME_AXI_DBKY_ADDR);
|
|
|
+ coda_write(dev, ctx->iram_info.buf_dbk_c_use,
|
|
|
+ CODA7_CMD_SET_FRAME_AXI_DBKC_ADDR);
|
|
|
+ coda_write(dev, ctx->iram_info.buf_ovl_use,
|
|
|
+ CODA7_CMD_SET_FRAME_AXI_OVL_ADDR);
|
|
|
}
|
|
|
ret = coda_command_sync(ctx, CODA_COMMAND_SET_FRAME_BUF);
|
|
|
if (ret < 0) {
|