Bläddra i källkod

video: driver: Add support to handle synx fence related hfi props/info

Add support to handle synx v2 fence related hfi properties and
infos mentioned below:
- HFI_PROP_FENCE_CLIENT_DATA
- HFI_PROP_FENCE_TYPE
- HFI_PROP_FENCE_DIRECTION
- HFI_PROP_FENCE_ERROR_DATA_CORRUPT
- HFI_INFO_FENCE_SIGNAL_ERROR

Change-Id: Ifac0230dbeb0da80c104860c0e115167e82e85c6
Signed-off-by: Akshata Sahukar <[email protected]>
Akshata Sahukar 2 år sedan
förälder
incheckning
203f619b7f

+ 7 - 0
driver/platform/common/inc/msm_vidc_platform.h

@@ -328,6 +328,9 @@ int msm_vidc_adjust_session_priority(void *instance, struct v4l2_ctrl *ctrl);
 int msm_vidc_adjust_roi_info(void *instance, struct v4l2_ctrl *ctrl);
 int msm_vidc_adjust_all_intra(void *instance, struct v4l2_ctrl *ctrl);
 int msm_vidc_adjust_dec_outbuf_fence(void *instance, struct v4l2_ctrl *ctrl);
+int msm_vidc_adjust_dec_outbuf_fence_type(void *instance, struct v4l2_ctrl *ctrl);
+int msm_vidc_adjust_dec_outbuf_fence_direction(void *instance,
+	struct v4l2_ctrl *ctrl);
 int msm_vidc_adjust_dec_slice_mode(void *instance, struct v4l2_ctrl *ctrl);
 int msm_vidc_adjust_preprocess(void *instance, struct v4l2_ctrl *ctrl);
 int msm_vidc_adjust_eva_stats(void *instance, struct v4l2_ctrl *ctrl);
@@ -400,5 +403,9 @@ int msm_vidc_set_q16(void *instance,
 	enum msm_vidc_inst_capability_type cap_id);
 int msm_vidc_set_vui_timing_info(void *instance,
 	enum msm_vidc_inst_capability_type cap_id);
+int msm_vidc_set_outbuf_fence_type(void *instance,
+	enum msm_vidc_inst_capability_type cap_id);
+int msm_vidc_set_outbuf_fence_direction(void *instance,
+	enum msm_vidc_inst_capability_type cap_id);
 
 #endif // _MSM_VIDC_PLATFORM_H_

+ 129 - 0
driver/platform/common/src/msm_vidc_platform.c

@@ -2632,6 +2632,83 @@ int msm_vidc_adjust_dec_outbuf_fence(void *instance, struct v4l2_ctrl *ctrl)
 	return 0;
 }
 
