|
@@ -2105,15 +2105,18 @@ static int cam_icp_mgr_cleanup_ctx(struct cam_icp_hw_ctx_data *ctx_data)
|
|
|
{
|
|
|
int i;
|
|
|
struct hfi_frame_process_info *hfi_frame_process;
|
|
|
- struct cam_hw_done_event_data buf_data;
|
|
|
+ struct cam_icp_hw_buf_done_evt_data icp_evt_data;
|
|
|
+ struct cam_hw_done_event_data buf_data = {0};
|
|
|
|
|
|
hfi_frame_process = &ctx_data->hfi_frame_process;
|
|
|
for (i = 0; i < CAM_FRAME_CMD_MAX; i++) {
|
|
|
if (!hfi_frame_process->request_id[i])
|
|
|
continue;
|
|
|
buf_data.request_id = hfi_frame_process->request_id[i];
|
|
|
+ icp_evt_data.evt_id = CAM_CTX_EVT_ID_SUCCESS;
|
|
|
+ icp_evt_data.buf_done_data = &buf_data;
|
|
|
ctx_data->ctxt_event_cb(ctx_data->context_priv,
|
|
|
- CAM_CTX_EVT_ID_SUCCESS, &buf_data);
|
|
|
+ CAM_ICP_EVT_ID_BUF_DONE, &icp_evt_data);
|
|
|
hfi_frame_process->request_id[i] = 0;
|
|
|
if (ctx_data->hfi_frame_process.in_resource[i] > 0) {
|
|
|
CAM_DBG(CAM_ICP, "Delete merged sync in object: %d",
|
|
@@ -2141,6 +2144,46 @@ static int cam_icp_mgr_cleanup_ctx(struct cam_icp_hw_ctx_data *ctx_data)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+static uint32_t cam_icp_handle_err_type_to_evt_param(uint32_t error_type)
|
|
|
+{
|
|
|
+ switch (error_type) {
|
|
|
+ case CAMERAICP_ENOMEMORY:
|
|
|
+ return CAM_SYNC_ICP_EVENT_NO_MEMORY;
|
|
|
+ case CAMERAICP_EFAILED:
|
|
|
+ return CAM_SYNC_ICP_EVENT_FRAME_PROCESS_FAILURE;
|
|
|
+ case CAMERAICP_EBADSTATE:
|
|
|
+ return CAM_SYNC_ICP_EVENT_BAD_STATE;
|
|
|
+ case CAMERAICP_EBADPARM:
|
|
|
+ return CAM_SYNC_ICP_EVENT_BAD_PARAM;
|
|
|
+ case CAMERAICP_EBADITEM:
|
|
|
+ return CAM_SYNC_ICP_EVENT_BAD_ITEM;
|
|
|
+ case CAMERAICP_EINVALIDFORMAT:
|
|
|
+ return CAM_SYNC_ICP_EVENT_INVALID_FORMAT;
|
|
|
+ case CAMERAICP_EUNSUPPORTED:
|
|
|
+ return CAM_SYNC_ICP_EVENT_UNSUPPORTED;
|
|
|
+ case CAMERAICP_EOUTOFBOUND:
|
|
|
+ return CAM_SYNC_ICP_EVENT_OUT_OF_BOUND;
|
|
|
+ case CAMERAICP_ETIMEDOUT:
|
|
|
+ return CAM_SYNC_ICP_EVENT_TIME_OUT;
|
|
|
+ case CAMERAICP_EABORTED:
|
|
|
+ return CAM_SYNC_ICP_EVENT_ABORTED;
|
|
|
+ case CAMERAICP_EHWVIOLATION:
|
|
|
+ return CAM_SYNC_ICP_EVENT_HW_VIOLATION;
|
|
|
+ case CAMERAICP_ECDMERROR:
|
|
|
+ return CAM_SYNC_ICP_EVENT_CMD_ERROR;
|
|
|
+ case CAMERAICP_HFI_ERR_COMMAND_SIZE:
|
|
|
+ return CAM_SYNC_ICP_EVENT_HFI_ERR_COMMAND_SIZE;
|
|
|
+ case CAMERAICP_HFI_ERR_MESSAGE_SIZE:
|
|
|
+ return CAM_SYNC_ICP_EVENT_HFI_ERR_MESSAGE_SIZE;
|
|
|
+ case CAMERAICP_HFI_QUEUE_EMPTY:
|
|
|
+ return CAM_SYNC_ICP_EVENT_HFI_ERR_QUEUE_EMPTY;
|
|
|
+ case CAMERAICP_HFI_QUEUE_FULL:
|
|
|
+ return CAM_SYNC_ICP_EVENT_HFI_ERR_QUEUE_FULL;
|
|
|
+ default:
|
|
|
+ return CAM_SYNC_ICP_EVENT_UNKNOWN;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
static const char *cam_icp_error_handle_id_to_type(
|
|
|
uint32_t error_handle)
|
|
|
{
|
|
@@ -2213,7 +2256,9 @@ static int cam_icp_mgr_handle_frame_process(uint32_t *msg_ptr, int flag)
|
|
|
struct cam_icp_hw_ctx_data *ctx_data = NULL;
|
|
|
struct hfi_msg_ipebps_async_ack *ioconfig_ack = NULL;
|
|
|
struct hfi_frame_process_info *hfi_frame_process;
|
|
|
- struct cam_hw_done_event_data buf_data;
|
|
|
+ struct cam_hw_done_event_data buf_data = {0};
|
|
|
+ struct cam_icp_hw_buf_done_evt_data icp_done_evt;
|
|
|
+ struct cam_icp_hw_error_evt_data icp_err_evt = {0};
|
|
|
uint32_t clk_type;
|
|
|
uint32_t event_id;
|
|
|
struct cam_hangdump_mem_regions *mem_regions = NULL;
|
|
@@ -2259,7 +2304,6 @@ static int cam_icp_mgr_handle_frame_process(uint32_t *msg_ptr, int flag)
|
|
|
idx = i;
|
|
|
|
|
|
if (flag == ICP_FRAME_PROCESS_FAILURE) {
|
|
|
- buf_data.evt_param = CAM_SYNC_ICP_EVENT_FRAME_PROCESS_FAILURE;
|
|
|
if (ioconfig_ack->err_type == CAMERAICP_EABORTED) {
|
|
|
CAM_WARN(CAM_ICP,
|
|
|
"ctx_id %d req %llu dev %d has been aborted[flushed]",
|
|
@@ -2277,6 +2321,7 @@ static int cam_icp_mgr_handle_frame_process(uint32_t *msg_ptr, int flag)
|
|
|
request_id);
|
|
|
event_id = CAM_CTX_EVT_ID_ERROR;
|
|
|
}
|
|
|
+ buf_data.evt_param = cam_icp_handle_err_type_to_evt_param(ioconfig_ack->err_type);
|
|
|
} else {
|
|
|
event_id = CAM_CTX_EVT_ID_SUCCESS;
|
|
|
}
|
|
@@ -2303,7 +2348,11 @@ static int cam_icp_mgr_handle_frame_process(uint32_t *msg_ptr, int flag)
|
|
|
ctx_data->ctx_id_string, hfi_frame_process->request_id[idx], event_id);
|
|
|
|
|
|
buf_data.request_id = hfi_frame_process->request_id[idx];
|
|
|
- ctx_data->ctxt_event_cb(ctx_data->context_priv, event_id, &buf_data);
|
|
|
+ icp_done_evt.evt_id = event_id;
|
|
|
+ icp_done_evt.buf_done_data = &buf_data;
|
|
|
+ ctx_data->ctxt_event_cb(ctx_data->context_priv, CAM_ICP_EVT_ID_BUF_DONE,
|
|
|
+ &icp_done_evt);
|
|
|
+
|
|
|
hfi_frame_process->request_id[idx] = 0;
|
|
|
if (ctx_data->hfi_frame_process.in_resource[idx] > 0) {
|
|
|
CAM_DBG(CAM_ICP, "Delete merged sync in object: %d",
|
|
@@ -2313,6 +2362,14 @@ static int cam_icp_mgr_handle_frame_process(uint32_t *msg_ptr, int flag)
|
|
|
}
|
|
|
clear_bit(idx, ctx_data->hfi_frame_process.bitmap);
|
|
|
hfi_frame_process->fw_process_flag[idx] = false;
|
|
|
+
|
|
|
+ /* report recovery to userspace if FW encounters no memory */
|
|
|
+ if (ioconfig_ack->err_type == CAMERAICP_ENOMEMORY) {
|
|
|
+ icp_err_evt.err_type = CAM_ICP_HW_ERROR_NO_MEM;
|
|
|
+ icp_err_evt.req_id = request_id;
|
|
|
+ ctx_data->ctxt_event_cb(ctx_data->context_priv, CAM_ICP_EVT_ID_ERROR,
|
|
|
+ &icp_err_evt);
|
|
|
+ }
|
|
|
mutex_unlock(&ctx_data->ctx_mutex);
|
|
|
|
|
|
return 0;
|
|
@@ -2609,8 +2666,10 @@ static int cam_icp_ipebps_reset(struct cam_icp_hw_mgr *hw_mgr)
|
|
|
|
|
|
static int cam_icp_mgr_trigger_recovery(struct cam_icp_hw_mgr *hw_mgr)
|
|
|
{
|
|
|
- int rc = 0;
|
|
|
+ int rc = 0, i;
|
|
|
struct sfr_buf *sfr_buffer = NULL;
|
|
|
+ struct cam_icp_hw_ctx_data *ctx_data;
|
|
|
+ struct cam_icp_hw_error_evt_data icp_err_evt = {0};
|
|
|
|
|
|
CAM_DBG(CAM_ICP, "Enter");
|
|
|
|
|
@@ -2627,6 +2686,27 @@ static int cam_icp_mgr_trigger_recovery(struct cam_icp_hw_mgr *hw_mgr)
|
|
|
cam_icp_ipebps_reset(hw_mgr);
|
|
|
|
|
|
atomic_set(&hw_mgr->recovery, 1);
|
|
|
+
|
|
|
+ /* Find any active context and notify userspace of system failure */
|
|
|
+ icp_err_evt.err_type = CAM_ICP_HW_ERROR_SYSTEM_FAILURE;
|
|
|
+ mutex_lock(&hw_mgr->hw_mgr_mutex);
|
|
|
+ for (i = 0; i < CAM_ICP_CTX_MAX; i++) {
|
|
|
+ ctx_data = &hw_mgr->ctx_data[i];
|
|
|
+ mutex_lock(&ctx_data->ctx_mutex);
|
|
|
+ if (ctx_data->state != CAM_CTX_ACQUIRED) {
|
|
|
+ mutex_unlock(&ctx_data->ctx_mutex);
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ ctx_data->ctxt_event_cb(ctx_data->context_priv, CAM_ICP_EVT_ID_ERROR,
|
|
|
+ &icp_err_evt);
|
|
|
+ mutex_unlock(&ctx_data->ctx_mutex);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ mutex_unlock(&hw_mgr->hw_mgr_mutex);
|
|
|
+ if (i == CAM_ICP_CTX_MAX)
|
|
|
+ CAM_ERR(CAM_ICP,
|
|
|
+ "Fail to report system failure to userspace due to no active ctx");
|
|
|
+
|
|
|
CAM_DBG(CAM_ICP, "Done");
|
|
|
return rc;
|
|
|
}
|
|
@@ -4418,12 +4498,15 @@ static int cam_icp_mgr_handle_config_err(
|
|
|
struct cam_icp_hw_ctx_data *ctx_data,
|
|
|
int idx)
|
|
|
{
|
|
|
- struct cam_hw_done_event_data buf_data;
|
|
|
+ struct cam_icp_hw_buf_done_evt_data icp_evt_data;
|
|
|
+ struct cam_hw_done_event_data buf_data = {0};
|
|
|
|
|
|
buf_data.request_id = *(uint64_t *)config_args->priv;
|
|
|
buf_data.evt_param = CAM_SYNC_ICP_EVENT_CONFIG_ERR;
|
|
|
- ctx_data->ctxt_event_cb(ctx_data->context_priv, CAM_CTX_EVT_ID_SUCCESS,
|
|
|
- &buf_data);
|
|
|
+ icp_evt_data.evt_id = CAM_CTX_EVT_ID_ERROR;
|
|
|
+ icp_evt_data.buf_done_data = &buf_data;
|
|
|
+ ctx_data->ctxt_event_cb(ctx_data->context_priv, CAM_ICP_EVT_ID_BUF_DONE,
|
|
|
+ &icp_evt_data);
|
|
|
|
|
|
ctx_data->hfi_frame_process.request_id[idx] = 0;
|
|
|
ctx_data->hfi_frame_process.fw_process_flag[idx] = false;
|
|
@@ -5573,17 +5656,23 @@ static int cam_icp_mgr_prepare_hw_update(void *hw_mgr_priv,
|
|
|
static int cam_icp_mgr_send_abort_status(struct cam_icp_hw_ctx_data *ctx_data)
|
|
|
{
|
|
|
struct hfi_frame_process_info *hfi_frame_process;
|
|
|
+ struct cam_icp_hw_buf_done_evt_data icp_evt_data;
|
|
|
+ struct cam_hw_done_event_data buf_data = {0};
|
|
|
int idx;
|
|
|
|
|
|
mutex_lock(&ctx_data->ctx_mutex);
|
|
|
hfi_frame_process = &ctx_data->hfi_frame_process;
|
|
|
+ buf_data.evt_param = CAM_SYNC_ICP_EVENT_ABORTED;
|
|
|
+ icp_evt_data.evt_id = CAM_CTX_EVT_ID_CANCEL;
|
|
|
for (idx = 0; idx < CAM_FRAME_CMD_MAX; idx++) {
|
|
|
if (!hfi_frame_process->request_id[idx])
|
|
|
continue;
|
|
|
|
|
|
+ buf_data.request_id = hfi_frame_process->request_id[idx];
|
|
|
+ icp_evt_data.buf_done_data = &buf_data;
|
|
|
ctx_data->ctxt_event_cb(ctx_data->context_priv,
|
|
|
- CAM_CTX_EVT_ID_CANCEL,
|
|
|
- &hfi_frame_process->request_id[idx]);
|
|
|
+ CAM_ICP_EVT_ID_BUF_DONE,
|
|
|
+ &icp_evt_data);
|
|
|
|
|
|
/* now release memory for hfi frame process command */
|
|
|
hfi_frame_process->request_id[idx] = 0;
|
|
@@ -5593,7 +5682,7 @@ static int cam_icp_mgr_send_abort_status(struct cam_icp_hw_ctx_data *ctx_data)
|
|
|
cam_sync_destroy(
|
|
|
ctx_data->hfi_frame_process.in_resource[idx]);
|
|
|
ctx_data->hfi_frame_process.in_resource[idx] = 0;
|
|
|
- }
|
|
|
+ }
|
|
|
clear_bit(idx, ctx_data->hfi_frame_process.bitmap);
|
|
|
}
|
|
|
mutex_unlock(&ctx_data->ctx_mutex);
|