Re: RE: [PATCH v2 5/5] media: chips-media: wave5: support Wave515 decoder

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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
> 




[Index of Archives]     [Linux Input]     [Video for Linux]     [Gstreamer Embedded]     [Mplayer Users]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]

  Powered by Linux