diff --git a/driver/platform/common/inc/msm_vidc_platform.h b/driver/platform/common/inc/msm_vidc_platform.h index 5874719c65..c2486a52f3 100644 --- a/driver/platform/common/inc/msm_vidc_platform.h +++ b/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_ diff --git a/driver/platform/common/src/msm_vidc_platform.c b/driver/platform/common/src/msm_vidc_platform.c index 976441d367..874c6e1bee 100644 --- a/driver/platform/common/src/msm_vidc_platform.c +++ b/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 **************************/ diff --git a/driver/platform/pineapple/src/msm_vidc_pineapple.c b/driver/platform/pineapple/src/msm_vidc_pineapple.c index 278e05da9e..d3302657b9 100644 --- a/driver/platform/pineapple/src/msm_vidc_pineapple.c +++ b/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, H264|HEVC|VP9|AV1, + 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, H264|HEVC|VP9|AV1, + 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, H264|HEVC|VP9|AV1, + 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, H264|HEVC|VP9|AV1, + 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, H264|HEVC|VP9|AV1, + 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, H264|HEVC|VP9|AV1, + {0}, + NULL, + NULL}, + + {OUTBUF_FENCE_TYPE, DEC, H264|HEVC|VP9|AV1, + {0}, + msm_vidc_adjust_dec_outbuf_fence_type, + msm_vidc_set_outbuf_fence_type}, + + {INBUF_FENCE_DIRECTION, DEC, H264|HEVC|VP9|AV1, + {0}, + NULL, + NULL}, + + {OUTBUF_FENCE_DIRECTION, DEC, H264|HEVC|VP9|AV1, + {0}, + msm_vidc_adjust_dec_outbuf_fence_direction, + msm_vidc_set_outbuf_fence_direction}, + + {FENCE_ERROR_DATA_CORRUPT, DEC, H264|HEVC|VP9|AV1, + {0}, + NULL, + msm_vidc_set_u32}, + {HFLIP, ENC, CODECS_ALL, {0}, NULL, @@ -2698,12 +2765,12 @@ static const struct device_region_table pineapple_device_region_table[] = { }, { "ipc_protocol4_client8_version-registers", - 0x00508000, 0x1000, 0xFFADD000, + 0x00508000, 0x1000, 0xFFADF000, MSM_VIDC_PROTOCOL_FENCE_CLIENT_VPU }, { "qtimer_f0v1_qtmr_v1_cntpct_lo", - 0x17421000, 0x1000, 0xFFADC000, + 0x17421000, 0x1000, 0xFFADE000, MSM_VIDC_QTIMER }, }; diff --git a/driver/variant/iris33/src/msm_vidc_iris33.c b/driver/variant/iris33/src/msm_vidc_iris33.c index 4281c42550..9d9aee708c 100644 --- a/driver/variant/iris33/src/msm_vidc_iris33.c +++ b/driver/variant/iris33/src/msm_vidc_iris33.c @@ -954,7 +954,8 @@ static int __boot_firmware_iris33(struct msm_vidc_core *vidc_core) return rc; if ((ctrl_status & HFI_CTRL_ERROR_FATAL) || - (ctrl_status & HFI_CTRL_ERROR_UC_REGION_NOT_SET)) { + (ctrl_status & HFI_CTRL_ERROR_UC_REGION_NOT_SET) || + (ctrl_status & HFI_CTRL_ERROR_HW_FENCE_QUEUE)) { d_vpr_e("%s: boot firmware failed, ctrl status %#x\n", __func__, ctrl_status); return -EINVAL; diff --git a/driver/vidc/inc/msm_vidc_debug.h b/driver/vidc/inc/msm_vidc_debug.h index 18ccbd538a..84bc7820c1 100644 --- a/driver/vidc/inc/msm_vidc_debug.h +++ b/driver/vidc/inc/msm_vidc_debug.h @@ -39,7 +39,7 @@ extern int msm_vidc_ddr_bw; extern int msm_vidc_llc_bw; extern bool msm_vidc_fw_dump; extern unsigned int msm_vidc_enable_bugon; -extern bool msm_vidc_disable_synx_fence; +extern bool msm_vidc_synx_fence_enable; /* do not modify the log message as it is used in test scripts */ #define FMT_STRING_SET_CTRL \ diff --git a/driver/vidc/inc/msm_vidc_internal.h b/driver/vidc/inc/msm_vidc_internal.h index 06275a2634..c53c5c2c7a 100644 --- a/driver/vidc/inc/msm_vidc_internal.h +++ b/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; diff --git a/driver/vidc/src/hfi_packet.c b/driver/vidc/src/hfi_packet.c index ae85d60506..214b3025ab 100644 --- a/driver/vidc/src/hfi_packet.c +++ b/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; diff --git a/driver/vidc/src/msm_vidc_debug.c b/driver/vidc/src/msm_vidc_debug.c index af05a9b725..3f15528f6f 100644 --- a/driver/vidc/src/msm_vidc_debug.c +++ b/driver/vidc/src/msm_vidc_debug.c @@ -22,6 +22,8 @@ extern struct msm_vidc_core *g_core; #define MSM_VIDC_MAX_STATS_DELAY_MS 10000 unsigned int msm_vidc_debug = (DRV_LOG | FW_LOG); +/* disabled synx fence by default temporarily */ +bool msm_vidc_synx_fence_enable = false; static int debug_level_set(const char *val, const struct kernel_param *kp) @@ -34,12 +36,6 @@ static int debug_level_set(const char *val, d_vpr_e("%s: Invalid params\n", __func__); return -EINVAL; } - core = *(struct msm_vidc_core **)kp->arg; - - if (!core || !core->capabilities) { - d_vpr_e("%s: Invalid core/capabilities\n", __func__); - return -EINVAL; - } ret = kstrtouint(val, 0, &dvalue); if (ret) @@ -47,6 +43,13 @@ static int debug_level_set(const char *val, msm_vidc_debug = dvalue; + core = *(struct msm_vidc_core **)kp->arg; + + if (!core || !core->capabilities) { + d_vpr_e("%s: Invalid core/capabilities\n", __func__); + return 0; + } + /* check if driver or FW logmask is more than default level */ if (((dvalue & DRV_LOGMASK) & ~(DRV_LOG)) || ((dvalue & FW_LOGMASK) & ~(FW_LOG))) { @@ -82,7 +85,6 @@ static const struct kernel_param_ops msm_vidc_debug_fops = { static int fw_dump_set(const char *val, const struct kernel_param *kp) { - struct msm_vidc_core *core = NULL; unsigned int dvalue; int ret; @@ -90,12 +92,6 @@ static int fw_dump_set(const char *val, d_vpr_e("%s: Invalid params\n", __func__); return -EINVAL; } - core = *(struct msm_vidc_core **) kp->arg; - - if (!core || !core->capabilities) { - d_vpr_e("%s: Invalid core/capabilities\n", __func__); - return -EINVAL; - } ret = kstrtouint(val, 0, &dvalue); if (ret) @@ -118,16 +114,44 @@ static const struct kernel_param_ops msm_vidc_fw_dump_fops = { .get = fw_dump_get, }; +static int synx_fence_set(const char *val, + const struct kernel_param *kp) +{ + unsigned int dvalue; + int ret; + + if (!kp || !kp->arg || !val) { + d_vpr_e("%s: Invalid params\n", __func__); + return -EINVAL; + } + + ret = kstrtouint(val, 0, &dvalue); + if (ret) + return ret; + + msm_vidc_synx_fence_enable = dvalue; + + return 0; +} + +static int synx_fence_get(char *buffer, const struct kernel_param *kp) +{ + return scnprintf(buffer, PAGE_SIZE, "%#x", msm_vidc_synx_fence_enable); +} + +static const struct kernel_param_ops msm_vidc_synx_fence_debug_fops = { + .set = synx_fence_set, + .get = synx_fence_get, +}; + module_param_cb(msm_vidc_debug, &msm_vidc_debug_fops, &g_core, 0644); module_param_cb(msm_vidc_fw_dump, &msm_vidc_fw_dump_fops, &g_core, 0644); +module_param_cb(msm_vidc_synx_fence_enable, + &msm_vidc_synx_fence_debug_fops, &g_core, 0644); bool msm_vidc_lossless_encode = !true; EXPORT_SYMBOL(msm_vidc_lossless_encode); -/* disabled synx fence by default temporarily */ -bool msm_vidc_disable_synx_fence = !false; -EXPORT_SYMBOL(msm_vidc_disable_synx_fence); - bool msm_vidc_syscache_disable = !true; EXPORT_SYMBOL(msm_vidc_syscache_disable); @@ -402,8 +426,6 @@ struct dentry* msm_vidc_debugfs_init_drv(void) &msm_vidc_syscache_disable); debugfs_create_bool("lossless_encoding", 0644, dir, &msm_vidc_lossless_encode); - debugfs_create_bool("disable_synx_v2_fence", 0644, dir, - &msm_vidc_disable_synx_fence); debugfs_create_u32("enable_bugon", 0644, dir, &msm_vidc_enable_bugon); diff --git a/driver/vidc/src/msm_vidc_probe.c b/driver/vidc/src/msm_vidc_probe.c index dbd8f14569..ad31393eaf 100644 --- a/driver/vidc/src/msm_vidc_probe.c +++ b/driver/vidc/src/msm_vidc_probe.c @@ -569,7 +569,16 @@ static int msm_vidc_component_master_bind(struct device *dev) } if (core->capabilities[SUPPORTS_SYNX_FENCE].value) { - if (msm_vidc_disable_synx_fence) { + if (msm_vidc_synx_fence_enable) { + /* register for synx fence */ + rc = call_fence_op(core, fence_register, core); + if (rc) { + d_vpr_e("%s: failed to register synx fence\n", + __func__); + core->capabilities[SUPPORTS_SYNX_FENCE].value = 0; + return rc; + } + } else { /* override synx fence ops with dma fence ops */ core->fence_ops = get_dma_fence_ops(); if (!core->fence_ops) { @@ -577,28 +586,6 @@ static int msm_vidc_component_master_bind(struct device *dev) return -EINVAL; } core->capabilities[SUPPORTS_SYNX_FENCE].value = 0; - } else { - /* register for synx fence */ - rc = call_fence_op(core, fence_register, core); - if (rc) { - d_vpr_e("%s: failed to register synx fence\n", - __func__); - core->capabilities[SUPPORTS_SYNX_FENCE].value = 0; - /* - * - Bail out the session for time being for this - * case where synx fence register call retunrs error - * to help with debugging - * - Re-initialize fence ops with dma_fence_ops. - * This is required once we start ignoring this - * synx fence register call error. - */ - core->fence_ops = get_dma_fence_ops(); - if (!core->fence_ops) { - d_vpr_e("%s: invalid dma fence ops\n", __func__); - return -EINVAL; - } - return rc; - } } } diff --git a/driver/vidc/src/msm_vidc_synx.c b/driver/vidc/src/msm_vidc_synx.c index 8e0b38339d..946d56ec4c 100644 --- a/driver/vidc/src/msm_vidc_synx.c +++ b/driver/vidc/src/msm_vidc_synx.c @@ -145,6 +145,7 @@ static int msm_vidc_synx_fence_register(struct msm_vidc_core *core) "video synx fence"); params.name = synx_session_name; params.ptr = &queue_desc; + params.flags = SYNX_INIT_MAX; /* unused */ session = (struct synx_session *)synx_hwfence_initialize(¶ms); @@ -155,6 +156,7 @@ static int msm_vidc_synx_fence_register(struct msm_vidc_core *core) /* fill core synx fence data */ core->synx_fence_data.client_id = (u32)params.id; + core->synx_fence_data.client_flags = (u32)params.flags; core->synx_fence_data.session = (void *)session; core->synx_fence_data.queue.size = (u32)queue_desc.size; core->synx_fence_data.queue.kvaddr = queue_desc.vaddr; diff --git a/driver/vidc/src/venus_hfi_response.c b/driver/vidc/src/venus_hfi_response.c index b9352110f8..fc3c4c9248 100644 --- a/driver/vidc/src/venus_hfi_response.c +++ b/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;