summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/media/platform/coda.c398
-rw-r--r--drivers/media/platform/coda.h115
2 files changed, 466 insertions, 47 deletions
diff --git a/drivers/media/platform/coda.c b/drivers/media/platform/coda.c
index 31a1848f3674..667149485d99 100644
--- a/drivers/media/platform/coda.c
+++ b/drivers/media/platform/coda.c
@@ -44,19 +44,24 @@
#define CODA_FMO_BUF_SIZE 32
#define CODADX6_WORK_BUF_SIZE (288 * 1024 + CODA_FMO_BUF_SIZE * 8 * 1024)
#define CODA7_WORK_BUF_SIZE (128 * 1024)
+#define CODA9_WORK_BUF_SIZE (80 * 1024)
#define CODA7_TEMP_BUF_SIZE (304 * 1024)
+#define CODA9_TEMP_BUF_SIZE (204 * 1024)
#define CODA_PARA_BUF_SIZE (10 * 1024)
#define CODA_ISRAM_SIZE (2048 * 2)
#define CODADX6_IRAM_SIZE 0xb000
#define CODA7_IRAM_SIZE 0x14000
+#define CODA9_IRAM_SIZE 0x21000
#define CODA7_PS_BUF_SIZE 0x28000
+#define CODA9_PS_SAVE_SIZE (512 * 1024)
#define CODA_MAX_FRAMEBUFFERS 8
#define CODA_MAX_FRAME_SIZE 0x100000
#define FMO_SLICE_SAVE_BUF_SIZE (32)
#define CODA_DEFAULT_GAMMA 4096
+#define CODA9_DEFAULT_GAMMA 24576 /* 0.75 * 32768 */
#define MIN_W 176
#define MIN_H 144
@@ -84,6 +89,7 @@ enum coda_inst_type {
enum coda_product {
CODA_DX6 = 0xf001,
CODA_7541 = 0xf012,
+ CODA_960 = 0xf020,
};
struct coda_fmt {
@@ -177,6 +183,16 @@ struct coda_iram_info {
phys_addr_t next_paddr;
};
+struct gdi_tiled_map {
+ int xy2ca_map[16];
+ int xy2ba_map[16];
+ int xy2ra_map[16];
+ int rbc2axi_map[32];
+ int xy2rbc_config;
+ int map_type;
+#define GDI_LINEAR_FRAME_MAP 0
+};
+
struct coda_ctx {
struct coda_dev *dev;
struct mutex buffer_mutex;
@@ -215,8 +231,10 @@ struct coda_ctx {
int idx;
int reg_idx;
struct coda_iram_info iram_info;
+ struct gdi_tiled_map tiled_map;
u32 bit_stream_param;
u32 frm_dis_flg;
+ u32 frame_mem_ctrl;
int display_idx;
};
@@ -265,15 +283,23 @@ static void coda_command_async(struct coda_ctx *ctx, int cmd)
{
struct coda_dev *dev = ctx->dev;
- if (dev->devtype->product == CODA_7541) {
+ if (dev->devtype->product == CODA_960 ||
+ dev->devtype->product == CODA_7541) {
/* Restore context related registers to CODA */
coda_write(dev, ctx->bit_stream_param,
CODA_REG_BIT_BIT_STREAM_PARAM);
coda_write(dev, ctx->frm_dis_flg,
CODA_REG_BIT_FRM_DIS_FLG(ctx->reg_idx));
+ coda_write(dev, ctx->frame_mem_ctrl,
+ CODA_REG_BIT_FRAME_MEM_CTRL);
coda_write(dev, ctx->workbuf.paddr, CODA_REG_BIT_WORK_BUF_ADDR);
}
+ if (dev->devtype->product == CODA_960) {
+ coda_write(dev, 1, CODA9_GDI_WPROT_ERR_CLR);
+ coda_write(dev, 0, CODA9_GDI_WPROT_RGN_EN);
+ }
+
coda_write(dev, CODA_REG_BIT_BUSY_FLAG, CODA_REG_BIT_BUSY);
coda_write(dev, ctx->idx, CODA_REG_BIT_RUN_INDEX);
@@ -349,6 +375,13 @@ static struct coda_codec coda7_codecs[] = {
CODA_CODEC(CODA7_MODE_DECODE_MP4, V4L2_PIX_FMT_MPEG4, V4L2_PIX_FMT_YUV420, 1920, 1080),
};
+static struct coda_codec coda9_codecs[] = {
+ CODA_CODEC(CODA9_MODE_ENCODE_H264, V4L2_PIX_FMT_YUV420, V4L2_PIX_FMT_H264, 1920, 1080),
+ CODA_CODEC(CODA9_MODE_ENCODE_MP4, V4L2_PIX_FMT_YUV420, V4L2_PIX_FMT_MPEG4, 1920, 1080),
+ CODA_CODEC(CODA9_MODE_DECODE_H264, V4L2_PIX_FMT_H264, V4L2_PIX_FMT_YUV420, 1920, 1080),
+ CODA_CODEC(CODA9_MODE_DECODE_MP4, V4L2_PIX_FMT_MPEG4, V4L2_PIX_FMT_YUV420, 1920, 1080),
+};
+
static bool coda_format_is_yuv(u32 fourcc)
{
switch (fourcc) {
@@ -427,6 +460,8 @@ static char *coda_product_name(int product)
return "CodaDx6";
case CODA_7541:
return "CODA7541";
+ case CODA_960:
+ return "CODA960";
default:
snprintf(buf, sizeof(buf), "(0x%04x)", product);
return buf;
@@ -855,6 +890,7 @@ static int coda_decoder_cmd(struct file *file, void *fh,
struct v4l2_decoder_cmd *dc)
{
struct coda_ctx *ctx = fh_to_ctx(fh);
+ struct coda_dev *dev = ctx->dev;
int ret;
ret = coda_try_decoder_cmd(file, fh, dc);
@@ -868,6 +904,13 @@ static int coda_decoder_cmd(struct file *file, void *fh,
/* Set the strem-end flag on this context */
ctx->bit_stream_param |= CODA_BIT_STREAM_END_FLAG;
+ if ((dev->devtype->product == CODA_960) &&
+ coda_isbusy(dev) &&
+ (ctx->idx == coda_read(dev, CODA_REG_BIT_RUN_INDEX))) {
+ /* If this context is currently running, update the hardware flag */
+ coda_write(dev, ctx->bit_stream_param, CODA_REG_BIT_BIT_STREAM_PARAM);
+ }
+
return 0;
}
@@ -1023,6 +1066,27 @@ static void coda_fill_bitstream(struct coda_ctx *ctx)
}
}
+static void coda_set_gdi_regs(struct coda_ctx *ctx)
+{
+ struct gdi_tiled_map *tiled_map = &ctx->tiled_map;
+ struct coda_dev *dev = ctx->dev;
+ int i;
+
+ for (i = 0; i < 16; i++)
+ coda_write(dev, tiled_map->xy2ca_map[i],
+ CODA9_GDI_XY2_CAS_0 + 4 * i);
+ for (i = 0; i < 4; i++)
+ coda_write(dev, tiled_map->xy2ba_map[i],
+ CODA9_GDI_XY2_BA_0 + 4 * i);
+ for (i = 0; i < 16; i++)
+ coda_write(dev, tiled_map->xy2ra_map[i],
+ CODA9_GDI_XY2_RAS_0 + 4 * i);
+ coda_write(dev, tiled_map->xy2rbc_config, CODA9_GDI_XY2_RBC_CONFIG);
+ for (i = 0; i < 32; i++)
+ coda_write(dev, tiled_map->rbc2axi_map[i],
+ CODA9_GDI_RBC2_AXI_0 + 4 * i);
+}
+
/*
* Mem-to-mem operations.
*/
@@ -1071,6 +1135,9 @@ static int coda_prepare_decode(struct coda_ctx *ctx)
}
}
+ if (dev->devtype->product == CODA_960)
+ coda_set_gdi_regs(ctx);
+
/* Set rotator output */
picture_y = vb2_dma_contig_plane_dma_addr(dst_buf, 0);
if (q_data_dst->fourcc == V4L2_PIX_FMT_YVU420) {
@@ -1081,10 +1148,26 @@ static int coda_prepare_decode(struct coda_ctx *ctx)
picture_cb = picture_y + stridey * height;
picture_cr = picture_cb + stridey / 2 * height / 2;
}
- coda_write(dev, picture_y, CODA_CMD_DEC_PIC_ROT_ADDR_Y);
- coda_write(dev, picture_cb, CODA_CMD_DEC_PIC_ROT_ADDR_CB);
- coda_write(dev, picture_cr, CODA_CMD_DEC_PIC_ROT_ADDR_CR);
- coda_write(dev, stridey, CODA_CMD_DEC_PIC_ROT_STRIDE);
+
+ if (dev->devtype->product == CODA_960) {
+ /*
+ * The CODA960 seems to have an internal list of buffers with
+ * 64 entries that includes the registered frame buffers as
+ * well as the rotator buffer output.
+ * ROT_INDEX needs to be < 0x40, but > ctx->num_internal_frames.
+ */
+ coda_write(dev, CODA_MAX_FRAMEBUFFERS + dst_buf->v4l2_buf.index,
+ CODA9_CMD_DEC_PIC_ROT_INDEX);
+ coda_write(dev, picture_y, CODA9_CMD_DEC_PIC_ROT_ADDR_Y);
+ coda_write(dev, picture_cb, CODA9_CMD_DEC_PIC_ROT_ADDR_CB);
+ coda_write(dev, picture_cr, CODA9_CMD_DEC_PIC_ROT_ADDR_CR);
+ coda_write(dev, stridey, CODA9_CMD_DEC_PIC_ROT_STRIDE);
+ } else {
+ coda_write(dev, picture_y, CODA_CMD_DEC_PIC_ROT_ADDR_Y);
+ coda_write(dev, picture_cb, CODA_CMD_DEC_PIC_ROT_ADDR_CB);
+ coda_write(dev, picture_cr, CODA_CMD_DEC_PIC_ROT_ADDR_CR);
+ coda_write(dev, stridey, CODA_CMD_DEC_PIC_ROT_STRIDE);
+ }
coda_write(dev, CODA_ROT_MIR_ENABLE | ctx->params.rot_mode,
CODA_CMD_DEC_PIC_ROT_MODE);
@@ -1094,6 +1177,9 @@ static int coda_prepare_decode(struct coda_ctx *ctx)
case CODA_7541:
coda_write(dev, CODA_PRE_SCAN_EN, CODA_CMD_DEC_PIC_OPTION);
break;
+ case CODA_960:
+ coda_write(dev, (1 << 10), CODA_CMD_DEC_PIC_OPTION); /* 'hardcode to use interrupt disable mode'? */
+ break;
}
coda_write(dev, 0, CODA_CMD_DEC_PIC_SKIP_NUM);
@@ -1138,6 +1224,9 @@ static void coda_prepare_encode(struct coda_ctx *ctx)
src_buf->v4l2_buf.flags &= ~V4L2_BUF_FLAG_PFRAME;
}
+ if (dev->devtype->product == CODA_960)
+ coda_set_gdi_regs(ctx);
+
/*
* Copy headers at the beginning of the first frame for H.264 only.
* In MPEG4 they are already copied by the coda.
@@ -1216,15 +1305,31 @@ static void coda_prepare_encode(struct coda_ctx *ctx)
break;
}
- coda_write(dev, picture_y, CODA_CMD_ENC_PIC_SRC_ADDR_Y);
- coda_write(dev, picture_cb, CODA_CMD_ENC_PIC_SRC_ADDR_CB);
- coda_write(dev, picture_cr, CODA_CMD_ENC_PIC_SRC_ADDR_CR);
+ if (dev->devtype->product == CODA_960) {
+ coda_write(dev, 4/*FIXME: 0*/, CODA9_CMD_ENC_PIC_SRC_INDEX);
+ coda_write(dev, q_data_src->width, CODA9_CMD_ENC_PIC_SRC_STRIDE);
+ coda_write(dev, 0, CODA9_CMD_ENC_PIC_SUB_FRAME_SYNC);
+
+ coda_write(dev, picture_y, CODA9_CMD_ENC_PIC_SRC_ADDR_Y);
+ coda_write(dev, picture_cb, CODA9_CMD_ENC_PIC_SRC_ADDR_CB);
+ coda_write(dev, picture_cr, CODA9_CMD_ENC_PIC_SRC_ADDR_CR);
+ } else {
+ coda_write(dev, picture_y, CODA_CMD_ENC_PIC_SRC_ADDR_Y);
+ coda_write(dev, picture_cb, CODA_CMD_ENC_PIC_SRC_ADDR_CB);
+ coda_write(dev, picture_cr, CODA_CMD_ENC_PIC_SRC_ADDR_CR);
+ }
coda_write(dev, force_ipicture << 1 & 0x2,
CODA_CMD_ENC_PIC_OPTION);
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 (!ctx->streamon_out) {
+ /* After streamoff on the output side, set the stream end flag */
+ ctx->bit_stream_param |= CODA_BIT_STREAM_END_FLAG;
+ coda_write(dev, ctx->bit_stream_param, CODA_REG_BIT_BIT_STREAM_PARAM);
+ }
}
static void coda_device_run(void *m2m_priv)
@@ -1350,6 +1455,32 @@ static struct v4l2_m2m_ops coda_m2m_ops = {
.unlock = coda_unlock,
};
+static void coda_set_tiled_map_type(struct coda_ctx *ctx, int tiled_map_type)
+{
+ struct gdi_tiled_map *tiled_map = &ctx->tiled_map;
+ int luma_map, chro_map, i;
+
+ memset(tiled_map, 0, sizeof(*tiled_map));
+
+ luma_map = 64;
+ chro_map = 64;
+ tiled_map->map_type = tiled_map_type;
+ for (i = 0; i < 16; i++)
+ tiled_map->xy2ca_map[i] = luma_map << 8 | chro_map;
+ for (i = 0; i < 4; i++)
+ tiled_map->xy2ba_map[i] = luma_map << 8 | chro_map;
+ for (i = 0; i < 16; i++)
+ tiled_map->xy2ra_map[i] = luma_map << 8 | chro_map;
+
+ if (tiled_map_type == GDI_LINEAR_FRAME_MAP) {
+ tiled_map->xy2rbc_config = 0;
+ } else {
+ dev_err(&ctx->dev->plat_dev->dev, "invalid map type: %d\n",
+ tiled_map_type);
+ return;
+ }
+}
+
static void set_default_params(struct coda_ctx *ctx)
{
int max_w;
@@ -1373,6 +1504,9 @@ static void set_default_params(struct coda_ctx *ctx)
ctx->q_data[V4L2_M2M_DST].width = max_w;
ctx->q_data[V4L2_M2M_DST].height = max_h;
ctx->q_data[V4L2_M2M_DST].sizeimage = CODA_MAX_FRAME_SIZE;
+
+ if (ctx->dev->devtype->product == CODA_960)
+ coda_set_tiled_map_type(ctx, GDI_LINEAR_FRAME_MAP);
}
/*
@@ -1422,6 +1556,7 @@ static int coda_buf_prepare(struct vb2_buffer *vb)
static void coda_buf_queue(struct vb2_buffer *vb)
{
struct coda_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
+ struct coda_dev *dev = ctx->dev;
struct coda_q_data *q_data;
q_data = get_q_data(ctx, vb->vb2_queue->type);
@@ -1436,8 +1571,15 @@ static void coda_buf_queue(struct vb2_buffer *vb)
* For backwards compatibility, queuing an empty buffer marks
* the stream end
*/
- if (vb2_get_plane_payload(vb, 0) == 0)
+ if (vb2_get_plane_payload(vb, 0) == 0) {
ctx->bit_stream_param |= CODA_BIT_STREAM_END_FLAG;
+ if ((dev->devtype->product == CODA_960) &&
+ coda_isbusy(dev) &&
+ (ctx->idx == coda_read(dev, CODA_REG_BIT_RUN_INDEX))) {
+ /* if this decoder instance is running, set the stream end flag */
+ coda_write(dev, ctx->bit_stream_param, CODA_REG_BIT_BIT_STREAM_PARAM);
+ }
+ }
mutex_lock(&ctx->bitstream_mutex);
v4l2_m2m_buf_queue(ctx->m2m_ctx, vb);
coda_fill_bitstream(ctx);
@@ -1612,6 +1754,11 @@ static void coda_setup_iram(struct coda_ctx *ctx)
bit_bits = CODA7_USE_HOST_BIT_ENABLE | CODA7_USE_BIT_ENABLE;
ip_bits = CODA7_USE_HOST_IP_ENABLE | CODA7_USE_IP_ENABLE;
break;
+ case CODA_960:
+ dbk_bits = CODA9_USE_HOST_DBK_ENABLE | CODA9_USE_DBK_ENABLE;
+ bit_bits = CODA9_USE_HOST_BIT_ENABLE | CODA7_USE_BIT_ENABLE;
+ ip_bits = CODA9_USE_HOST_IP_ENABLE | CODA7_USE_IP_ENABLE;
+ break;
default: /* CODA_DX6 */
return;
}
@@ -1721,6 +1868,11 @@ static int coda_alloc_context_buffers(struct coda_ctx *ctx,
case CODA_7541:
size = CODA7_WORK_BUF_SIZE;
break;
+ case CODA_960:
+ size = CODA9_WORK_BUF_SIZE;
+ if (q_data->fourcc == V4L2_PIX_FMT_H264)
+ size += CODA9_PS_SAVE_SIZE;
+ break;
default:
return 0;
}
@@ -1805,12 +1957,17 @@ static int coda_start_decoding(struct coda_ctx *ctx)
coda_write(dev, bitstream_buf, CODA_CMD_DEC_SEQ_BB_START);
coda_write(dev, bitstream_size / 1024, CODA_CMD_DEC_SEQ_BB_SIZE);
val = 0;
- if (dev->devtype->product == CODA_7541)
+ if ((dev->devtype->product == CODA_7541) ||
+ (dev->devtype->product == CODA_960))
val |= CODA_REORDER_ENABLE;
coda_write(dev, val, CODA_CMD_DEC_SEQ_OPTION);
ctx->params.codec_mode = ctx->codec->mode;
- ctx->params.codec_mode_aux = 0;
+ if (dev->devtype->product == CODA_960 &&
+ src_fourcc == V4L2_PIX_FMT_MPEG4)
+ ctx->params.codec_mode_aux = CODA_MP4_AUX_MPEG4;
+ else
+ ctx->params.codec_mode_aux = 0;
if (src_fourcc == V4L2_PIX_FMT_H264) {
if (dev->devtype->product == CODA_7541) {
coda_write(dev, ctx->psbuf.paddr,
@@ -1818,6 +1975,13 @@ static int coda_start_decoding(struct coda_ctx *ctx)
coda_write(dev, (CODA7_PS_BUF_SIZE / 1024),
CODA_CMD_DEC_SEQ_PS_BB_SIZE);
}
+ if (dev->devtype->product == CODA_960) {
+ coda_write(dev, 0, CODA_CMD_DEC_SEQ_X264_MV_EN);
+ coda_write(dev, 512, CODA_CMD_DEC_SEQ_SPP_CHUNK_SIZE);
+ }
+ }
+ if (dev->devtype->product != CODA_960) {
+ coda_write(dev, 0, CODA_CMD_DEC_SEQ_SRC_SIZE);
}
if (coda_command_sync(ctx, CODA_COMMAND_SEQ_INIT)) {
@@ -1889,6 +2053,20 @@ static int coda_start_decoding(struct coda_ctx *ctx)
CODA7_CMD_SET_FRAME_AXI_DBKC_ADDR);
coda_write(dev, ctx->iram_info.buf_ovl_use,
CODA7_CMD_SET_FRAME_AXI_OVL_ADDR);
+ if (dev->devtype->product == CODA_960)
+ coda_write(dev, ctx->iram_info.buf_btp_use,
+ CODA9_CMD_SET_FRAME_AXI_BTP_ADDR);
+ }
+
+ if (dev->devtype->product == CODA_960) {
+ coda_write(dev, -1, CODA9_CMD_SET_FRAME_DELAY);
+
+ coda_write(dev, 0x20262024, CODA9_CMD_SET_FRAME_CACHE_SIZE);
+ coda_write(dev, 2 << CODA9_CACHE_PAGEMERGE_OFFSET |
+ 32 << CODA9_CACHE_LUMA_BUFFER_SIZE_OFFSET |
+ 8 << CODA9_CACHE_CB_BUFFER_SIZE_OFFSET |
+ 8 << CODA9_CACHE_CR_BUFFER_SIZE_OFFSET,
+ CODA9_CMD_SET_FRAME_CACHE_CONFIG);
}
if (src_fourcc == V4L2_PIX_FMT_H264) {
@@ -1902,8 +2080,16 @@ static int coda_start_decoding(struct coda_ctx *ctx)
int max_mb_x = 1920 / 16;
int max_mb_y = 1088 / 16;
int max_mb_num = max_mb_x * max_mb_y;
+
coda_write(dev, max_mb_num << 16 | max_mb_x << 8 | max_mb_y,
CODA7_CMD_SET_FRAME_MAX_DEC_SIZE);
+ } else if (dev->devtype->product == CODA_960) {
+ int max_mb_x = 1920 / 16;
+ int max_mb_y = 1088 / 16;
+ int max_mb_num = max_mb_x * max_mb_y;
+
+ coda_write(dev, max_mb_num << 16 | max_mb_x << 8 | max_mb_y,
+ CODA9_CMD_SET_FRAME_MAX_DEC_SIZE);
}
if (coda_command_sync(ctx, CODA_COMMAND_SET_FRAME_BUF)) {
@@ -1919,34 +2105,49 @@ static int coda_encode_header(struct coda_ctx *ctx, struct vb2_buffer *buf,
int header_code, u8 *header, int *size)
{
struct coda_dev *dev = ctx->dev;
+ size_t bufsize;
int ret;
+ int i;
+
+ if (dev->devtype->product == CODA_960)
+ memset(vb2_plane_vaddr(buf, 0), 0, 64);
coda_write(dev, vb2_dma_contig_plane_dma_addr(buf, 0),
CODA_CMD_ENC_HEADER_BB_START);
- coda_write(dev, vb2_plane_size(buf, 0), CODA_CMD_ENC_HEADER_BB_SIZE);
+ bufsize = vb2_plane_size(buf, 0);
+ if (dev->devtype->product == CODA_960)
+ bufsize /= 1024;
+ coda_write(dev, bufsize, CODA_CMD_ENC_HEADER_BB_SIZE);
coda_write(dev, header_code, CODA_CMD_ENC_HEADER_CODE);
ret = coda_command_sync(ctx, CODA_COMMAND_ENCODE_HEADER);
if (ret < 0) {
v4l2_err(&dev->v4l2_dev, "CODA_COMMAND_ENCODE_HEADER timeout\n");
return ret;
}
- *size = coda_read(dev, CODA_REG_BIT_WR_PTR(ctx->reg_idx)) -
- coda_read(dev, CODA_CMD_ENC_HEADER_BB_START);
+
+ if (dev->devtype->product == CODA_960) {
+ for (i = 63; i > 0; i--)
+ if (((char *)vb2_plane_vaddr(buf, 0))[i] != 0)
+ break;
+ *size = i + 1;
+ } else {
+ *size = coda_read(dev, CODA_REG_BIT_WR_PTR(ctx->reg_idx)) -
+ coda_read(dev, CODA_CMD_ENC_HEADER_BB_START);
+ }
memcpy(header, vb2_plane_vaddr(buf, 0), *size);
return 0;
}
+static int coda_start_encoding(struct coda_ctx *ctx);
+
static int coda_start_streaming(struct vb2_queue *q, unsigned int count)
{
struct coda_ctx *ctx = vb2_get_drv_priv(q);
struct v4l2_device *v4l2_dev = &ctx->dev->v4l2_dev;
- u32 bitstream_buf, bitstream_size;
struct coda_dev *dev = ctx->dev;
struct coda_q_data *q_data_src, *q_data_dst;
- struct vb2_buffer *buf;
u32 dst_fourcc;
- u32 value;
int ret = 0;
q_data_src = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT);
@@ -1981,10 +2182,7 @@ static int coda_start_streaming(struct vb2_queue *q, unsigned int count)
v4l2_m2m_set_src_buffered(ctx->m2m_ctx, true);
ctx->gopcounter = ctx->params.gop_size - 1;
- buf = v4l2_m2m_next_dst_buf(ctx->m2m_ctx);
- bitstream_buf = vb2_dma_contig_plane_dma_addr(buf, 0);
q_data_dst = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
- bitstream_size = q_data_dst->sizeimage;
dst_fourcc = q_data_dst->fourcc;
ctx->codec = coda_find_codec(ctx->dev, q_data_src->fourcc,
@@ -2003,16 +2201,36 @@ static int coda_start_streaming(struct vb2_queue *q, unsigned int count)
mutex_lock(&dev->coda_mutex);
ret = coda_start_decoding(ctx);
mutex_unlock(&dev->coda_mutex);
- if (ret == -EAGAIN) {
+ if (ret == -EAGAIN)
return 0;
- } else if (ret < 0) {
+ else if (ret < 0)
return ret;
- } else {
- ctx->initialized = 1;
- return 0;
- }
+ } else {
+ ret = coda_start_encoding(ctx);
}
+ ctx->initialized = 1;
+ return ret;
+}
+
+static int coda_start_encoding(struct coda_ctx *ctx)
+{
+ struct coda_dev *dev = ctx->dev;
+ struct v4l2_device *v4l2_dev = &dev->v4l2_dev;
+ struct coda_q_data *q_data_src, *q_data_dst;
+ u32 bitstream_buf, bitstream_size;
+ struct vb2_buffer *buf;
+ int gamma, ret, value;
+ u32 dst_fourcc;
+
+ q_data_src = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT);
+ q_data_dst = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
+ dst_fourcc = q_data_dst->fourcc;
+
+ buf = v4l2_m2m_next_dst_buf(ctx->m2m_ctx);
+ bitstream_buf = vb2_dma_contig_plane_dma_addr(buf, 0);
+ bitstream_size = q_data_dst->sizeimage;
+
if (!coda_is_initialized(dev)) {
v4l2_err(v4l2_dev, "coda is not initialized.\n");
return -EFAULT;
@@ -2028,11 +2246,20 @@ static int coda_start_streaming(struct vb2_queue *q, unsigned int count)
coda_write(dev, CODADX6_STREAM_BUF_DYNALLOC_EN |
CODADX6_STREAM_BUF_PIC_RESET, CODA_REG_BIT_STREAM_CTRL);
break;
- default:
+ case CODA_960:
+ coda_write(dev, 0, CODA9_GDI_WPROT_RGN_EN);
+ /* fallthrough */
+ case CODA_7541:
coda_write(dev, CODA7_STREAM_BUF_DYNALLOC_EN |
CODA7_STREAM_BUF_PIC_RESET, CODA_REG_BIT_STREAM_CTRL);
+ break;
}
+ value = coda_read(dev, CODA_REG_BIT_FRAME_MEM_CTRL);
+ value &= ~(1 << 2 | 0x7 << 9);
+ ctx->frame_mem_ctrl = value;
+ coda_write(dev, value, CODA_REG_BIT_FRAME_MEM_CTRL);
+
if (dev->devtype->product == CODA_DX6) {
/* Configure the coda */
coda_write(dev, dev->iram.paddr, CODADX6_REG_BIT_SEARCH_RAM_BASE_ADDR);
@@ -2055,11 +2282,17 @@ static int coda_start_streaming(struct vb2_queue *q, unsigned int count)
ctx->params.codec_mode = ctx->codec->mode;
switch (dst_fourcc) {
case V4L2_PIX_FMT_MPEG4:
- coda_write(dev, CODA_STD_MPEG4, CODA_CMD_ENC_SEQ_COD_STD);
+ if (dev->devtype->product == CODA_960)
+ coda_write(dev, CODA9_STD_MPEG4, CODA_CMD_ENC_SEQ_COD_STD);
+ else
+ coda_write(dev, CODA_STD_MPEG4, CODA_CMD_ENC_SEQ_COD_STD);
coda_write(dev, 0, CODA_CMD_ENC_SEQ_MP4_PARA);
break;
case V4L2_PIX_FMT_H264:
- coda_write(dev, CODA_STD_H264, CODA_CMD_ENC_SEQ_COD_STD);
+ if (dev->devtype->product == CODA_960)
+ coda_write(dev, CODA9_STD_H264, CODA_CMD_ENC_SEQ_COD_STD);
+ else
+ coda_write(dev, CODA_STD_H264, CODA_CMD_ENC_SEQ_COD_STD);
coda_write(dev, 0, CODA_CMD_ENC_SEQ_264_PARA);
break;
default:
@@ -2092,6 +2325,8 @@ static int coda_start_streaming(struct vb2_queue *q, unsigned int count)
/* Rate control enabled */
value = (ctx->params.bitrate & CODA_RATECONTROL_BITRATE_MASK) << CODA_RATECONTROL_BITRATE_OFFSET;
value |= 1 & CODA_RATECONTROL_ENABLE_MASK;
+ if (dev->devtype->product == CODA_960)
+ value |= BIT(31); /* disable autoskip */
} else {
value = 0;
}
@@ -2103,31 +2338,48 @@ static int coda_start_streaming(struct vb2_queue *q, unsigned int count)
coda_write(dev, bitstream_buf, CODA_CMD_ENC_SEQ_BB_START);
coda_write(dev, bitstream_size / 1024, CODA_CMD_ENC_SEQ_BB_SIZE);
- /* set default gamma */
- value = (CODA_DEFAULT_GAMMA & CODA_GAMMA_MASK) << CODA_GAMMA_OFFSET;
- coda_write(dev, value, CODA_CMD_ENC_SEQ_RC_GAMMA);
- if (CODA_DEFAULT_GAMMA > 0) {
- if (dev->devtype->product == CODA_DX6)
- value = 1 << CODADX6_OPTION_GAMMA_OFFSET;
- else
- value = 1 << CODA7_OPTION_GAMMA_OFFSET;
+ value = 0;
+ if (dev->devtype->product == CODA_960)
+ gamma = CODA9_DEFAULT_GAMMA;
+ else
+ gamma = CODA_DEFAULT_GAMMA;
+ if (gamma > 0) {
+ coda_write(dev, (gamma & CODA_GAMMA_MASK) << CODA_GAMMA_OFFSET,
+ CODA_CMD_ENC_SEQ_RC_GAMMA);
+ }
+ if (dev->devtype->product == CODA_960) {
+ if (CODA_DEFAULT_GAMMA > 0)
+ value |= 1 << CODA9_OPTION_GAMMA_OFFSET;
} else {
- value = 0;
+ if (CODA_DEFAULT_GAMMA > 0) {
+ if (dev->devtype->product == CODA_DX6)
+ value |= 1 << CODADX6_OPTION_GAMMA_OFFSET;
+ else
+ value |= 1 << CODA7_OPTION_GAMMA_OFFSET;
+ }
}
coda_write(dev, value, CODA_CMD_ENC_SEQ_OPTION);
+ coda_write(dev, 0, CODA_CMD_ENC_SEQ_RC_INTERVAL_MODE);
+
coda_setup_iram(ctx);
if (dst_fourcc == V4L2_PIX_FMT_H264) {
- if (dev->devtype->product == CODA_DX6) {
+ switch (dev->devtype->product) {
+ case CODA_DX6:
value = FMO_SLICE_SAVE_BUF_SIZE << 7;
coda_write(dev, value, CODADX6_CMD_ENC_SEQ_FMO);
- } else {
+ break;
+ case CODA_7541:
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);
+ break;
+ case CODA_960:
+ coda_write(dev, 0, CODA9_CMD_ENC_SEQ_ME_OPTION);
+ coda_write(dev, 0, CODA9_CMD_ENC_SEQ_INTRA_WEIGHT);
}
}
@@ -2143,7 +2395,10 @@ static int coda_start_streaming(struct vb2_queue *q, unsigned int count)
goto out;
}
- ctx->num_internal_frames = 2;
+ if (dev->devtype->product == CODA_960)
+ ctx->num_internal_frames = 4;
+ else
+ ctx->num_internal_frames = 2;
ret = coda_alloc_framebuffers(ctx, q_data_src, dst_fourcc);
if (ret < 0) {
v4l2_err(v4l2_dev, "failed to allocate framebuffers\n");
@@ -2166,7 +2421,16 @@ static int coda_start_streaming(struct vb2_queue *q, unsigned int count)
CODA7_CMD_SET_FRAME_AXI_DBKC_ADDR);
coda_write(dev, ctx->iram_info.buf_ovl_use,
CODA7_CMD_SET_FRAME_AXI_OVL_ADDR);
+ if (dev->devtype->product == CODA_960) {
+ coda_write(dev, ctx->iram_info.buf_btp_use,
+ CODA9_CMD_SET_FRAME_AXI_BTP_ADDR);
+
+ /* FIXME */
+ coda_write(dev, ctx->internal_frames[2].paddr, CODA9_CMD_SET_FRAME_SUBSAMP_A);
+ coda_write(dev, ctx->internal_frames[3].paddr, CODA9_CMD_SET_FRAME_SUBSAMP_B);
+ }
}
+
ret = coda_command_sync(ctx, CODA_COMMAND_SET_FRAME_BUF);
if (ret < 0) {
v4l2_err(v4l2_dev, "CODA_COMMAND_SET_FRAME_BUF timeout\n");
@@ -2250,6 +2514,17 @@ static void coda_stop_streaming(struct vb2_queue *q)
"%s: output\n", __func__);
ctx->streamon_out = 0;
+ if (ctx->inst_type == CODA_INST_DECODER &&
+ coda_isbusy(dev) && ctx->idx == coda_read(dev, CODA_REG_BIT_RUN_INDEX)) {
+ /* if this decoder instance is running, set the stream end flag */
+ if (dev->devtype->product == CODA_960) {
+ u32 val = coda_read(dev, CODA_REG_BIT_BIT_STREAM_PARAM);
+
+ val |= CODA_BIT_STREAM_END_FLAG;
+ coda_write(dev, val, CODA_REG_BIT_BIT_STREAM_PARAM);
+ ctx->bit_stream_param = val;
+ }
+ }
ctx->bit_stream_param |= CODA_BIT_STREAM_END_FLAG;
ctx->isequence = 0;
@@ -2451,6 +2726,7 @@ static int coda_open(struct file *file)
ctx->idx = idx;
switch (dev->devtype->product) {
case CODA_7541:
+ case CODA_960:
ctx->reg_idx = 0;
break;
default:
@@ -2771,7 +3047,7 @@ static void coda_finish_encode(struct coda_ctx *ctx)
u32 wr_ptr, start_ptr;
src_buf = v4l2_m2m_src_buf_remove(ctx->m2m_ctx);
- dst_buf = v4l2_m2m_dst_buf_remove(ctx->m2m_ctx);
+ dst_buf = v4l2_m2m_next_dst_buf(ctx->m2m_ctx);
/* Get results from the coda */
start_ptr = coda_read(dev, CODA_CMD_ENC_PIC_BB_START);
@@ -2808,6 +3084,8 @@ static void coda_finish_encode(struct coda_ctx *ctx)
dst_buf->v4l2_buf.timecode = src_buf->v4l2_buf.timecode;
v4l2_m2m_buf_done(src_buf, VB2_BUF_STATE_DONE);
+
+ dst_buf = v4l2_m2m_dst_buf_remove(ctx->m2m_ctx);
v4l2_m2m_buf_done(dst_buf, VB2_BUF_STATE_DONE);
ctx->gopcounter--;
@@ -2906,6 +3184,7 @@ static void coda_timeout(struct work_struct *work)
static u32 coda_supported_firmwares[] = {
CODA_FIRMWARE_VERNUM(CODA_DX6, 2, 2, 5),
CODA_FIRMWARE_VERNUM(CODA_7541, 1, 4, 50),
+ CODA_FIRMWARE_VERNUM(CODA_960, 2, 1, 5),
};
static bool coda_firmware_supported(u32 vernum)
@@ -2960,7 +3239,8 @@ static int coda_hw_init(struct coda_dev *dev)
coda_write(dev, 0, CODA_REG_BIT_CODE_BUF_ADDR + i * 4);
/* Tell the BIT where to find everything it needs */
- if (dev->devtype->product == CODA_7541) {
+ if (dev->devtype->product == CODA_960 ||
+ dev->devtype->product == CODA_7541) {
coda_write(dev, dev->tempbuf.paddr,
CODA_REG_BIT_TEMP_BUF_ADDR);
coda_write(dev, 0, CODA_REG_BIT_BIT_STREAM_PARAM);
@@ -2980,7 +3260,10 @@ static int coda_hw_init(struct coda_dev *dev)
default:
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_960)
+ coda_write(dev, 1 << 12, CODA_REG_BIT_FRAME_MEM_CTRL);
+ else
+ 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);
@@ -3010,6 +3293,12 @@ static int coda_hw_init(struct coda_dev *dev)
return -EIO;
}
+ if (dev->devtype->product == CODA_960) {
+ data = coda_read(dev, CODA9_CMD_FIRMWARE_CODE_REV);
+ v4l2_info(&dev->v4l2_dev, "Firmware code revision: %d\n",
+ data);
+ }
+
/* Check we are compatible with the loaded firmware */
data = coda_read(dev, CODA_CMD_FIRMWARE_VERNUM);
product = CODA_FIRMWARE_PRODUCT(data);
@@ -3125,6 +3414,8 @@ static int coda_firmware_request(struct coda_dev *dev)
enum coda_platform {
CODA_IMX27,
CODA_IMX53,
+ CODA_IMX6Q,
+ CODA_IMX6DL,
};
static const struct coda_devtype coda_devdata[] = {
@@ -3140,6 +3431,18 @@ static const struct coda_devtype coda_devdata[] = {
.codecs = coda7_codecs,
.num_codecs = ARRAY_SIZE(coda7_codecs),
},
+ [CODA_IMX6Q] = {
+ .firmware = "v4l-coda960-imx6q.bin",
+ .product = CODA_960,
+ .codecs = coda9_codecs,
+ .num_codecs = ARRAY_SIZE(coda9_codecs),
+ },
+ [CODA_IMX6DL] = {
+ .firmware = "v4l-coda960-imx6dl.bin",
+ .product = CODA_960,
+ .codecs = coda9_codecs,
+ .num_codecs = ARRAY_SIZE(coda9_codecs),
+ },
};
static struct platform_device_id coda_platform_ids[] = {
@@ -3153,6 +3456,8 @@ MODULE_DEVICE_TABLE(platform, coda_platform_ids);
static const struct of_device_id coda_dt_ids[] = {
{ .compatible = "fsl,imx27-vpu", .data = &coda_devdata[CODA_IMX27] },
{ .compatible = "fsl,imx53-vpu", .data = &coda_devdata[CODA_IMX53] },
+ { .compatible = "fsl,imx6q-vpu", .data = &coda_devdata[CODA_IMX6Q] },
+ { .compatible = "fsl,imx6dl-vpu", .data = &coda_devdata[CODA_IMX6DL] },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, coda_dt_ids);
@@ -3255,6 +3560,9 @@ static int coda_probe(struct platform_device *pdev)
case CODA_7541:
dev->tempbuf.size = CODA7_TEMP_BUF_SIZE;
break;
+ case CODA_960:
+ dev->tempbuf.size = CODA9_TEMP_BUF_SIZE;
+ break;
}
if (dev->tempbuf.size) {
ret = coda_alloc_aux_buf(dev, &dev->tempbuf,
@@ -3273,6 +3581,8 @@ static int coda_probe(struct platform_device *pdev)
case CODA_7541:
dev->iram.size = CODA7_IRAM_SIZE;
break;
+ case CODA_960:
+ dev->iram.size = CODA9_IRAM_SIZE;
}
dev->iram.vaddr = gen_pool_dma_alloc(dev->iram_pool, dev->iram.size,
&dev->iram.paddr);
diff --git a/drivers/media/platform/coda.h b/drivers/media/platform/coda.h
index 4e32e2edea62..c791275e307b 100644
--- a/drivers/media/platform/coda.h
+++ b/drivers/media/platform/coda.h
@@ -27,6 +27,14 @@
#define CODA_REG_BIT_CODE_RESET 0x014
#define CODA_REG_RESET_ENABLE (1 << 0)
#define CODA_REG_BIT_CUR_PC 0x018
+#define CODA9_REG_BIT_SW_RESET 0x024
+#define CODA9_SW_RESET_BPU_CORE 0x008
+#define CODA9_SW_RESET_BPU_BUS 0x010
+#define CODA9_SW_RESET_VCE_CORE 0x020
+#define CODA9_SW_RESET_VCE_BUS 0x040
+#define CODA9_SW_RESET_GDI_CORE 0x080
+#define CODA9_SW_RESET_GDI_BUS 0x100
+#define CODA9_REG_BIT_SW_RESET_STATUS 0x034
/* Static SW registers */
#define CODA_REG_BIT_CODE_BUF_ADDR 0x100
@@ -39,9 +47,11 @@
#define CODADX6_STREAM_BUF_PIC_FLUSH (1 << 2)
#define CODA7_STREAM_BUF_DYNALLOC_EN (1 << 5)
#define CODADX6_STREAM_BUF_DYNALLOC_EN (1 << 4)
-#define CODA_STREAM_CHKDIS_OFFSET (1 << 1)
+#define CODADX6_STREAM_CHKDIS_OFFSET (1 << 1)
+#define CODA7_STREAM_SEL_64BITS_ENDIAN (1 << 1)
#define CODA_STREAM_ENDIAN_SELECT (1 << 0)
#define CODA_REG_BIT_FRAME_MEM_CTRL 0x110
+#define CODA_FRAME_CHROMA_INTERLEAVE (1 << 2)
#define CODA_IMAGE_ENDIAN_SELECT (1 << 0)
#define CODA_REG_BIT_BIT_STREAM_PARAM 0x114
#define CODA_BIT_STREAM_END_FLAG (1 << 2)
@@ -52,13 +62,21 @@
#define CODA_REG_BIT_FRM_DIS_FLG(x) (0x150 + 4 * (x))
#define CODADX6_REG_BIT_SEARCH_RAM_BASE_ADDR 0x140
#define CODA7_REG_BIT_AXI_SRAM_USE 0x140
+#define CODA9_USE_HOST_BTP_ENABLE (1 << 13)
+#define CODA9_USE_HOST_OVL_ENABLE (1 << 12)
#define CODA7_USE_HOST_ME_ENABLE (1 << 11)
+#define CODA9_USE_HOST_DBK_ENABLE (3 << 10)
#define CODA7_USE_HOST_OVL_ENABLE (1 << 10)
#define CODA7_USE_HOST_DBK_ENABLE (1 << 9)
+#define CODA9_USE_HOST_IP_ENABLE (1 << 9)
#define CODA7_USE_HOST_IP_ENABLE (1 << 8)
+#define CODA9_USE_HOST_BIT_ENABLE (1 << 8)
#define CODA7_USE_HOST_BIT_ENABLE (1 << 7)
+#define CODA9_USE_BTP_ENABLE (1 << 5)
#define CODA7_USE_ME_ENABLE (1 << 4)
+#define CODA9_USE_OVL_ENABLE (1 << 4)
#define CODA7_USE_OVL_ENABLE (1 << 3)
+#define CODA9_USE_DBK_ENABLE (3 << 2)
#define CODA7_USE_DBK_ENABLE (1 << 2)
#define CODA7_USE_IP_ENABLE (1 << 1)
#define CODA7_USE_BIT_ENABLE (1 << 0)
@@ -93,6 +111,18 @@
#define CODA7_MODE_ENCODE_H264 8
#define CODA7_MODE_ENCODE_MP4 11
#define CODA7_MODE_ENCODE_MJPG 13
+#define CODA9_MODE_DECODE_H264 0
+#define CODA9_MODE_DECODE_VC1 1
+#define CODA9_MODE_DECODE_MP2 2
+#define CODA9_MODE_DECODE_MP4 3
+#define CODA9_MODE_DECODE_DV3 3
+#define CODA9_MODE_DECODE_RV 4
+#define CODA9_MODE_DECODE_AVS 5
+#define CODA9_MODE_DECODE_MJPG 6
+#define CODA9_MODE_DECODE_VPX 7
+#define CODA9_MODE_ENCODE_H264 8
+#define CODA9_MODE_ENCODE_MP4 11
+#define CODA9_MODE_ENCODE_MJPG 13
#define CODA_MODE_INVALID 0xffff
#define CODA_REG_BIT_INT_ENABLE 0x170
#define CODA_INT_INTERRUPT_ENABLE (1 << 3)
@@ -129,6 +159,7 @@
#define CODA_CMD_DEC_SEQ_SPP_CHUNK_SIZE 0x1a0
#define CODA7_RET_DEC_SEQ_ASPECT 0x1b0
+#define CODA9_RET_DEC_SEQ_BITRATE 0x1b4
#define CODA_RET_DEC_SEQ_SUCCESS 0x1c0
#define CODA_RET_DEC_SEQ_SRC_FMT 0x1c4 /* SRC_SIZE on CODA7 */
#define CODA_RET_DEC_SEQ_SRC_SIZE 0x1c4
@@ -145,13 +176,19 @@
#define CODA_RET_DEC_SEQ_FRATE_DR 0x1e8
#define CODA_RET_DEC_SEQ_JPG_PARA 0x1e4
#define CODA_RET_DEC_SEQ_JPG_THUMB_IND 0x1e8
+#define CODA9_RET_DEC_SEQ_HEADER_REPORT 0x1ec
/* Decoder Picture Run */
#define CODA_CMD_DEC_PIC_ROT_MODE 0x180
#define CODA_CMD_DEC_PIC_ROT_ADDR_Y 0x184
+#define CODA9_CMD_DEC_PIC_ROT_INDEX 0x184
#define CODA_CMD_DEC_PIC_ROT_ADDR_CB 0x188
+#define CODA9_CMD_DEC_PIC_ROT_ADDR_Y 0x188
#define CODA_CMD_DEC_PIC_ROT_ADDR_CR 0x18c
+#define CODA9_CMD_DEC_PIC_ROT_ADDR_CB 0x18c
#define CODA_CMD_DEC_PIC_ROT_STRIDE 0x190
+#define CODA9_CMD_DEC_PIC_ROT_ADDR_CR 0x190
+#define CODA9_CMD_DEC_PIC_ROT_STRIDE 0x1b8
#define CODA_CMD_DEC_PIC_OPTION 0x194
#define CODA_PRE_SCAN_EN (1 << 0)
@@ -183,25 +220,39 @@
#define CODA_RET_DEC_PIC_CROP_TOP_BOTTOM 0x1e4
#define CODA_RET_DEC_PIC_FRAME_NEED 0x1ec
+#define CODA9_RET_DEC_PIC_VP8_PIC_REPORT 0x1e8
+#define CODA9_RET_DEC_PIC_ASPECT 0x1f0
+#define CODA9_RET_DEC_PIC_VP8_SCALE_INFO 0x1f0
+#define CODA9_RET_DEC_PIC_FRATE_NR 0x1f4
+#define CODA9_RET_DEC_PIC_FRATE_DR 0x1f8
+
/* Encoder Sequence Initialization */
#define CODA_CMD_ENC_SEQ_BB_START 0x180
#define CODA_CMD_ENC_SEQ_BB_SIZE 0x184
#define CODA_CMD_ENC_SEQ_OPTION 0x188
#define CODA7_OPTION_AVCINTRA16X16ONLY_OFFSET 9
+#define CODA9_OPTION_MVC_PREFIX_NAL_OFFSET 9
#define CODA7_OPTION_GAMMA_OFFSET 8
+#define CODA9_OPTION_MVC_PARASET_REFRESH_OFFSET 8
#define CODA7_OPTION_RCQPMAX_OFFSET 7
+#define CODA9_OPTION_GAMMA_OFFSET 7
#define CODADX6_OPTION_GAMMA_OFFSET 7
#define CODA7_OPTION_RCQPMIN_OFFSET 6
+#define CODA9_OPTION_RCQPMAX_OFFSET 6
#define CODA_OPTION_LIMITQP_OFFSET 6
#define CODA_OPTION_RCINTRAQP_OFFSET 5
#define CODA_OPTION_FMO_OFFSET 4
+#define CODA9_OPTION_MVC_INTERVIEW_OFFSET 4
#define CODA_OPTION_AVC_AUD_OFFSET 2
#define CODA_OPTION_SLICEREPORT_OFFSET 1
#define CODA_CMD_ENC_SEQ_COD_STD 0x18c
#define CODA_STD_MPEG4 0
+#define CODA9_STD_H264 0
#define CODA_STD_H263 1
#define CODA_STD_H264 2
#define CODA_STD_MJPG 3
+#define CODA9_STD_MPEG4 3
+
#define CODA_CMD_ENC_SEQ_SRC_SIZE 0x190
#define CODA7_PICWIDTH_OFFSET 16
#define CODA7_PICWIDTH_MASK 0xffff
@@ -268,15 +319,26 @@
#define CODA7_CMD_ENC_SEQ_SEARCH_BASE 0x1b8
#define CODA7_CMD_ENC_SEQ_SEARCH_SIZE 0x1bc
#define CODA7_CMD_ENC_SEQ_INTRA_QP 0x1c4
-#define CODA_CMD_ENC_SEQ_RC_QP_MAX 0x1c8
+#define CODA_CMD_ENC_SEQ_RC_QP_MIN_MAX 0x1c8
+#define CODA_QPMIN_OFFSET 8
+#define CODA_QPMIN_MASK 0x3f
#define CODA_QPMAX_OFFSET 0
#define CODA_QPMAX_MASK 0x3f
#define CODA_CMD_ENC_SEQ_RC_GAMMA 0x1cc
#define CODA_GAMMA_OFFSET 0
#define CODA_GAMMA_MASK 0xffff
+#define CODA_CMD_ENC_SEQ_RC_INTERVAL_MODE 0x1d0
+#define CODA9_CMD_ENC_SEQ_INTRA_WEIGHT 0x1d4
+#define CODA9_CMD_ENC_SEQ_ME_OPTION 0x1d8
#define CODA_RET_ENC_SEQ_SUCCESS 0x1c0
/* Encoder Picture Run */
+#define CODA9_CMD_ENC_PIC_SRC_INDEX 0x180
+#define CODA9_CMD_ENC_PIC_SRC_STRIDE 0x184
+#define CODA9_CMD_ENC_PIC_SUB_FRAME_SYNC 0x1a4
+#define CODA9_CMD_ENC_PIC_SRC_ADDR_Y 0x1a8
+#define CODA9_CMD_ENC_PIC_SRC_ADDR_CB 0x1ac
+#define CODA9_CMD_ENC_PIC_SRC_ADDR_CR 0x1b0
#define CODA_CMD_ENC_PIC_SRC_ADDR_Y 0x180
#define CODA_CMD_ENC_PIC_SRC_ADDR_CB 0x184
#define CODA_CMD_ENC_PIC_SRC_ADDR_CR 0x188
@@ -291,7 +353,11 @@
#define CODA_MIR_VER (0x1 << 2)
#define CODA_MIR_HOR (0x2 << 2)
#define CODA_MIR_VER_HOR (0x3 << 2)
-#define CODA_CMD_ENC_PIC_OPTION 0x194
+#define CODA_CMD_ENC_PIC_OPTION 0x194
+#define CODA_FORCE_IPICTURE BIT(1)
+#define CODA_REPORT_MB_INFO BIT(3)
+#define CODA_REPORT_MV_INFO BIT(4)
+#define CODA_REPORT_SLICE_INFO BIT(5)
#define CODA_CMD_ENC_PIC_BB_START 0x198
#define CODA_CMD_ENC_PIC_BB_SIZE 0x19c
#define CODA_RET_ENC_FRAME_NUM 0x1c0
@@ -306,13 +372,30 @@
#define CODA_CMD_SET_FRAME_BUF_STRIDE 0x184
#define CODA_CMD_SET_FRAME_SLICE_BB_START 0x188
#define CODA_CMD_SET_FRAME_SLICE_BB_SIZE 0x18c
+#define CODA9_CMD_SET_FRAME_SUBSAMP_A 0x188
+#define CODA9_CMD_SET_FRAME_SUBSAMP_B 0x18c
#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_MAX_DEC_SIZE 0x1a4
+#define CODA9_CMD_SET_FRAME_AXI_BTP_ADDR 0x1a4
#define CODA7_CMD_SET_FRAME_SOURCE_BUF_STRIDE 0x1a8
+#define CODA9_CMD_SET_FRAME_CACHE_SIZE 0x1a8
+#define CODA9_CMD_SET_FRAME_CACHE_CONFIG 0x1ac
+#define CODA9_CACHE_BYPASS_OFFSET 28
+#define CODA9_CACHE_DUALCONF_OFFSET 26
+#define CODA9_CACHE_PAGEMERGE_OFFSET 24
+#define CODA9_CACHE_LUMA_BUFFER_SIZE_OFFSET 16
+#define CODA9_CACHE_CB_BUFFER_SIZE_OFFSET 8
+#define CODA9_CACHE_CR_BUFFER_SIZE_OFFSET 0
+#define CODA9_CMD_SET_FRAME_SUBSAMP_A_MVC 0x1b0
+#define CODA9_CMD_SET_FRAME_SUBSAMP_B_MVC 0x1b4
+#define CODA9_CMD_SET_FRAME_DP_BUF_BASE 0x1b0
+#define CODA9_CMD_SET_FRAME_DP_BUF_SIZE 0x1b4
+#define CODA9_CMD_SET_FRAME_MAX_DEC_SIZE 0x1b8
+#define CODA9_CMD_SET_FRAME_DELAY 0x1bc
/* Encoder Header */
#define CODA_CMD_ENC_HEADER_CODE 0x180
@@ -322,8 +405,11 @@
#define CODA_HEADER_MP4V_VOL 0
#define CODA_HEADER_MP4V_VOS 1
#define CODA_HEADER_MP4V_VIS 2
+#define CODA9_HEADER_FRAME_CROP (1 << 3)
#define CODA_CMD_ENC_HEADER_BB_START 0x184
#define CODA_CMD_ENC_HEADER_BB_SIZE 0x188
+#define CODA9_CMD_ENC_HEADER_FRAME_CROP_H 0x18c
+#define CODA9_CMD_ENC_HEADER_FRAME_CROP_V 0x190
/* Get Version */
#define CODA_CMD_FIRMWARE_VERNUM 0x1c0
@@ -334,5 +420,28 @@
#define CODA_FIRMWARE_VERNUM(product, major, minor, release) \
((product) << 16 | ((major) << 12) | \
((minor) << 8) | (release))
+#define CODA9_CMD_FIRMWARE_CODE_REV 0x1c4
+
+#define CODA9_GDMA_BASE 0x1000
+#define CODA9_GDI_WPROT_ERR_CLR (CODA9_GDMA_BASE + 0x0a0)
+#define CODA9_GDI_WPROT_RGN_EN (CODA9_GDMA_BASE + 0x0ac)
+
+#define CODA9_GDI_BUS_CTRL (CODA9_GDMA_BASE + 0x0f0)
+#define CODA9_GDI_BUS_STATUS (CODA9_GDMA_BASE + 0x0f4)
+
+#define CODA9_GDI_XY2_CAS_0 (CODA9_GDMA_BASE + 0x800)
+#define CODA9_GDI_XY2_CAS_F (CODA9_GDMA_BASE + 0x83c)
+
+#define CODA9_GDI_XY2_BA_0 (CODA9_GDMA_BASE + 0x840)
+#define CODA9_GDI_XY2_BA_1 (CODA9_GDMA_BASE + 0x844)
+#define CODA9_GDI_XY2_BA_2 (CODA9_GDMA_BASE + 0x848)
+#define CODA9_GDI_XY2_BA_3 (CODA9_GDMA_BASE + 0x84c)
+
+#define CODA9_GDI_XY2_RAS_0 (CODA9_GDMA_BASE + 0x850)
+#define CODA9_GDI_XY2_RAS_F (CODA9_GDMA_BASE + 0x88c)
+
+#define CODA9_GDI_XY2_RBC_CONFIG (CODA9_GDMA_BASE + 0x890)
+#define CODA9_GDI_RBC2_AXI_0 (CODA9_GDMA_BASE + 0x8a0)
+#define CODA9_GDI_RBC2_AXI_1F (CODA9_GDMA_BASE + 0x91c)
#endif