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 <quic_asahukar@quicinc.com>
This commit is contained in:
Akshata Sahukar
2023-03-15 18:42:14 -07:00
committed by Gerrit - the friendly Code Review server
parent 1fdfa4758c
commit 203f619b7f
6 changed files with 320 additions and 15 deletions

View File

@@ -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_roi_info(void *instance, struct v4l2_ctrl *ctrl);
int msm_vidc_adjust_all_intra(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(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_dec_slice_mode(void *instance, struct v4l2_ctrl *ctrl);
int msm_vidc_adjust_preprocess(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); 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); enum msm_vidc_inst_capability_type cap_id);
int msm_vidc_set_vui_timing_info(void *instance, int msm_vidc_set_vui_timing_info(void *instance,
enum msm_vidc_inst_capability_type cap_id); 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_ #endif // _MSM_VIDC_PLATFORM_H_

View File

@@ -2632,6 +2632,83 @@ int msm_vidc_adjust_dec_outbuf_fence(void *instance, struct v4l2_ctrl *ctrl)
return 0; 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) int msm_vidc_adjust_dec_slice_mode(void *instance, struct v4l2_ctrl *ctrl)
{ {
struct msm_vidc_inst_capability *capability; struct msm_vidc_inst_capability *capability;
@@ -4095,4 +4172,56 @@ int msm_vidc_set_vui_timing_info(void *instance,
return rc; 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 **************************/ /********************* End of Control Set functions **************************/

View File

@@ -633,6 +633,47 @@ static struct msm_platform_inst_capability instance_cap_data_pineapple[] = {
0, 0,
CAP_FLAG_VOLATILE}, 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, {TS_REORDER, DEC, H264|HEVC,
0, 1, 1, 0, 0, 1, 1, 0,
V4L2_CID_MPEG_VIDC_TS_REORDER}, 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}, msm_vidc_set_u32},
{META_OUTBUF_FENCE, DEC, H264|HEVC|AV1, {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, msm_vidc_adjust_dec_outbuf_fence,
NULL}, NULL},
{META_OUTBUF_FENCE, DEC, VP9, {META_OUTBUF_FENCE, DEC, VP9,
{LOWLATENCY_MODE}, {LOWLATENCY_MODE, OUTBUF_FENCE_TYPE, OUTBUF_FENCE_DIRECTION},
msm_vidc_adjust_dec_outbuf_fence, msm_vidc_adjust_dec_outbuf_fence,
NULL}, 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, {HFLIP, ENC, CODECS_ALL,
{0}, {0},
NULL, NULL,

View File

@@ -258,6 +258,10 @@ enum msm_vidc_metadata_bits {
CAP(DELIVERY_MODE) \ CAP(DELIVERY_MODE) \
CAP(VUI_TIMING_INFO) \ CAP(VUI_TIMING_INFO) \
CAP(SLICE_DECODE) \ CAP(SLICE_DECODE) \
CAP(INBUF_FENCE_TYPE) \
CAP(OUTBUF_FENCE_TYPE) \
CAP(INBUF_FENCE_DIRECTION) \
CAP(OUTBUF_FENCE_DIRECTION) \
CAP(PROFILE) \ CAP(PROFILE) \
CAP(ENH_LAYER_COUNT) \ CAP(ENH_LAYER_COUNT) \
CAP(BIT_RATE) \ CAP(BIT_RATE) \
@@ -299,6 +303,7 @@ enum msm_vidc_metadata_bits {
CAP(SECURE_MODE) \ CAP(SECURE_MODE) \
CAP(FENCE_ID) \ CAP(FENCE_ID) \
CAP(FENCE_FD) \ CAP(FENCE_FD) \
CAP(FENCE_ERROR_DATA_CORRUPT) \
CAP(TS_REORDER) \ CAP(TS_REORDER) \
CAP(HFLIP) \ CAP(HFLIP) \
CAP(VFLIP) \ CAP(VFLIP) \
@@ -794,6 +799,7 @@ struct msm_vidc_hfi_frame_info {
u32 data_corrupt; u32 data_corrupt;
u32 overflow; u32 overflow;
u32 fence_id; u32 fence_id;
u32 fence_error;
}; };
struct msm_vidc_decode_vpp_delay { struct msm_vidc_decode_vpp_delay {
@@ -853,6 +859,18 @@ struct msm_vidc_power {
u32 fw_cf; 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 { struct msm_vidc_fence_context {
char name[MAX_NAME_LENGTH]; char name[MAX_NAME_LENGTH];
u64 ctx_num; u64 ctx_num;

View File

@@ -401,8 +401,9 @@ int hfi_packet_sys_init(struct msm_vidc_core *core,
{ {
int rc = 0; int rc = 0;
u32 payload = 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__); d_vpr_e("%s: Invalid params\n", __func__);
return -EINVAL; return -EINVAL;
} }
@@ -528,6 +529,24 @@ int hfi_packet_sys_init(struct msm_vidc_core *core,
if (rc) if (rc)
goto err_sys_init; 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"); d_vpr_h("System init packet created\n");
return rc; return rc;

View File

@@ -342,6 +342,10 @@ static int handle_session_info(struct msm_vidc_inst *inst,
info = "buffer overflow"; info = "buffer overflow";
inst->hfi_frame_info.overflow = 1; inst->hfi_frame_info.overflow = 1;
break; 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: case HFI_INFO_HFI_FLAG_DRAIN_LAST:
info = "drain last flag"; info = "drain last flag";
rc = handle_session_last_flag_info(inst, pkt); rc = handle_session_last_flag_info(inst, pkt);
@@ -856,6 +860,76 @@ static int handle_input_buffer(struct msm_vidc_inst *inst,
return rc; 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, static int handle_output_buffer(struct msm_vidc_inst *inst,
struct hfi_buffer *buffer) struct hfi_buffer *buffer)
{ {
@@ -997,18 +1071,9 @@ static int handle_output_buffer(struct msm_vidc_inst *inst,
buf->flags = 0; buf->flags = 0;
buf->flags = get_driver_buffer_flags(inst, buffer->flags); buf->flags = get_driver_buffer_flags(inst, buffer->flags);
/* fence signalling */ rc = msm_vidc_handle_fence_signal(inst, buf);
if (inst->hfi_frame_info.fence_id) { if (rc)
if (buf->data_size) { msm_vidc_change_state(inst, MSM_VIDC_ERROR, __func__);
/* 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);
}
}
if (is_decode_session(inst)) { if (is_decode_session(inst)) {
inst->power.fw_cr = inst->hfi_frame_info.cr; inst->power.fw_cr = inst->hfi_frame_info.cr;