+int msm_vidc_adjust_dec_outbuf_fence_type(void *instance, struct v4l2_ctrl *ctrl)
+{
+	struct msm_vidc_inst_capability *capability;
+	s32 adjusted_value, meta_outbuf_fence = 0;
+	struct msm_vidc_inst *inst = (struct msm_vidc_inst *) instance;
+	struct msm_vidc_core *core;
+
+	if (!inst || !inst->capabilities || !inst->core) {
+		d_vpr_e("%s: invalid params\n", __func__);
+		return -EINVAL;
+	}
+	capability = inst->capabilities;
+	core = inst->core;
+	if (!core->capabilities) {
+		d_vpr_e("%s: invalid core caps\n", __func__);
+		return -EINVAL;
+	}
+
+	adjusted_value = ctrl ? ctrl->val :
+		capability->cap[OUTBUF_FENCE_TYPE].value;
+
+	if (msm_vidc_get_parent_value(inst, OUTBUF_FENCE_TYPE,
+		META_OUTBUF_FENCE, &meta_outbuf_fence, __func__))
+		return -EINVAL;
+
+	if (is_meta_rx_inp_enabled(inst, META_OUTBUF_FENCE)) {
+		if (core->capabilities[SUPPORTS_SYNX_FENCE].value)
+			adjusted_value = MSM_VIDC_SYNX_V2_FENCE;
+		else
+			adjusted_value = MSM_VIDC_SW_FENCE;
+	} else {
+		adjusted_value = MSM_VIDC_FENCE_NONE;
+	}
+
+	msm_vidc_update_cap_value(inst, OUTBUF_FENCE_TYPE,
+		adjusted_value, __func__);
+
+	return 0;
+}
+
+int msm_vidc_adjust_dec_outbuf_fence_direction(void *instance, struct v4l2_ctrl *ctrl)
+{
+	struct msm_vidc_inst_capability *capability;
+	s32 adjusted_value, meta_outbuf_fence = 0;
+	struct msm_vidc_inst *inst = (struct msm_vidc_inst *) instance;
+	struct msm_vidc_core *core;
+
+	if (!inst || !inst->capabilities || !inst->core) {
+		d_vpr_e("%s: invalid params\n", __func__);
+		return -EINVAL;
+	}
+	capability = inst->capabilities;
+	core = inst->core;
+	if (!core->capabilities) {
+		d_vpr_e("%s: invalid core caps\n", __func__);
+		return -EINVAL;
+	}
+
+	adjusted_value = ctrl ? ctrl->val :
+		capability->cap[OUTBUF_FENCE_DIRECTION].value;
+
+	if (msm_vidc_get_parent_value(inst, OUTBUF_FENCE_DIRECTION,
+		META_OUTBUF_FENCE, &meta_outbuf_fence, __func__))
+		return -EINVAL;
+
+	if (is_meta_rx_inp_enabled(inst, META_OUTBUF_FENCE)) {
+		adjusted_value = MSM_VIDC_FENCE_DIR_TX;
+	} else {
+		adjusted_value = MSM_VIDC_FENCE_DIR_NONE;
+	}
+
+	msm_vidc_update_cap_value(inst, OUTBUF_FENCE_DIRECTION,
+		adjusted_value, __func__);
+
+	return 0;
+}
+
 int msm_vidc_adjust_dec_slice_mode(void *instance, struct v4l2_ctrl *ctrl)
 {
 	struct msm_vidc_inst_capability *capability;
@@ -4095,4 +4172,56 @@ int msm_vidc_set_vui_timing_info(void *instance,
 	return rc;
 }
 
+int msm_vidc_set_outbuf_fence_type(void *instance,
+	enum msm_vidc_inst_capability_type cap_id)
+{
+	int rc = 0;
+	struct msm_vidc_inst *inst = (struct msm_vidc_inst *)instance;
+	u32 hfi_value;
+
+	if (!inst || !inst->capabilities) {
+		d_vpr_e("%s: invalid params\n", __func__);
+		return -EINVAL;
+	}
+
+	if (inst->capabilities->cap[OUTBUF_FENCE_TYPE].value ==
+		MSM_VIDC_FENCE_NONE)
+		return 0;
+
+	hfi_value = inst->capabilities->cap[cap_id].value;
+
+	rc = msm_vidc_packetize_control(inst, cap_id, HFI_PAYLOAD_U32_ENUM,
+		&hfi_value, sizeof(u32), __func__);
+	if (rc)
+		return rc;
+
+	return rc;
+}
+
+int msm_vidc_set_outbuf_fence_direction(void *instance,
+	enum msm_vidc_inst_capability_type cap_id)
+{
+	int rc = 0;
+	struct msm_vidc_inst *inst = (struct msm_vidc_inst *)instance;
+	u32 hfi_value;
+
+	if (!inst || !inst->capabilities) {
+		d_vpr_e("%s: invalid params\n", __func__);
+		return -EINVAL;
+	}
+
+	if (inst->capabilities->cap[OUTBUF_FENCE_DIRECTION].value ==
+		MSM_VIDC_FENCE_DIR_NONE)
+		return 0;
+
+	hfi_value = inst->capabilities->cap[cap_id].value;
+
+	rc = msm_vidc_packetize_control(inst, cap_id, HFI_PAYLOAD_U32_ENUM,
+		&hfi_value, sizeof(u32), __func__);
+	if (rc)
+		return rc;
+
+	return rc;
+}
+
 /********************* End of Control Set functions **************************/

+ 69 - 2
driver/platform/pineapple/src/msm_vidc_pineapple.c

@@ -633,6 +633,47 @@ static struct msm_platform_inst_capability instance_cap_data_pineapple[] = {
 		0,
 		CAP_FLAG_VOLATILE},
 
+	/* Fence type for input buffer. Currently unsed */
+	{INBUF_FENCE_TYPE, DEC, CODECS_ALL,
+		MSM_VIDC_FENCE_NONE, MSM_VIDC_FENCE_NONE,
+		BIT(MSM_VIDC_FENCE_NONE),
+		MSM_VIDC_FENCE_NONE,
+		0,
+		HFI_PROP_FENCE_TYPE,
+		CAP_FLAG_MENU | CAP_FLAG_INPUT_PORT},
+
+	{OUTBUF_FENCE_TYPE, DEC, CODECS_ALL,
+		MSM_VIDC_FENCE_NONE, MSM_VIDC_SYNX_V2_FENCE,
+		BIT(MSM_VIDC_FENCE_NONE) | BIT(MSM_VIDC_SW_FENCE) |
+			BIT(MSM_VIDC_SYNX_V2_FENCE),
+		MSM_VIDC_FENCE_NONE,
+		0,
+		HFI_PROP_FENCE_TYPE,
+		CAP_FLAG_MENU | CAP_FLAG_OUTPUT_PORT},
+
+	/* Fence direction for input buffer. Currently unsed */
+	{INBUF_FENCE_DIRECTION, DEC, CODECS_ALL,
+		MSM_VIDC_FENCE_DIR_NONE, MSM_VIDC_FENCE_DIR_NONE,
+		BIT(MSM_VIDC_FENCE_DIR_NONE),
+		MSM_VIDC_FENCE_DIR_NONE,
+		0,
+		HFI_PROP_FENCE_DIRECTION,
+		CAP_FLAG_MENU | CAP_FLAG_INPUT_PORT},
+
+	{OUTBUF_FENCE_DIRECTION, DEC, CODECS_ALL,
+		MSM_VIDC_FENCE_DIR_NONE, MSM_VIDC_FENCE_DIR_RX,
+		BIT(MSM_VIDC_FENCE_DIR_NONE) | BIT(MSM_VIDC_FENCE_DIR_TX) |
+			BIT(MSM_VIDC_FENCE_DIR_RX),
+		MSM_VIDC_FENCE_DIR_NONE,
+		0,
+		HFI_PROP_FENCE_DIRECTION,
+		CAP_FLAG_MENU | CAP_FLAG_OUTPUT_PORT},
+
+	{FENCE_ERROR_DATA_CORRUPT, DEC, CODECS_ALL,
+		0, 1, 1, 0,
+		0,
+		HFI_PROP_FENCE_ERROR_DATA_CORRUPT},
+
 	{TS_REORDER, DEC, H264|HEVC,
 		0, 1, 1, 0,
 		V4L2_CID_MPEG_VIDC_TS_REORDER},
@@ -2060,15 +2101,41 @@ static struct msm_platform_inst_cap_dependency instance_cap_dependency_data_pine
 		msm_vidc_set_u32},
 
 	{META_OUTBUF_FENCE, DEC, H264|HEVC|AV1,
-		{LOWLATENCY_MODE, SLICE_DECODE},
+		{LOWLATENCY_MODE, SLICE_DECODE,
+			OUTBUF_FENCE_TYPE, OUTBUF_FENCE_DIRECTION},
 		msm_vidc_adjust_dec_outbuf_fence,
 		NULL},
 
 	{META_OUTBUF_FENCE, DEC, VP9,
-		{LOWLATENCY_MODE},
+		{LOWLATENCY_MODE, OUTBUF_FENCE_TYPE, OUTBUF_FENCE_DIRECTION},
 		msm_vidc_adjust_dec_outbuf_fence,
 		NULL},
 
