Resguardo inicial

This commit is contained in:
lastdragon
2026-09-06 12:53:21 -06:00
parent 662efe3c2a
commit ad2088d178
94853 changed files with 43200404 additions and 0 deletions
@@ -0,0 +1,15 @@
# SPDX-License-Identifier: GPL-2.0
config VIDEO_WAVE_VPU
tristate "Chips&Media Wave Codec Driver"
depends on V4L_MEM2MEM_DRIVERS
depends on VIDEO_DEV && OF
depends on ARCH_K3 || COMPILE_TEST
select VIDEOBUF2_DMA_CONTIG
select VIDEOBUF2_VMALLOC
select V4L2_MEM2MEM_DEV
select GENERIC_ALLOCATOR
help
Chips&Media stateful encoder and decoder driver.
The driver supports HEVC and H264 formats.
To compile this driver as modules, choose M here: the
modules will be called wave5.
@@ -0,0 +1,10 @@
# SPDX-License-Identifier: GPL-2.0
obj-$(CONFIG_VIDEO_WAVE_VPU) += wave5.o
wave5-objs += wave5-hw.o \
wave5-vpuapi.o \
wave5-vdi.o \
wave5-vpu-dec.o \
wave5-vpu.o \
wave5-vpu-enc.o \
wave5-helper.o
@@ -0,0 +1,271 @@
// SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause)
/*
* Wave5 series multi-standard codec IP - decoder interface
*
* Copyright (C) 2021-2023 CHIPS&MEDIA INC
*/
#include "wave5-helper.h"
#define DEFAULT_BS_SIZE(width, height) ((width) * (height) / 8 * 3)
const char *state_to_str(enum vpu_instance_state state)
{
switch (state) {
case VPU_INST_STATE_NONE:
return "NONE";
case VPU_INST_STATE_OPEN:
return "OPEN";
case VPU_INST_STATE_INIT_SEQ:
return "INIT_SEQ";
case VPU_INST_STATE_PIC_RUN:
return "PIC_RUN";
case VPU_INST_STATE_STOP:
return "STOP";
default:
return "UNKNOWN";
}
}
int wave5_kfifo_alloc(struct vpu_instance *inst)
{
return kfifo_alloc(&inst->irq_status, 16 * sizeof(int), GFP_KERNEL);
}
void wave5_cleanup_instance(struct vpu_instance *inst, struct file *filp)
{
int i;
/*
* For Wave515 SRAM memory is allocated at
* wave5_vpu_dec_register_device() and freed at
* wave5_vpu_dec_unregister_device().
*/
if (list_is_singular(&inst->list) &&
inst->dev->product_code != WAVE515_CODE)
wave5_vdi_free_sram(inst->dev);
for (i = 0; i < inst->fbc_buf_count; i++)
wave5_vpu_dec_reset_framebuffer(inst, i);
wave5_vdi_free_dma_memory(inst->dev, &inst->bitstream_vbuf);
v4l2_ctrl_handler_free(&inst->v4l2_ctrl_hdl);
if (inst->v4l2_fh.vdev) {
v4l2_fh_del(&inst->v4l2_fh, filp);
v4l2_fh_exit(&inst->v4l2_fh);
}
kfifo_free(&inst->irq_status);
ida_free(&inst->dev->inst_ida, inst->id);
kfree(inst->codec_info);
kfree(inst);
}
int wave5_vpu_release_device(struct file *filp,
int (*close_func)(struct vpu_instance *inst, u32 *fail_res),
char *name)
{
struct vpu_instance *inst = file_to_vpu_inst(filp);
int ret = 0;
unsigned long flags;
/*
* To prevent Null reference exception, the existing irq handler were
* separated to two modules.
* One is to queue interrupt reason into the irq handler,
* the other is irq_thread to call the wave5_vpu_dec_finish_decode
* to get decoded frame.
* The list of instances should be protected between all flow of the
* decoding process, but to protect the list in the irq_handler, spin lock
* should be used, and mutex should be used in the irq_thread because spin lock
* is not able to be used because mutex is already being used
* in the wave5_vpu_dec_finish_decode.
* So the spin lock and mutex were used to protect the list in the release function.
*/
ret = mutex_lock_interruptible(&inst->dev->irq_lock);
if (ret)
return ret;
spin_lock_irqsave(&inst->dev->irq_spinlock, flags);
list_del_init(&inst->list);
spin_unlock_irqrestore(&inst->dev->irq_spinlock, flags);
mutex_unlock(&inst->dev->irq_lock);
v4l2_m2m_ctx_release(inst->v4l2_fh.m2m_ctx);
if (inst->state != VPU_INST_STATE_NONE) {
u32 fail_res;
ret = close_func(inst, &fail_res);
if (fail_res == WAVE5_SYSERR_VPU_STILL_RUNNING) {
dev_err(inst->dev->dev, "%s close failed, device is still running\n",
name);
return -EBUSY;
}
if (ret && ret != -EIO) {
dev_err(inst->dev->dev, "%s close, fail: %d\n", name, ret);
return ret;
}
}
wave5_cleanup_instance(inst, filp);
return ret;
}
int wave5_vpu_queue_init(void *priv, struct vb2_queue *src_vq, struct vb2_queue *dst_vq,
const struct vb2_ops *ops)
{
struct vpu_instance *inst = priv;
int ret;
src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
src_vq->io_modes = VB2_MMAP | VB2_DMABUF;
src_vq->mem_ops = &vb2_dma_contig_memops;
src_vq->ops = ops;
src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
src_vq->buf_struct_size = sizeof(struct vpu_src_buffer);
src_vq->drv_priv = inst;
src_vq->lock = &inst->dev->dev_lock;
src_vq->dev = inst->dev->v4l2_dev.dev;
ret = vb2_queue_init(src_vq);
if (ret)
return ret;
dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
dst_vq->io_modes = VB2_MMAP | VB2_DMABUF;
dst_vq->mem_ops = &vb2_dma_contig_memops;
dst_vq->ops = ops;
dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
dst_vq->buf_struct_size = sizeof(struct vpu_src_buffer);
dst_vq->drv_priv = inst;
dst_vq->lock = &inst->dev->dev_lock;
dst_vq->dev = inst->dev->v4l2_dev.dev;
ret = vb2_queue_init(dst_vq);
if (ret)
return ret;
return 0;
}
int wave5_vpu_subscribe_event(struct v4l2_fh *fh, const struct v4l2_event_subscription *sub)
{
struct vpu_instance *inst = wave5_to_vpu_inst(fh);
bool is_decoder = inst->type == VPU_INST_TYPE_DEC;
dev_dbg(inst->dev->dev, "%s: [%s] type: %u id: %u | flags: %u\n", __func__,
is_decoder ? "decoder" : "encoder", sub->type, sub->id, sub->flags);
switch (sub->type) {
case V4L2_EVENT_EOS:
return v4l2_event_subscribe(fh, sub, 0, NULL);
case V4L2_EVENT_SOURCE_CHANGE:
if (is_decoder)
return v4l2_src_change_event_subscribe(fh, sub);
return -EINVAL;
case V4L2_EVENT_CTRL:
return v4l2_ctrl_subscribe_event(fh, sub);
default:
return -EINVAL;
}
}
int wave5_vpu_g_fmt_out(struct file *file, void *fh, struct v4l2_format *f)
{
struct vpu_instance *inst = file_to_vpu_inst(file);
int i;
f->fmt.pix_mp.width = inst->src_fmt.width;
f->fmt.pix_mp.height = inst->src_fmt.height;
f->fmt.pix_mp.pixelformat = inst->src_fmt.pixelformat;
f->fmt.pix_mp.field = inst->src_fmt.field;
f->fmt.pix_mp.flags = inst->src_fmt.flags;
f->fmt.pix_mp.num_planes = inst->src_fmt.num_planes;
for (i = 0; i < f->fmt.pix_mp.num_planes; i++) {
f->fmt.pix_mp.plane_fmt[i].bytesperline = inst->src_fmt.plane_fmt[i].bytesperline;
f->fmt.pix_mp.plane_fmt[i].sizeimage = inst->src_fmt.plane_fmt[i].sizeimage;
}
f->fmt.pix_mp.colorspace = inst->colorspace;
f->fmt.pix_mp.ycbcr_enc = inst->ycbcr_enc;
f->fmt.pix_mp.quantization = inst->quantization;
f->fmt.pix_mp.xfer_func = inst->xfer_func;
return 0;
}
const struct vpu_format *wave5_find_vpu_fmt(unsigned int v4l2_pix_fmt,
const struct vpu_format fmt_list[MAX_FMTS])
{
unsigned int index;
for (index = 0; index < MAX_FMTS; index++) {
if (fmt_list[index].v4l2_pix_fmt == v4l2_pix_fmt)
return &fmt_list[index];
}
return NULL;
}
const struct vpu_format *wave5_find_vpu_fmt_by_idx(unsigned int idx,
const struct vpu_format fmt_list[MAX_FMTS])
{
if (idx >= MAX_FMTS)
return NULL;
if (!fmt_list[idx].v4l2_pix_fmt)
return NULL;
return &fmt_list[idx];
}
enum wave_std wave5_to_vpu_std(unsigned int v4l2_pix_fmt, enum vpu_instance_type type)
{
switch (v4l2_pix_fmt) {
case V4L2_PIX_FMT_H264:
return type == VPU_INST_TYPE_DEC ? W_AVC_DEC : W_AVC_ENC;
case V4L2_PIX_FMT_HEVC:
return type == VPU_INST_TYPE_DEC ? W_HEVC_DEC : W_HEVC_ENC;
default:
return STD_UNKNOWN;
}
}
void wave5_return_bufs(struct vb2_queue *q, u32 state)
{
struct vpu_instance *inst = vb2_get_drv_priv(q);
struct v4l2_m2m_ctx *m2m_ctx = inst->v4l2_fh.m2m_ctx;
struct v4l2_ctrl_handler v4l2_ctrl_hdl = inst->v4l2_ctrl_hdl;
struct vb2_v4l2_buffer *vbuf;
for (;;) {
if (q->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
vbuf = v4l2_m2m_src_buf_remove(m2m_ctx);
else
vbuf = v4l2_m2m_dst_buf_remove(m2m_ctx);
if (!vbuf)
return;
v4l2_ctrl_request_complete(vbuf->vb2_buf.req_obj.req, &v4l2_ctrl_hdl);
v4l2_m2m_buf_done(vbuf, state);
}
}
void wave5_update_pix_fmt(struct v4l2_pix_format_mplane *pix_mp,
int pix_fmt_type,
unsigned int width,
unsigned int height,
const struct v4l2_frmsize_stepwise *frmsize)
{
v4l2_apply_frmsize_constraints(&width, &height, frmsize);
if (pix_fmt_type == VPU_FMT_TYPE_CODEC) {
pix_mp->width = width;
pix_mp->height = height;
pix_mp->num_planes = 1;
pix_mp->plane_fmt[0].bytesperline = 0;
pix_mp->plane_fmt[0].sizeimage = max(DEFAULT_BS_SIZE(width, height),
pix_mp->plane_fmt[0].sizeimage);
} else {
v4l2_fill_pixfmt_mp(pix_mp, pix_mp->pixelformat, width, height);
}
pix_mp->flags = 0;
pix_mp->field = V4L2_FIELD_NONE;
}
@@ -0,0 +1,37 @@
/* SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) */
/*
* Wave5 series multi-standard codec IP - basic types
*
* Copyright (C) 2021-2023 CHIPS&MEDIA INC
*/
#ifndef __WAVE_HELPER_H__
#define __WAVE_HELPER_H__
#include "wave5-vpu.h"
#define FMT_TYPES 2
#define MAX_FMTS 16
const char *state_to_str(enum vpu_instance_state state);
void wave5_cleanup_instance(struct vpu_instance *inst, struct file *filp);
int wave5_vpu_release_device(struct file *filp,
int (*close_func)(struct vpu_instance *inst, u32 *fail_res),
char *name);
int wave5_vpu_queue_init(void *priv, struct vb2_queue *src_vq, struct vb2_queue *dst_vq,
const struct vb2_ops *ops);
int wave5_vpu_subscribe_event(struct v4l2_fh *fh, const struct v4l2_event_subscription *sub);
int wave5_vpu_g_fmt_out(struct file *file, void *fh, struct v4l2_format *f);
const struct vpu_format *wave5_find_vpu_fmt(unsigned int v4l2_pix_fmt,
const struct vpu_format fmt_list[MAX_FMTS]);
const struct vpu_format *wave5_find_vpu_fmt_by_idx(unsigned int idx,
const struct vpu_format fmt_list[MAX_FMTS]);
enum wave_std wave5_to_vpu_std(unsigned int v4l2_pix_fmt, enum vpu_instance_type type);
void wave5_return_bufs(struct vb2_queue *q, u32 state);
void wave5_update_pix_fmt(struct v4l2_pix_format_mplane *pix_mp,
int pix_fmt_type,
unsigned int width,
unsigned int height,
const struct v4l2_frmsize_stepwise *frmsize);
int wave5_kfifo_alloc(struct vpu_instance *inst);
#endif
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,737 @@
/* SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) */
/*
* Wave5 series multi-standard codec IP - wave5 register definitions
*
* Copyright (C) 2021-2023 CHIPS&MEDIA INC
*/
#ifndef __WAVE5_REGISTER_DEFINE_H__
#define __WAVE5_REGISTER_DEFINE_H__
enum W5_VPU_COMMAND {
W5_INIT_VPU = 0x0001,
W5_WAKEUP_VPU = 0x0002,
W5_SLEEP_VPU = 0x0004,
W5_CREATE_INSTANCE = 0x0008, /* queuing command */
W5_FLUSH_INSTANCE = 0x0010,
W5_DESTROY_INSTANCE = 0x0020, /* queuing command */
W5_INIT_SEQ = 0x0040, /* queuing command */
W5_SET_FB = 0x0080,
W5_DEC_ENC_PIC = 0x0100, /* queuing command */
W5_ENC_SET_PARAM = 0x0200, /* queuing command */
W5_QUERY = 0x4000,
W5_UPDATE_BS = 0x8000,
W5_MAX_VPU_COMD = 0x10000,
};
enum query_opt {
GET_VPU_INFO = 0,
SET_WRITE_PROT = 1,
GET_RESULT = 2,
UPDATE_DISP_FLAG = 3,
GET_BW_REPORT = 4,
GET_BS_RD_PTR = 5, /* for decoder */
GET_BS_WR_PTR = 6, /* for encoder */
GET_SRC_BUF_FLAG = 7, /* for encoder */
SET_BS_RD_PTR = 8, /* for decoder */
GET_DEBUG_INFO = 0x61,
};
#define W5_REG_BASE 0x00000000
#define W5_CMD_REG_BASE 0x00000100
#define W5_CMD_REG_END 0x00000200
/*
* COMMON
*
* ----
*
* Power on configuration
* PO_DEBUG_MODE [0] 1 - power on with debug mode
* USE_PO_CONF [3] 1 - use power-on-configuration
*/
#define W5_PO_CONF (W5_REG_BASE + 0x0000)
#define W5_VCPU_CUR_PC (W5_REG_BASE + 0x0004)
#define W5_VCPU_CUR_LR (W5_REG_BASE + 0x0008)
#define W5_VPU_PDBG_STEP_MASK_V (W5_REG_BASE + 0x000C)
#define W5_VPU_PDBG_CTRL (W5_REG_BASE + 0x0010) /* v_cpu debugger ctrl register */
#define W5_VPU_PDBG_IDX_REG (W5_REG_BASE + 0x0014) /* v_cpu debugger index register */
#define W5_VPU_PDBG_WDATA_REG (W5_REG_BASE + 0x0018) /* v_cpu debugger write data reg */
#define W5_VPU_PDBG_RDATA_REG (W5_REG_BASE + 0x001C) /* v_cpu debugger read data reg */
#define W5_VPU_FIO_CTRL_ADDR (W5_REG_BASE + 0x0020)
#define W5_VPU_FIO_DATA (W5_REG_BASE + 0x0024)
#define W5_VPU_VINT_REASON_USR (W5_REG_BASE + 0x0030)
#define W5_VPU_VINT_REASON_CLR (W5_REG_BASE + 0x0034)
#define W5_VPU_HOST_INT_REQ (W5_REG_BASE + 0x0038)
#define W5_VPU_VINT_CLEAR (W5_REG_BASE + 0x003C)
#define W5_VPU_HINT_CLEAR (W5_REG_BASE + 0x0040)
#define W5_VPU_VPU_INT_STS (W5_REG_BASE + 0x0044)
#define W5_VPU_VINT_ENABLE (W5_REG_BASE + 0x0048)
#define W5_VPU_VINT_REASON (W5_REG_BASE + 0x004C)
#define W5_VPU_RESET_REQ (W5_REG_BASE + 0x0050)
#define W5_RST_BLOCK_CCLK(_core) BIT((_core))
#define W5_RST_BLOCK_CCLK_ALL (0xff)
#define W5_RST_BLOCK_BCLK(_core) (0x100 << (_core))
#define W5_RST_BLOCK_BCLK_ALL (0xff00)
#define W5_RST_BLOCK_ACLK(_core) (0x10000 << (_core))
#define W5_RST_BLOCK_ACLK_ALL (0xff0000)
#define W5_RST_BLOCK_VCPU_ALL (0x3f000000)
#define W5_RST_BLOCK_ALL (0x3fffffff)
#define W5_VPU_RESET_STATUS (W5_REG_BASE + 0x0054)
#define W5_VCPU_RESTART (W5_REG_BASE + 0x0058)
#define W5_VPU_CLK_MASK (W5_REG_BASE + 0x005C)
/* REMAP_CTRL
* PAGE SIZE: [8:0] 0x001 - 4K
* 0x002 - 8K
* 0x004 - 16K
* ...
* 0x100 - 1M
* REGION ATTR1 [10] 0 - normal
* 1 - make bus error for the region
* REGION ATTR2 [11] 0 - normal
* 1 - bypass region
* REMAP INDEX [15:12] - 0 ~ 3
* ENDIAN [19:16] - NOTE: Currently not supported in this driver
* AXI-ID [23:20] - upper AXI-ID
* BUS_ERROR [29] 0 - bypass
* 1 - make BUS_ERROR for unmapped region
* BYPASS_ALL [30] 1 - bypass all
* ENABLE [31] 1 - update control register[30:16]
*/
#define W5_VPU_REMAP_CTRL (W5_REG_BASE + 0x0060)
#define W5_VPU_REMAP_VADDR (W5_REG_BASE + 0x0064)
#define W5_VPU_REMAP_PADDR (W5_REG_BASE + 0x0068)
#define W5_VPU_REMAP_CORE_START (W5_REG_BASE + 0x006C)
#define W5_VPU_BUSY_STATUS (W5_REG_BASE + 0x0070)
#define W5_VPU_HALT_STATUS (W5_REG_BASE + 0x0074)
#define W5_VPU_VCPU_STATUS (W5_REG_BASE + 0x0078)
#define W5_VPU_RET_PRODUCT_VERSION (W5_REG_BASE + 0x0094)
/*
* assign vpu_config0 = {conf_map_converter_reg, // [31]
* conf_map_converter_sig, // [30]
* 8'd0, // [29:22]
* conf_std_switch_en, // [21]
* conf_bg_detect, // [20]
* conf_3dnr_en, // [19]
* conf_one_axi_en, // [18]
* conf_sec_axi_en, // [17]
* conf_bus_info, // [16]
* conf_afbc_en, // [15]
* conf_afbc_version_id, // [14:12]
* conf_fbc_en, // [11]
* conf_fbc_version_id, // [10:08]
* conf_scaler_en, // [07]
* conf_scaler_version_id, // [06:04]
* conf_bwb_en, // [03]
* 3'd0}; // [02:00]
*/
#define W5_VPU_RET_VPU_CONFIG0 (W5_REG_BASE + 0x0098)
/*
* assign vpu_config1 = {4'd0, // [31:28]
* conf_perf_timer_en, // [27]
* conf_multi_core_en, // [26]
* conf_gcu_en, // [25]
* conf_cu_report, // [24]
* 4'd0, // [23:20]
* conf_vcore_id_3, // [19]
* conf_vcore_id_2, // [18]
* conf_vcore_id_1, // [17]
* conf_vcore_id_0, // [16]
* conf_bwb_opt, // [15]
* 7'd0, // [14:08]
* conf_cod_std_en_reserved_7, // [7]
* conf_cod_std_en_reserved_6, // [6]
* conf_cod_std_en_reserved_5, // [5]
* conf_cod_std_en_reserved_4, // [4]
* conf_cod_std_en_reserved_3, // [3]
* conf_cod_std_en_reserved_2, // [2]
* conf_cod_std_en_vp9, // [1]
* conf_cod_std_en_hevc}; // [0]
* }
*/
#define W5_VPU_RET_VPU_CONFIG1 (W5_REG_BASE + 0x009C)
#define W5_VPU_DBG_REG0 (W5_REG_BASE + 0x00f0)
#define W5_VPU_DBG_REG1 (W5_REG_BASE + 0x00f4)
#define W5_VPU_DBG_REG2 (W5_REG_BASE + 0x00f8)
#define W5_VPU_DBG_REG3 (W5_REG_BASE + 0x00fc)
/************************************************************************/
/* PRODUCT INFORMATION */
/************************************************************************/
#define W5_PRODUCT_NAME (W5_REG_BASE + 0x1040)
#define W5_PRODUCT_NUMBER (W5_REG_BASE + 0x1044)
/************************************************************************/
/* DECODER/ENCODER COMMON */
/************************************************************************/
#define W5_COMMAND (W5_REG_BASE + 0x0100)
#define W5_COMMAND_OPTION (W5_REG_BASE + 0x0104)
#define W5_QUERY_OPTION (W5_REG_BASE + 0x0104)
#define W5_RET_SUCCESS (W5_REG_BASE + 0x0108)
#define W5_RET_FAIL_REASON (W5_REG_BASE + 0x010C)
#define W5_RET_QUEUE_FAIL_REASON (W5_REG_BASE + 0x0110)
#define W5_CMD_INSTANCE_INFO (W5_REG_BASE + 0x0110)
#define W5_RET_QUEUE_STATUS (W5_REG_BASE + 0x01E0)
#define W5_RET_BS_EMPTY_INST (W5_REG_BASE + 0x01E4)
#define W5_RET_QUEUE_CMD_DONE_INST (W5_REG_BASE + 0x01E8)
#define W5_RET_STAGE0_INSTANCE_INFO (W5_REG_BASE + 0x01EC)
#define W5_RET_STAGE1_INSTANCE_INFO (W5_REG_BASE + 0x01F0)
#define W5_RET_STAGE2_INSTANCE_INFO (W5_REG_BASE + 0x01F4)
#define W5_RET_SEQ_DONE_INSTANCE_INFO (W5_REG_BASE + 0x01FC)
#define W5_BS_OPTION (W5_REG_BASE + 0x0120)
/* return info when QUERY (GET_RESULT) for en/decoder */
#define W5_RET_VLC_BUF_SIZE (W5_REG_BASE + 0x01B0)
/* return info when QUERY (GET_RESULT) for en/decoder */
#define W5_RET_PARAM_BUF_SIZE (W5_REG_BASE + 0x01B4)
/* set when SET_FB for en/decoder */
#define W5_CMD_SET_FB_ADDR_TASK_BUF (W5_REG_BASE + 0x01D4)
#define W5_CMD_SET_FB_TASK_BUF_SIZE (W5_REG_BASE + 0x01D8)
/************************************************************************/
/* INIT_VPU - COMMON */
/************************************************************************/
/* note: W5_ADDR_CODE_BASE should be aligned to 4KB */
#define W5_ADDR_CODE_BASE (W5_REG_BASE + 0x0110)
#define W5_CODE_SIZE (W5_REG_BASE + 0x0114)
#define W5_CODE_PARAM (W5_REG_BASE + 0x0118)
#define W5_ADDR_TEMP_BASE (W5_REG_BASE + 0x011C)
#define W5_TEMP_SIZE (W5_REG_BASE + 0x0120)
#define W5_HW_OPTION (W5_REG_BASE + 0x012C)
#define W5_CMD_INIT_NUM_TASK_BUF (W5_REG_BASE + 0x0134)
#define W5_CMD_INIT_ADDR_TASK_BUF0 (W5_REG_BASE + 0x0138)
#define W5_CMD_INIT_TASK_BUF_SIZE (W5_REG_BASE + 0x0178)
#define W5_SEC_AXI_PARAM (W5_REG_BASE + 0x0180)
/************************************************************************/
/* CREATE_INSTANCE - COMMON */
/************************************************************************/
#define W5_ADDR_WORK_BASE (W5_REG_BASE + 0x0114)
#define W5_WORK_SIZE (W5_REG_BASE + 0x0118)
#define W5_CMD_DEC_BS_START_ADDR (W5_REG_BASE + 0x011C)
#define W5_CMD_DEC_BS_SIZE (W5_REG_BASE + 0x0120)
#define W5_CMD_BS_PARAM (W5_REG_BASE + 0x0124)
#define W5_CMD_ADDR_SEC_AXI (W5_REG_BASE + 0x0130)
#define W515_CMD_ADDR_SEC_AXI (W5_REG_BASE + 0x0124)
#define W5_CMD_SEC_AXI_SIZE (W5_REG_BASE + 0x0134)
#define W515_CMD_SEC_AXI_SIZE (W5_REG_BASE + 0x0128)
#define W5_CMD_EXT_ADDR (W5_REG_BASE + 0x0138)
#define W5_CMD_NUM_CQ_DEPTH_M1 (W5_REG_BASE + 0x013C)
#define W5_CMD_ERR_CONCEAL (W5_REG_BASE + 0x0140)
/************************************************************************/
/* DECODER - INIT_SEQ */
/************************************************************************/
#define W5_BS_RD_PTR (W5_REG_BASE + 0x0118)
#define W5_BS_WR_PTR (W5_REG_BASE + 0x011C)
/************************************************************************/
/* SET_FRAME_BUF */
/************************************************************************/
/* SET_FB_OPTION 0x00 REGISTER FRAMEBUFFERS
* 0x01 UPDATE FRAMEBUFFER, just one framebuffer(linear, fbc and mvcol)
*/
#define W5_SFB_OPTION (W5_REG_BASE + 0x0104)
#define W5_COMMON_PIC_INFO (W5_REG_BASE + 0x0118)
#define W5_PIC_SIZE (W5_REG_BASE + 0x011C)
#define W5_SET_FB_NUM (W5_REG_BASE + 0x0120)
#define W5_EXTRA_PIC_INFO (W5_REG_BASE + 0x0124)
#define W5_ADDR_LUMA_BASE0 (W5_REG_BASE + 0x0134)
#define W5_ADDR_CB_BASE0 (W5_REG_BASE + 0x0138)
#define W5_ADDR_CR_BASE0 (W5_REG_BASE + 0x013C)
/* compression offset table for luma */
#define W5_ADDR_FBC_Y_OFFSET0 (W5_REG_BASE + 0x013C)
/* compression offset table for chroma */
#define W5_ADDR_FBC_C_OFFSET0 (W5_REG_BASE + 0x0140)
#define W5_ADDR_LUMA_BASE1 (W5_REG_BASE + 0x0144)
#define W5_ADDR_CB_ADDR1 (W5_REG_BASE + 0x0148)
#define W5_ADDR_CR_ADDR1 (W5_REG_BASE + 0x014C)
/* compression offset table for luma */
#define W5_ADDR_FBC_Y_OFFSET1 (W5_REG_BASE + 0x014C)
/* compression offset table for chroma */
#define W5_ADDR_FBC_C_OFFSET1 (W5_REG_BASE + 0x0150)
#define W5_ADDR_LUMA_BASE2 (W5_REG_BASE + 0x0154)
#define W5_ADDR_CB_ADDR2 (W5_REG_BASE + 0x0158)
#define W5_ADDR_CR_ADDR2 (W5_REG_BASE + 0x015C)
/* compression offset table for luma */
#define W5_ADDR_FBC_Y_OFFSET2 (W5_REG_BASE + 0x015C)
/* compression offset table for chroma */
#define W5_ADDR_FBC_C_OFFSET2 (W5_REG_BASE + 0x0160)
#define W5_ADDR_LUMA_BASE3 (W5_REG_BASE + 0x0164)
#define W5_ADDR_CB_ADDR3 (W5_REG_BASE + 0x0168)
#define W5_ADDR_CR_ADDR3 (W5_REG_BASE + 0x016C)
/* compression offset table for luma */
#define W5_ADDR_FBC_Y_OFFSET3 (W5_REG_BASE + 0x016C)
/* compression offset table for chroma */
#define W5_ADDR_FBC_C_OFFSET3 (W5_REG_BASE + 0x0170)
#define W5_ADDR_LUMA_BASE4 (W5_REG_BASE + 0x0174)
#define W5_ADDR_CB_ADDR4 (W5_REG_BASE + 0x0178)
#define W5_ADDR_CR_ADDR4 (W5_REG_BASE + 0x017C)
/* compression offset table for luma */
#define W5_ADDR_FBC_Y_OFFSET4 (W5_REG_BASE + 0x017C)
/* compression offset table for chroma */
#define W5_ADDR_FBC_C_OFFSET4 (W5_REG_BASE + 0x0180)
#define W5_ADDR_LUMA_BASE5 (W5_REG_BASE + 0x0184)
#define W5_ADDR_CB_ADDR5 (W5_REG_BASE + 0x0188)
#define W5_ADDR_CR_ADDR5 (W5_REG_BASE + 0x018C)
/* compression offset table for luma */
#define W5_ADDR_FBC_Y_OFFSET5 (W5_REG_BASE + 0x018C)
/* compression offset table for chroma */
#define W5_ADDR_FBC_C_OFFSET5 (W5_REG_BASE + 0x0190)
#define W5_ADDR_LUMA_BASE6 (W5_REG_BASE + 0x0194)
#define W5_ADDR_CB_ADDR6 (W5_REG_BASE + 0x0198)
#define W5_ADDR_CR_ADDR6 (W5_REG_BASE + 0x019C)
/* compression offset table for luma */
#define W5_ADDR_FBC_Y_OFFSET6 (W5_REG_BASE + 0x019C)
/* compression offset table for chroma */
#define W5_ADDR_FBC_C_OFFSET6 (W5_REG_BASE + 0x01A0)
#define W5_ADDR_LUMA_BASE7 (W5_REG_BASE + 0x01A4)
#define W5_ADDR_CB_ADDR7 (W5_REG_BASE + 0x01A8)
#define W5_ADDR_CR_ADDR7 (W5_REG_BASE + 0x01AC)
/* compression offset table for luma */
#define W5_ADDR_FBC_Y_OFFSET7 (W5_REG_BASE + 0x01AC)
/* compression offset table for chroma */
#define W5_ADDR_FBC_C_OFFSET7 (W5_REG_BASE + 0x01B0)
#define W5_ADDR_MV_COL0 (W5_REG_BASE + 0x01B4)
#define W5_ADDR_MV_COL1 (W5_REG_BASE + 0x01B8)
#define W5_ADDR_MV_COL2 (W5_REG_BASE + 0x01BC)
#define W5_ADDR_MV_COL3 (W5_REG_BASE + 0x01C0)
#define W5_ADDR_MV_COL4 (W5_REG_BASE + 0x01C4)
#define W5_ADDR_MV_COL5 (W5_REG_BASE + 0x01C8)
#define W5_ADDR_MV_COL6 (W5_REG_BASE + 0x01CC)
#define W5_ADDR_MV_COL7 (W5_REG_BASE + 0x01D0)
/* UPDATE_FB */
/* CMD_SET_FB_STRIDE [15:0] - FBC framebuffer stride
* [31:15] - linear framebuffer stride
*/
#define W5_CMD_SET_FB_STRIDE (W5_REG_BASE + 0x0118)
#define W5_CMD_SET_FB_INDEX (W5_REG_BASE + 0x0120)
#define W5_ADDR_LUMA_BASE (W5_REG_BASE + 0x0134)
#define W5_ADDR_CB_BASE (W5_REG_BASE + 0x0138)
#define W5_ADDR_CR_BASE (W5_REG_BASE + 0x013C)
#define W5_ADDR_MV_COL (W5_REG_BASE + 0x0140)
#define W5_ADDR_FBC_Y_BASE (W5_REG_BASE + 0x0144)
#define W5_ADDR_FBC_C_BASE (W5_REG_BASE + 0x0148)
#define W5_ADDR_FBC_Y_OFFSET (W5_REG_BASE + 0x014C)
#define W5_ADDR_FBC_C_OFFSET (W5_REG_BASE + 0x0150)
/************************************************************************/
/* DECODER - DEC_PIC */
/************************************************************************/
#define W5_CMD_DEC_VCORE_INFO (W5_REG_BASE + 0x0194)
/* sequence change enable mask register
* CMD_SEQ_CHANGE_ENABLE_FLAG [5] profile_idc
* [16] pic_width/height_in_luma_sample
* [19] sps_max_dec_pic_buffering, max_num_reorder, max_latency_increase
*/
#define W5_CMD_SEQ_CHANGE_ENABLE_FLAG (W5_REG_BASE + 0x0128)
#define W5_CMD_DEC_USER_MASK (W5_REG_BASE + 0x012C)
#define W5_CMD_DEC_TEMPORAL_ID_PLUS1 (W5_REG_BASE + 0x0130)
#define W5_CMD_DEC_FORCE_FB_LATENCY_PLUS1 (W5_REG_BASE + 0x0134)
#define W5_USE_SEC_AXI (W5_REG_BASE + 0x0150)
/************************************************************************/
/* DECODER - QUERY : GET_VPU_INFO */
/************************************************************************/
#define W5_RET_FW_VERSION (W5_REG_BASE + 0x0118)
#define W5_RET_PRODUCT_NAME (W5_REG_BASE + 0x011C)
#define W5_RET_PRODUCT_VERSION (W5_REG_BASE + 0x0120)
#define W5_RET_STD_DEF0 (W5_REG_BASE + 0x0124)
#define W5_RET_STD_DEF1 (W5_REG_BASE + 0x0128)
#define W5_RET_CONF_FEATURE (W5_REG_BASE + 0x012C)
#define W5_RET_CONF_DATE (W5_REG_BASE + 0x0130)
#define W5_RET_CONF_REVISION (W5_REG_BASE + 0x0134)
#define W5_RET_CONF_TYPE (W5_REG_BASE + 0x0138)
#define W5_RET_PRODUCT_ID (W5_REG_BASE + 0x013C)
#define W5_RET_CUSTOMER_ID (W5_REG_BASE + 0x0140)
/************************************************************************/
/* DECODER - QUERY : GET_RESULT */
/************************************************************************/
#define W5_CMD_DEC_ADDR_REPORT_BASE (W5_REG_BASE + 0x0114)
#define W5_CMD_DEC_REPORT_SIZE (W5_REG_BASE + 0x0118)
#define W5_CMD_DEC_REPORT_PARAM (W5_REG_BASE + 0x011C)
#define W5_RET_DEC_BS_RD_PTR (W5_REG_BASE + 0x011C)
#define W5_RET_DEC_SEQ_PARAM (W5_REG_BASE + 0x0120)
#define W5_RET_DEC_COLOR_SAMPLE_INFO (W5_REG_BASE + 0x0124)
#define W5_RET_DEC_ASPECT_RATIO (W5_REG_BASE + 0x0128)
#define W5_RET_DEC_BIT_RATE (W5_REG_BASE + 0x012C)
#define W5_RET_DEC_FRAME_RATE_NR (W5_REG_BASE + 0x0130)
#define W5_RET_DEC_FRAME_RATE_DR (W5_REG_BASE + 0x0134)
#define W5_RET_DEC_NUM_REQUIRED_FB (W5_REG_BASE + 0x0138)
#define W5_RET_DEC_NUM_REORDER_DELAY (W5_REG_BASE + 0x013C)
#define W5_RET_DEC_SUB_LAYER_INFO (W5_REG_BASE + 0x0140)
#define W5_RET_DEC_NOTIFICATION (W5_REG_BASE + 0x0144)
/*
* USER_DATA_FLAGS for HEVC/H264 only.
* Bits:
* [1] - User data buffer full boolean
* [2] - VUI parameter flag
* [4] - Pic_timing SEI flag
* [5] - 1st user_data_registed_itu_t_t35 prefix SEI flag
* [6] - user_data_unregistered prefix SEI flag
* [7] - 1st user_data_registed_itu_t_t35 suffix SEI flag
* [8] - user_data_unregistered suffix SEI flag
* [10]- mastering_display_color_volume prefix SEI flag
* [11]- chroma_resampling_display_color_volume prefix SEI flag
* [12]- knee_function_info SEI flag
* [13]- tone_mapping_info prefix SEI flag
* [14]- film_grain_characteristics_info prefix SEI flag
* [15]- content_light_level_info prefix SEI flag
* [16]- color_remapping_info prefix SEI flag
* [28]- 2nd user_data_registed_itu_t_t35 prefix SEI flag
* [29]- 3rd user_data_registed_itu_t_t35 prefix SEI flag
* [30]- 2nd user_data_registed_itu_t_t35 suffix SEI flag
* [31]- 3rd user_data_registed_itu_t_t35 suffix SEI flag
*/
#define W5_RET_DEC_USERDATA_IDC (W5_REG_BASE + 0x0148)
#define W5_RET_DEC_PIC_SIZE (W5_REG_BASE + 0x014C)
#define W5_RET_DEC_CROP_TOP_BOTTOM (W5_REG_BASE + 0x0150)
#define W5_RET_DEC_CROP_LEFT_RIGHT (W5_REG_BASE + 0x0154)
/*
* #define W5_RET_DEC_AU_START_POS (W5_REG_BASE + 0x0158)
* => Access unit (AU) Bitstream start position
* #define W5_RET_DEC_AU_END_POS (W5_REG_BASE + 0x015C)
* => Access unit (AU) Bitstream end position
*/
/*
* Decoded picture type:
* reg_val & 0x7 => picture type
* (reg_val >> 4) & 0x3f => VCL NAL unit type
* (reg_val >> 31) & 0x1 => output_flag
* 16 << ((reg_val >> 10) & 0x3) => ctu_size
*/
#define W5_RET_DEC_PIC_TYPE (W5_REG_BASE + 0x0160)
#define W5_RET_DEC_PIC_POC (W5_REG_BASE + 0x0164)
/*
* #define W5_RET_DEC_RECOVERY_POINT (W5_REG_BASE + 0x0168)
* => HEVC recovery point
* reg_val & 0xff => number of signed recovery picture order counts
* (reg_val >> 16) & 0x1 => exact match flag
* (reg_val >> 17) & 0x1 => broken link flag
* (reg_val >> 18) & 0x1 => exist flag
*/
#define W5_RET_DEC_DEBUG_INDEX (W5_REG_BASE + 0x016C)
#define W5_RET_DEC_DECODED_INDEX (W5_REG_BASE + 0x0170)
#define W5_RET_DEC_DISPLAY_INDEX (W5_REG_BASE + 0x0174)
/*
* #define W5_RET_DEC_REALLOC_INDEX (W5_REG_BASE + 0x0178)
* => display picture index in decoded picture buffer
* reg_val & 0xf => display picture index for FBC buffer (by reordering)
*/
#define W5_RET_DEC_DISP_IDC (W5_REG_BASE + 0x017C)
/*
* #define W5_RET_DEC_ERR_CTB_NUM (W5_REG_BASE + 0x0180)
* => Number of error CTUs
* reg_val >> 16 => erroneous CTUs in bitstream
* reg_val & 0xffff => total CTUs in bitstream
*
* #define W5_RET_DEC_PIC_PARAM (W5_REG_BASE + 0x01A0)
* => Bitstream sequence/picture parameter information (AV1 only)
* reg_val & 0x1 => intrabc tool enable
* (reg_val >> 1) & 0x1 => screen content tools enable
*/
#define W5_RET_DEC_HOST_CMD_TICK (W5_REG_BASE + 0x01B8)
/*
* #define W5_RET_DEC_SEEK_START_TICK (W5_REG_BASE + 0x01BC)
* #define W5_RET_DEC_SEEK_END_TICK (W5_REG_BASE + 0x01C0)
* => Start and end ticks for seeking slices of the picture
* #define W5_RET_DEC_PARSING_START_TICK (W5_REG_BASE + 0x01C4)
* #define W5_RET_DEC_PARSING_END_TICK (W5_REG_BASE + 0x01C8)
* => Start and end ticks for parsing slices of the picture
* #define W5_RET_DEC_DECODING_START_TICK (W5_REG_BASE + 0x01CC)
* => Start tick for decoding slices of the picture
*/
#define W5_RET_DEC_DECODING_ENC_TICK (W5_REG_BASE + 0x01D0)
#define W5_RET_DEC_WARN_INFO (W5_REG_BASE + 0x01D4)
#define W5_RET_DEC_ERR_INFO (W5_REG_BASE + 0x01D8)
#define W5_RET_DEC_DECODING_SUCCESS (W5_REG_BASE + 0x01DC)
/************************************************************************/
/* DECODER - FLUSH_INSTANCE */
/************************************************************************/
#define W5_CMD_FLUSH_INST_OPT (W5_REG_BASE + 0x104)
/************************************************************************/
/* DECODER - QUERY : UPDATE_DISP_FLAG */
/************************************************************************/
#define W5_CMD_DEC_SET_DISP_IDC (W5_REG_BASE + 0x0118)
#define W5_CMD_DEC_CLR_DISP_IDC (W5_REG_BASE + 0x011C)
/************************************************************************/
/* DECODER - QUERY : SET_BS_RD_PTR */
/************************************************************************/
#define W5_RET_QUERY_DEC_SET_BS_RD_PTR (W5_REG_BASE + 0x011C)
/************************************************************************/
/* DECODER - QUERY : GET_BS_RD_PTR */
/************************************************************************/
#define W5_RET_QUERY_DEC_BS_RD_PTR (W5_REG_BASE + 0x011C)
/************************************************************************/
/* QUERY : GET_DEBUG_INFO */
/************************************************************************/
#define W5_RET_QUERY_DEBUG_PRI_REASON (W5_REG_BASE + 0x114)
/************************************************************************/
/* GDI register for debugging */
/************************************************************************/
#define W5_GDI_BASE 0x8800
#define W5_GDI_BUS_CTRL (W5_GDI_BASE + 0x0F0)
#define W5_GDI_BUS_STATUS (W5_GDI_BASE + 0x0F4)
#define W5_BACKBONE_BASE_VCPU 0xFE00
#define W5_BACKBONE_BUS_CTRL_VCPU (W5_BACKBONE_BASE_VCPU + 0x010)
#define W5_BACKBONE_BUS_STATUS_VCPU (W5_BACKBONE_BASE_VCPU + 0x014)
#define W5_BACKBONE_PROG_AXI_ID (W5_BACKBONE_BASE_VCPU + 0x00C)
#define W5_BACKBONE_PROC_EXT_ADDR (W5_BACKBONE_BASE_VCPU + 0x0C0)
#define W5_BACKBONE_AXI_PARAM (W5_BACKBONE_BASE_VCPU + 0x0E0)
#define W5_BACKBONE_BASE_VCORE0 0x8E00
#define W5_BACKBONE_BUS_CTRL_VCORE0 (W5_BACKBONE_BASE_VCORE0 + 0x010)
#define W5_BACKBONE_BUS_STATUS_VCORE0 (W5_BACKBONE_BASE_VCORE0 + 0x014)
#define W5_BACKBONE_BASE_VCORE1 0x9E00 /* for dual-core product */
#define W5_BACKBONE_BUS_CTRL_VCORE1 (W5_BACKBONE_BASE_VCORE1 + 0x010)
#define W5_BACKBONE_BUS_STATUS_VCORE1 (W5_BACKBONE_BASE_VCORE1 + 0x014)
#define W5_COMBINED_BACKBONE_BASE 0xFE00
#define W5_COMBINED_BACKBONE_BUS_CTRL (W5_COMBINED_BACKBONE_BASE + 0x010)
#define W5_COMBINED_BACKBONE_BUS_STATUS (W5_COMBINED_BACKBONE_BASE + 0x014)
/************************************************************************/
/* */
/* for ENCODER */
/* */
/************************************************************************/
#define W5_RET_STAGE3_INSTANCE_INFO (W5_REG_BASE + 0x1F8)
/************************************************************************/
/* ENCODER - CREATE_INSTANCE */
/************************************************************************/
/* 0x114 ~ 0x124 : defined above (CREATE_INSTANCE COMMON) */
#define W5_CMD_ENC_VCORE_INFO (W5_REG_BASE + 0x0194)
#define W5_CMD_ENC_SRC_OPTIONS (W5_REG_BASE + 0x0128)
/************************************************************************/
/* ENCODER - SET_FB */
/************************************************************************/
#define W5_FBC_STRIDE (W5_REG_BASE + 0x128)
#define W5_ADDR_SUB_SAMPLED_FB_BASE (W5_REG_BASE + 0x12C)
#define W5_SUB_SAMPLED_ONE_FB_SIZE (W5_REG_BASE + 0x130)
/************************************************************************/
/* ENCODER - ENC_SET_PARAM (COMMON & CHANGE_PARAM) */
/************************************************************************/
#define W5_CMD_ENC_SEQ_SET_PARAM_OPTION (W5_REG_BASE + 0x104)
#define W5_CMD_ENC_SEQ_SET_PARAM_ENABLE (W5_REG_BASE + 0x118)
#define W5_CMD_ENC_SEQ_SRC_SIZE (W5_REG_BASE + 0x11C)
#define W5_CMD_ENC_SEQ_CUSTOM_MAP_ENDIAN (W5_REG_BASE + 0x120)
#define W5_CMD_ENC_SEQ_SPS_PARAM (W5_REG_BASE + 0x124)
#define W5_CMD_ENC_SEQ_PPS_PARAM (W5_REG_BASE + 0x128)
#define W5_CMD_ENC_SEQ_GOP_PARAM (W5_REG_BASE + 0x12C)
#define W5_CMD_ENC_SEQ_INTRA_PARAM (W5_REG_BASE + 0x130)
#define W5_CMD_ENC_SEQ_CONF_WIN_TOP_BOT (W5_REG_BASE + 0x134)
#define W5_CMD_ENC_SEQ_CONF_WIN_LEFT_RIGHT (W5_REG_BASE + 0x138)
#define W5_CMD_ENC_SEQ_RDO_PARAM (W5_REG_BASE + 0x13C)
#define W5_CMD_ENC_SEQ_INDEPENDENT_SLICE (W5_REG_BASE + 0x140)
#define W5_CMD_ENC_SEQ_DEPENDENT_SLICE (W5_REG_BASE + 0x144)
#define W5_CMD_ENC_SEQ_INTRA_REFRESH (W5_REG_BASE + 0x148)
#define W5_CMD_ENC_SEQ_INPUT_SRC_PARAM (W5_REG_BASE + 0x14C)
#define W5_CMD_ENC_SEQ_RC_FRAME_RATE (W5_REG_BASE + 0x150)
#define W5_CMD_ENC_SEQ_RC_TARGET_RATE (W5_REG_BASE + 0x154)
#define W5_CMD_ENC_SEQ_RC_PARAM (W5_REG_BASE + 0x158)
#define W5_CMD_ENC_SEQ_RC_MIN_MAX_QP (W5_REG_BASE + 0x15C)
#define W5_CMD_ENC_SEQ_RC_BIT_RATIO_LAYER_0_3 (W5_REG_BASE + 0x160)
#define W5_CMD_ENC_SEQ_RC_BIT_RATIO_LAYER_4_7 (W5_REG_BASE + 0x164)
#define W5_CMD_ENC_SEQ_RC_INTER_MIN_MAX_QP (W5_REG_BASE + 0x168)
#define W5_CMD_ENC_SEQ_RC_WEIGHT_PARAM (W5_REG_BASE + 0x16C)
#define W5_CMD_ENC_SEQ_ROT_PARAM (W5_REG_BASE + 0x170)
#define W5_CMD_ENC_SEQ_NUM_UNITS_IN_TICK (W5_REG_BASE + 0x174)
#define W5_CMD_ENC_SEQ_TIME_SCALE (W5_REG_BASE + 0x178)
#define W5_CMD_ENC_SEQ_NUM_TICKS_POC_DIFF_ONE (W5_REG_BASE + 0x17C)
#define W5_CMD_ENC_SEQ_CUSTOM_MD_PU04 (W5_REG_BASE + 0x184)
#define W5_CMD_ENC_SEQ_CUSTOM_MD_PU08 (W5_REG_BASE + 0x188)
#define W5_CMD_ENC_SEQ_CUSTOM_MD_PU16 (W5_REG_BASE + 0x18C)
#define W5_CMD_ENC_SEQ_CUSTOM_MD_PU32 (W5_REG_BASE + 0x190)
#define W5_CMD_ENC_SEQ_CUSTOM_MD_CU08 (W5_REG_BASE + 0x194)
#define W5_CMD_ENC_SEQ_CUSTOM_MD_CU16 (W5_REG_BASE + 0x198)
#define W5_CMD_ENC_SEQ_CUSTOM_MD_CU32 (W5_REG_BASE + 0x19C)
#define W5_CMD_ENC_SEQ_NR_PARAM (W5_REG_BASE + 0x1A0)
#define W5_CMD_ENC_SEQ_NR_WEIGHT (W5_REG_BASE + 0x1A4)
#define W5_CMD_ENC_SEQ_BG_PARAM (W5_REG_BASE + 0x1A8)
#define W5_CMD_ENC_SEQ_CUSTOM_LAMBDA_ADDR (W5_REG_BASE + 0x1AC)
#define W5_CMD_ENC_SEQ_USER_SCALING_LIST_ADDR (W5_REG_BASE + 0x1B0)
#define W5_CMD_ENC_SEQ_VUI_HRD_PARAM (W5_REG_BASE + 0x180)
#define W5_CMD_ENC_SEQ_VUI_RBSP_ADDR (W5_REG_BASE + 0x1B8)
#define W5_CMD_ENC_SEQ_HRD_RBSP_ADDR (W5_REG_BASE + 0x1BC)
/************************************************************************/
/* ENCODER - ENC_SET_PARAM (CUSTOM_GOP) */
/************************************************************************/
#define W5_CMD_ENC_CUSTOM_GOP_PARAM (W5_REG_BASE + 0x11C)
#define W5_CMD_ENC_CUSTOM_GOP_PIC_PARAM_0 (W5_REG_BASE + 0x120)
#define W5_CMD_ENC_CUSTOM_GOP_PIC_PARAM_1 (W5_REG_BASE + 0x124)
#define W5_CMD_ENC_CUSTOM_GOP_PIC_PARAM_2 (W5_REG_BASE + 0x128)
#define W5_CMD_ENC_CUSTOM_GOP_PIC_PARAM_3 (W5_REG_BASE + 0x12C)
#define W5_CMD_ENC_CUSTOM_GOP_PIC_PARAM_4 (W5_REG_BASE + 0x130)
#define W5_CMD_ENC_CUSTOM_GOP_PIC_PARAM_5 (W5_REG_BASE + 0x134)
#define W5_CMD_ENC_CUSTOM_GOP_PIC_PARAM_6 (W5_REG_BASE + 0x138)
#define W5_CMD_ENC_CUSTOM_GOP_PIC_PARAM_7 (W5_REG_BASE + 0x13C)
#define W5_CMD_ENC_CUSTOM_GOP_PIC_PARAM_8 (W5_REG_BASE + 0x140)
#define W5_CMD_ENC_CUSTOM_GOP_PIC_PARAM_9 (W5_REG_BASE + 0x144)
#define W5_CMD_ENC_CUSTOM_GOP_PIC_PARAM_10 (W5_REG_BASE + 0x148)
#define W5_CMD_ENC_CUSTOM_GOP_PIC_PARAM_11 (W5_REG_BASE + 0x14C)
#define W5_CMD_ENC_CUSTOM_GOP_PIC_PARAM_12 (W5_REG_BASE + 0x150)
#define W5_CMD_ENC_CUSTOM_GOP_PIC_PARAM_13 (W5_REG_BASE + 0x154)
#define W5_CMD_ENC_CUSTOM_GOP_PIC_PARAM_14 (W5_REG_BASE + 0x158)
#define W5_CMD_ENC_CUSTOM_GOP_PIC_PARAM_15 (W5_REG_BASE + 0x15C)
/************************************************************************/
/* ENCODER - ENC_PIC */
/************************************************************************/
#define W5_CMD_ENC_BS_START_ADDR (W5_REG_BASE + 0x118)
#define W5_CMD_ENC_BS_SIZE (W5_REG_BASE + 0x11C)
#define W5_CMD_ENC_PIC_USE_SEC_AXI (W5_REG_BASE + 0x124)
#define W5_CMD_ENC_PIC_REPORT_PARAM (W5_REG_BASE + 0x128)
#define W5_CMD_ENC_PIC_CUSTOM_MAP_OPTION_PARAM (W5_REG_BASE + 0x138)
#define W5_CMD_ENC_PIC_CUSTOM_MAP_OPTION_ADDR (W5_REG_BASE + 0x13C)
#define W5_CMD_ENC_PIC_SRC_PIC_IDX (W5_REG_BASE + 0x144)
#define W5_CMD_ENC_PIC_SRC_ADDR_Y (W5_REG_BASE + 0x148)
#define W5_CMD_ENC_PIC_SRC_ADDR_U (W5_REG_BASE + 0x14C)
#define W5_CMD_ENC_PIC_SRC_ADDR_V (W5_REG_BASE + 0x150)
#define W5_CMD_ENC_PIC_SRC_STRIDE (W5_REG_BASE + 0x154)
#define W5_CMD_ENC_PIC_SRC_FORMAT (W5_REG_BASE + 0x158)
#define W5_CMD_ENC_PIC_SRC_AXI_SEL (W5_REG_BASE + 0x160)
#define W5_CMD_ENC_PIC_CODE_OPTION (W5_REG_BASE + 0x164)
#define W5_CMD_ENC_PIC_PIC_PARAM (W5_REG_BASE + 0x168)
#define W5_CMD_ENC_PIC_LONGTERM_PIC (W5_REG_BASE + 0x16C)
#define W5_CMD_ENC_PIC_WP_PIXEL_SIGMA_Y (W5_REG_BASE + 0x170)
#define W5_CMD_ENC_PIC_WP_PIXEL_SIGMA_C (W5_REG_BASE + 0x174)
#define W5_CMD_ENC_PIC_WP_PIXEL_MEAN_Y (W5_REG_BASE + 0x178)
#define W5_CMD_ENC_PIC_WP_PIXEL_MEAN_C (W5_REG_BASE + 0x17C)
#define W5_CMD_ENC_PIC_CF50_Y_OFFSET_TABLE_ADDR (W5_REG_BASE + 0x190)
#define W5_CMD_ENC_PIC_CF50_CB_OFFSET_TABLE_ADDR (W5_REG_BASE + 0x194)
#define W5_CMD_ENC_PIC_CF50_CR_OFFSET_TABLE_ADDR (W5_REG_BASE + 0x198)
#define W5_CMD_ENC_PIC_PREFIX_SEI_NAL_ADDR (W5_REG_BASE + 0x180)
#define W5_CMD_ENC_PIC_PREFIX_SEI_INFO (W5_REG_BASE + 0x184)
#define W5_CMD_ENC_PIC_SUFFIX_SEI_NAL_ADDR (W5_REG_BASE + 0x188)
#define W5_CMD_ENC_PIC_SUFFIX_SEI_INFO (W5_REG_BASE + 0x18c)
/************************************************************************/
/* ENCODER - QUERY (GET_RESULT) */
/************************************************************************/
#define W5_RET_ENC_NUM_REQUIRED_FB (W5_REG_BASE + 0x11C)
#define W5_RET_ENC_MIN_SRC_BUF_NUM (W5_REG_BASE + 0x120)
#define W5_RET_ENC_PIC_TYPE (W5_REG_BASE + 0x124)
/*
* #define W5_RET_ENC_PIC_POC (W5_REG_BASE + 0x128)
* => picture order count value of current encoded picture
*/
#define W5_RET_ENC_PIC_IDX (W5_REG_BASE + 0x12C)
/*
* #define W5_RET_ENC_PIC_SLICE_NUM (W5_REG_BASE + 0x130)
* reg_val & 0xffff = total independent slice segment number (16 bits)
* (reg_val >> 16) & 0xffff = total dependent slice segment number (16 bits)
*
* #define W5_RET_ENC_PIC_SKIP (W5_REG_BASE + 0x134)
* reg_val & 0xfe = picture skip flag (7 bits)
*
* #define W5_RET_ENC_PIC_NUM_INTRA (W5_REG_BASE + 0x138)
* => number of intra blocks in 8x8 (32 bits)
*
* #define W5_RET_ENC_PIC_NUM_MERGE (W5_REG_BASE + 0x13C)
* => number of merge blocks in 8x8 (32 bits)
*
* #define W5_RET_ENC_PIC_NUM_SKIP (W5_REG_BASE + 0x144)
* => number of skip blocks in 8x8 (32 bits)
*
* #define W5_RET_ENC_PIC_AVG_CTU_QP (W5_REG_BASE + 0x148)
* => Average CTU QP value (32 bits)
*/
#define W5_RET_ENC_PIC_BYTE (W5_REG_BASE + 0x14C)
/*
* #define W5_RET_ENC_GOP_PIC_IDX (W5_REG_BASE + 0x150)
* => picture index in group of pictures
*/
#define W5_RET_ENC_USED_SRC_IDX (W5_REG_BASE + 0x154)
/*
* #define W5_RET_ENC_PIC_NUM (W5_REG_BASE + 0x158)
* => encoded picture number
*/
#define W5_RET_ENC_VCL_NUT (W5_REG_BASE + 0x15C)
/*
* Only for H264:
* #define W5_RET_ENC_PIC_DIST_LOW (W5_REG_BASE + 0x164)
* => lower 32 bits of the sum of squared difference between source Y picture
* and reconstructed Y picture
* #define W5_RET_ENC_PIC_DIST_HIGH (W5_REG_BASE + 0x168)
* => upper 32 bits of the sum of squared difference between source Y picture
* and reconstructed Y picture
*/
#define W5_RET_ENC_PIC_MAX_LATENCY_PICS (W5_REG_BASE + 0x16C)
#define W5_RET_ENC_HOST_CMD_TICK (W5_REG_BASE + 0x1B8)
/*
* #define W5_RET_ENC_PREPARE_START_TICK (W5_REG_BASE + 0x1BC)
* #define W5_RET_ENC_PREPARE_END_TICK (W5_REG_BASE + 0x1C0)
* => Start and end ticks for preparing slices of the picture
* #define W5_RET_ENC_PROCESSING_START_TICK (W5_REG_BASE + 0x1C4)
* #define W5_RET_ENC_PROCESSING_END_TICK (W5_REG_BASE + 0x1C8)
* => Start and end ticks for processing slices of the picture
* #define W5_RET_ENC_ENCODING_START_TICK (W5_REG_BASE + 0x1CC)
* => Start tick for encoding slices of the picture
*/
#define W5_RET_ENC_ENCODING_END_TICK (W5_REG_BASE + 0x1D0)
#define W5_RET_ENC_WARN_INFO (W5_REG_BASE + 0x1D4)
#define W5_RET_ENC_ERR_INFO (W5_REG_BASE + 0x1D8)
#define W5_RET_ENC_ENCODING_SUCCESS (W5_REG_BASE + 0x1DC)
/************************************************************************/
/* ENCODER - QUERY (GET_BS_WR_PTR) */
/************************************************************************/
#define W5_RET_ENC_RD_PTR (W5_REG_BASE + 0x114)
#define W5_RET_ENC_WR_PTR (W5_REG_BASE + 0x118)
#define W5_CMD_ENC_REASON_SEL (W5_REG_BASE + 0x11C)
/************************************************************************/
/* ENCODER - QUERY (GET_BW_REPORT) */
/************************************************************************/
#define RET_QUERY_BW_PRP_AXI_READ (W5_REG_BASE + 0x118)
#define RET_QUERY_BW_PRP_AXI_WRITE (W5_REG_BASE + 0x11C)
#define RET_QUERY_BW_FBD_Y_AXI_READ (W5_REG_BASE + 0x120)
#define RET_QUERY_BW_FBC_Y_AXI_WRITE (W5_REG_BASE + 0x124)
#define RET_QUERY_BW_FBD_C_AXI_READ (W5_REG_BASE + 0x128)
#define RET_QUERY_BW_FBC_C_AXI_WRITE (W5_REG_BASE + 0x12C)
#define RET_QUERY_BW_PRI_AXI_READ (W5_REG_BASE + 0x130)
#define RET_QUERY_BW_PRI_AXI_WRITE (W5_REG_BASE + 0x134)
#define RET_QUERY_BW_SEC_AXI_READ (W5_REG_BASE + 0x138)
#define RET_QUERY_BW_SEC_AXI_WRITE (W5_REG_BASE + 0x13C)
#define RET_QUERY_BW_PROC_AXI_READ (W5_REG_BASE + 0x140)
#define RET_QUERY_BW_PROC_AXI_WRITE (W5_REG_BASE + 0x144)
#define RET_QUERY_BW_BWB_AXI_WRITE (W5_REG_BASE + 0x148)
#define W5_CMD_BW_OPTION (W5_REG_BASE + 0x14C)
/************************************************************************/
/* ENCODER - QUERY (GET_SRC_FLAG) */
/************************************************************************/
#define W5_RET_RELEASED_SRC_INSTANCE (W5_REG_BASE + 0x1EC)
#define W5_ENC_PIC_SUB_FRAME_SYNC_IF (W5_REG_BASE + 0x0300)
#endif /* __WAVE5_REGISTER_DEFINE_H__ */
@@ -0,0 +1,211 @@
// SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause)
/*
* Wave5 series multi-standard codec IP - low level access functions
*
* Copyright (C) 2021-2023 CHIPS&MEDIA INC
*/
#include <linux/bug.h>
#include "wave5-vdi.h"
#include "wave5-vpu.h"
#include "wave5-regdefine.h"
#include <linux/delay.h>
static int wave5_vdi_allocate_common_memory(struct device *dev)
{
struct vpu_device *vpu_dev = dev_get_drvdata(dev);
if (!vpu_dev->common_mem.vaddr) {
int ret;
if (vpu_dev->product_code == WAVE515_CODE)
vpu_dev->common_mem.size = WAVE515_SIZE_COMMON;
else
vpu_dev->common_mem.size = WAVE521_SIZE_COMMON;
ret = wave5_vdi_allocate_dma_memory(vpu_dev, &vpu_dev->common_mem);
if (ret) {
dev_err(dev, "unable to allocate common buffer\n");
return ret;
}
}
dev_dbg(dev, "[VDI] common_mem: daddr=%pad size=%zu vaddr=0x%p\n",
&vpu_dev->common_mem.daddr, vpu_dev->common_mem.size, vpu_dev->common_mem.vaddr);
return 0;
}
int wave5_vdi_init(struct device *dev)
{
struct vpu_device *vpu_dev = dev_get_drvdata(dev);
int ret;
ret = wave5_vdi_allocate_common_memory(dev);
if (ret < 0) {
dev_err(dev, "[VDI] failed to get vpu common buffer from driver\n");
return ret;
}
if (!PRODUCT_CODE_W_SERIES(vpu_dev->product_code)) {
WARN_ONCE(1, "unsupported product code: 0x%x\n", vpu_dev->product_code);
wave5_vdi_free_dma_memory(vpu_dev, &vpu_dev->common_mem);
return -EOPNOTSUPP;
}
/* if BIT processor is not running. */
if (wave5_vdi_read_register(vpu_dev, W5_VCPU_CUR_PC) == 0) {
int i;
for (i = 0; i < 64; i++)
wave5_vdi_write_register(vpu_dev, (i * 4) + 0x100, 0x0);
}
dev_dbg(dev, "[VDI] driver initialized successfully\n");
return 0;
}
int wave5_vdi_release(struct device *dev)
{
struct vpu_device *vpu_dev = dev_get_drvdata(dev);
vpu_dev->vdb_register = NULL;
wave5_vdi_free_dma_memory(vpu_dev, &vpu_dev->common_mem);
return 0;
}
void wave5_vdi_write_register(struct vpu_device *vpu_dev, u32 addr, u32 data)
{
writel(data, vpu_dev->vdb_register + addr);
}
unsigned int wave5_vdi_read_register(struct vpu_device *vpu_dev, u32 addr)
{
return readl(vpu_dev->vdb_register + addr);
}
int wave5_vdi_clear_memory(struct vpu_device *vpu_dev, struct vpu_buf *vb)
{
if (!vb || !vb->vaddr) {
dev_err(vpu_dev->dev, "%s: unable to clear unmapped buffer\n", __func__);
return -EINVAL;
}
memset(vb->vaddr, 0, vb->size);
return vb->size;
}
int wave5_vdi_write_memory(struct vpu_device *vpu_dev, struct vpu_buf *vb, size_t offset,
u8 *data, size_t len)
{
if (!vb || !vb->vaddr) {
dev_err(vpu_dev->dev, "%s: unable to write to unmapped buffer\n", __func__);
return -EINVAL;
}
if (offset > vb->size || len > vb->size || offset + len > vb->size) {
dev_err(vpu_dev->dev, "%s: buffer too small\n", __func__);
return -ENOSPC;
}
memcpy(vb->vaddr + offset, data, len);
return len;
}
int wave5_vdi_allocate_dma_memory(struct vpu_device *vpu_dev, struct vpu_buf *vb)
{
void *vaddr;
dma_addr_t daddr;
if (!vb->size) {
dev_err(vpu_dev->dev, "%s: requested size==0\n", __func__);
return -EINVAL;
}
vaddr = dma_alloc_coherent(vpu_dev->dev, vb->size, &daddr, GFP_KERNEL);
if (!vaddr)
return -ENOMEM;
vb->vaddr = vaddr;
vb->daddr = daddr;
return 0;
}
int wave5_vdi_free_dma_memory(struct vpu_device *vpu_dev, struct vpu_buf *vb)
{
if (vb->size == 0)
return -EINVAL;
if (!vb->vaddr)
dev_err(vpu_dev->dev, "%s: requested free of unmapped buffer\n", __func__);
else
dma_free_coherent(vpu_dev->dev, vb->size, vb->vaddr, vb->daddr);
memset(vb, 0, sizeof(*vb));
return 0;
}
int wave5_vdi_allocate_array(struct vpu_device *vpu_dev, struct vpu_buf *array, unsigned int count,
size_t size)
{
struct vpu_buf vb_buf;
int i, ret = 0;
vb_buf.size = size;
for (i = 0; i < count; i++) {
if (array[i].size == size)
continue;
if (array[i].size != 0)
wave5_vdi_free_dma_memory(vpu_dev, &array[i]);
ret = wave5_vdi_allocate_dma_memory(vpu_dev, &vb_buf);
if (ret)
return -ENOMEM;
array[i] = vb_buf;
}
for (i = count; i < MAX_REG_FRAME; i++)
wave5_vdi_free_dma_memory(vpu_dev, &array[i]);
return 0;
}
void wave5_vdi_allocate_sram(struct vpu_device *vpu_dev)
{
struct vpu_buf *vb = &vpu_dev->sram_buf;
dma_addr_t daddr;
void *vaddr;
size_t size;
if (!vpu_dev->sram_pool || vb->vaddr)
return;
size = min_t(size_t, vpu_dev->sram_size, gen_pool_avail(vpu_dev->sram_pool));
vaddr = gen_pool_dma_alloc(vpu_dev->sram_pool, size, &daddr);
if (vaddr) {
vb->vaddr = vaddr;
vb->daddr = daddr;
vb->size = size;
}
dev_dbg(vpu_dev->dev, "%s: sram daddr: %pad, size: %zu, vaddr: 0x%p\n",
__func__, &vb->daddr, vb->size, vb->vaddr);
}
void wave5_vdi_free_sram(struct vpu_device *vpu_dev)
{
struct vpu_buf *vb = &vpu_dev->sram_buf;
if (!vb->size || !vb->vaddr)
return;
gen_pool_free(vpu_dev->sram_pool, (unsigned long)vb->vaddr, vb->size);
memset(vb, 0, sizeof(*vb));
}
@@ -0,0 +1,35 @@
/* SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) */
/*
* Wave5 series multi-standard codec IP - low level access functions
*
* Copyright (C) 2021-2023 CHIPS&MEDIA INC
*/
#ifndef _VDI_H_
#define _VDI_H_
#include "wave5-vpuconfig.h"
#include <linux/string.h>
#include <linux/slab.h>
#include <linux/device.h>
/************************************************************************/
/* COMMON REGISTERS */
/************************************************************************/
#define VPU_PRODUCT_CODE_REGISTER 0x1044
/* system register write */
#define vpu_write_reg(VPU_INST, ADDR, DATA) wave5_vdi_write_register(VPU_INST, ADDR, DATA)
/* system register read */
#define vpu_read_reg(CORE, ADDR) wave5_vdi_read_register(CORE, ADDR)
struct vpu_buf {
size_t size;
dma_addr_t daddr;
void *vaddr;
};
int wave5_vdi_init(struct device *dev);
int wave5_vdi_release(struct device *dev); //this function may be called only at system off.
#endif //#ifndef _VDI_H_
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,484 @@
// SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause)
/*
* Wave5 series multi-standard codec IP - platform driver
*
* Copyright (C) 2021-2023 CHIPS&MEDIA INC
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/clk.h>
#include <linux/firmware.h>
#include <linux/interrupt.h>
#include <linux/pm_runtime.h>
#include <linux/reset.h>
#include "wave5-vpu.h"
#include "wave5-regdefine.h"
#include "wave5-vpuconfig.h"
#include "wave5.h"
#define VPU_PLATFORM_DEVICE_NAME "vdec"
#define VPU_CLK_NAME "vcodec"
#define WAVE5_IS_ENC BIT(0)
#define WAVE5_IS_DEC BIT(1)
struct wave5_match_data {
int flags;
const char *fw_name;
u32 sram_size;
};
static int vpu_poll_interval = 5;
module_param(vpu_poll_interval, int, 0644);
int wave5_vpu_wait_interrupt(struct vpu_instance *inst, unsigned int timeout)
{
int ret;
ret = wait_for_completion_timeout(&inst->irq_done,
msecs_to_jiffies(timeout));
if (!ret)
return -ETIMEDOUT;
reinit_completion(&inst->irq_done);
return 0;
}
static void wave5_vpu_handle_irq(void *dev_id)
{
u32 seq_done;
u32 cmd_done;
u32 irq_reason;
u32 irq_subreason;
struct vpu_instance *inst, *tmp;
struct vpu_device *dev = dev_id;
int val;
unsigned long flags;
irq_reason = wave5_vdi_read_register(dev, W5_VPU_VINT_REASON);
seq_done = wave5_vdi_read_register(dev, W5_RET_SEQ_DONE_INSTANCE_INFO);
cmd_done = wave5_vdi_read_register(dev, W5_RET_QUEUE_CMD_DONE_INST);
wave5_vdi_write_register(dev, W5_VPU_VINT_REASON_CLR, irq_reason);
wave5_vdi_write_register(dev, W5_VPU_VINT_CLEAR, 0x1);
spin_lock_irqsave(&dev->irq_spinlock, flags);
list_for_each_entry_safe(inst, tmp, &dev->instances, list) {
if (irq_reason & BIT(INT_WAVE5_INIT_SEQ) ||
irq_reason & BIT(INT_WAVE5_ENC_SET_PARAM)) {
if (dev->product_code == WAVE515_CODE &&
(cmd_done & BIT(inst->id))) {
cmd_done &= ~BIT(inst->id);
wave5_vdi_write_register(dev, W5_RET_QUEUE_CMD_DONE_INST,
cmd_done);
complete(&inst->irq_done);
} else if (seq_done & BIT(inst->id)) {
seq_done &= ~BIT(inst->id);
wave5_vdi_write_register(dev, W5_RET_SEQ_DONE_INSTANCE_INFO,
seq_done);
complete(&inst->irq_done);
}
}
if (irq_reason & BIT(INT_WAVE5_DEC_PIC) ||
irq_reason & BIT(INT_WAVE5_ENC_PIC)) {
if (cmd_done & BIT(inst->id)) {
cmd_done &= ~BIT(inst->id);
if (dev->irq >= 0) {
irq_subreason =
wave5_vdi_read_register(dev, W5_VPU_VINT_REASON);
if (!(irq_subreason & BIT(INT_WAVE5_DEC_PIC)))
wave5_vdi_write_register(dev,
W5_RET_QUEUE_CMD_DONE_INST,
cmd_done);
}
val = BIT(INT_WAVE5_DEC_PIC);
kfifo_in(&inst->irq_status, &val, sizeof(int));
}
}
}
spin_unlock_irqrestore(&dev->irq_spinlock, flags);
if (dev->irq < 0)
up(&dev->irq_sem);
}
static irqreturn_t wave5_vpu_irq(int irq, void *dev_id)
{
struct vpu_device *dev = dev_id;
if (wave5_vdi_read_register(dev, W5_VPU_VPU_INT_STS)) {
wave5_vpu_handle_irq(dev);
return IRQ_WAKE_THREAD;
}
return IRQ_HANDLED;
}
static irqreturn_t wave5_vpu_irq_thread(int irq, void *dev_id)
{
struct vpu_device *dev = dev_id;
struct vpu_instance *inst, *tmp;
int irq_status, ret;
mutex_lock(&dev->irq_lock);
list_for_each_entry_safe(inst, tmp, &dev->instances, list) {
while (kfifo_len(&inst->irq_status)) {
ret = kfifo_out(&inst->irq_status, &irq_status, sizeof(int));
if (!ret)
break;
inst->ops->finish_process(inst);
}
}
mutex_unlock(&dev->irq_lock);
return IRQ_HANDLED;
}
static void wave5_vpu_irq_work_fn(struct kthread_work *work)
{
struct vpu_device *dev = container_of(work, struct vpu_device, work);
if (wave5_vdi_read_register(dev, W5_VPU_VPU_INT_STS))
wave5_vpu_handle_irq(dev);
}
static enum hrtimer_restart wave5_vpu_timer_callback(struct hrtimer *timer)
{
struct vpu_device *dev =
container_of(timer, struct vpu_device, hrtimer);
kthread_queue_work(dev->worker, &dev->work);
hrtimer_forward_now(timer, ns_to_ktime(vpu_poll_interval * NSEC_PER_MSEC));
return HRTIMER_RESTART;
}
static int irq_thread(void *data)
{
struct vpu_device *dev = (struct vpu_device *)data;
struct vpu_instance *inst, *tmp;
int irq_status, ret;
while (!kthread_should_stop()) {
if (down_interruptible(&dev->irq_sem))
continue;
if (kthread_should_stop())
break;
mutex_lock(&dev->irq_lock);
list_for_each_entry_safe(inst, tmp, &dev->instances, list) {
while (kfifo_len(&inst->irq_status)) {
ret = kfifo_out(&inst->irq_status, &irq_status, sizeof(int));
if (!ret)
break;
inst->ops->finish_process(inst);
}
}
mutex_unlock(&dev->irq_lock);
}
return 0;
}
static int wave5_vpu_load_firmware(struct device *dev, const char *fw_name,
u32 *revision)
{
const struct firmware *fw;
int ret;
unsigned int product_id;
ret = request_firmware(&fw, fw_name, dev);
if (ret) {
dev_err(dev, "request_firmware, fail: %d\n", ret);
return ret;
}
ret = wave5_vpu_init_with_bitcode(dev, (u8 *)fw->data, fw->size);
if (ret) {
dev_err(dev, "vpu_init_with_bitcode, fail: %d\n", ret);
release_firmware(fw);
return ret;
}
release_firmware(fw);
ret = wave5_vpu_get_version_info(dev, revision, &product_id);
if (ret) {
dev_err(dev, "vpu_get_version_info fail: %d\n", ret);
return ret;
}
dev_dbg(dev, "%s: enum product_id: %08x, fw revision: %u\n",
__func__, product_id, *revision);
return 0;
}
static __maybe_unused int wave5_pm_suspend(struct device *dev)
{
struct vpu_device *vpu = dev_get_drvdata(dev);
if (pm_runtime_suspended(dev))
return 0;
if (vpu->irq < 0)
hrtimer_cancel(&vpu->hrtimer);
wave5_vpu_sleep_wake(dev, true, NULL, 0);
clk_bulk_disable_unprepare(vpu->num_clks, vpu->clks);
return 0;
}
static __maybe_unused int wave5_pm_resume(struct device *dev)
{
struct vpu_device *vpu = dev_get_drvdata(dev);
int ret = 0;
wave5_vpu_sleep_wake(dev, false, NULL, 0);
ret = clk_bulk_prepare_enable(vpu->num_clks, vpu->clks);
if (ret) {
dev_err(dev, "Enabling clocks, fail: %d\n", ret);
return ret;
}
if (vpu->irq < 0 && !hrtimer_active(&vpu->hrtimer))
hrtimer_start(&vpu->hrtimer, ns_to_ktime(vpu->vpu_poll_interval * NSEC_PER_MSEC),
HRTIMER_MODE_REL_PINNED);
return ret;
}
static const struct dev_pm_ops wave5_pm_ops = {
SET_RUNTIME_PM_OPS(wave5_pm_suspend, wave5_pm_resume, NULL)
};
static int wave5_vpu_probe(struct platform_device *pdev)
{
int ret;
struct vpu_device *dev;
const struct wave5_match_data *match_data;
u32 fw_revision;
match_data = device_get_match_data(&pdev->dev);
if (!match_data) {
dev_err(&pdev->dev, "missing device match data\n");
return -EINVAL;
}
/* physical addresses limited to 32 bits */
ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
if (ret) {
dev_err(&pdev->dev, "Failed to set DMA mask: %d\n", ret);
return ret;
}
dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL);
if (!dev)
return -ENOMEM;
dev->vdb_register = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(dev->vdb_register))
return PTR_ERR(dev->vdb_register);
ida_init(&dev->inst_ida);
mutex_init(&dev->dev_lock);
mutex_init(&dev->hw_lock);
mutex_init(&dev->irq_lock);
spin_lock_init(&dev->irq_spinlock);
dev_set_drvdata(&pdev->dev, dev);
dev->dev = &pdev->dev;
dev->resets = devm_reset_control_array_get_optional_exclusive(&pdev->dev);
if (IS_ERR(dev->resets)) {
return dev_err_probe(&pdev->dev, PTR_ERR(dev->resets),
"Failed to get reset control\n");
}
ret = reset_control_deassert(dev->resets);
if (ret)
return dev_err_probe(&pdev->dev, ret, "Failed to deassert resets\n");
ret = devm_clk_bulk_get_all(&pdev->dev, &dev->clks);
/* continue without clock, assume externally managed */
if (ret < 0) {
dev_warn(&pdev->dev, "Getting clocks, fail: %d\n", ret);
ret = 0;
}
dev->num_clks = ret;
ret = clk_bulk_prepare_enable(dev->num_clks, dev->clks);
if (ret) {
dev_err(&pdev->dev, "Enabling clocks, fail: %d\n", ret);
goto err_reset_assert;
}
dev->sram_pool = of_gen_pool_get(pdev->dev.of_node, "sram", 0);
if (!dev->sram_pool)
dev_warn(&pdev->dev, "sram node not found\n");
dev->sram_size = match_data->sram_size;
dev->product_code = wave5_vdi_read_register(dev, VPU_PRODUCT_CODE_REGISTER);
ret = wave5_vdi_init(&pdev->dev);
if (ret < 0) {
dev_err(&pdev->dev, "wave5_vdi_init, fail: %d\n", ret);
goto err_clk_dis;
}
dev->product = wave5_vpu_get_product_id(dev);
INIT_LIST_HEAD(&dev->instances);
dev->irq = platform_get_irq(pdev, 0);
if (dev->irq < 0) {
dev_err(&pdev->dev, "failed to get irq resource, falling back to polling\n");
sema_init(&dev->irq_sem, 1);
dev->irq_thread = kthread_run(irq_thread, dev, "irq thread");
hrtimer_setup(&dev->hrtimer, &wave5_vpu_timer_callback, CLOCK_MONOTONIC,
HRTIMER_MODE_REL_PINNED);
dev->worker = kthread_run_worker(0, "vpu_irq_thread");
if (IS_ERR(dev->worker)) {
dev_err(&pdev->dev, "failed to create vpu irq worker\n");
ret = PTR_ERR(dev->worker);
goto err_vdi_release;
}
dev->vpu_poll_interval = vpu_poll_interval;
kthread_init_work(&dev->work, wave5_vpu_irq_work_fn);
} else {
ret = devm_request_threaded_irq(&pdev->dev, dev->irq, wave5_vpu_irq,
wave5_vpu_irq_thread, IRQF_ONESHOT, "vpu_irq", dev);
if (ret) {
dev_err(&pdev->dev, "Register interrupt handler, fail: %d\n", ret);
goto err_enc_unreg;
}
}
ret = v4l2_device_register(&pdev->dev, &dev->v4l2_dev);
if (ret) {
dev_err(&pdev->dev, "v4l2_device_register, fail: %d\n", ret);
goto err_irq_release;
}
if (match_data->flags & WAVE5_IS_DEC) {
ret = wave5_vpu_dec_register_device(dev);
if (ret) {
dev_err(&pdev->dev, "wave5_vpu_dec_register_device, fail: %d\n", ret);
goto err_v4l2_unregister;
}
}
if (match_data->flags & WAVE5_IS_ENC) {
ret = wave5_vpu_enc_register_device(dev);
if (ret) {
dev_err(&pdev->dev, "wave5_vpu_enc_register_device, fail: %d\n", ret);
goto err_dec_unreg;
}
}
ret = wave5_vpu_load_firmware(&pdev->dev, match_data->fw_name, &fw_revision);
if (ret) {
dev_err(&pdev->dev, "wave5_vpu_load_firmware, fail: %d\n", ret);
goto err_enc_unreg;
}
dev_info(&pdev->dev, "Added wave5 driver with caps: %s %s\n",
(match_data->flags & WAVE5_IS_ENC) ? "'ENCODE'" : "",
(match_data->flags & WAVE5_IS_DEC) ? "'DECODE'" : "");
dev_info(&pdev->dev, "Product Code: 0x%x\n", dev->product_code);
dev_info(&pdev->dev, "Firmware Revision: %u\n", fw_revision);
pm_runtime_set_autosuspend_delay(&pdev->dev, 500);
pm_runtime_use_autosuspend(&pdev->dev);
pm_runtime_enable(&pdev->dev);
wave5_vpu_sleep_wake(&pdev->dev, true, NULL, 0);
return 0;
err_enc_unreg:
if (match_data->flags & WAVE5_IS_ENC)
wave5_vpu_enc_unregister_device(dev);
err_dec_unreg:
if (match_data->flags & WAVE5_IS_DEC)
wave5_vpu_dec_unregister_device(dev);
err_v4l2_unregister:
v4l2_device_unregister(&dev->v4l2_dev);
err_irq_release:
if (dev->irq < 0)
kthread_destroy_worker(dev->worker);
err_vdi_release:
if (dev->irq_thread) {
kthread_stop(dev->irq_thread);
up(&dev->irq_sem);
dev->irq_thread = NULL;
}
wave5_vdi_release(&pdev->dev);
err_clk_dis:
clk_bulk_disable_unprepare(dev->num_clks, dev->clks);
err_reset_assert:
reset_control_assert(dev->resets);
return ret;
}
static void wave5_vpu_remove(struct platform_device *pdev)
{
struct vpu_device *dev = dev_get_drvdata(&pdev->dev);
wave5_vpu_enc_unregister_device(dev);
wave5_vpu_dec_unregister_device(dev);
v4l2_device_unregister(&dev->v4l2_dev);
if (dev->irq < 0) {
if (dev->irq_thread) {
kthread_stop(dev->irq_thread);
up(&dev->irq_sem);
dev->irq_thread = NULL;
}
hrtimer_cancel(&dev->hrtimer);
kthread_cancel_work_sync(&dev->work);
kthread_destroy_worker(dev->worker);
}
pm_runtime_dont_use_autosuspend(&pdev->dev);
pm_runtime_disable(&pdev->dev);
mutex_destroy(&dev->dev_lock);
mutex_destroy(&dev->hw_lock);
mutex_destroy(&dev->irq_lock);
reset_control_assert(dev->resets);
clk_bulk_disable_unprepare(dev->num_clks, dev->clks);
wave5_vdi_release(&pdev->dev);
ida_destroy(&dev->inst_ida);
}
static const struct wave5_match_data ti_wave521c_data = {
.flags = WAVE5_IS_ENC | WAVE5_IS_DEC,
.fw_name = "cnm/wave521c_k3_codec_fw.bin",
.sram_size = (64 * 1024),
};
static const struct of_device_id wave5_dt_ids[] = {
{ .compatible = "ti,j721s2-wave521c", .data = &ti_wave521c_data },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, wave5_dt_ids);
static struct platform_driver wave5_vpu_driver = {
.driver = {
.name = VPU_PLATFORM_DEVICE_NAME,
.of_match_table = of_match_ptr(wave5_dt_ids),
.pm = &wave5_pm_ops,
},
.probe = wave5_vpu_probe,
.remove = wave5_vpu_remove,
};
module_platform_driver(wave5_vpu_driver);
MODULE_DESCRIPTION("chips&media VPU V4L2 driver");
MODULE_LICENSE("Dual BSD/GPL");
@@ -0,0 +1,85 @@
/* SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) */
/*
* Wave5 series multi-standard codec IP - basic types
*
* Copyright (C) 2021-2023 CHIPS&MEDIA INC
*/
#ifndef __VPU_DRV_H__
#define __VPU_DRV_H__
#include <media/v4l2-ctrls.h>
#include <media/v4l2-ioctl.h>
#include <media/v4l2-event.h>
#include <media/v4l2-fh.h>
#include <media/videobuf2-v4l2.h>
#include <media/videobuf2-dma-contig.h>
#include <media/videobuf2-vmalloc.h>
#include "wave5-vpuconfig.h"
#include "wave5-vpuapi.h"
#define VPU_BUF_SYNC_TO_DEVICE 0
#define VPU_BUF_SYNC_FROM_DEVICE 1
struct vpu_src_buffer {
struct v4l2_m2m_buffer v4l2_m2m_buf;
bool consumed;
struct list_head list;
};
struct vpu_dst_buffer {
struct v4l2_m2m_buffer v4l2_m2m_buf;
bool display;
};
enum vpu_fmt_type {
VPU_FMT_TYPE_CODEC = 0,
VPU_FMT_TYPE_RAW = 1
};
struct vpu_format {
unsigned int v4l2_pix_fmt;
const struct v4l2_frmsize_stepwise *v4l2_frmsize;
};
static inline struct vpu_instance *wave5_to_vpu_inst(struct v4l2_fh *vfh)
{
return container_of(vfh, struct vpu_instance, v4l2_fh);
}
static inline struct vpu_instance *file_to_vpu_inst(struct file *filp)
{
return wave5_to_vpu_inst(file_to_v4l2_fh(filp));
}
static inline struct vpu_instance *wave5_ctrl_to_vpu_inst(struct v4l2_ctrl *vctrl)
{
return container_of(vctrl->handler, struct vpu_instance, v4l2_ctrl_hdl);
}
static inline struct vpu_src_buffer *wave5_to_vpu_src_buf(struct vb2_v4l2_buffer *vbuf)
{
return container_of(vbuf, struct vpu_src_buffer, v4l2_m2m_buf.vb);
}
static inline struct vpu_dst_buffer *wave5_to_vpu_dst_buf(struct vb2_v4l2_buffer *vbuf)
{
return container_of(vbuf, struct vpu_dst_buffer, v4l2_m2m_buf.vb);
}
int wave5_vpu_wait_interrupt(struct vpu_instance *inst, unsigned int timeout);
int wave5_vpu_dec_register_device(struct vpu_device *dev);
void wave5_vpu_dec_unregister_device(struct vpu_device *dev);
int wave5_vpu_enc_register_device(struct vpu_device *dev);
void wave5_vpu_enc_unregister_device(struct vpu_device *dev);
static inline bool wave5_vpu_both_queues_are_streaming(struct vpu_instance *inst)
{
struct vb2_queue *vq_cap =
v4l2_m2m_get_vq(inst->v4l2_fh.m2m_ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
struct vb2_queue *vq_out =
v4l2_m2m_get_vq(inst->v4l2_fh.m2m_ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
return vb2_is_streaming(vq_cap) && vb2_is_streaming(vq_out);
}
#endif
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,892 @@
/* SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) */
/*
* Wave5 series multi-standard codec IP - helper definitions
*
* Copyright (C) 2021-2023 CHIPS&MEDIA INC
*/
#ifndef VPUAPI_H_INCLUDED
#define VPUAPI_H_INCLUDED
#include <linux/kfifo.h>
#include <linux/idr.h>
#include <linux/genalloc.h>
#include <media/v4l2-device.h>
#include <media/v4l2-mem2mem.h>
#include <media/v4l2-ctrls.h>
#include "wave5-vpuerror.h"
#include "wave5-vpuconfig.h"
#include "wave5-vdi.h"
enum product_id {
PRODUCT_ID_515,
PRODUCT_ID_521,
PRODUCT_ID_511,
PRODUCT_ID_517,
PRODUCT_ID_NONE,
};
struct vpu_attr;
enum vpu_instance_type {
VPU_INST_TYPE_DEC = 0,
VPU_INST_TYPE_ENC = 1
};
enum vpu_instance_state {
VPU_INST_STATE_NONE = 0,
VPU_INST_STATE_OPEN = 1,
VPU_INST_STATE_INIT_SEQ = 2,
VPU_INST_STATE_PIC_RUN = 3,
VPU_INST_STATE_STOP = 4
};
/* Maximum available on hardware. */
#define WAVE5_MAX_FBS 32
#define MAX_REG_FRAME (WAVE5_MAX_FBS * 2)
#define WAVE5_DEC_HEVC_BUF_SIZE(_w, _h) (DIV_ROUND_UP(_w, 64) * DIV_ROUND_UP(_h, 64) * 256 + 64)
#define WAVE5_DEC_AVC_BUF_SIZE(_w, _h) ((((ALIGN(_w, 256) / 16) * (ALIGN(_h, 16) / 16)) + 16) * 80)
#define WAVE5_FBC_LUMA_TABLE_SIZE(_w, _h) (ALIGN(_h, 64) * ALIGN(_w, 256) / 32)
#define WAVE5_FBC_CHROMA_TABLE_SIZE(_w, _h) (ALIGN((_h), 64) * ALIGN((_w) / 2, 256) / 32)
#define WAVE5_ENC_AVC_BUF_SIZE(_w, _h) (ALIGN(_w, 64) * ALIGN(_h, 64) / 32)
#define WAVE5_ENC_HEVC_BUF_SIZE(_w, _h) (ALIGN(_w, 64) / 64 * ALIGN(_h, 64) / 64 * 128)
/*
* common struct and definition
*/
enum cod_std {
STD_AVC = 0,
STD_HEVC = 12,
STD_MAX
};
enum wave_std {
W_HEVC_DEC = 0x00,
W_HEVC_ENC = 0x01,
W_AVC_DEC = 0x02,
W_AVC_ENC = 0x03,
STD_UNKNOWN = 0xFF
};
enum set_param_option {
OPT_COMMON = 0, /* SET_PARAM command option for encoding sequence */
OPT_CUSTOM_GOP = 1, /* SET_PARAM command option for setting custom GOP */
OPT_CUSTOM_HEADER = 2, /* SET_PARAM command option for setting custom VPS/SPS/PPS */
OPT_VUI = 3, /* SET_PARAM command option for encoding VUI */
OPT_CHANGE_PARAM = 0x10,
};
/************************************************************************/
/* PROFILE & LEVEL */
/************************************************************************/
/* HEVC */
#define HEVC_PROFILE_MAIN 1
#define HEVC_PROFILE_MAIN10 2
#define HEVC_PROFILE_STILLPICTURE 3
#define HEVC_PROFILE_MAIN10_STILLPICTURE 2
/* H.264 profile for encoder*/
#define H264_PROFILE_BP 1
#define H264_PROFILE_MP 2
#define H264_PROFILE_EXTENDED 3
#define H264_PROFILE_HP 4
#define H264_PROFILE_HIGH10 5
#define H264_PROFILE_HIGH422 6
#define H264_PROFILE_HIGH444 7
/************************************************************************/
/* error codes */
/************************************************************************/
/************************************************************************/
/* utility macros */
/************************************************************************/
/* Initialize sequence firmware command mode */
#define INIT_SEQ_NORMAL 1
/* Decode firmware command mode */
#define DEC_PIC_NORMAL 0
/* bit_alloc_mode */
#define BIT_ALLOC_MODE_FIXED_RATIO 2
/* bit_rate */
#define MAX_BIT_RATE 700000000
/* decoding_refresh_type */
#define DEC_REFRESH_TYPE_NON_IRAP 0
#define DEC_REFRESH_TYPE_CRA 1
#define DEC_REFRESH_TYPE_IDR 2
/* depend_slice_mode */
#define DEPEND_SLICE_MODE_RECOMMENDED 1
#define DEPEND_SLICE_MODE_BOOST 2
#define DEPEND_SLICE_MODE_FAST 3
/* hvs_max_delta_qp */
#define MAX_HVS_MAX_DELTA_QP 51
/* intra_refresh_mode */
#define REFRESH_MODE_CTU_ROWS 1
#define REFRESH_MODE_CTU_COLUMNS 2
#define REFRESH_MODE_CTU_STEP_SIZE 3
#define REFRESH_MODE_CTUS 4
/* intra_mb_refresh_mode */
#define REFRESH_MB_MODE_NONE 0
#define REFRESH_MB_MODE_CTU_ROWS 1
#define REFRESH_MB_MODE_CTU_COLUMNS 2
#define REFRESH_MB_MODE_CTU_STEP_SIZE 3
/* intra_qp */
#define MAX_INTRA_QP 63
/* nr_inter_weight_* */
#define MAX_INTER_WEIGHT 31
/* nr_intra_weight_* */
#define MAX_INTRA_WEIGHT 31
/* nr_noise_sigma_* */
#define MAX_NOISE_SIGMA 255
/* bitstream_buffer_size */
#define MIN_BITSTREAM_BUFFER_SIZE 1024
#define MIN_BITSTREAM_BUFFER_SIZE_WAVE521 (1024 * 64)
/* vbv_buffer_size */
#define MIN_VBV_BUFFER_SIZE 10
#define MAX_VBV_BUFFER_SIZE 3000
#define BUFFER_MARGIN 4096
#define MAX_FIRMWARE_CALL_RETRY 10
#define VDI_LITTLE_ENDIAN 0x0
/*
* Parameters of DEC_SET_SEQ_CHANGE_MASK
*/
#define SEQ_CHANGE_ENABLE_PROFILE BIT(5)
#define SEQ_CHANGE_ENABLE_SIZE BIT(16)
#define SEQ_CHANGE_ENABLE_BITDEPTH BIT(18)
#define SEQ_CHANGE_ENABLE_DPB_COUNT BIT(19)
#define SEQ_CHANGE_ENABLE_ASPECT_RATIO BIT(21)
#define SEQ_CHANGE_ENABLE_VIDEO_SIGNAL BIT(23)
#define SEQ_CHANGE_ENABLE_VUI_TIMING_INFO BIT(29)
#define SEQ_CHANGE_ENABLE_ALL_HEVC (SEQ_CHANGE_ENABLE_PROFILE | \
SEQ_CHANGE_ENABLE_SIZE | \
SEQ_CHANGE_ENABLE_BITDEPTH | \
SEQ_CHANGE_ENABLE_DPB_COUNT)
#define SEQ_CHANGE_ENABLE_ALL_AVC (SEQ_CHANGE_ENABLE_SIZE | \
SEQ_CHANGE_ENABLE_BITDEPTH | \
SEQ_CHANGE_ENABLE_DPB_COUNT | \
SEQ_CHANGE_ENABLE_ASPECT_RATIO | \
SEQ_CHANGE_ENABLE_VIDEO_SIGNAL | \
SEQ_CHANGE_ENABLE_VUI_TIMING_INFO)
#define DISPLAY_IDX_FLAG_SEQ_END -1
#define DISPLAY_IDX_FLAG_NO_FB -3
#define DECODED_IDX_FLAG_NO_FB -1
#define DECODED_IDX_FLAG_SKIP -2
#define RECON_IDX_FLAG_ENC_END -1
#define RECON_IDX_FLAG_ENC_DELAY -2
#define RECON_IDX_FLAG_HEADER_ONLY -3
#define RECON_IDX_FLAG_CHANGE_PARAM -4
enum codec_command {
ENABLE_ROTATION,
ENABLE_MIRRORING,
SET_MIRROR_DIRECTION,
SET_ROTATION_ANGLE,
DEC_GET_QUEUE_STATUS,
ENC_GET_QUEUE_STATUS,
DEC_RESET_FRAMEBUF_INFO,
DEC_GET_SEQ_INFO,
};
enum mirror_direction {
MIRDIR_NONE, /* no mirroring */
MIRDIR_VER, /* vertical mirroring */
MIRDIR_HOR, /* horizontal mirroring */
MIRDIR_HOR_VER /* horizontal and vertical mirroring */
};
enum frame_buffer_format {
FORMAT_ERR = -1,
FORMAT_420 = 0, /* 8bit */
FORMAT_422, /* 8bit */
FORMAT_224, /* 8bit */
FORMAT_444, /* 8bit */
FORMAT_400, /* 8bit */
/* little endian perspective */
/* | addr 0 | addr 1 | */
FORMAT_420_P10_16BIT_MSB = 5, /* lsb |000000xx|xxxxxxxx | msb */
FORMAT_420_P10_16BIT_LSB, /* lsb |xxxxxxx |xx000000 | msb */
FORMAT_420_P10_32BIT_MSB, /* lsb |00xxxxxxxxxxxxxxxxxxxxxxxxxxx| msb */
FORMAT_420_P10_32BIT_LSB, /* lsb |xxxxxxxxxxxxxxxxxxxxxxxxxxx00| msb */
/* 4:2:2 packed format */
/* little endian perspective */
/* | addr 0 | addr 1 | */
FORMAT_422_P10_16BIT_MSB, /* lsb |000000xx |xxxxxxxx | msb */
FORMAT_422_P10_16BIT_LSB, /* lsb |xxxxxxxx |xx000000 | msb */
FORMAT_422_P10_32BIT_MSB, /* lsb |00xxxxxxxxxxxxxxxxxxxxxxxxxxx| msb */
FORMAT_422_P10_32BIT_LSB, /* lsb |xxxxxxxxxxxxxxxxxxxxxxxxxxx00| msb */
FORMAT_YUYV, /* 8bit packed format : Y0U0Y1V0 Y2U1Y3V1 ... */
FORMAT_YUYV_P10_16BIT_MSB,
FORMAT_YUYV_P10_16BIT_LSB,
FORMAT_YUYV_P10_32BIT_MSB,
FORMAT_YUYV_P10_32BIT_LSB,
FORMAT_YVYU, /* 8bit packed format : Y0V0Y1U0 Y2V1Y3U1 ... */
FORMAT_YVYU_P10_16BIT_MSB,
FORMAT_YVYU_P10_16BIT_LSB,
FORMAT_YVYU_P10_32BIT_MSB,
FORMAT_YVYU_P10_32BIT_LSB,
FORMAT_UYVY, /* 8bit packed format : U0Y0V0Y1 U1Y2V1Y3 ... */
FORMAT_UYVY_P10_16BIT_MSB,
FORMAT_UYVY_P10_16BIT_LSB,
FORMAT_UYVY_P10_32BIT_MSB,
FORMAT_UYVY_P10_32BIT_LSB,
FORMAT_VYUY, /* 8bit packed format : V0Y0U0Y1 V1Y2U1Y3 ... */
FORMAT_VYUY_P10_16BIT_MSB,
FORMAT_VYUY_P10_16BIT_LSB,
FORMAT_VYUY_P10_32BIT_MSB,
FORMAT_VYUY_P10_32BIT_LSB,
FORMAT_MAX,
};
enum packed_format_num {
NOT_PACKED = 0,
PACKED_YUYV,
PACKED_YVYU,
PACKED_UYVY,
PACKED_VYUY,
};
enum wave5_interrupt_bit {
INT_WAVE5_INIT_VPU = 0,
INT_WAVE5_WAKEUP_VPU = 1,
INT_WAVE5_SLEEP_VPU = 2,
INT_WAVE5_CREATE_INSTANCE = 3,
INT_WAVE5_FLUSH_INSTANCE = 4,
INT_WAVE5_DESTROY_INSTANCE = 5,
INT_WAVE5_INIT_SEQ = 6,
INT_WAVE5_SET_FRAMEBUF = 7,
INT_WAVE5_DEC_PIC = 8,
INT_WAVE5_ENC_PIC = 8,
INT_WAVE5_ENC_SET_PARAM = 9,
INT_WAVE5_DEC_QUERY = 14,
INT_WAVE5_BSBUF_EMPTY = 15,
INT_WAVE5_BSBUF_FULL = 15,
};
enum pic_type {
PIC_TYPE_I = 0,
PIC_TYPE_P = 1,
PIC_TYPE_B = 2,
PIC_TYPE_IDR = 5, /* H.264/H.265 IDR (Instantaneous Decoder Refresh) picture */
PIC_TYPE_MAX /* no meaning */
};
enum sw_reset_mode {
SW_RESET_SAFETY,
SW_RESET_FORCE,
SW_RESET_ON_BOOT
};
enum tiled_map_type {
LINEAR_FRAME_MAP = 0, /* linear frame map type */
COMPRESSED_FRAME_MAP = 17, /* compressed frame map type*/
};
enum temporal_id_mode {
TEMPORAL_ID_MODE_ABSOLUTE,
TEMPORAL_ID_MODE_RELATIVE,
};
struct vpu_attr {
u32 product_id;
char product_name[8]; /* product name in ascii code */
u32 product_version;
u32 fw_version;
u32 customer_id;
u32 support_decoders; /* bitmask */
u32 support_encoders; /* bitmask */
u32 support_backbone: 1;
u32 support_avc10bit_enc: 1;
u32 support_hevc10bit_enc: 1;
u32 support_hevc10bit_dec: 1;
u32 support_vcore_backbone: 1;
u32 support_vcpu_backbone: 1;
};
struct frame_buffer {
dma_addr_t buf_y;
dma_addr_t buf_cb;
dma_addr_t buf_cr;
unsigned int buf_y_size;
unsigned int buf_cb_size;
unsigned int buf_cr_size;
enum tiled_map_type map_type;
unsigned int stride; /* horizontal stride for the given frame buffer */
unsigned int width; /* width of the given frame buffer */
unsigned int height; /* height of the given frame buffer */
size_t size; /* size of the given frame buffer */
unsigned int sequence_no;
bool update_fb_info;
};
struct vpu_rect {
unsigned int left; /* horizontal pixel offset from left edge */
unsigned int top; /* vertical pixel offset from top edge */
unsigned int right; /* horizontal pixel offset from right edge */
unsigned int bottom; /* vertical pixel offset from bottom edge */
};
/*
* decode struct and definition
*/
struct dec_open_param {
dma_addr_t bitstream_buffer;
size_t bitstream_buffer_size;
};
struct dec_initial_info {
u32 pic_width;
u32 pic_height;
struct vpu_rect pic_crop_rect;
u32 min_frame_buffer_count; /* between 1 to 16 */
u32 profile;
u32 luma_bitdepth; /* bit-depth of the luma sample */
u32 chroma_bitdepth; /* bit-depth of the chroma sample */
u32 seq_init_err_reason;
dma_addr_t rd_ptr; /* read pointer of bitstream buffer */
dma_addr_t wr_ptr; /* write pointer of bitstream buffer */
u32 sequence_no;
u32 vlc_buf_size;
u32 param_buf_size;
};
struct dec_output_info {
/**
* This is a frame buffer index for the picture to be displayed at the moment
* among frame buffers which are registered using vpu_dec_register_frame_buffer().
* Frame data that will be displayed is stored in the frame buffer with this index
* When there is no display delay, this index is always the equal to
* index_frame_decoded, however, if displaying is delayed (for display
* reordering in AVC or B-frames in VC1), this index might be different to
* index_frame_decoded. By checking this index, HOST applications can easily figure
* out whether sequence decoding has been finished or not.
*
* -3(0xFFFD) or -2(0xFFFE) : when a display output cannot be given due to picture
* reordering or skip option
* -1(0xFFFF) : when there is no more output for display at the end of sequence
* decoding
*/
s32 index_frame_display;
/**
* This is the frame buffer index of the decoded picture among the frame buffers which were
* registered using vpu_dec_register_frame_buffer(). The currently decoded frame is stored
* into the frame buffer specified by this index.
*
* -2 : indicates that no decoded output is generated because decoder meets EOS
* (end of sequence) or skip
* -1 : indicates that the decoder fails to decode a picture because there is no available
* frame buffer
*/
s32 index_frame_decoded;
s32 index_frame_decoded_for_tiled;
u32 nal_type;
unsigned int pic_type;
struct vpu_rect rc_display;
unsigned int disp_pic_width;
unsigned int disp_pic_height;
struct vpu_rect rc_decoded;
u32 dec_pic_width;
u32 dec_pic_height;
s32 decoded_poc;
int temporal_id; /* temporal ID of the picture */
dma_addr_t rd_ptr; /* stream buffer read pointer for the current decoder instance */
dma_addr_t wr_ptr; /* stream buffer write pointer for the current decoder instance */
struct frame_buffer disp_frame;
u32 frame_display_flag; /* it reports a frame buffer flag to be displayed */
/**
* this variable reports that sequence has been changed while H.264/AVC stream decoding.
* if it is 1, HOST application can get the new sequence information by calling
* vpu_dec_get_initial_info() or wave5_vpu_dec_issue_seq_init().
*
* for H.265/HEVC decoder, each bit has a different meaning as follows.
*
* sequence_changed[5] : it indicates that the profile_idc has been changed
* sequence_changed[16] : it indicates that the resolution has been changed
* sequence_changed[19] : it indicates that the required number of frame buffer has
* been changed.
*/
unsigned int frame_cycle; /* reports the number of cycles for processing a frame */
u32 sequence_no;
u32 dec_host_cmd_tick; /* tick of DEC_PIC command for the picture */
u32 dec_decode_end_tick; /* end tick of decoding slices of the picture */
u32 sequence_changed;
};
struct queue_status_info {
u32 instance_queue_count;
u32 report_queue_count;
};
/*
* encode struct and definition
*/
#define MAX_NUM_TEMPORAL_LAYER 7
#define MAX_NUM_SPATIAL_LAYER 3
#define MAX_GOP_NUM 8
struct custom_gop_pic_param {
u32 pic_type; /* picture type of nth picture in the custom GOP */
u32 poc_offset; /* POC of nth picture in the custom GOP */
u32 pic_qp; /* quantization parameter of nth picture in the custom GOP */
u32 use_multi_ref_p; /* use multiref pic for P picture. valid only if PIC_TYPE is P */
u32 ref_poc_l0; /* POC of reference L0 of nth picture in the custom GOP */
u32 ref_poc_l1; /* POC of reference L1 of nth picture in the custom GOP */
s32 temporal_id; /* temporal ID of nth picture in the custom GOP */
};
struct enc_wave_param {
/*
* profile indicator (HEVC only)
*
* 0 : the firmware determines a profile according to the internal_bit_depth
* 1 : main profile
* 2 : main10 profile
* 3 : main still picture profile
* In the AVC encoder, a profile cannot be set by the host application.
* The firmware decides it based on internal_bit_depth.
* profile = HIGH (bitdepth 8) profile = HIGH10 (bitdepth 10)
*/
u32 profile;
u32 level; /* level indicator (level * 10) */
u32 internal_bit_depth: 4; /* 8/10 */
u32 gop_preset_idx: 4; /* 0 - 9 */
u32 decoding_refresh_type: 2; /* 0=non-IRAP, 1=CRA, 2=IDR */
u32 intra_qp; /* quantization parameter of intra picture */
u32 intra_period; /* period of intra picture in GOP size */
u32 conf_win_top; /* top offset of conformance window */
u32 conf_win_bot; /* bottom offset of conformance window */
u32 conf_win_left; /* left offset of conformance window */
u32 conf_win_right; /* right offset of conformance window */
u32 intra_refresh_mode: 3;
/*
* Argument for intra_ctu_refresh_mode.
*
* Depending on intra_refresh_mode, it can mean one of the following:
* - intra_ctu_refresh_mode (1) -> number of consecutive CTU rows
* - intra_ctu_refresh_mode (2) -> the number of consecutive CTU columns
* - intra_ctu_refresh_mode (3) -> step size in CTU
* - intra_ctu_refresh_mode (4) -> number of intra ct_us to be encoded in a picture
*/
u32 intra_refresh_arg;
/*
* 0 : custom setting
* 1 : recommended encoder parameters (slow encoding speed, highest picture quality)
* 2 : boost mode (normal encoding speed, moderate picture quality)
* 3 : fast mode (fast encoding speed, low picture quality)
*/
u32 depend_slice_mode : 2;
u32 depend_slice_mode_arg;
u32 independ_slice_mode : 1; /* 0=no-multi-slice, 1=slice-in-ctu-number*/
u32 independ_slice_mode_arg;
u32 max_num_merge: 2;
s32 beta_offset_div2: 4; /* sets beta_offset_div2 for deblocking filter */
s32 tc_offset_div2: 4; /* sets tc_offset_div3 for deblocking filter */
u32 hvs_qp_scale: 4; /* QP scaling factor for CU QP adjust if hvs_qp_scale_enable is 1 */
u32 hvs_max_delta_qp; /* maximum delta QP for HVS */
s32 chroma_cb_qp_offset; /* the value of chroma(cb) QP offset */
s32 chroma_cr_qp_offset; /* the value of chroma(cr) QP offset */
s32 initial_rc_qp;
u32 nr_intra_weight_y;
u32 nr_intra_weight_cb; /* weight to cb noise level for intra picture (0 ~ 31) */
u32 nr_intra_weight_cr; /* weight to cr noise level for intra picture (0 ~ 31) */
u32 nr_inter_weight_y;
u32 nr_inter_weight_cb; /* weight to cb noise level for inter picture (0 ~ 31) */
u32 nr_inter_weight_cr; /* weight to cr noise level for inter picture (0 ~ 31) */
u32 min_qp_i; /* minimum QP of I picture for rate control */
u32 max_qp_i; /* maximum QP of I picture for rate control */
u32 min_qp_p; /* minimum QP of P picture for rate control */
u32 max_qp_p; /* maximum QP of P picture for rate control */
u32 min_qp_b; /* minimum QP of B picture for rate control */
u32 max_qp_b; /* maximum QP of B picture for rate control */
u32 avc_idr_period; /* period of IDR picture (0 ~ 1024). 0 - implies an infinite period */
u32 avc_slice_arg; /* the number of MB for a slice when avc_slice_mode is set with 1 */
u32 intra_mb_refresh_mode: 2; /* 0=none, 1=row, 2=column, 3=step-size-in-mb */
/**
* Argument for intra_mb_refresh_mode.
*
* intra_mb_refresh_mode (1) -> number of consecutive MB rows
* intra_mb_refresh_mode (2) ->the number of consecutive MB columns
* intra_mb_refresh_mode (3) -> step size in MB
*/
u32 intra_mb_refresh_arg;
u32 rc_weight_param;
u32 rc_weight_buf;
/* flags */
u32 en_still_picture: 1; /* still picture profile */
u32 tier: 1; /* 0=main, 1=high */
u32 avc_slice_mode: 1; /* 0=none, 1=slice-in-mb-number */
u32 entropy_coding_mode: 1; /* 0=CAVLC, 1=CABAC */
u32 lossless_enable: 1; /* enable lossless encoding */
u32 const_intra_pred_flag: 1; /* enable constrained intra prediction */
u32 tmvp_enable: 1; /* enable temporal motion vector prediction */
u32 wpp_enable: 1;
u32 disable_deblk: 1; /* disable in-loop deblocking filtering */
u32 lf_cross_slice_boundary_enable: 1;
u32 skip_intra_trans: 1;
u32 sao_enable: 1; /* enable SAO (sample adaptive offset) */
u32 intra_nx_n_enable: 1; /* enables intra nx_n p_us */
u32 cu_level_rc_enable: 1; /* enable CU level rate control */
u32 hvs_qp_enable: 1; /* enable CU QP adjustment for subjective quality enhancement */
u32 strong_intra_smooth_enable: 1; /* enable strong intra smoothing */
u32 rdo_skip: 1; /* skip RDO (rate distortion optimization) */
u32 lambda_scaling_enable: 1; /* enable lambda scaling using custom GOP */
u32 transform8x8_enable: 1; /* enable 8x8 intra prediction and 8x8 transform */
u32 mb_level_rc_enable: 1; /* enable MB-level rate control */
u32 forced_idr_header_enable: 1; /* enable header encoding before IDR frame */
u32 constraint_set1_flag: 1; /* enable CBP */
u32 bg_detection: 1; /* enable background detection */
};
struct enc_open_param {
dma_addr_t bitstream_buffer;
unsigned int bitstream_buffer_size;
u32 pic_width; /* width of a picture to be encoded in unit of sample */
u32 pic_height; /* height of a picture to be encoded in unit of sample */
u32 frame_rate_info;/* desired fps */
u32 vbv_buffer_size;
u32 bit_rate; /* target bitrate in bps */
struct enc_wave_param wave_param;
enum packed_format_num packed_format; /* <<vpuapi_h_packed_format_num>> */
enum frame_buffer_format src_format;
bool line_buf_int_en;
u32 rc_enable : 1; /* rate control */
};
struct enc_initial_info {
u32 min_frame_buffer_count; /* minimum number of frame buffers */
u32 min_src_frame_count; /* minimum number of source buffers */
u32 seq_init_err_reason;
u32 warn_info;
u32 vlc_buf_size; /* size of task buffer */
u32 param_buf_size; /* size of task buffer */
};
/*
* Flags to encode NAL units explicitly
*/
struct enc_code_opt {
u32 implicit_header_encode: 1;
u32 encode_vcl: 1;
u32 encode_vps: 1;
u32 encode_sps: 1;
u32 encode_pps: 1;
u32 encode_aud: 1;
u32 encode_eos: 1;
u32 encode_eob: 1;
u32 encode_vui: 1;
};
struct enc_param {
struct frame_buffer *source_frame;
u32 pic_stream_buffer_addr;
u64 pic_stream_buffer_size;
u32 src_idx; /* source frame buffer index */
struct enc_code_opt code_option;
u64 pts; /* presentation timestamp (PTS) of the input source */
bool src_end_flag;
};
struct enc_output_info {
u32 bitstream_buffer;
u32 bitstream_size; /* byte size of encoded bitstream */
u32 pic_type: 2; /* <<vpuapi_h_pic_type>> */
s32 recon_frame_index;
dma_addr_t rd_ptr;
dma_addr_t wr_ptr;
u32 enc_pic_byte; /* number of encoded picture bytes */
s32 enc_src_idx; /* source buffer index of the currently encoded picture */
u32 enc_vcl_nut;
u32 error_reason; /* error reason of the currently encoded picture */
u32 warn_info; /* warning information on the currently encoded picture */
unsigned int frame_cycle; /* param for reporting the cycle number of encoding one frame*/
u64 pts;
u32 enc_host_cmd_tick; /* tick of ENC_PIC command for the picture */
u32 enc_encode_end_tick; /* end tick of encoding slices of the picture */
};
enum enc_pic_code_option {
CODEOPT_ENC_HEADER_IMPLICIT = BIT(0),
CODEOPT_ENC_VCL = BIT(1), /* flag to encode VCL nal unit explicitly */
};
enum gop_preset_idx {
PRESET_IDX_CUSTOM_GOP = 0, /* user defined GOP structure */
PRESET_IDX_ALL_I = 1, /* all intra, gopsize = 1 */
PRESET_IDX_IPP = 2, /* consecutive P, cyclic gopsize = 1 */
PRESET_IDX_IBBB = 3, /* consecutive B, cyclic gopsize = 1 */
PRESET_IDX_IBPBP = 4, /* gopsize = 2 */
PRESET_IDX_IBBBP = 5, /* gopsize = 4 */
PRESET_IDX_IPPPP = 6, /* consecutive P, cyclic gopsize = 4 */
PRESET_IDX_IBBBB = 7, /* consecutive B, cyclic gopsize = 4 */
PRESET_IDX_RA_IB = 8, /* random access, cyclic gopsize = 8 */
PRESET_IDX_IPP_SINGLE = 9, /* consecutive P, cyclic gopsize = 1, with single ref */
};
struct sec_axi_info {
u32 use_ip_enable;
u32 use_bit_enable;
u32 use_lf_row_enable: 1;
u32 use_enc_rdo_enable: 1;
u32 use_enc_lf_enable: 1;
};
struct dec_info {
struct dec_open_param open_param;
struct dec_initial_info initial_info;
struct dec_initial_info new_seq_info; /* temporal new sequence information */
u32 stream_wr_ptr;
u32 stream_rd_ptr;
u32 frame_display_flag;
dma_addr_t stream_buf_start_addr;
dma_addr_t stream_buf_end_addr;
u32 stream_buf_size;
struct vpu_buf vb_mv[MAX_REG_FRAME];
struct vpu_buf vb_fbc_y_tbl[MAX_REG_FRAME];
struct vpu_buf vb_fbc_c_tbl[MAX_REG_FRAME];
unsigned int num_of_decoding_fbs: 7;
unsigned int num_of_display_fbs: 7;
unsigned int stride;
struct sec_axi_info sec_axi_info;
dma_addr_t user_data_buf_addr;
u32 user_data_enable;
u32 user_data_buf_size;
struct vpu_buf vb_work;
struct vpu_buf vb_task;
struct dec_output_info dec_out_info[WAVE5_MAX_FBS];
u32 seq_change_mask;
enum temporal_id_mode temp_id_select_mode;
u32 target_temp_id;
u32 target_spatial_id;
u32 instance_queue_count;
u32 report_queue_count;
u32 cycle_per_tick;
u32 product_code;
u32 vlc_buf_size;
u32 param_buf_size;
bool initial_info_obtained;
bool reorder_enable;
bool first_cycle_check;
u32 stream_endflag: 1;
};
struct enc_info {
struct enc_open_param open_param;
struct enc_initial_info initial_info;
u32 stream_rd_ptr;
u32 stream_wr_ptr;
dma_addr_t stream_buf_start_addr;
dma_addr_t stream_buf_end_addr;
u32 stream_buf_size;
unsigned int num_frame_buffers;
unsigned int stride;
bool rotation_enable;
bool mirror_enable;
enum mirror_direction mirror_direction;
unsigned int rotation_angle;
bool initial_info_obtained;
struct sec_axi_info sec_axi_info;
bool line_buf_int_en;
struct vpu_buf vb_work;
struct vpu_buf vb_mv; /* col_mv buffer */
struct vpu_buf vb_fbc_y_tbl; /* FBC luma table buffer */
struct vpu_buf vb_fbc_c_tbl; /* FBC chroma table buffer */
struct vpu_buf vb_sub_sam_buf; /* sub-sampled buffer for ME */
struct vpu_buf vb_task;
u64 cur_pts; /* current timestamp in 90_k_hz */
u64 pts_map[32]; /* PTS mapped with source frame index */
u32 instance_queue_count;
u32 report_queue_count;
bool first_cycle_check;
u32 cycle_per_tick;
u32 product_code;
u32 vlc_buf_size;
u32 param_buf_size;
};
struct vpu_device {
struct device *dev;
struct v4l2_device v4l2_dev;
struct v4l2_m2m_dev *v4l2_m2m_dec_dev;
struct v4l2_m2m_dev *v4l2_m2m_enc_dev;
struct list_head instances;
struct video_device *video_dev_dec;
struct video_device *video_dev_enc;
struct mutex dev_lock; /* lock for the src, dst v4l2 queues */
struct mutex hw_lock; /* lock hw configurations */
struct mutex irq_lock;
int irq;
enum product_id product;
struct vpu_attr attr;
struct vpu_buf common_mem;
u32 last_performance_cycles;
u32 sram_size;
struct gen_pool *sram_pool;
struct vpu_buf sram_buf;
void __iomem *vdb_register;
u32 product_code;
struct ida inst_ida;
struct clk_bulk_data *clks;
struct hrtimer hrtimer;
struct kthread_work work;
struct kthread_worker *worker;
int vpu_poll_interval;
int num_clks;
struct task_struct *irq_thread;
struct semaphore irq_sem; /* signal to irq_thread when interrupt happens*/
struct reset_control *resets;
spinlock_t irq_spinlock; /* protect instances list */
};
struct vpu_instance;
struct vpu_instance_ops {
void (*finish_process)(struct vpu_instance *inst);
};
struct vpu_instance {
struct list_head list;
struct v4l2_fh v4l2_fh;
struct v4l2_m2m_dev *v4l2_m2m_dev;
struct v4l2_ctrl_handler v4l2_ctrl_hdl;
struct vpu_device *dev;
struct completion irq_done;
struct v4l2_pix_format_mplane src_fmt;
struct v4l2_pix_format_mplane dst_fmt;
enum v4l2_colorspace colorspace;
enum v4l2_xfer_func xfer_func;
enum v4l2_ycbcr_encoding ycbcr_enc;
enum v4l2_quantization quantization;
struct kfifo irq_status;
enum vpu_instance_state state;
enum vpu_instance_type type;
const struct vpu_instance_ops *ops;
spinlock_t state_spinlock; /* This protects the instance state */
enum wave_std std;
s32 id;
union {
struct enc_info enc_info;
struct dec_info dec_info;
} *codec_info;
struct frame_buffer frame_buf[MAX_REG_FRAME];
struct vpu_buf frame_vbuf[MAX_REG_FRAME];
u32 fbc_buf_count;
u32 queued_src_buf_num;
u32 queued_dst_buf_num;
struct list_head avail_src_bufs;
struct list_head avail_dst_bufs;
struct v4l2_rect conf_win;
u64 timestamp;
enum frame_buffer_format output_format;
bool cbcr_interleave;
bool nv21;
bool eos;
bool sent_eos; /* check if EOS is sent to application */
bool retry; /* retry to feed bitstream if failure reason is WAVE5_SYSERR_QUEUEING_FAIL*/
int queuing_num; /* count of bitstream queued */
struct mutex feed_lock; /* lock for feeding bitstream buffers */
bool queuing_fail; /* if there is the queuing failure */
bool empty_queue;
struct vpu_buf bitstream_vbuf;
dma_addr_t last_rd_ptr;
size_t remaining_consumed_bytes;
bool needs_reallocation;
unsigned int min_src_buf_count;
unsigned int rot_angle;
unsigned int mirror_direction;
unsigned int bit_depth;
unsigned int frame_rate;
unsigned int vbv_buf_size;
unsigned int rc_mode;
unsigned int rc_enable;
unsigned int bit_rate;
unsigned int encode_aud;
struct enc_wave_param enc_param;
};
void wave5_vdi_write_register(struct vpu_device *vpu_dev, u32 addr, u32 data);
u32 wave5_vdi_read_register(struct vpu_device *vpu_dev, u32 addr);
int wave5_vdi_clear_memory(struct vpu_device *vpu_dev, struct vpu_buf *vb);
int wave5_vdi_allocate_dma_memory(struct vpu_device *vpu_dev, struct vpu_buf *vb);
int wave5_vdi_allocate_array(struct vpu_device *vpu_dev, struct vpu_buf *array, unsigned int count,
size_t size);
int wave5_vdi_write_memory(struct vpu_device *vpu_dev, struct vpu_buf *vb, size_t offset,
u8 *data, size_t len);
int wave5_vdi_free_dma_memory(struct vpu_device *vpu_dev, struct vpu_buf *vb);
void wave5_vdi_allocate_sram(struct vpu_device *vpu_dev);
void wave5_vdi_free_sram(struct vpu_device *vpu_dev);
int wave5_vpu_init_with_bitcode(struct device *dev, u8 *bitcode, size_t size);
int wave5_vpu_flush_instance(struct vpu_instance *inst);
int wave5_vpu_get_version_info(struct device *dev, u32 *revision, unsigned int *product_id);
int wave5_vpu_dec_open(struct vpu_instance *inst, struct dec_open_param *open_param);
int wave5_vpu_dec_close(struct vpu_instance *inst, u32 *fail_res);
int wave5_vpu_dec_issue_seq_init(struct vpu_instance *inst);
int wave5_vpu_dec_complete_seq_init(struct vpu_instance *inst, struct dec_initial_info *info);
int wave5_vpu_dec_register_frame_buffer_ex(struct vpu_instance *inst, int num_of_decoding_fbs,
int num_of_display_fbs, int stride, int height);
int wave5_vpu_dec_start_one_frame(struct vpu_instance *inst, u32 *res_fail);
int wave5_vpu_dec_get_output_info(struct vpu_instance *inst, struct dec_output_info *info);
int wave5_vpu_dec_set_rd_ptr(struct vpu_instance *inst, dma_addr_t addr, int update_wr_ptr);
dma_addr_t wave5_vpu_dec_get_rd_ptr(struct vpu_instance *inst);
int wave5_vpu_dec_reset_framebuffer(struct vpu_instance *inst, unsigned int index);
int wave5_vpu_dec_give_command(struct vpu_instance *inst, enum codec_command cmd, void *parameter);
int wave5_vpu_dec_get_bitstream_buffer(struct vpu_instance *inst, dma_addr_t *prd_ptr,
dma_addr_t *pwr_ptr, size_t *size);
int wave5_vpu_dec_update_bitstream_buffer(struct vpu_instance *inst, size_t size);
int wave5_vpu_dec_clr_disp_flag(struct vpu_instance *inst, int index);
int wave5_vpu_dec_set_disp_flag(struct vpu_instance *inst, int index);
int wave5_vpu_enc_open(struct vpu_instance *inst, struct enc_open_param *open_param);
int wave5_vpu_enc_close(struct vpu_instance *inst, u32 *fail_res);
int wave5_vpu_enc_issue_seq_init(struct vpu_instance *inst);
int wave5_vpu_enc_complete_seq_init(struct vpu_instance *inst, struct enc_initial_info *info);
int wave5_vpu_enc_register_frame_buffer(struct vpu_instance *inst, unsigned int num,
unsigned int stride, int height,
enum tiled_map_type map_type);
int wave5_vpu_enc_start_one_frame(struct vpu_instance *inst, struct enc_param *param,
u32 *fail_res);
int wave5_vpu_enc_get_output_info(struct vpu_instance *inst, struct enc_output_info *info);
int wave5_vpu_enc_give_command(struct vpu_instance *inst, enum codec_command cmd, void *parameter);
#endif
@@ -0,0 +1,103 @@
/* SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) */
/*
* Wave5 series multi-standard codec IP - product config definitions
*
* Copyright (C) 2021-2023 CHIPS&MEDIA INC
*/
#ifndef _VPU_CONFIG_H_
#define _VPU_CONFIG_H_
#define WAVE515_CODE 0x5150
#define WAVE517_CODE 0x5170
#define WAVE537_CODE 0x5370
#define WAVE511_CODE 0x5110
#define WAVE521_CODE 0x5210
#define WAVE521C_CODE 0x521c
#define WAVE521C_DUAL_CODE 0x521d // wave521 dual core
#define WAVE521E1_CODE 0x5211
#define PRODUCT_CODE_W_SERIES(x) ({ \
int c = x; \
((c) == WAVE517_CODE || (c) == WAVE537_CODE || \
(c) == WAVE511_CODE || (c) == WAVE521_CODE || \
(c) == WAVE521E1_CODE || (c) == WAVE521C_CODE || \
(c) == WAVE521C_DUAL_CODE) || (c) == WAVE515_CODE; \
})
#define WAVE517_WORKBUF_SIZE (2 * 1024 * 1024)
#define WAVE521ENC_WORKBUF_SIZE (128 * 1024) //HEVC 128K, AVC 40K
#define WAVE521DEC_WORKBUF_SIZE (1784 * 1024)
#define WAVE515DEC_WORKBUF_SIZE (2 * 1024 * 1024)
#define MAX_NUM_INSTANCE 32
#define W5_DEF_DEC_PIC_WIDTH 720U
#define W5_DEF_DEC_PIC_HEIGHT 480U
#define W5_MIN_DEC_PIC_8_WIDTH 8U
#define W5_MIN_DEC_PIC_8_HEIGHT 8U
#define W5_MIN_DEC_PIC_32_WIDTH 32U
#define W5_MIN_DEC_PIC_32_HEIGHT 32U
#define W5_MAX_DEC_PIC_WIDTH 8192U
#define W5_MAX_DEC_PIC_HEIGHT 4320U
#define W5_DEC_CODEC_STEP_WIDTH 1U
#define W5_DEC_CODEC_STEP_HEIGHT 1U
#define W5_DEC_RAW_STEP_WIDTH 32U
#define W5_DEC_RAW_STEP_HEIGHT 16U
#define W5_DEF_ENC_PIC_WIDTH 416U
#define W5_DEF_ENC_PIC_HEIGHT 240U
#define W5_MIN_ENC_PIC_WIDTH 256U
#define W5_MIN_ENC_PIC_HEIGHT 128U
#define W5_MAX_ENC_PIC_WIDTH 8192U
#define W5_MAX_ENC_PIC_HEIGHT 8192U
#define W5_ENC_CODEC_STEP_WIDTH 8U
#define W5_ENC_CODEC_STEP_HEIGHT 8U
#define W5_ENC_RAW_STEP_WIDTH 32U
#define W5_ENC_RAW_STEP_HEIGHT 16U
// application specific configuration
#define VPU_ENC_TIMEOUT 60000
#define VPU_DEC_TIMEOUT 60000
#define VPU_DEC_STOP_TIMEOUT 10
// for WAVE encoder
#define USE_SRC_PRP_AXI 0
#define USE_SRC_PRI_AXI 1
#define DEFAULT_SRC_AXI USE_SRC_PRP_AXI
/************************************************************************/
/* VPU COMMON MEMORY */
/************************************************************************/
#define VLC_BUF_NUM (2)
#define WAVE521_COMMAND_QUEUE_DEPTH (2)
#define WAVE515_COMMAND_QUEUE_DEPTH (4)
#define W5_REMAP_INDEX0 0
#define W5_REMAP_INDEX1 1
#define W5_REMAP_MAX_SIZE (1024 * 1024)
#define WAVE521_MAX_CODE_BUF_SIZE (2 * 1024 * 1024)
#define WAVE515_MAX_CODE_BUF_SIZE (1024 * 1024)
#define WAVE5_TEMPBUF_SIZE (1024 * 1024)
#define WAVE521_SIZE_COMMON (WAVE521_MAX_CODE_BUF_SIZE + WAVE5_TEMPBUF_SIZE)
#define WAVE515_ONE_TASKBUF_SIZE (8 * 1024 * 1024)
#define WAVE515_SIZE_COMMON (WAVE515_MAX_CODE_BUF_SIZE + WAVE5_TEMPBUF_SIZE + \
WAVE515_COMMAND_QUEUE_DEPTH * WAVE515_ONE_TASKBUF_SIZE)
//=====4. VPU REPORT MEMORY ======================//
#define WAVE5_UPPER_PROC_AXI_ID 0x0
#define WAVE5_PROC_AXI_ID 0x0
#define WAVE5_PRP_AXI_ID 0x0
#define WAVE5_FBD_Y_AXI_ID 0x0
#define WAVE5_FBC_Y_AXI_ID 0x0
#define WAVE5_FBD_C_AXI_ID 0x0
#define WAVE5_FBC_C_AXI_ID 0x0
#define WAVE5_SEC_AXI_ID 0x0
#define WAVE5_PRI_AXI_ID 0x0
#endif /* _VPU_CONFIG_H_ */
@@ -0,0 +1,292 @@
/* SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) */
/*
* Wave5 series multi-standard codec IP - error values
*
* Copyright (C) 2021-2023 CHIPS&MEDIA INC
*/
#ifndef ERROR_CODE_H_INCLUDED
#define ERROR_CODE_H_INCLUDED
/*
* WAVE5
*/
/************************************************************************/
/* WAVE5 COMMON SYSTEM ERROR (FAIL_REASON) */
/************************************************************************/
#define WAVE5_SYSERR_QUEUEING_FAIL 0x00000001
#define WAVE5_SYSERR_ACCESS_VIOLATION_HW 0x00000040
#define WAVE5_SYSERR_BUS_ERROR 0x00000200
#define WAVE5_SYSERR_DOUBLE_FAULT 0x00000400
#define WAVE5_SYSERR_RESULT_NOT_READY 0x00000800
#define WAVE5_SYSERR_VPU_STILL_RUNNING 0x00001000
#define WAVE5_SYSERR_UNKNOWN_CMD 0x00002000
#define WAVE5_SYSERR_UNKNOWN_CODEC_STD 0x00004000
#define WAVE5_SYSERR_UNKNOWN_QUERY_OPTION 0x00008000
#define WAVE5_SYSERR_VLC_BUF_FULL 0x00010000
#define WAVE5_SYSERR_WATCHDOG_TIMEOUT 0x00020000
#define WAVE5_SYSERR_VCPU_TIMEOUT 0x00080000
#define WAVE5_SYSERR_TEMP_SEC_BUF_OVERFLOW 0x00200000
#define WAVE5_SYSERR_NEED_MORE_TASK_BUF 0x00400000
#define WAVE5_SYSERR_PRESCAN_ERR 0x00800000
#define WAVE5_SYSERR_ENC_GBIN_OVERCONSUME 0x01000000
#define WAVE5_SYSERR_ENC_MAX_ZERO_DETECT 0x02000000
#define WAVE5_SYSERR_ENC_LVL_FIRST_ERROR 0x04000000
#define WAVE5_SYSERR_ENC_EG_RANGE_OVER 0x08000000
#define WAVE5_SYSERR_ENC_IRB_FRAME_DROP 0x10000000
#define WAVE5_SYSERR_INPLACE_V 0x20000000
#define WAVE5_SYSERR_FATAL_VPU_HANGUP 0xf0000000
/************************************************************************/
/* WAVE5 COMMAND QUEUE ERROR (FAIL_REASON) */
/************************************************************************/
#define WAVE5_CMDQ_ERR_NOT_QUEABLE_CMD 0x00000001
#define WAVE5_CMDQ_ERR_SKIP_MODE_ENABLE 0x00000002
#define WAVE5_CMDQ_ERR_INST_FLUSHING 0x00000003
#define WAVE5_CMDQ_ERR_INST_INACTIVE 0x00000004
#define WAVE5_CMDQ_ERR_QUEUE_FAIL 0x00000005
#define WAVE5_CMDQ_ERR_CMD_BUF_FULL 0x00000006
/************************************************************************/
/* WAVE5 ERROR ON DECODER (ERR_INFO) */
/************************************************************************/
// HEVC
#define HEVC_SPSERR_SEQ_PARAMETER_SET_ID 0x00001000
#define HEVC_SPSERR_CHROMA_FORMAT_IDC 0x00001001
#define HEVC_SPSERR_PIC_WIDTH_IN_LUMA_SAMPLES 0x00001002
#define HEVC_SPSERR_PIC_HEIGHT_IN_LUMA_SAMPLES 0x00001003
#define HEVC_SPSERR_CONF_WIN_LEFT_OFFSET 0x00001004
#define HEVC_SPSERR_CONF_WIN_RIGHT_OFFSET 0x00001005
#define HEVC_SPSERR_CONF_WIN_TOP_OFFSET 0x00001006
#define HEVC_SPSERR_CONF_WIN_BOTTOM_OFFSET 0x00001007
#define HEVC_SPSERR_BIT_DEPTH_LUMA_MINUS8 0x00001008
#define HEVC_SPSERR_BIT_DEPTH_CHROMA_MINUS8 0x00001009
#define HEVC_SPSERR_LOG2_MAX_PIC_ORDER_CNT_LSB_MINUS4 0x0000100A
#define HEVC_SPSERR_SPS_MAX_DEC_PIC_BUFFERING 0x0000100B
#define HEVC_SPSERR_SPS_MAX_NUM_REORDER_PICS 0x0000100C
#define HEVC_SPSERR_SPS_MAX_LATENCY_INCREASE 0x0000100D
#define HEVC_SPSERR_LOG2_MIN_LUMA_CODING_BLOCK_SIZE_MINUS3 0x0000100E
#define HEVC_SPSERR_LOG2_DIFF_MAX_MIN_LUMA_CODING_BLOCK_SIZE 0x0000100F
#define HEVC_SPSERR_LOG2_MIN_TRANSFORM_BLOCK_SIZE_MINUS2 0x00001010
#define HEVC_SPSERR_LOG2_DIFF_MAX_MIN_TRANSFORM_BLOCK_SIZE 0x00001011
#define HEVC_SPSERR_MAX_TRANSFORM_HIERARCHY_DEPTH_INTER 0x00001012
#define HEVC_SPSERR_MAX_TRANSFORM_HIERARCHY_DEPTH_INTRA 0x00001013
#define HEVC_SPSERR_SCALING_LIST 0x00001014
#define HEVC_SPSERR_LOG2_DIFF_MIN_PCM_LUMA_CODING_BLOCK_SIZE_MINUS3 0x00001015
#define HEVC_SPSERR_LOG2_DIFF_MAX_MIN_PCM_LUMA_CODING_BLOCK_SIZE 0x00001016
#define HEVC_SPSERR_NUM_SHORT_TERM_REF_PIC_SETS 0x00001017
#define HEVC_SPSERR_NUM_LONG_TERM_REF_PICS_SPS 0x00001018
#define HEVC_SPSERR_GBU_PARSING_ERROR 0x00001019
#define HEVC_SPSERR_EXTENSION_FLAG 0x0000101A
#define HEVC_SPSERR_VUI_ERROR 0x0000101B
#define HEVC_SPSERR_ACTIVATE_SPS 0x0000101C
#define HEVC_SPSERR_PROFILE_SPACE 0x0000101D
#define HEVC_PPSERR_PPS_PIC_PARAMETER_SET_ID 0x00002000
#define HEVC_PPSERR_PPS_SEQ_PARAMETER_SET_ID 0x00002001
#define HEVC_PPSERR_NUM_REF_IDX_L0_DEFAULT_ACTIVE_MINUS1 0x00002002
#define HEVC_PPSERR_NUM_REF_IDX_L1_DEFAULT_ACTIVE_MINUS1 0x00002003
#define HEVC_PPSERR_INIT_QP_MINUS26 0x00002004
#define HEVC_PPSERR_DIFF_CU_QP_DELTA_DEPTH 0x00002005
#define HEVC_PPSERR_PPS_CB_QP_OFFSET 0x00002006
#define HEVC_PPSERR_PPS_CR_QP_OFFSET 0x00002007
#define HEVC_PPSERR_NUM_TILE_COLUMNS_MINUS1 0x00002008
#define HEVC_PPSERR_NUM_TILE_ROWS_MINUS1 0x00002009
#define HEVC_PPSERR_COLUMN_WIDTH_MINUS1 0x0000200A
#define HEVC_PPSERR_ROW_HEIGHT_MINUS1 0x0000200B
#define HEVC_PPSERR_PPS_BETA_OFFSET_DIV2 0x0000200C
#define HEVC_PPSERR_PPS_TC_OFFSET_DIV2 0x0000200D
#define HEVC_PPSERR_SCALING_LIST 0x0000200E
#define HEVC_PPSERR_LOG2_PARALLEL_MERGE_LEVEL_MINUS2 0x0000200F
#define HEVC_PPSERR_NUM_TILE_COLUMNS_RANGE_OUT 0x00002010
#define HEVC_PPSERR_NUM_TILE_ROWS_RANGE_OUT 0x00002011
#define HEVC_PPSERR_MORE_RBSP_DATA_ERROR 0x00002012
#define HEVC_PPSERR_PPS_PIC_PARAMETER_SET_ID_RANGE_OUT 0x00002013
#define HEVC_PPSERR_PPS_SEQ_PARAMETER_SET_ID_RANGE_OUT 0x00002014
#define HEVC_PPSERR_NUM_REF_IDX_L0_DEFAULT_ACTIVE_MINUS1_RANGE_OUT 0x00002015
#define HEVC_PPSERR_NUM_REF_IDX_L1_DEFAULT_ACTIVE_MINUS1_RANGE_OUT 0x00002016
#define HEVC_PPSERR_PPS_CB_QP_OFFSET_RANGE_OUT 0x00002017
#define HEVC_PPSERR_PPS_CR_QP_OFFSET_RANGE_OUT 0x00002018
#define HEVC_PPSERR_COLUMN_WIDTH_MINUS1_RANGE_OUT 0x00002019
#define HEVC_PPSERR_ROW_HEIGHT_MINUS1_RANGE_OUT 0x00002020
#define HEVC_PPSERR_PPS_BETA_OFFSET_DIV2_RANGE_OUT 0x00002021
#define HEVC_PPSERR_PPS_TC_OFFSET_DIV2_RANGE_OUT 0x00002022
#define HEVC_SHERR_SLICE_PIC_PARAMETER_SET_ID 0x00003000
#define HEVC_SHERR_ACTIVATE_PPS 0x00003001
#define HEVC_SHERR_ACTIVATE_SPS 0x00003002
#define HEVC_SHERR_SLICE_TYPE 0x00003003
#define HEVC_SHERR_FIRST_SLICE_IS_DEPENDENT_SLICE 0x00003004
#define HEVC_SHERR_SHORT_TERM_REF_PIC_SET_SPS_FLAG 0x00003005
#define HEVC_SHERR_SHORT_TERM_REF_PIC_SET 0x00003006
#define HEVC_SHERR_SHORT_TERM_REF_PIC_SET_IDX 0x00003007
#define HEVC_SHERR_NUM_LONG_TERM_SPS 0x00003008
#define HEVC_SHERR_NUM_LONG_TERM_PICS 0x00003009
#define HEVC_SHERR_LT_IDX_SPS_IS_OUT_OF_RANGE 0x0000300A
#define HEVC_SHERR_DELTA_POC_MSB_CYCLE_LT 0x0000300B
#define HEVC_SHERR_NUM_REF_IDX_L0_ACTIVE_MINUS1 0x0000300C
#define HEVC_SHERR_NUM_REF_IDX_L1_ACTIVE_MINUS1 0x0000300D
#define HEVC_SHERR_COLLOCATED_REF_IDX 0x0000300E
#define HEVC_SHERR_PRED_WEIGHT_TABLE 0x0000300F
#define HEVC_SHERR_FIVE_MINUS_MAX_NUM_MERGE_CAND 0x00003010
#define HEVC_SHERR_SLICE_QP_DELTA 0x00003011
#define HEVC_SHERR_SLICE_QP_DELTA_IS_OUT_OF_RANGE 0x00003012
#define HEVC_SHERR_SLICE_CB_QP_OFFSET 0x00003013
#define HEVC_SHERR_SLICE_CR_QP_OFFSET 0x00003014
#define HEVC_SHERR_SLICE_BETA_OFFSET_DIV2 0x00003015
#define HEVC_SHERR_SLICE_TC_OFFSET_DIV2 0x00003016
#define HEVC_SHERR_NUM_ENTRY_POINT_OFFSETS 0x00003017
#define HEVC_SHERR_OFFSET_LEN_MINUS1 0x00003018
#define HEVC_SHERR_SLICE_SEGMENT_HEADER_EXTENSION_LENGTH 0x00003019
#define HEVC_SHERR_WRONG_POC_IN_STILL_PICTURE_PROFILE 0x0000301A
#define HEVC_SHERR_SLICE_TYPE_ERROR_IN_STILL_PICTURE_PROFILE 0x0000301B
#define HEVC_SHERR_PPS_ID_NOT_EQUAL_PREV_VALUE 0x0000301C
#define HEVC_SPECERR_OVER_PICTURE_WIDTH_SIZE 0x00004000
#define HEVC_SPECERR_OVER_PICTURE_HEIGHT_SIZE 0x00004001
#define HEVC_SPECERR_OVER_CHROMA_FORMAT 0x00004002
#define HEVC_SPECERR_OVER_BIT_DEPTH 0x00004003
#define HEVC_SPECERR_OVER_BUFFER_OVER_FLOW 0x00004004
#define HEVC_SPECERR_OVER_WRONG_BUFFER_ACCESS 0x00004005
#define HEVC_ETCERR_INIT_SEQ_SPS_NOT_FOUND 0x00005000
#define HEVC_ETCERR_DEC_PIC_VCL_NOT_FOUND 0x00005001
#define HEVC_ETCERR_NO_VALID_SLICE_IN_AU 0x00005002
#define HEVC_ETCERR_INPLACE_V 0x0000500F
// AVC
#define AVC_SPSERR_SEQ_PARAMETER_SET_ID 0x00001000
#define AVC_SPSERR_CHROMA_FORMAT_IDC 0x00001001
#define AVC_SPSERR_PIC_WIDTH_IN_LUMA_SAMPLES 0x00001002
#define AVC_SPSERR_PIC_HEIGHT_IN_LUMA_SAMPLES 0x00001003
#define AVC_SPSERR_CONF_WIN_LEFT_OFFSET 0x00001004
#define AVC_SPSERR_CONF_WIN_RIGHT_OFFSET 0x00001005
#define AVC_SPSERR_CONF_WIN_TOP_OFFSET 0x00001006
#define AVC_SPSERR_CONF_WIN_BOTTOM_OFFSET 0x00001007
#define AVC_SPSERR_BIT_DEPTH_LUMA_MINUS8 0x00001008
#define AVC_SPSERR_BIT_DEPTH_CHROMA_MINUS8 0x00001009
#define AVC_SPSERR_SPS_MAX_DEC_PIC_BUFFERING 0x0000100B
#define AVC_SPSERR_SPS_MAX_NUM_REORDER_PICS 0x0000100C
#define AVC_SPSERR_SCALING_LIST 0x00001014
#define AVC_SPSERR_GBU_PARSING_ERROR 0x00001019
#define AVC_SPSERR_VUI_ERROR 0x0000101B
#define AVC_SPSERR_ACTIVATE_SPS 0x0000101C
#define AVC_PPSERR_PPS_PIC_PARAMETER_SET_ID 0x00002000
#define AVC_PPSERR_PPS_SEQ_PARAMETER_SET_ID 0x00002001
#define AVC_PPSERR_NUM_REF_IDX_L0_DEFAULT_ACTIVE_MINUS1 0x00002002
#define AVC_PPSERR_NUM_REF_IDX_L1_DEFAULT_ACTIVE_MINUS1 0x00002003
#define AVC_PPSERR_INIT_QP_MINUS26 0x00002004
#define AVC_PPSERR_PPS_CB_QP_OFFSET 0x00002006
#define AVC_PPSERR_PPS_CR_QP_OFFSET 0x00002007
#define AVC_PPSERR_SCALING_LIST 0x0000200E
#define AVC_PPSERR_MORE_RBSP_DATA_ERROR 0x00002012
#define AVC_PPSERR_PPS_PIC_PARAMETER_SET_ID_RANGE_OUT 0x00002013
#define AVC_PPSERR_PPS_SEQ_PARAMETER_SET_ID_RANGE_OUT 0x00002014
#define AVC_PPSERR_NUM_REF_IDX_L0_DEFAULT_ACTIVE_MINUS1_RANGE_OUT 0x00002015
#define AVC_PPSERR_NUM_REF_IDX_L1_DEFAULT_ACTIVE_MINUS1_RANGE_OUT 0x00002016
#define AVC_PPSERR_PPS_CB_QP_OFFSET_RANGE_OUT 0x00002017
#define AVC_PPSERR_PPS_CR_QP_OFFSET_RANGE_OUT 0x00002018
#define AVC_SHERR_SLICE_PIC_PARAMETER_SET_ID 0x00003000
#define AVC_SHERR_ACTIVATE_PPS 0x00003001
#define AVC_SHERR_ACTIVATE_SPS 0x00003002
#define AVC_SHERR_SLICE_TYPE 0x00003003
#define AVC_SHERR_FIRST_MB_IN_SLICE 0x00003004
#define AVC_SHERR_RPLM 0x00003006
#define AVC_SHERR_LT_IDX_SPS_IS_OUT_OF_RANGE 0x0000300A
#define AVC_SHERR_NUM_REF_IDX_L0_ACTIVE_MINUS1 0x0000300C
#define AVC_SHERR_NUM_REF_IDX_L1_ACTIVE_MINUS1 0x0000300D
#define AVC_SHERR_PRED_WEIGHT_TABLE 0x0000300F
#define AVC_SHERR_SLICE_QP_DELTA 0x00003011
#define AVC_SHERR_SLICE_BETA_OFFSET_DIV2 0x00003015
#define AVC_SHERR_SLICE_TC_OFFSET_DIV2 0x00003016
#define AVC_SHERR_DISABLE_DEBLOCK_FILTER_IDC 0x00003017
#define AVC_SPECERR_OVER_PICTURE_WIDTH_SIZE 0x00004000
#define AVC_SPECERR_OVER_PICTURE_HEIGHT_SIZE 0x00004001
#define AVC_SPECERR_OVER_CHROMA_FORMAT 0x00004002
#define AVC_SPECERR_OVER_BIT_DEPTH 0x00004003
#define AVC_SPECERR_OVER_BUFFER_OVER_FLOW 0x00004004
#define AVC_SPECERR_OVER_WRONG_BUFFER_ACCESS 0x00004005
#define AVC_ETCERR_INIT_SEQ_SPS_NOT_FOUND 0x00005000
#define AVC_ETCERR_DEC_PIC_VCL_NOT_FOUND 0x00005001
#define AVC_ETCERR_NO_VALID_SLICE_IN_AU 0x00005002
#define AVC_ETCERR_ASO 0x00005004
#define AVC_ETCERR_FMO 0x00005005
#define AVC_ETCERR_INPLACE_V 0x0000500F
/************************************************************************/
/* WAVE5 WARNING ON DECODER (WARN_INFO) */
/************************************************************************/
// HEVC
#define HEVC_SPSWARN_MAX_SUB_LAYERS_MINUS1 0x00000001
#define HEVC_SPSWARN_GENERAL_RESERVED_ZERO_44BITS 0x00000002
#define HEVC_SPSWARN_RESERVED_ZERO_2BITS 0x00000004
#define HEVC_SPSWARN_SUB_LAYER_RESERVED_ZERO_44BITS 0x00000008
#define HEVC_SPSWARN_GENERAL_LEVEL_IDC 0x00000010
#define HEVC_SPSWARN_SPS_MAX_DEC_PIC_BUFFERING_VALUE_OVER 0x00000020
#define HEVC_SPSWARN_RBSP_TRAILING_BITS 0x00000040
#define HEVC_SPSWARN_ST_RPS_UE_ERROR 0x00000080
#define HEVC_SPSWARN_EXTENSION_FLAG 0x01000000
#define HEVC_SPSWARN_REPLACED_WITH_PREV_SPS 0x02000000
#define HEVC_PPSWARN_RBSP_TRAILING_BITS 0x00000100
#define HEVC_PPSWARN_REPLACED_WITH_PREV_PPS 0x00000200
#define HEVC_SHWARN_FIRST_SLICE_SEGMENT_IN_PIC_FLAG 0x00001000
#define HEVC_SHWARN_NO_OUTPUT_OF_PRIOR_PICS_FLAG 0x00002000
#define HEVC_SHWARN_PIC_OUTPUT_FLAG 0x00004000
#define HEVC_SHWARN_DUPLICATED_SLICE_SEGMENT 0x00008000
#define HEVC_ETCWARN_INIT_SEQ_VCL_NOT_FOUND 0x00010000
#define HEVC_ETCWARN_MISSING_REFERENCE_PICTURE 0x00020000
#define HEVC_ETCWARN_WRONG_TEMPORAL_ID 0x00040000
#define HEVC_ETCWARN_ERROR_PICTURE_IS_REFERENCED 0x00080000
#define HEVC_SPECWARN_OVER_PROFILE 0x00100000
#define HEVC_SPECWARN_OVER_LEVEL 0x00200000
#define HEVC_PRESWARN_PARSING_ERR 0x04000000
#define HEVC_PRESWARN_MVD_OUT_OF_RANGE 0x08000000
#define HEVC_PRESWARN_CU_QP_DELTA_VAL_OUT_OF_RANGE 0x09000000
#define HEVC_PRESWARN_COEFF_LEVEL_REMAINING_OUT_OF_RANGE 0x0A000000
#define HEVC_PRESWARN_PCM_ERR 0x0B000000
#define HEVC_PRESWARN_OVERCONSUME 0x0C000000
#define HEVC_PRESWARN_END_OF_SUBSET_ONE_BIT_ERR 0x10000000
#define HEVC_PRESWARN_END_OF_SLICE_SEGMENT_FLAG 0x20000000
// AVC
#define AVC_SPSWARN_RESERVED_ZERO_2BITS 0x00000004
#define AVC_SPSWARN_GENERAL_LEVEL_IDC 0x00000010
#define AVC_SPSWARN_RBSP_TRAILING_BITS 0x00000040
#define AVC_PPSWARN_RBSP_TRAILING_BITS 0x00000100
#define AVC_SHWARN_NO_OUTPUT_OF_PRIOR_PICS_FLAG 0x00002000
#define AVC_ETCWARN_INIT_SEQ_VCL_NOT_FOUND 0x00010000
#define AVC_ETCWARN_MISSING_REFERENCE_PICTURE 0x00020000
#define AVC_ETCWARN_ERROR_PICTURE_IS_REFERENCED 0x00080000
#define AVC_SPECWARN_OVER_PROFILE 0x00100000
#define AVC_SPECWARN_OVER_LEVEL 0x00200000
#define AVC_PRESWARN_MVD_RANGE_OUT 0x00400000
#define AVC_PRESWARN_MB_QPD_RANGE_OUT 0x00500000
#define AVC_PRESWARN_COEFF_RANGE_OUT 0x00600000
#define AVC_PRESWARN_MV_RANGE_OUT 0x00700000
#define AVC_PRESWARN_MB_SKIP_RUN_RANGE_OUT 0x00800000
#define AVC_PRESWARN_MB_TYPE_RANGE_OUT 0x00900000
#define AVC_PRESWARN_SUB_MB_TYPE_RANGE_OUT 0x00A00000
#define AVC_PRESWARN_CBP_RANGE_OUT 0x00B00000
#define AVC_PRESWARN_INTRA_CHROMA_PRED_MODE_RANGE_OUT 0x00C00000
#define AVC_PRESWARN_REF_IDX_RANGE_OUT 0x00D00000
#define AVC_PRESWARN_COEFF_TOKEN_RANGE_OUT 0x00E00000
#define AVC_PRESWARN_TOTAL_ZERO_RANGE_OUT 0x00F00000
#define AVC_PRESWARN_RUN_BEFORE_RANGE_OUT 0x01000000
#define AVC_PRESWARN_OVERCONSUME 0x01100000
#define AVC_PRESWARN_MISSING_SLICE 0x01200000
/************************************************************************/
/* WAVE5 ERROR ON ENCODER (ERR_INFO) */
/************************************************************************/
/************************************************************************/
/* WAVE5 WARNING ON ENCODER (WARN_INFO) */
/************************************************************************/
#define WAVE5_ETCWARN_FORCED_SPLIT_BY_CU8X8 0x000000001
/************************************************************************/
/* WAVE5 debug info (PRI_REASON) */
/************************************************************************/
#define WAVE5_DEC_VCORE_VCE_HANGUP 0x0001
#define WAVE5_DEC_VCORE_UNDETECTED_SYNTAX_ERR 0x0002
#define WAVE5_DEC_VCORE_MIB_BUSY 0x0003
#define WAVE5_DEC_VCORE_VLC_BUSY 0x0004
#endif /* ERROR_CODE_H_INCLUDED */
@@ -0,0 +1,123 @@
/* SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) */
/*
* Wave5 series multi-standard codec IP - wave5 backend definitions
*
* Copyright (C) 2021-2023 CHIPS&MEDIA INC
*/
#ifndef __WAVE5_FUNCTION_H__
#define __WAVE5_FUNCTION_H__
#define WAVE5_SUBSAMPLED_ONE_SIZE(_w, _h) (ALIGN((_w) / 4, 16) * ALIGN((_h) / 4, 8))
#define WAVE5_SUBSAMPLED_ONE_SIZE_AVC(_w, _h) (ALIGN((_w) / 4, 32) * ALIGN((_h) / 4, 4))
/*
* Bitstream buffer option: Explicit End
* When set to 1 the VPU assumes that the bitstream has at least one frame and
* will read until the end of the bitstream buffer.
* When set to 0 the VPU will not read the last few bytes.
* This option can be set anytime but cannot be cleared during processing.
* It can be set to force finish decoding even though there is not enough
* bitstream data for a full frame.
*/
#define BSOPTION_ENABLE_EXPLICIT_END BIT(0)
#define BSOPTION_HIGHLIGHT_STREAM_END BIT(1)
/*
* When RD_PTR_VALID_FLAG is 0 Wave515 ignores RD_PTR value and starts to
* decode from the access unit end position of the last decoded picture in
* bitstream buffer.
*/
#define BSOPTION_RD_PTR_VALID_FLAG BIT(31)
/*
* Currently the driver only supports hardware with little endian but for source
* picture format, the bitstream and the report parameter the hardware works
* with the opposite endianness, thus hard-code big endian for the register
* writes
*/
#define PIC_SRC_ENDIANNESS_BIG_ENDIAN 0xf
#define BITSTREAM_ENDIANNESS_BIG_ENDIAN 0xf
#define REPORT_PARAM_ENDIANNESS_BIG_ENDIAN 0xf
#define WTL_RIGHT_JUSTIFIED 0
#define WTL_LEFT_JUSTIFIED 1
#define WTL_PIXEL_8BIT 0
#define WTL_PIXEL_16BIT 1
#define WTL_PIXEL_32BIT 2
/* Mirror & rotation modes of the PRP (pre-processing) module */
#define NONE_ROTATE 0x0
#define ROT_CLOCKWISE_90 0x3
#define ROT_CLOCKWISE_180 0x5
#define ROT_CLOCKWISE_270 0x7
#define MIR_HOR_FLIP 0x11
#define MIR_VER_FLIP 0x9
#define MIR_HOR_VER_FLIP (MIR_HOR_FLIP | MIR_VER_FLIP)
bool wave5_vpu_is_init(struct vpu_device *vpu_dev);
unsigned int wave5_vpu_get_product_id(struct vpu_device *vpu_dev);
int wave5_vpu_get_version(struct vpu_device *vpu_dev, u32 *revision);
int wave5_vpu_init(struct device *dev, u8 *fw, size_t size);
int wave5_vpu_sleep_wake(struct device *dev, bool i_sleep_wake, const uint16_t *code,
size_t size);
int wave5_vpu_reset(struct device *dev, enum sw_reset_mode reset_mode);
int wave5_vpu_build_up_dec_param(struct vpu_instance *inst, struct dec_open_param *param);
int wave5_vpu_dec_set_bitstream_flag(struct vpu_instance *inst, bool eos);
int wave5_vpu_hw_flush_instance(struct vpu_instance *inst);
int wave5_vpu_dec_register_framebuffer(struct vpu_instance *inst,
struct frame_buffer *fb_arr, enum tiled_map_type map_type,
unsigned int count);
int wave5_vpu_re_init(struct device *dev, u8 *fw, size_t size);
int wave5_vpu_dec_init_seq(struct vpu_instance *inst);
int wave5_vpu_dec_get_seq_info(struct vpu_instance *inst, struct dec_initial_info *info);
int wave5_vpu_decode(struct vpu_instance *inst, u32 *fail_res);
int wave5_vpu_dec_get_result(struct vpu_instance *inst, struct dec_output_info *result);
int wave5_vpu_dec_finish_seq(struct vpu_instance *inst, u32 *fail_res);
int wave5_dec_clr_disp_flag(struct vpu_instance *inst, unsigned int index);
int wave5_dec_set_disp_flag(struct vpu_instance *inst, unsigned int index);
int wave5_vpu_clear_interrupt(struct vpu_instance *inst, u32 flags);
dma_addr_t wave5_dec_get_rd_ptr(struct vpu_instance *inst);
int wave5_dec_set_rd_ptr(struct vpu_instance *inst, dma_addr_t addr);
/***< WAVE5 encoder >******/
int wave5_vpu_build_up_enc_param(struct device *dev, struct vpu_instance *inst,
struct enc_open_param *open_param);
int wave5_vpu_enc_init_seq(struct vpu_instance *inst);
int wave5_vpu_enc_get_seq_info(struct vpu_instance *inst, struct enc_initial_info *info);
int wave5_vpu_enc_register_framebuffer(struct device *dev, struct vpu_instance *inst,
struct frame_buffer *fb_arr, enum tiled_map_type map_type,
unsigned int count);
int wave5_vpu_encode(struct vpu_instance *inst, struct enc_param *option, u32 *fail_res);
int wave5_vpu_enc_get_result(struct vpu_instance *inst, struct enc_output_info *result);
int wave5_vpu_enc_finish_seq(struct vpu_instance *inst, u32 *fail_res);
int wave5_vpu_enc_check_open_param(struct vpu_instance *inst, struct enc_open_param *open_param);
#endif /* __WAVE5_FUNCTION_H__ */