diff --git a/msm/vidc/hfi_common.c b/msm/vidc/hfi_common.c index 16f9d17e3d2c6..74aa73796f394 100644 --- a/msm/vidc/hfi_common.c +++ b/msm/vidc/hfi_common.c @@ -1807,6 +1807,34 @@ static int venus_hfi_core_release(void *dev) return rc; } +static int venus_hfi_core_ping(void *device, u32 sid) +{ + struct hfi_cmd_sys_ping_packet pkt; + int rc = 0; + struct venus_hfi_device *dev; + + if (!device) { + d_vpr_e("invalid device\n"); + return -ENODEV; + } + + dev = device; + mutex_lock(&dev->lock); + + rc = call_hfi_pkt_op(dev, sys_ping, &pkt, sid); + if (rc) { + d_vpr_e("core_ping: failed to create packet\n"); + goto err_create_pkt; + } + + if (__iface_cmdq_write(dev, &pkt, sid)) + rc = -ENOTEMPTY; + +err_create_pkt: + mutex_unlock(&dev->lock); + return rc; +} + static int venus_hfi_core_trigger_ssr(void *device, enum hal_ssr_trigger_type ssr_type, u32 sub_client_id, u32 test_addr) @@ -2790,6 +2818,7 @@ static int __response_handler(struct venus_hfi_device *device) case HAL_SESSION_RELEASE_BUFFER_DONE: case HAL_SESSION_RELEASE_RESOURCE_DONE: case HAL_SESSION_PROPERTY_INFO: + case HAL_SYS_PING_ACK: inst_id = &info->response.cmd.inst_id; break; case HAL_SESSION_ERROR: @@ -4284,6 +4313,7 @@ void venus_hfi_delete_device(void *device) static void venus_init_hfi_callbacks(struct hfi_device *hdev) { hdev->core_init = venus_hfi_core_init; + hdev->core_ping = venus_hfi_core_ping; hdev->core_release = venus_hfi_core_release; hdev->core_trigger_ssr = venus_hfi_core_trigger_ssr; hdev->session_init = venus_hfi_session_init; diff --git a/msm/vidc/hfi_packetization.c b/msm/vidc/hfi_packetization.c index 345638f869029..00f92a68c4069 100644 --- a/msm/vidc/hfi_packetization.c +++ b/msm/vidc/hfi_packetization.c @@ -71,6 +71,20 @@ int create_pkt_cmd_sys_init(struct hfi_cmd_sys_init_packet *pkt, return rc; } +int create_pkt_cmd_sys_ping(struct hfi_cmd_sys_ping_packet *pkt, u32 sid) +{ + int rc = 0; + + if (!pkt) + return -EINVAL; + + pkt->size = sizeof(struct hfi_cmd_sys_ping_packet); + pkt->packet_type = HFI_CMD_SYS_PING; + pkt->sid = sid; + + return rc; +} + int create_pkt_cmd_sys_pc_prep(struct hfi_cmd_sys_pc_prep_packet *pkt) { int rc = 0; @@ -692,6 +706,7 @@ int create_pkt_cmd_sys_image_version( static struct hfi_packetization_ops hfi_default = { .sys_init = create_pkt_cmd_sys_init, + .sys_ping = create_pkt_cmd_sys_ping, .sys_pc_prep = create_pkt_cmd_sys_pc_prep, .sys_power_control = create_pkt_cmd_sys_power_control, .sys_set_resource = create_pkt_cmd_sys_set_resource, diff --git a/msm/vidc/hfi_packetization.h b/msm/vidc/hfi_packetization.h index accce3144aa40..412f83199660c 100644 --- a/msm/vidc/hfi_packetization.h +++ b/msm/vidc/hfi_packetization.h @@ -19,6 +19,7 @@ enum hfi_packetization_type { struct hfi_packetization_ops { int (*sys_init)(struct hfi_cmd_sys_init_packet *pkt, u32 arch_type); + int (*sys_ping)(struct hfi_cmd_sys_ping_packet *pkt, u32 sid); int (*sys_pc_prep)(struct hfi_cmd_sys_pc_prep_packet *pkt); int (*sys_power_control)(struct hfi_cmd_sys_set_property_packet *pkt, u32 enable); diff --git a/msm/vidc/hfi_response_handler.c b/msm/vidc/hfi_response_handler.c index b129dec72f31d..ca5c21f3a9d65 100644 --- a/msm/vidc/hfi_response_handler.c +++ b/msm/vidc/hfi_response_handler.c @@ -1079,6 +1079,29 @@ static int hfi_process_session_abort_done(u32 device_id, return 0; } +static int hfi_process_sys_ping_ack(u32 device_id, + void *_pkt, + struct msm_vidc_cb_info *info) +{ + struct hfi_msg_sys_ping_ack_pkt *pkt = _pkt; + struct msm_vidc_cb_cmd_done cmd_done = {0}; + if (!pkt || pkt->size != + sizeof(struct hfi_msg_sys_ping_ack_pkt)) { + d_vpr_e("%s: bad packet/packet size: %d\n", + __func__, pkt ? pkt->size : 0); + return -E2BIG; + } + s_vpr_h(pkt->sid, "RECEIVED: SYS PING ACK\n"); + cmd_done.device_id = device_id; + cmd_done.inst_id = (void *)(uintptr_t)pkt->sid; + cmd_done.size = 0; + + info->response_type = HAL_SYS_PING_ACK; + info->response.cmd = cmd_done; + + return 0; +} + static void hfi_process_sys_get_prop_image_version( struct hfi_msg_sys_property_info_packet *pkt) { @@ -1213,6 +1236,9 @@ int hfi_process_msg_packet(u32 device_id, struct vidc_hal_msg_pkt_hdr *msg_hdr, case HFI_MSG_SYS_SESSION_ABORT_DONE: pkt_func = (pkt_func_def)hfi_process_session_abort_done; break; + case HFI_MSG_SYS_PING_ACK: + pkt_func = (pkt_func_def)hfi_process_sys_ping_ack; + break; default: d_vpr_l("Unable to parse message: %#x\n", msg_hdr->packet); break; diff --git a/msm/vidc/msm_vidc_common.c b/msm/vidc/msm_vidc_common.c index b4de4e3b235ee..b8a97f53c7783 100644 --- a/msm/vidc/msm_vidc_common.c +++ b/msm/vidc/msm_vidc_common.c @@ -1269,8 +1269,20 @@ static int wait_for_sess_signal_receipt(struct msm_vidc_inst *inst, msecs_to_jiffies( inst->core->resources.msm_vidc_hw_rsp_timeout)); if (!rc) { - s_vpr_e(inst->sid, "Wait interrupted or timed out: %d\n", + s_vpr_e(inst->sid, "Wait interrupted or timed out(sending ping cmd): %d\n", SESSION_MSG_INDEX(cmd)); + rc = call_hfi_op(hdev, core_ping, hdev->hfi_device_data, inst->sid); + rc = wait_for_completion_timeout( + &inst->core->completions[SYS_MSG_INDEX(HAL_SYS_PING_ACK)], + msecs_to_jiffies( + inst->core->resources.msm_vidc_hw_rsp_timeout)); + if (rc) { + if (try_wait_for_completion(&inst->completions[SESSION_MSG_INDEX(cmd)])) { + s_vpr_e(inst->sid, "Received %d response. Continue session\n", + SESSION_MSG_INDEX(cmd)); + return 0; + } + } msm_comm_kill_session(inst); rc = -EIO; } else { @@ -1900,6 +1912,28 @@ static void handle_stop_done(enum hal_command_response cmd, void *data) put_inst(inst); } +static void handle_ping_done(enum hal_command_response cmd, void *data) +{ + struct msm_vidc_cb_cmd_done *response = data; + struct msm_vidc_inst *inst; + + if (!response) { + d_vpr_e("Failed to get valid response for stop\n"); + return; + } + + inst = get_inst(get_vidc_core(response->device_id), + response->inst_id); + if (!inst) { + d_vpr_e("Got a response for an inactive session\n"); + return; + } + + s_vpr_l(inst->sid, "handled: SYS_PING_DONE\n"); + complete(&inst->core->completions[SYS_MSG_INDEX(HAL_SYS_PING_ACK)]); + put_inst(inst); +} + static void handle_release_res_done(enum hal_command_response cmd, void *data) { struct msm_vidc_cb_cmd_done *response = data; @@ -2728,6 +2762,9 @@ void handle_cmd_response(enum hal_command_response cmd, void *data) case HAL_SESSION_ABORT_DONE: handle_session_close(cmd, data); break; + case HAL_SYS_PING_ACK: + handle_ping_done(cmd, data); + break; case HAL_SESSION_EVENT_CHANGE: handle_event_change(cmd, data); break; diff --git a/msm/vidc/vidc_hfi.h b/msm/vidc/vidc_hfi.h index 9d2ab5d0dfe75..3ae3d0ffb2ab5 100644 --- a/msm/vidc/vidc_hfi.h +++ b/msm/vidc/vidc_hfi.h @@ -313,6 +313,8 @@ struct hfi_uncompressed_plane_actual_constraints_info { #define HFI_CMD_SYS_OX_START \ (HFI_DOMAIN_BASE_COMMON + HFI_ARCH_OX_OFFSET + HFI_CMD_START_OFFSET + 0x0000) #define HFI_CMD_SYS_SESSION_ABORT (HFI_CMD_SYS_OX_START + 0x001) +#define HFI_CMD_SYS_PING (HFI_CMD_SYS_OX_START + 0x002) + #define HFI_CMD_SESSION_OX_START \ (HFI_DOMAIN_BASE_COMMON + HFI_ARCH_OX_OFFSET + HFI_CMD_START_OFFSET + 0x1000) @@ -336,6 +338,7 @@ struct hfi_uncompressed_plane_actual_constraints_info { #define HFI_MSG_SYS_OX_START \ (HFI_DOMAIN_BASE_COMMON + HFI_ARCH_OX_OFFSET + HFI_MSG_START_OFFSET + 0x0000) +#define HFI_MSG_SYS_PING_ACK (HFI_MSG_SYS_OX_START + 0x2) #define HFI_MSG_SYS_SESSION_ABORT_DONE (HFI_MSG_SYS_OX_START + 0x4) #define HFI_MSG_SESSION_OX_START \ @@ -368,6 +371,12 @@ struct hfi_cmd_sys_session_abort_packet { u32 sid; }; +struct hfi_cmd_sys_ping_packet { + u32 size; + u32 packet_type; + u32 sid; +}; + struct hfi_cmd_session_load_resources_packet { u32 size; u32 packet_type; @@ -507,6 +516,12 @@ struct hfi_msg_sys_session_abort_done_packet { u32 error_type; }; +struct hfi_msg_sys_ping_ack_pkt { + u32 size; + u32 packet_type; + u32 sid; +}; + struct hfi_msg_sys_property_info_packet { u32 size; u32 packet_type; diff --git a/msm/vidc/vidc_hfi_api.h b/msm/vidc/vidc_hfi_api.h index ee86ad85f7be1..230c217d3db61 100644 --- a/msm/vidc/vidc_hfi_api.h +++ b/msm/vidc/vidc_hfi_api.h @@ -423,7 +423,7 @@ enum hal_command_response { HAL_SYS_SET_RESOURCE_DONE, HAL_SYS_RELEASE_RESOURCE_DONE, HAL_SYS_PC_PREP_DONE, - HAL_SYS_IDLE, + HAL_SYS_PING_ACK, HAL_SYS_DEBUG, HAL_SYS_WATCHDOG_TIMEOUT, HAL_SYS_ERROR, @@ -635,6 +635,7 @@ struct hfi_device { /*Add function pointers for all the hfi functions below*/ int (*core_init)(void *device); + int (*core_ping)(void *device, u32 sid); int (*core_release)(void *device); int (*core_trigger_ssr)(void *device, enum hal_ssr_trigger_type ssr_type, u32 sub_client_id,