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

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

 



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)
As you know, wave515 can support VP9 and AVS2.
Did you have any chance to test VP9 or AVS2 streams ?

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