+	{INBUF_FENCE_TYPE, DEC, CODECS_ALL,
+		{0},
+		NULL,
+		NULL},
+
+	{OUTBUF_FENCE_TYPE, DEC, CODECS_ALL,
+		{0},
+		msm_vidc_adjust_dec_outbuf_fence_type,
+		msm_vidc_set_outbuf_fence_type},
+
+	{INBUF_FENCE_DIRECTION, DEC, CODECS_ALL,
+		{0},
+		NULL,
+		NULL},
+
+	{OUTBUF_FENCE_DIRECTION, DEC, CODECS_ALL,
+		{0},
+		msm_vidc_adjust_dec_outbuf_fence_direction,
+		msm_vidc_set_outbuf_fence_direction},
+
+	{FENCE_ERROR_DATA_CORRUPT, DEC, CODECS_ALL,
+		{0},
+		NULL,
+		msm_vidc_set_u32},
+
 	{HFLIP, ENC, CODECS_ALL,
 		{0},
 		NULL,

+ 18 - 0
driver/vidc/inc/msm_vidc_internal.h

@@ -258,6 +258,10 @@ enum msm_vidc_metadata_bits {
 	CAP(DELIVERY_MODE)                        \
 	CAP(VUI_TIMING_INFO)                      \
 	CAP(SLICE_DECODE)                         \
+	CAP(INBUF_FENCE_TYPE)                     \
+	CAP(OUTBUF_FENCE_TYPE)                    \
+	CAP(INBUF_FENCE_DIRECTION)                \
+	CAP(OUTBUF_FENCE_DIRECTION)               \
 	CAP(PROFILE)                              \
 	CAP(ENH_LAYER_COUNT)                      \
 	CAP(BIT_RATE)                             \
@@ -299,6 +303,7 @@ enum msm_vidc_metadata_bits {
 	CAP(SECURE_MODE)                          \
 	CAP(FENCE_ID)                             \
 	CAP(FENCE_FD)                             \
+	CAP(FENCE_ERROR_DATA_CORRUPT)             \
 	CAP(TS_REORDER)                           \
 	CAP(HFLIP)                                \
 	CAP(VFLIP)                                \
@@ -794,6 +799,7 @@ struct msm_vidc_hfi_frame_info {
 	u32                    data_corrupt;
 	u32                    overflow;
 	u32                    fence_id;
+	u32                    fence_error;
 };
 
 struct msm_vidc_decode_vpp_delay {
@@ -853,6 +859,18 @@ struct msm_vidc_power {
 	u32                    fw_cf;
 };
 
+enum msm_vidc_fence_type {
+	MSM_VIDC_FENCE_NONE         = 0,
+	MSM_VIDC_SW_FENCE           = 1,
+	MSM_VIDC_SYNX_V2_FENCE      = 2,
+};
+
+enum msm_vidc_fence_direction {
+	MSM_VIDC_FENCE_DIR_NONE    = 0,
+	MSM_VIDC_FENCE_DIR_TX      = 1,
+	MSM_VIDC_FENCE_DIR_RX      = 2,
+};
+
 struct msm_vidc_fence_context {
 	char                      name[MAX_NAME_LENGTH];
 	u64                       ctx_num;

+ 20 - 1
driver/vidc/src/hfi_packet.c

@@ -401,8 +401,9 @@ int hfi_packet_sys_init(struct msm_vidc_core *core,
 {
 	int rc = 0;
 	u32 payload = 0;
+	u32 synx_client_data[2];
 
-	if (!core || !pkt) {
+	if (!core || !pkt || !core->capabilities) {
 		d_vpr_e("%s: Invalid params\n", __func__);
 		return -EINVAL;
 	}
@@ -528,6 +529,24 @@ int hfi_packet_sys_init(struct msm_vidc_core *core,
 	if (rc)
 		goto err_sys_init;
 
+	/* HFI_PROP_FENCE_CLIENT_DATA */
+	if (core->capabilities[SUPPORTS_SYNX_FENCE].value) {
+		synx_client_data[0] = core->synx_fence_data.client_id;
+		synx_client_data[1] = core->synx_fence_data.client_flags;
+		d_vpr_h("%s: synx fence client id: %u client flags: %u\n",
+			__func__, synx_client_data[0], synx_client_data[1]);
+		rc = hfi_create_packet(pkt, pkt_size,
+					HFI_PROP_FENCE_CLIENT_DATA,
+					HFI_HOST_FLAGS_NONE,
+					HFI_PAYLOAD_U32_ARRAY,
+					HFI_PORT_NONE,
+					core->packet_id++,
+					synx_client_data,
+					sizeof(u32) * 2);
+		if (rc)
+			goto err_sys_init;
+	}
+
 	d_vpr_h("System init packet created\n");
 	return rc;
 

+ 77 - 12
driver/vidc/src/venus_hfi_response.c

@@ -342,6 +342,10 @@ static int handle_session_info(struct msm_vidc_inst *inst,
 		info = "buffer overflow";
 		inst->hfi_frame_info.overflow = 1;
 		break;
+	case HFI_INFO_FENCE_SIGNAL_ERROR:
+		info = "synx v2 fence error";
+		inst->hfi_frame_info.fence_error = 1;
+		break;
 	case HFI_INFO_HFI_FLAG_DRAIN_LAST:
 		info = "drain last flag";
 		rc = handle_session_last_flag_info(inst, pkt);
@@ -856,6 +860,76 @@ static int handle_input_buffer(struct msm_vidc_inst *inst,
 	return rc;
 }
 
+static int msm_vidc_handle_fence_signal(struct msm_vidc_inst *inst,
+	struct msm_vidc_buffer *buf)
+{
+	int rc = 0;
+	bool signal_error = false;
+	struct msm_vidc_core *core = inst->core;
+
+	if (!buf) {
+		i_vpr_e(inst, "%s: invalid params\n", __func__);
+		return -EINVAL;
+	}
+
+	if (inst->capabilities->cap[OUTBUF_FENCE_TYPE].value ==
+		MSM_VIDC_FENCE_NONE)
+		return 0;
+
+	if (is_meta_rx_inp_enabled(inst, META_OUTBUF_FENCE)) {
+		if (!inst->hfi_frame_info.fence_id) {
+			i_vpr_e(inst,
+				"%s: fence id is not received although fencing is enabled\n",
+				__func__);
+			return -EINVAL;
+		}
+	} else {
+		if (inst->hfi_frame_info.fence_id)
+			i_vpr_e(inst,
+				"%s: fence id is received although fencing is not enabled\n",
+				__func__);
+		return 0;
+	}
+
+	if (inst->capabilities->cap[OUTBUF_FENCE_TYPE].value ==
+		MSM_VIDC_SYNX_V2_FENCE) {
+		if (inst->hfi_frame_info.fence_error)
+			signal_error = true;
+	} else if (inst->capabilities->cap[OUTBUF_FENCE_TYPE].value ==
+		MSM_VIDC_SW_FENCE) {
+		if (!buf->data_size)
+			signal_error = true;
+
+		if (inst->hfi_frame_info.fence_error)
+			i_vpr_e(inst,
+				"%s: fence error info recieved for SW fence\n",
+				__func__);
+	} else {
+		i_vpr_e(inst, "%s: invalid fence type\n", __func__);
+		return -EINVAL;
+	}
+
+	/* fence signalling */
+	if (signal_error) {
+		/* signal fence error */
+		i_vpr_l(inst,
+			"%s: signalling fence error for buf idx %d daddr %#llx\n",
+			__func__, buf->index, buf->device_addr);
+		call_fence_op(core, fence_destroy, inst,
+			inst->hfi_frame_info.fence_id);
+	} else {
+		/* signal fence success*/
+		rc = call_fence_op(core, fence_signal, inst,
+			inst->hfi_frame_info.fence_id);
+		if (rc) {
+			i_vpr_e(inst, "%s: failed to signal fence\n", __func__);
+			return -EINVAL;
+		}
+	}
+
+	return 0;
+}
+
 static int handle_output_buffer(struct msm_vidc_inst *inst,
 	struct hfi_buffer *buffer)
 {
@@ -997,18 +1071,9 @@ static int handle_output_buffer(struct msm_vidc_inst *inst,
 	buf->flags = 0;
 	buf->flags = get_driver_buffer_flags(inst, buffer->flags);
 
-	/* fence signalling */
-	if (inst->hfi_frame_info.fence_id) {
-		if (buf->data_size) {
-			/* signal fence */
-			call_fence_op(core, fence_signal, inst,
-				inst->hfi_frame_info.fence_id);
-		} else {
-			/* destroy fence */
-			call_fence_op(core, fence_destroy, inst,
-				inst->hfi_frame_info.fence_id);
-		}
-	}
+	rc = msm_vidc_handle_fence_signal(inst, buf);
+	if (rc)
+		msm_vidc_change_state(inst, MSM_VIDC_ERROR, __func__);
 
 	if (is_decode_session(inst)) {
 		inst->power.fw_cr = inst->hfi_frame_info.cr;