On Wed, Mar 27, 2024 at 10:34:15AM +0000, Nas Chung wrote: > Hi, Ivan. > > >-----Original Message----- > >From: Ivan Bornyakov <brnkv.i1@xxxxxxxxx> > >Sent: Monday, March 25, 2024 3:41 PM > >To: Nas Chung <nas.chung@xxxxxxxxxxxxxxx>; jackson.lee > ><jackson.lee@xxxxxxxxxxxxxxx>; Mauro Carvalho Chehab <mchehab@xxxxxxxxxx>; > >Philipp Zabel <p.zabel@xxxxxxxxxxxxxx> > >Cc: Ivan Bornyakov <brnkv.i1@xxxxxxxxx>; linux-media@xxxxxxxxxxxxxxx; > >linux-kernel@xxxxxxxxxxxxxxx > >Subject: [PATCH v2 5/5] media: chips-media: wave5: support Wave515 > >decoder > > > >Add initial support for Wave515 multi-decoder IP. For now it is only > >able to decode HEVC Main/Main10 profile videos. > > Thanks for your updates. > Could you share some test result for HEVC decoding ? (ex. Fluster test) I've tested decoding with ffmpeg like so: ffmpeg -c:v hevc_v4l2m2m -i coded_file.h265 -fps_mode passthrough decoded_file.yuv I didn't run fluster test, but I will. > As you know, wave515 can support VP9 and AVS2. > Did you have any chance to test VP9 or AVS2 streams ? The plan is to settle initial support, then start working on support for other formats. > > Thanks. > Nas. > > > > >This was tested on FPGA prototype, so wave5_dt_ids[] was not expanded. > >Users of the real hardware with Wave515 IP will have to > > * provide firmware specific to their SoC > > * add struct wave5_match_data like this: > > > > static const struct wave5_match_data platform_name_wave515_data = { > > .flags = WAVE5_IS_DEC, > > .fw_name = "cnm/wave515_platform_name_fw.bin", > > }; > > > > * add item to wave5_dt_ids[] like this: > > > > { > > .compatible = "vendor,soc-wave515", > > .data = &platform_name_wave515_data, > > }, > > > > * describe new compatible in > > Documentation/devicetree/bindings/media/cnm,wave521c.yaml > > > >Signed-off-by: Ivan Bornyakov <brnkv.i1@xxxxxxxxx> > >--- > > .../platform/chips-media/wave5/wave5-helper.c | 3 +- > > .../platform/chips-media/wave5/wave5-hw.c | 245 ++++++++++++++---- > > .../chips-media/wave5/wave5-regdefine.h | 5 + > > .../platform/chips-media/wave5/wave5-vdi.c | 6 +- > > .../chips-media/wave5/wave5-vpu-dec.c | 14 +- > > .../platform/chips-media/wave5/wave5-vpu.c | 8 +- > > .../platform/chips-media/wave5/wave5-vpuapi.h | 1 + > > .../chips-media/wave5/wave5-vpuconfig.h | 9 +- > > .../media/platform/chips-media/wave5/wave5.h | 1 + > > 9 files changed, 233 insertions(+), 59 deletions(-) > > > >diff --git a/drivers/media/platform/chips-media/wave5/wave5-helper.c > >b/drivers/media/platform/chips-media/wave5/wave5-helper.c > >index 8433ecab230c..c68f1e110ed9 100644 > >--- a/drivers/media/platform/chips-media/wave5/wave5-helper.c > >+++ b/drivers/media/platform/chips-media/wave5/wave5-helper.c > >@@ -29,7 +29,8 @@ void wave5_cleanup_instance(struct vpu_instance *inst) > > { > > int i; > > > >- if (list_is_singular(&inst->list)) > >+ 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++) > >diff --git a/drivers/media/platform/chips-media/wave5/wave5-hw.c > >b/drivers/media/platform/chips-media/wave5/wave5-hw.c > >index cdd0a0948a94..e38995de6870 100644 > >--- a/drivers/media/platform/chips-media/wave5/wave5-hw.c > >+++ b/drivers/media/platform/chips-media/wave5/wave5-hw.c > >@@ -24,8 +24,10 @@ > > #define FEATURE_HEVC_ENCODER BIT(0) > > > > /* Decoder support fields */ > >+#define W515_FEATURE_HEVC10BIT_DEC BIT(1) > > #define FEATURE_AVC_DECODER BIT(3) > > #define FEATURE_HEVC_DECODER BIT(2) > >+#define W515_FEATURE_HEVC_DECODER BIT(0) > > > > #define FEATURE_BACKBONE BIT(16) > > #define FEATURE_VCORE_BACKBONE BIT(22) > >@@ -155,6 +157,8 @@ static int wave5_wait_bus_busy(struct vpu_device > >*vpu_dev, unsigned int addr) > > { > > u32 gdi_status_check_value = 0x3f; > > > >+ if (vpu_dev->product_code == WAVE515_CODE) > >+ gdi_status_check_value = 0x0738; > > if (vpu_dev->product_code == WAVE521C_CODE || > > vpu_dev->product_code == WAVE521_CODE || > > vpu_dev->product_code == WAVE521E1_CODE) > >@@ -186,6 +190,8 @@ unsigned int wave5_vpu_get_product_id(struct > >vpu_device *vpu_dev) > > u32 val = vpu_read_reg(vpu_dev, W5_PRODUCT_NUMBER); > > > > switch (val) { > >+ case WAVE515_CODE: > >+ return PRODUCT_ID_515; > > case WAVE521C_CODE: > > return PRODUCT_ID_521; > > case WAVE521_CODE: > >@@ -349,17 +355,33 @@ static int setup_wave5_properties(struct device > >*dev) > > hw_config_def1 = vpu_read_reg(vpu_dev, W5_RET_STD_DEF1); > > hw_config_feature = vpu_read_reg(vpu_dev, W5_RET_CONF_FEATURE); > > > >- p_attr->support_hevc10bit_enc = FIELD_GET(FEATURE_HEVC10BIT_ENC, > >hw_config_feature); > >- p_attr->support_avc10bit_enc = FIELD_GET(FEATURE_AVC10BIT_ENC, > >hw_config_feature); > >- > >- p_attr->support_decoders = FIELD_GET(FEATURE_AVC_DECODER, > >hw_config_def1) << STD_AVC; > >- p_attr->support_decoders |= FIELD_GET(FEATURE_HEVC_DECODER, > >hw_config_def1) << STD_HEVC; > >- p_attr->support_encoders = FIELD_GET(FEATURE_AVC_ENCODER, > >hw_config_def1) << STD_AVC; > >- p_attr->support_encoders |= FIELD_GET(FEATURE_HEVC_ENCODER, > >hw_config_def1) << STD_HEVC; > >- > >- p_attr->support_backbone = FIELD_GET(FEATURE_BACKBONE, > >hw_config_def0); > >- p_attr->support_vcpu_backbone = FIELD_GET(FEATURE_VCPU_BACKBONE, > >hw_config_def0); > >- p_attr->support_vcore_backbone = FIELD_GET(FEATURE_VCORE_BACKBONE, > >hw_config_def0); > >+ if (vpu_dev->product_code == WAVE515_CODE) { > >+ p_attr->support_hevc10bit_dec = > >FIELD_GET(W515_FEATURE_HEVC10BIT_DEC, > >+ hw_config_feature); > >+ p_attr->support_decoders = > >FIELD_GET(W515_FEATURE_HEVC_DECODER, > >+ hw_config_def1) << STD_HEVC; > >+ } else { > >+ p_attr->support_hevc10bit_enc = > >FIELD_GET(FEATURE_HEVC10BIT_ENC, > >+ hw_config_feature); > >+ p_attr->support_avc10bit_enc = > >FIELD_GET(FEATURE_AVC10BIT_ENC, > >+ hw_config_feature); > >+ > >+ p_attr->support_decoders = FIELD_GET(FEATURE_AVC_DECODER, > >+ hw_config_def1) << STD_AVC; > >+ p_attr->support_decoders |= FIELD_GET(FEATURE_HEVC_DECODER, > >+ hw_config_def1) << STD_HEVC; > >+ p_attr->support_encoders = FIELD_GET(FEATURE_AVC_ENCODER, > >+ hw_config_def1) << STD_AVC; > >+ p_attr->support_encoders |= FIELD_GET(FEATURE_HEVC_ENCODER, > >+ hw_config_def1) << STD_HEVC; > >+ > >+ p_attr->support_backbone = FIELD_GET(FEATURE_BACKBONE, > >+ hw_config_def0); > >+ p_attr->support_vcpu_backbone = > >FIELD_GET(FEATURE_VCPU_BACKBONE, > >+ hw_config_def0); > >+ p_attr->support_vcore_backbone = > >FIELD_GET(FEATURE_VCORE_BACKBONE, > >+ hw_config_def0); > >+ } > > > > setup_wave5_interrupts(vpu_dev); > > > >@@ -403,12 +425,18 @@ int wave5_vpu_init(struct device *dev, u8 *fw, > >size_t size) > > common_vb = &vpu_dev->common_mem; > > > > code_base = common_vb->daddr; > >+ > >+ if (vpu_dev->product_code == WAVE515_CODE) > >+ code_size = WAVE515_MAX_CODE_BUF_SIZE; > >+ else > >+ code_size = WAVE5_MAX_CODE_BUF_SIZE; > >+ > > /* ALIGN TO 4KB */ > >- code_size = (WAVE5_MAX_CODE_BUF_SIZE & ~0xfff); > >+ code_size &= ~0xfff; > > if (code_size < size * 2) > > return -EINVAL; > > > >- temp_base = common_vb->daddr + WAVE5_TEMPBUF_OFFSET; > >+ temp_base = code_base + code_size; > > temp_size = WAVE5_TEMPBUF_SIZE; > > > > ret = wave5_vdi_write_memory(vpu_dev, common_vb, 0, fw, size); > >@@ -436,9 +464,12 @@ int wave5_vpu_init(struct device *dev, u8 *fw, > >size_t size) > > > > /* These register must be reset explicitly */ > > vpu_write_reg(vpu_dev, W5_HW_OPTION, 0); > >- wave5_fio_writel(vpu_dev, W5_BACKBONE_PROC_EXT_ADDR, 0); > >- wave5_fio_writel(vpu_dev, W5_BACKBONE_AXI_PARAM, 0); > >- vpu_write_reg(vpu_dev, W5_SEC_AXI_PARAM, 0); > >+ > >+ if (vpu_dev->product_code != WAVE515_CODE) { > >+ wave5_fio_writel(vpu_dev, W5_BACKBONE_PROC_EXT_ADDR, 0); > >+ wave5_fio_writel(vpu_dev, W5_BACKBONE_AXI_PARAM, 0); > >+ vpu_write_reg(vpu_dev, W5_SEC_AXI_PARAM, 0); > >+ } > > > > reg_val = vpu_read_reg(vpu_dev, W5_VPU_RET_VPU_CONFIG0); > > if (FIELD_GET(FEATURE_BACKBONE, reg_val)) { > >@@ -453,6 +484,24 @@ int wave5_vpu_init(struct device *dev, u8 *fw, > >size_t size) > > wave5_fio_writel(vpu_dev, W5_BACKBONE_PROG_AXI_ID, reg_val); > > } > > > >+ if (vpu_dev->product_code == WAVE515_CODE) { > >+ dma_addr_t task_buf_base; > >+ > >+ vpu_write_reg(vpu_dev, W5_CMD_INIT_NUM_TASK_BUF, > >WAVE515_COMMAND_QUEUE_DEPTH); > >+ vpu_write_reg(vpu_dev, W5_CMD_INIT_TASK_BUF_SIZE, > >WAVE515_ONE_TASKBUF_SIZE); > >+ > >+ for (i = 0; i < WAVE515_COMMAND_QUEUE_DEPTH; i++) { > >+ task_buf_base = temp_base + temp_size + > >+ (i * WAVE515_ONE_TASKBUF_SIZE); > >+ vpu_write_reg(vpu_dev, > >+ W5_CMD_INIT_ADDR_TASK_BUF0 + (i * 4), > >+ task_buf_base); > >+ } > >+ > >+ vpu_write_reg(vpu_dev, W515_CMD_ADDR_SEC_AXI, vpu_dev- > >>sram_buf.daddr); > >+ vpu_write_reg(vpu_dev, W515_CMD_SEC_AXI_SIZE, vpu_dev- > >>sram_buf.size); > >+ } > >+ > > vpu_write_reg(vpu_dev, W5_VPU_BUSY_STATUS, 1); > > vpu_write_reg(vpu_dev, W5_COMMAND, W5_INIT_VPU); > > vpu_write_reg(vpu_dev, W5_VPU_REMAP_CORE_START, 1); > >@@ -493,29 +542,39 @@ int wave5_vpu_build_up_dec_param(struct > >vpu_instance *inst, > > return -EINVAL; > > } > > > >- p_dec_info->vb_work.size = WAVE521DEC_WORKBUF_SIZE; > >+ if (vpu_dev->product == PRODUCT_ID_515) > >+ p_dec_info->vb_work.size = WAVE515DEC_WORKBUF_SIZE; > >+ else > >+ p_dec_info->vb_work.size = WAVE521DEC_WORKBUF_SIZE; > >+ > > ret = wave5_vdi_allocate_dma_memory(inst->dev, &p_dec_info- > >>vb_work); > > if (ret) > > return ret; > > > >- vpu_write_reg(inst->dev, W5_CMD_DEC_VCORE_INFO, 1); > >+ if (inst->dev->product_code != WAVE515_CODE) > >+ vpu_write_reg(inst->dev, W5_CMD_DEC_VCORE_INFO, 1); > > > > wave5_vdi_clear_memory(inst->dev, &p_dec_info->vb_work); > > > > vpu_write_reg(inst->dev, W5_ADDR_WORK_BASE, p_dec_info- > >>vb_work.daddr); > > vpu_write_reg(inst->dev, W5_WORK_SIZE, p_dec_info->vb_work.size); > > > >- vpu_write_reg(inst->dev, W5_CMD_ADDR_SEC_AXI, vpu_dev- > >>sram_buf.daddr); > >- vpu_write_reg(inst->dev, W5_CMD_SEC_AXI_SIZE, vpu_dev- > >>sram_buf.size); > >+ if (inst->dev->product_code != WAVE515_CODE) { > >+ vpu_write_reg(inst->dev, W5_CMD_ADDR_SEC_AXI, vpu_dev- > >>sram_buf.daddr); > >+ vpu_write_reg(inst->dev, W5_CMD_SEC_AXI_SIZE, vpu_dev- > >>sram_buf.size); > >+ } > > > > vpu_write_reg(inst->dev, W5_CMD_DEC_BS_START_ADDR, p_dec_info- > >>stream_buf_start_addr); > > vpu_write_reg(inst->dev, W5_CMD_DEC_BS_SIZE, p_dec_info- > >>stream_buf_size); > > > > /* NOTE: SDMA reads MSB first */ > > vpu_write_reg(inst->dev, W5_CMD_BS_PARAM, > >BITSTREAM_ENDIANNESS_BIG_ENDIAN); > >- /* This register must be reset explicitly */ > >- vpu_write_reg(inst->dev, W5_CMD_EXT_ADDR, 0); > >- vpu_write_reg(inst->dev, W5_CMD_NUM_CQ_DEPTH_M1, > >(COMMAND_QUEUE_DEPTH - 1)); > >+ > >+ if (inst->dev->product_code != WAVE515_CODE) { > >+ /* This register must be reset explicitly */ > >+ vpu_write_reg(inst->dev, W5_CMD_EXT_ADDR, 0); > >+ vpu_write_reg(inst->dev, W5_CMD_NUM_CQ_DEPTH_M1, > >(COMMAND_QUEUE_DEPTH - 1)); > >+ } > > > > ret = send_firmware_command(inst, W5_CREATE_INSTANCE, true, NULL, > >NULL); > > if (ret) { > >@@ -566,7 +625,7 @@ static u32 get_bitstream_options(struct dec_info > >*info) > > int wave5_vpu_dec_init_seq(struct vpu_instance *inst) > > { > > struct dec_info *p_dec_info = &inst->codec_info->dec_info; > >- u32 cmd_option = INIT_SEQ_NORMAL; > >+ u32 bs_option, cmd_option = INIT_SEQ_NORMAL; > > u32 reg_val, fail_res; > > int ret; > > > >@@ -576,7 +635,12 @@ int wave5_vpu_dec_init_seq(struct vpu_instance *inst) > > vpu_write_reg(inst->dev, W5_BS_RD_PTR, p_dec_info->stream_rd_ptr); > > vpu_write_reg(inst->dev, W5_BS_WR_PTR, p_dec_info->stream_wr_ptr); > > > >- vpu_write_reg(inst->dev, W5_BS_OPTION, > >get_bitstream_options(p_dec_info)); > >+ bs_option = get_bitstream_options(p_dec_info); > >+ > >+ if (inst->dev->product_code == WAVE515_CODE) > >+ bs_option |= BSOPTION_RD_PTR_VALID_FLAG; > >+ > >+ vpu_write_reg(inst->dev, W5_BS_OPTION, bs_option); > > > > vpu_write_reg(inst->dev, W5_COMMAND_OPTION, cmd_option); > > vpu_write_reg(inst->dev, W5_CMD_DEC_USER_MASK, p_dec_info- > >>user_data_enable); > >@@ -642,10 +706,12 @@ static void wave5_get_dec_seq_result(struct > >vpu_instance *inst, struct dec_initi > > info->profile = FIELD_GET(SEQ_PARAM_PROFILE_MASK, reg_val); > > } > > > >- info->vlc_buf_size = vpu_read_reg(inst->dev, W5_RET_VLC_BUF_SIZE); > >- info->param_buf_size = vpu_read_reg(inst->dev, > >W5_RET_PARAM_BUF_SIZE); > >- p_dec_info->vlc_buf_size = info->vlc_buf_size; > >- p_dec_info->param_buf_size = info->param_buf_size; > >+ if (inst->dev->product_code != WAVE515_CODE) { > >+ info->vlc_buf_size = vpu_read_reg(inst->dev, > >W5_RET_VLC_BUF_SIZE); > >+ info->param_buf_size = vpu_read_reg(inst->dev, > >W5_RET_PARAM_BUF_SIZE); > >+ p_dec_info->vlc_buf_size = info->vlc_buf_size; > >+ p_dec_info->param_buf_size = info->param_buf_size; > >+ } > > } > > > > int wave5_vpu_dec_get_seq_info(struct vpu_instance *inst, struct > >dec_initial_info *info) > >@@ -747,22 +813,27 @@ int wave5_vpu_dec_register_framebuffer(struct > >vpu_instance *inst, struct frame_b > > > > pic_size = (init_info->pic_width << 16) | (init_info- > >>pic_height); > > > >- vb_buf.size = (p_dec_info->vlc_buf_size * VLC_BUF_NUM) + > >+ if (inst->dev->product_code != WAVE515_CODE) { > >+ vb_buf.size = (p_dec_info->vlc_buf_size * VLC_BUF_NUM) > >+ > > (p_dec_info->param_buf_size * > >COMMAND_QUEUE_DEPTH); > >- vb_buf.daddr = 0; > >+ vb_buf.daddr = 0; > > > >- if (vb_buf.size != p_dec_info->vb_task.size) { > >- wave5_vdi_free_dma_memory(inst->dev, &p_dec_info- > >>vb_task); > >- ret = wave5_vdi_allocate_dma_memory(inst->dev, > >&vb_buf); > >- if (ret) > >- goto free_fbc_c_tbl_buffers; > >+ if (vb_buf.size != p_dec_info->vb_task.size) { > >+ wave5_vdi_free_dma_memory(inst->dev, > >+ &p_dec_info->vb_task); > >+ ret = wave5_vdi_allocate_dma_memory(inst->dev, > >+ &vb_buf); > >+ if (ret) > >+ goto free_fbc_c_tbl_buffers; > > > >- p_dec_info->vb_task = vb_buf; > >- } > >+ p_dec_info->vb_task = vb_buf; > >+ } > > > >- vpu_write_reg(inst->dev, W5_CMD_SET_FB_ADDR_TASK_BUF, > >- p_dec_info->vb_task.daddr); > >- vpu_write_reg(inst->dev, W5_CMD_SET_FB_TASK_BUF_SIZE, > >vb_buf.size); > >+ vpu_write_reg(inst->dev, W5_CMD_SET_FB_ADDR_TASK_BUF, > >+ p_dec_info->vb_task.daddr); > >+ vpu_write_reg(inst->dev, W5_CMD_SET_FB_TASK_BUF_SIZE, > >+ vb_buf.size); > >+ } > > } else { > > pic_size = (init_info->pic_width << 16) | (init_info- > >>pic_height); > > > >@@ -999,17 +1070,24 @@ int wave5_vpu_re_init(struct device *dev, u8 *fw, > >size_t size) > > dma_addr_t code_base, temp_base; > > dma_addr_t old_code_base, temp_size; > > u32 code_size, reason_code; > >- u32 reg_val; > >+ u32 i, reg_val; > > struct vpu_device *vpu_dev = dev_get_drvdata(dev); > > > > common_vb = &vpu_dev->common_mem; > > > > code_base = common_vb->daddr; > >+ > >+ if (vpu_dev->product_code == WAVE515_CODE) > >+ code_size = WAVE515_MAX_CODE_BUF_SIZE; > >+ else > >+ code_size = WAVE5_MAX_CODE_BUF_SIZE; > >+ > > /* ALIGN TO 4KB */ > >- code_size = (WAVE5_MAX_CODE_BUF_SIZE & ~0xfff); > >+ code_size &= ~0xfff; > > if (code_size < size * 2) > > return -EINVAL; > >- temp_base = common_vb->daddr + WAVE5_TEMPBUF_OFFSET; > >+ > >+ temp_base = code_base + code_size; > > temp_size = WAVE5_TEMPBUF_SIZE; > > > > old_code_base = vpu_read_reg(vpu_dev, W5_VPU_REMAP_PADDR); > >@@ -1043,9 +1121,12 @@ int wave5_vpu_re_init(struct device *dev, u8 *fw, > >size_t size) > > > > /* These register must be reset explicitly */ > > vpu_write_reg(vpu_dev, W5_HW_OPTION, 0); > >- wave5_fio_writel(vpu_dev, W5_BACKBONE_PROC_EXT_ADDR, 0); > >- wave5_fio_writel(vpu_dev, W5_BACKBONE_AXI_PARAM, 0); > >- vpu_write_reg(vpu_dev, W5_SEC_AXI_PARAM, 0); > >+ > >+ if (vpu_dev->product_code != WAVE515_CODE) { > >+ wave5_fio_writel(vpu_dev, W5_BACKBONE_PROC_EXT_ADDR, > >0); > >+ wave5_fio_writel(vpu_dev, W5_BACKBONE_AXI_PARAM, 0); > >+ vpu_write_reg(vpu_dev, W5_SEC_AXI_PARAM, 0); > >+ } > > > > reg_val = vpu_read_reg(vpu_dev, W5_VPU_RET_VPU_CONFIG0); > > if (FIELD_GET(FEATURE_BACKBONE, reg_val)) { > >@@ -1060,6 +1141,28 @@ int wave5_vpu_re_init(struct device *dev, u8 *fw, > >size_t size) > > wave5_fio_writel(vpu_dev, W5_BACKBONE_PROG_AXI_ID, > >reg_val); > > } > > > >+ if (vpu_dev->product_code == WAVE515_CODE) { > >+ dma_addr_t task_buf_base; > >+ > >+ vpu_write_reg(vpu_dev, W5_CMD_INIT_NUM_TASK_BUF, > >+ WAVE515_COMMAND_QUEUE_DEPTH); > >+ vpu_write_reg(vpu_dev, W5_CMD_INIT_TASK_BUF_SIZE, > >+ WAVE515_ONE_TASKBUF_SIZE); > >+ > >+ for (i = 0; i < WAVE515_COMMAND_QUEUE_DEPTH; i++) { > >+ task_buf_base = temp_base + temp_size + > >+ (i * WAVE515_ONE_TASKBUF_SIZE); > >+ vpu_write_reg(vpu_dev, > >+ W5_CMD_INIT_ADDR_TASK_BUF0 + (i * 4), > >+ task_buf_base); > >+ } > >+ > >+ vpu_write_reg(vpu_dev, W515_CMD_ADDR_SEC_AXI, > >+ vpu_dev->sram_buf.daddr); > >+ vpu_write_reg(vpu_dev, W515_CMD_SEC_AXI_SIZE, > >+ vpu_dev->sram_buf.size); > >+ } > >+ > > vpu_write_reg(vpu_dev, W5_VPU_BUSY_STATUS, 1); > > vpu_write_reg(vpu_dev, W5_COMMAND, W5_INIT_VPU); > > vpu_write_reg(vpu_dev, W5_VPU_REMAP_CORE_START, 1); > >@@ -1081,10 +1184,10 @@ int wave5_vpu_re_init(struct device *dev, u8 *fw, > >size_t size) > > static int wave5_vpu_sleep_wake(struct device *dev, bool i_sleep_wake, > >const uint16_t *code, > > size_t size) > > { > >- u32 reg_val; > >+ u32 i, reg_val; > > struct vpu_buf *common_vb; > >- dma_addr_t code_base; > >- u32 code_size, reason_code; > >+ dma_addr_t code_base, temp_base; > >+ u32 code_size, temp_size, reason_code; > > struct vpu_device *vpu_dev = dev_get_drvdata(dev); > > int ret; > > > >@@ -1114,13 +1217,22 @@ static int wave5_vpu_sleep_wake(struct device > >*dev, bool i_sleep_wake, const uin > > common_vb = &vpu_dev->common_mem; > > > > code_base = common_vb->daddr; > >+ > >+ if (vpu_dev->product_code == WAVE515_CODE) > >+ code_size = WAVE515_MAX_CODE_BUF_SIZE; > >+ else > >+ code_size = WAVE5_MAX_CODE_BUF_SIZE; > >+ > > /* ALIGN TO 4KB */ > >- code_size = (WAVE5_MAX_CODE_BUF_SIZE & ~0xfff); > >+ code_size &= ~0xfff; > > if (code_size < size * 2) { > > dev_err(dev, "size too small\n"); > > return -EINVAL; > > } > > > >+ temp_base = code_base + code_size; > >+ temp_size = WAVE5_TEMPBUF_SIZE; > >+ > > /* Power on without DEBUG mode */ > > vpu_write_reg(vpu_dev, W5_PO_CONF, 0); > > > >@@ -1133,9 +1245,12 @@ static int wave5_vpu_sleep_wake(struct device *dev, > >bool i_sleep_wake, const uin > > > > /* These register must be reset explicitly */ > > vpu_write_reg(vpu_dev, W5_HW_OPTION, 0); > >- wave5_fio_writel(vpu_dev, W5_BACKBONE_PROC_EXT_ADDR, 0); > >- wave5_fio_writel(vpu_dev, W5_BACKBONE_AXI_PARAM, 0); > >- vpu_write_reg(vpu_dev, W5_SEC_AXI_PARAM, 0); > >+ > >+ if (vpu_dev->product_code != WAVE515_CODE) { > >+ wave5_fio_writel(vpu_dev, W5_BACKBONE_PROC_EXT_ADDR, > >0); > >+ wave5_fio_writel(vpu_dev, W5_BACKBONE_AXI_PARAM, 0); > >+ vpu_write_reg(vpu_dev, W5_SEC_AXI_PARAM, 0); > >+ } > > > > setup_wave5_interrupts(vpu_dev); > > > >@@ -1152,6 +1267,28 @@ static int wave5_vpu_sleep_wake(struct device *dev, > >bool i_sleep_wake, const uin > > wave5_fio_writel(vpu_dev, W5_BACKBONE_PROG_AXI_ID, > >reg_val); > > } > > > >+ if (vpu_dev->product_code == WAVE515_CODE) { > >+ dma_addr_t task_buf_base; > >+ > >+ vpu_write_reg(vpu_dev, W5_CMD_INIT_NUM_TASK_BUF, > >+ WAVE515_COMMAND_QUEUE_DEPTH); > >+ vpu_write_reg(vpu_dev, W5_CMD_INIT_TASK_BUF_SIZE, > >+ WAVE515_ONE_TASKBUF_SIZE); > >+ > >+ for (i = 0; i < WAVE515_COMMAND_QUEUE_DEPTH; i++) { > >+ task_buf_base = temp_base + temp_size + > >+ (i * WAVE515_ONE_TASKBUF_SIZE); > >+ vpu_write_reg(vpu_dev, > >+ W5_CMD_INIT_ADDR_TASK_BUF0 + (i * 4), > >+ task_buf_base); > >+ } > >+ > >+ vpu_write_reg(vpu_dev, W515_CMD_ADDR_SEC_AXI, > >+ vpu_dev->sram_buf.daddr); > >+ vpu_write_reg(vpu_dev, W515_CMD_SEC_AXI_SIZE, > >+ vpu_dev->sram_buf.size); > >+ } > >+ > > vpu_write_reg(vpu_dev, W5_VPU_BUSY_STATUS, 1); > > vpu_write_reg(vpu_dev, W5_COMMAND, W5_WAKEUP_VPU); > > /* Start VPU after settings */ > >diff --git a/drivers/media/platform/chips-media/wave5/wave5-regdefine.h > >b/drivers/media/platform/chips-media/wave5/wave5-regdefine.h > >index a15c6b2c3d8b..557344754c4c 100644 > >--- a/drivers/media/platform/chips-media/wave5/wave5-regdefine.h > >+++ b/drivers/media/platform/chips-media/wave5/wave5-regdefine.h > >@@ -205,6 +205,9 @@ enum query_opt { > > #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) > > > > > >/************************************************************************ > >/ > >@@ -216,7 +219,9 @@ enum query_opt { > > #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) > >diff --git a/drivers/media/platform/chips-media/wave5/wave5-vdi.c > >b/drivers/media/platform/chips-media/wave5/wave5-vdi.c > >index a63fffed55e9..78888c57b6da 100644 > >--- a/drivers/media/platform/chips-media/wave5/wave5-vdi.c > >+++ b/drivers/media/platform/chips-media/wave5/wave5-vdi.c > >@@ -18,7 +18,11 @@ static int wave5_vdi_allocate_common_memory(struct > >device *dev) > > if (!vpu_dev->common_mem.vaddr) { > > int ret; > > > >- vpu_dev->common_mem.size = SIZE_COMMON; > >+ if (vpu_dev->product_code == WAVE515_CODE) > >+ vpu_dev->common_mem.size = WAVE515_SIZE_COMMON; > >+ else > >+ vpu_dev->common_mem.size = 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"); > >diff --git a/drivers/media/platform/chips-media/wave5/wave5-vpu-dec.c > >b/drivers/media/platform/chips-media/wave5/wave5-vpu-dec.c > >index 5a71a711f2e8..65a99053c5e8 100644 > >--- a/drivers/media/platform/chips-media/wave5/wave5-vpu-dec.c > >+++ b/drivers/media/platform/chips-media/wave5/wave5-vpu-dec.c > >@@ -1869,7 +1869,8 @@ static int wave5_vpu_open_dec(struct file *filp) > > goto cleanup_inst; > > } > > > >- wave5_vdi_allocate_sram(inst->dev); > >+ if (inst->dev->product_code != WAVE515_CODE) > >+ wave5_vdi_allocate_sram(inst->dev); > > > > return 0; > > > >@@ -1897,6 +1898,14 @@ int wave5_vpu_dec_register_device(struct > >vpu_device *dev) > > struct video_device *vdev_dec; > > int ret; > > > >+ /* > >+ * secondary AXI setup for Wave515 is done by INIT_VPU command, > >+ * that's why SRAM memory is allocated at VPU device register > >+ * rather than at device open. > >+ */ > >+ if (dev->product_code == WAVE515_CODE) > >+ wave5_vdi_allocate_sram(dev); > >+ > > vdev_dec = devm_kzalloc(dev->v4l2_dev.dev, sizeof(*vdev_dec), > >GFP_KERNEL); > > if (!vdev_dec) > > return -ENOMEM; > >@@ -1930,6 +1939,9 @@ int wave5_vpu_dec_register_device(struct vpu_device > >*dev) > > > > void wave5_vpu_dec_unregister_device(struct vpu_device *dev) > > { > >+ if (dev->product_code == WAVE515_CODE) > >+ wave5_vdi_free_sram(dev); > >+ > > video_unregister_device(dev->video_dev_dec); > > if (dev->v4l2_m2m_dec_dev) > > v4l2_m2m_release(dev->v4l2_m2m_dec_dev); > >diff --git a/drivers/media/platform/chips-media/wave5/wave5-vpu.c > >b/drivers/media/platform/chips-media/wave5/wave5-vpu.c > >index 2a972cddf4a6..fc267348399e 100644 > >--- a/drivers/media/platform/chips-media/wave5/wave5-vpu.c > >+++ b/drivers/media/platform/chips-media/wave5/wave5-vpu.c > >@@ -60,7 +60,13 @@ static irqreturn_t wave5_vpu_irq_thread(int irq, void > >*dev_id) > > > > if (irq_reason & BIT(INT_WAVE5_INIT_SEQ) || > > irq_reason & BIT(INT_WAVE5_ENC_SET_PARAM)) { > >- if (seq_done & BIT(inst->id)) { > >+ 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); > >diff --git a/drivers/media/platform/chips-media/wave5/wave5-vpuapi.h > >b/drivers/media/platform/chips-media/wave5/wave5-vpuapi.h > >index 975d96b22191..601205df4433 100644 > >--- a/drivers/media/platform/chips-media/wave5/wave5-vpuapi.h > >+++ b/drivers/media/platform/chips-media/wave5/wave5-vpuapi.h > >@@ -18,6 +18,7 @@ > > #include "wave5-vdi.h" > > > > enum product_id { > >+ PRODUCT_ID_515, > > PRODUCT_ID_521, > > PRODUCT_ID_511, > > PRODUCT_ID_517, > >diff --git a/drivers/media/platform/chips-media/wave5/wave5-vpuconfig.h > >b/drivers/media/platform/chips-media/wave5/wave5-vpuconfig.h > >index 9d99afb78c89..b4128524fcfd 100644 > >--- a/drivers/media/platform/chips-media/wave5/wave5-vpuconfig.h > >+++ b/drivers/media/platform/chips-media/wave5/wave5-vpuconfig.h > >@@ -8,6 +8,7 @@ > > #ifndef _VPU_CONFIG_H_ > > #define _VPU_CONFIG_H_ > > > >+#define WAVE515_CODE 0x5150 > > #define WAVE517_CODE 0x5170 > > #define WAVE537_CODE 0x5370 > > #define WAVE511_CODE 0x5110 > >@@ -21,12 +22,13 @@ > > ((c) == WAVE517_CODE || (c) == WAVE537_CODE || \ > > (c) == WAVE511_CODE || (c) == WAVE521_CODE || \ > > (c) == WAVE521E1_CODE || (c) == WAVE521C_CODE || \ > >- (c) == WAVE521C_DUAL_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 WAVE5_MAX_SRAM_SIZE (64 * 1024) > > > >@@ -52,16 +54,21 @@ > > #define VLC_BUF_NUM (2) > > > > #define 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 WAVE5_MAX_CODE_BUF_SIZE (2 * 1024 * 1024) > >+#define WAVE515_MAX_CODE_BUF_SIZE (1024 * 1024) > > #define WAVE5_TEMPBUF_OFFSET WAVE5_MAX_CODE_BUF_SIZE > > #define WAVE5_TEMPBUF_SIZE (1024 * 1024) > >+#define WAVE515_TASKBUF_OFFSET (WAVE515_MAX_CODE_BUF_SIZE + > >WAVE5_TEMPBUF_SIZE) > > > > #define SIZE_COMMON (WAVE5_MAX_CODE_BUF_SIZE + > >WAVE5_TEMPBUF_SIZE) > >+#define WAVE515_ONE_TASKBUF_SIZE (8 * 1024 * 1024) > >+#define WAVE515_SIZE_COMMON (WAVE515_TASKBUF_OFFSET + > >WAVE515_COMMAND_QUEUE_DEPTH * WAVE515_ONE_TASKBUF_SIZE) > > > > //=====4. VPU REPORT MEMORY ======================// > > > >diff --git a/drivers/media/platform/chips-media/wave5/wave5.h > >b/drivers/media/platform/chips-media/wave5/wave5.h > >index 063028eccd3b..57b00e182b6e 100644 > >--- a/drivers/media/platform/chips-media/wave5/wave5.h > >+++ b/drivers/media/platform/chips-media/wave5/wave5.h > >@@ -22,6 +22,7 @@ > > */ > > #define BSOPTION_ENABLE_EXPLICIT_END BIT(0) > > #define BSOPTION_HIGHLIGHT_STREAM_END BIT(1) > >+#define BSOPTION_RD_PTR_VALID_FLAG BIT(31) > > > > /* > > * Currently the driver only supports hardware with little endian but for > >source > >-- > >2.44.0 >