diff options
author | Raja Mallik <rmallik@codeaurora.org> | 2019-07-22 12:21:54 +0530 |
---|---|---|
committer | Gerrit - the friendly Code Review server <code-review@localhost> | 2019-08-12 21:06:25 -0700 |
commit | 584d92571c422c454063c73bdd8fe2e9a3e4c203 (patch) | |
tree | a21088be0666f95723a0b1b113f993553477841d | |
parent | d230848ebe7bafd378284b44102ad0be62868834 (diff) |
Merge remote-tracking branch 'dev/msm-4.14' into msm-4.9 07/03LA.UM.7.6.2.c1-03100-89xx.0
* commit '8819f223628c45a1934349cff8e7c7e2f27190c0':
msm: camera: sensor: Add check to know if device acquired
msm: camera: isp: remove the check for bpp
msm: camera: jpeg: Check the HW state before accessing register
msm: camera: isp: Enabling critical logs to improve debugging
msm: camera: cpas: Avoid array underflow during client registration
msm: camera: isp: Halt device with the command parsed
msm: camera: core: Fix context release timing issue
msm: camera: mem: print error value
msm: camera: isp: Update the context hw events dump
msm: camera: smmu: Set smmu non fatal flag true
msm: camera: isp: Buffer size validation at IFE
Change-Id: Iee23d9b045065e8a5569c3ad7355333d2825d3a3
Signed-off-by: Raja Mallik <rmallik@codeaurora.org>
13 files changed, 501 insertions, 147 deletions
diff --git a/drivers/media/platform/msm/camera_v3/cam_core/cam_context_utils.c b/drivers/media/platform/msm/camera_v3/cam_core/cam_context_utils.c index 7600cbb77cee..11bad5dd4647 100644 --- a/drivers/media/platform/msm/camera_v3/cam_core/cam_context_utils.c +++ b/drivers/media/platform/msm/camera_v3/cam_core/cam_context_utils.c @@ -462,6 +462,17 @@ int32_t cam_context_prepare_dev_to_hw(struct cam_context *ctx, ctx->dev_name, ctx->ctx_id, req->request_id); for (j = 0; j < req->num_in_map_entries; j++) { + rc = cam_sync_check_valid( + req->in_map_entries[j].sync_id); + if (rc) { + CAM_ERR(CAM_CTXT, + "invalid in map sync object %d", + req->in_map_entries[j].sync_id); + goto put_ref; + } + } + + for (j = 0; j < req->num_in_map_entries; j++) { cam_context_getref(ctx); rc = cam_sync_register_callback( cam_context_sync_callback, @@ -482,7 +493,9 @@ int32_t cam_context_prepare_dev_to_hw(struct cam_context *ctx, ctx->dev_name, ctx->ctx_id, req->request_id); - goto put_ctx_ref; + cam_context_putref(ctx); + goto put_ref; + } CAM_DBG(CAM_CTXT, "register in fence cb: %d ret = %d", req->in_map_entries[j].sync_id, rc); @@ -491,9 +504,6 @@ int32_t cam_context_prepare_dev_to_hw(struct cam_context *ctx, } return rc; -put_ctx_ref: - for (--j; j >= 0; j--) - cam_context_putref(ctx); put_ref: for (--i; i >= 0; i--) { rc = cam_sync_put_obj_ref(req->out_map_entries[i].sync_id); diff --git a/drivers/media/platform/msm/camera_v3/cam_cpas/cam_cpas_hw.c b/drivers/media/platform/msm/camera_v3/cam_cpas/cam_cpas_hw.c index 4276b356da73..a68032cf6c19 100644 --- a/drivers/media/platform/msm/camera_v3/cam_cpas/cam_cpas_hw.c +++ b/drivers/media/platform/msm/camera_v3/cam_cpas/cam_cpas_hw.c @@ -1234,6 +1234,13 @@ static int cam_cpas_hw_register_client(struct cam_hw_info *cpas_hw, rc = cam_common_util_get_string_index(soc_private->client_name, soc_private->num_clients, client_name, &client_indx); + if (rc) { + CAM_ERR(CAM_CPAS, "No match found for client %s", + client_name); + mutex_unlock(&cpas_hw->hw_mutex); + return rc; + } + mutex_lock(&cpas_core->client_mutex[client_indx]); if (rc || !CAM_CPAS_CLIENT_VALID(client_indx) || diff --git a/drivers/media/platform/msm/camera_v3/cam_isp/cam_isp_context.c b/drivers/media/platform/msm/camera_v3/cam_isp/cam_isp_context.c index 57375c4ad50f..1eb7389b2516 100644 --- a/drivers/media/platform/msm/camera_v3/cam_isp/cam_isp_context.c +++ b/drivers/media/platform/msm/camera_v3/cam_isp/cam_isp_context.c @@ -38,18 +38,26 @@ static int cam_isp_context_dump_active_request(void *data, unsigned long iova, static void __cam_isp_ctx_update_state_monitor_array( struct cam_isp_context *ctx_isp, - enum cam_isp_state_change_trigger trigger_type, - uint32_t req_id) + enum cam_isp_hw_event_type hw_event, + enum cam_isp_ctx_activated_substate curr_state, + enum cam_isp_ctx_activated_substate next_state) { int iterator = 0; iterator = INC_STATE_MONITOR_HEAD(&ctx_isp->state_monitor_head); ctx_isp->cam_isp_ctx_state_monitor[iterator].curr_state = - ctx_isp->substate_activated; - ctx_isp->cam_isp_ctx_state_monitor[iterator].trigger = - trigger_type; - ctx_isp->cam_isp_ctx_state_monitor[iterator].req_id = - req_id; + curr_state; + ctx_isp->cam_isp_ctx_state_monitor[iterator].next_state = + next_state; + ctx_isp->cam_isp_ctx_state_monitor[iterator].hw_event = + hw_event; + ctx_isp->cam_isp_ctx_state_monitor[iterator].last_reported_id = + ctx_isp->req_info.reported_req_id; + ctx_isp->cam_isp_ctx_state_monitor[iterator].last_applied_req_id = + ctx_isp->req_info.last_applied_req_id; + ctx_isp->cam_isp_ctx_state_monitor[iterator].frame_id = + ctx_isp->frame_id; + ctx_isp->cam_isp_ctx_state_monitor[iterator].evt_time_stamp = jiffies_to_msecs(jiffies); } @@ -79,17 +87,17 @@ static const char *__cam_isp_hw_evt_val_to_type( uint32_t evt_id) { switch (evt_id) { - case CAM_ISP_STATE_CHANGE_TRIGGER_ERROR: + case CAM_ISP_HW_EVENT_ERROR: return "ERROR"; - case CAM_ISP_STATE_CHANGE_TRIGGER_SOF: + case CAM_ISP_HW_EVENT_SOF: return "SOF"; - case CAM_ISP_STATE_CHANGE_TRIGGER_REG_UPDATE: + case CAM_ISP_HW_EVENT_REG_UPDATE: return "REG_UPDATE"; - case CAM_ISP_STATE_CHANGE_TRIGGER_EPOCH: + case CAM_ISP_HW_EVENT_EPOCH: return "EPOCH"; - case CAM_ISP_STATE_CHANGE_TRIGGER_EOF: + case CAM_ISP_HW_EVENT_EOF: return "EOF"; - case CAM_ISP_STATE_CHANGE_TRIGGER_DONE: + case CAM_ISP_HW_EVENT_DONE: return "DONE"; default: return "CAM_ISP_EVENT_INVALID"; @@ -97,29 +105,58 @@ static const char *__cam_isp_hw_evt_val_to_type( } static void __cam_isp_ctx_dump_state_monitor_array( - struct cam_isp_context *ctx_isp) + struct cam_isp_context *ctx_isp, bool log_rate_limit) { int i = 0; uint64_t state_head = 0; uint64_t index; + struct cam_isp_context_state_monitor *ctx_monitor; state_head = atomic64_read(&ctx_isp->state_monitor_head); - CAM_ERR_RATE_LIMIT(CAM_ISP, - "Dumping state information for preceding requests"); + + ctx_monitor = ctx_isp->cam_isp_ctx_state_monitor; + + if (log_rate_limit) + CAM_INFO_RATE_LIMIT_CUSTOM(CAM_ISP, 5, 20, + "Dumping state information for preceding requests"); + else + CAM_INFO(CAM_ISP, + "Dumping state information for preceding requests"); for (i = CAM_ISP_CTX_STATE_MONITOR_MAX_ENTRIES - 1; i >= 0; i--) { index = (((state_head - i) + CAM_ISP_CTX_STATE_MONITOR_MAX_ENTRIES) % CAM_ISP_CTX_STATE_MONITOR_MAX_ENTRIES); - CAM_ERR_RATE_LIMIT(CAM_ISP, - "time[0x%llx] req_id[%u] state[%s] evt_type[%s]", - ctx_isp->cam_isp_ctx_state_monitor[index].evt_time_stamp, - ctx_isp->cam_isp_ctx_state_monitor[index].req_id, - __cam_isp_ctx_substate_val_to_type( - ctx_isp->cam_isp_ctx_state_monitor[index].curr_state), - __cam_isp_hw_evt_val_to_type( - ctx_isp->cam_isp_ctx_state_monitor[index].trigger)); + + if (log_rate_limit) { + CAM_INFO_RATE_LIMIT_CUSTOM(CAM_ISP, 5, 20, + "time[%lld] last reported req_id[%lld] frame id[%lld] applied id[%lld] current state[%s] next state[%s] hw_event[%s]", + ctx_monitor[index].evt_time_stamp, + ctx_monitor[index].last_reported_id, + ctx_monitor[index].frame_id, + ctx_monitor[index].last_applied_req_id, + __cam_isp_ctx_substate_val_to_type( + ctx_monitor[index].curr_state), + __cam_isp_ctx_substate_val_to_type( + ctx_monitor[index].next_state), + __cam_isp_hw_evt_val_to_type( + ctx_monitor[index].hw_event)); + + } else { + CAM_INFO(CAM_ISP, + "time[%lld] last reported req_id[%lld] frame id[%lld] applied id[%lld] current state[%s] next state[%s] hw_event[%s]", + ctx_monitor[index].evt_time_stamp, + ctx_monitor[index].last_reported_id, + ctx_monitor[index].frame_id, + ctx_monitor[index].last_applied_req_id, + __cam_isp_ctx_substate_val_to_type( + ctx_monitor[index].curr_state), + __cam_isp_ctx_substate_val_to_type( + ctx_monitor[index].next_state), + __cam_isp_hw_evt_val_to_type( + ctx_monitor[index].hw_event)); + } } } @@ -403,7 +440,7 @@ static int __cam_isp_ctx_handle_buf_done_in_activated_state( struct cam_context *ctx = ctx_isp->base; if (list_empty(&ctx->active_req_list)) { - CAM_DBG(CAM_ISP, "Buf done with no active request!"); + CAM_WARN(CAM_ISP, "Buf done with no active request!"); goto end; } @@ -508,6 +545,10 @@ static int __cam_isp_ctx_handle_buf_done_in_activated_state( CAM_DBG(CAM_REQ, "Move active request %lld to pending list(cnt = %d) [bubble recovery], ctx %u", req->request_id, ctx_isp->active_req_cnt, ctx->ctx_id); + __cam_isp_ctx_update_state_monitor_array(ctx_isp, + CAM_ISP_HW_EVENT_DONE, + ctx_isp->substate_activated, + ctx_isp->substate_activated); } else { list_del_init(&req->list); list_add_tail(&req->list, &ctx->free_req_list); @@ -515,12 +556,16 @@ static int __cam_isp_ctx_handle_buf_done_in_activated_state( CAM_DBG(CAM_REQ, "Move active request %lld to free list(cnt = %d) [all fences done], ctx %u", req->request_id, ctx_isp->active_req_cnt, ctx->ctx_id); + ctx_isp->req_info.last_bufdone_req_id = req->request_id; + ctx_isp->req_info.last_bufdone_time_stamp = + jiffies_to_msecs(jiffies); + __cam_isp_ctx_update_state_monitor_array(ctx_isp, + CAM_ISP_HW_EVENT_DONE, + ctx_isp->substate_activated, + ctx_isp->substate_activated); } end: - __cam_isp_ctx_update_state_monitor_array(ctx_isp, - CAM_ISP_STATE_CHANGE_TRIGGER_DONE, - ctx_isp->base->req_list->request_id); return rc; } @@ -665,9 +710,12 @@ static int __cam_isp_ctx_notify_sof_in_activated_state( } list_for_each_entry(req, &ctx->active_req_list, list) { - if (req->request_id > ctx_isp->reported_req_id) { + if (req->request_id > + ctx_isp->req_info.reported_req_id) { request_id = req->request_id; - ctx_isp->reported_req_id = request_id; + ctx_isp->req_info.reported_req_id = request_id; + ctx_isp->req_info.last_reported_id_time_stamp = + jiffies_to_msecs(jiffies); break; } } @@ -675,6 +723,17 @@ static int __cam_isp_ctx_notify_sof_in_activated_state( if (ctx_isp->substate_activated == CAM_ISP_CTX_ACTIVATED_BUBBLE) request_id = 0; + if (request_id && ctx_isp->req_info.reported_req_id && + ((request_id - ctx_isp->req_info.reported_req_id) > + 1)){ + CAM_INFO(CAM_ISP, + "ctx:%d curr req id: %lld last reported id:%lld", + ctx->ctx_id, request_id, + ctx_isp->req_info.reported_req_id); + + __cam_isp_ctx_dump_state_monitor_array(ctx_isp, true); + } + __cam_isp_ctx_send_sof_timestamp(ctx_isp, request_id, CAM_REQ_MGR_SOF_EVENT_SUCCESS); } else { @@ -742,8 +801,7 @@ static int __cam_isp_ctx_sof_in_activated_state( ctx_isp->frame_id++; ctx_isp->sof_timestamp_val = sof_event_data->timestamp; ctx_isp->boot_timestamp = sof_event_data->boot_time; - __cam_isp_ctx_update_state_monitor_array(ctx_isp, - CAM_ISP_STATE_CHANGE_TRIGGER_SOF, req->request_id); + CAM_DBG(CAM_ISP, "frame id: %lld time stamp:0x%llx, ctx %u", ctx_isp->frame_id, ctx_isp->sof_timestamp_val, ctx->ctx_id); @@ -778,11 +836,7 @@ static int __cam_isp_ctx_reg_upd_in_sof(struct cam_isp_context *ctx_isp, CAM_ERR(CAM_ISP, "receive rup in unexpected state"); } - if (req != NULL) { - __cam_isp_ctx_update_state_monitor_array(ctx_isp, - CAM_ISP_STATE_CHANGE_TRIGGER_REG_UPDATE, - req->request_id); - } + end: return rc; } @@ -800,7 +854,8 @@ static int __cam_isp_ctx_epoch_in_applied(struct cam_isp_context *ctx_isp, * If no wait req in epoch, this is an error case. * The recovery is to go back to sof state */ - CAM_ERR(CAM_ISP, "No wait request"); + CAM_ERR(CAM_ISP, "Ctx:%d No wait request", ctx->ctx_id); + __cam_isp_ctx_dump_state_monitor_array(ctx_isp, true); ctx_isp->substate_activated = CAM_ISP_CTX_ACTIVATED_SOF; /* Send SOF event as empty frame*/ @@ -815,7 +870,9 @@ static int __cam_isp_ctx_epoch_in_applied(struct cam_isp_context *ctx_isp, req_isp = (struct cam_isp_ctx_req *)req->req_priv; req_isp->bubble_detected = true; - CAM_DBG(CAM_ISP, "Report Bubble flag %d", req_isp->bubble_report); + CAM_INFO(CAM_ISP, "ctx:%d Report Bubble flag %d req id:%lld", + ctx->ctx_id, req_isp->bubble_report, req->request_id); + __cam_isp_ctx_dump_state_monitor_array(ctx_isp, true); if (req_isp->bubble_report && ctx->ctx_crm_intf && ctx->ctx_crm_intf->notify_err) { struct cam_req_mgr_error_notify notify; @@ -842,9 +899,11 @@ static int __cam_isp_ctx_epoch_in_applied(struct cam_isp_context *ctx_isp, list_del_init(&req->list); list_add_tail(&req->list, &ctx->active_req_list); - if (req->request_id > ctx_isp->reported_req_id) { + if (req->request_id > ctx_isp->req_info.reported_req_id) { request_id = req->request_id; - ctx_isp->reported_req_id = request_id; + ctx_isp->req_info.reported_req_id = request_id; + ctx_isp->req_info.last_reported_id_time_stamp = + jiffies_to_msecs(jiffies); } __cam_isp_ctx_send_sof_timestamp(ctx_isp, request_id, CAM_REQ_MGR_SOF_EVENT_ERROR); @@ -853,15 +912,7 @@ static int __cam_isp_ctx_epoch_in_applied(struct cam_isp_context *ctx_isp, CAM_DBG(CAM_ISP, "next substate %d", ctx_isp->substate_activated); end: - if (request_id == 0) { - req = list_last_entry(&ctx->active_req_list, - struct cam_ctx_request, list); - __cam_isp_ctx_update_state_monitor_array(ctx_isp, - CAM_ISP_STATE_CHANGE_TRIGGER_EPOCH, req->request_id); - } else { - __cam_isp_ctx_update_state_monitor_array(ctx_isp, - CAM_ISP_STATE_CHANGE_TRIGGER_EPOCH, request_id); - } + return 0; } @@ -884,7 +935,6 @@ static int __cam_isp_ctx_sof_in_epoch(struct cam_isp_context *ctx_isp, int rc = 0; struct cam_context *ctx = ctx_isp->base; struct cam_isp_hw_sof_event_data *sof_event_data = evt_data; - struct cam_ctx_request *req; if (!evt_data) { CAM_ERR(CAM_ISP, "in valid sof event data"); @@ -900,12 +950,6 @@ static int __cam_isp_ctx_sof_in_epoch(struct cam_isp_context *ctx_isp, else CAM_DBG(CAM_ISP, "Still need to wait for the buf done"); - req = list_last_entry(&ctx->active_req_list, - struct cam_ctx_request, list); - if (req) - __cam_isp_ctx_update_state_monitor_array(ctx_isp, - CAM_ISP_STATE_CHANGE_TRIGGER_SOF, - ctx->req_list->request_id); CAM_DBG(CAM_ISP, "next substate %d", ctx_isp->substate_activated); @@ -952,7 +996,8 @@ static int __cam_isp_ctx_epoch_in_bubble_applied( * If no pending req in epoch, this is an error case. * Just go back to the bubble state. */ - CAM_ERR(CAM_ISP, "No pending request."); + CAM_ERR(CAM_ISP, "ctx:%d No pending request.", ctx->ctx_id); + __cam_isp_ctx_dump_state_monitor_array(ctx_isp, true); __cam_isp_ctx_send_sof_timestamp(ctx_isp, request_id, CAM_REQ_MGR_SOF_EVENT_SUCCESS); @@ -964,6 +1009,9 @@ static int __cam_isp_ctx_epoch_in_bubble_applied( list); req_isp = (struct cam_isp_ctx_req *)req->req_priv; req_isp->bubble_detected = true; + CAM_INFO(CAM_ISP, "Ctx:%d Report Bubble flag %d req id:%lld", + ctx->ctx_id, req_isp->bubble_report, req->request_id); + __cam_isp_ctx_dump_state_monitor_array(ctx_isp, true); if (req_isp->bubble_report && ctx->ctx_crm_intf && ctx->ctx_crm_intf->notify_err) { @@ -992,9 +1040,11 @@ static int __cam_isp_ctx_epoch_in_bubble_applied( list_add_tail(&req->list, &ctx->active_req_list); if (!req_isp->bubble_report) { - if (req->request_id > ctx_isp->reported_req_id) { + if (req->request_id > ctx_isp->req_info.reported_req_id) { request_id = req->request_id; - ctx_isp->reported_req_id = request_id; + ctx_isp->req_info.reported_req_id = request_id; + ctx_isp->req_info.last_reported_id_time_stamp = + jiffies_to_msecs(jiffies); __cam_isp_ctx_send_sof_timestamp(ctx_isp, request_id, CAM_REQ_MGR_SOF_EVENT_ERROR); } else @@ -1007,11 +1057,7 @@ static int __cam_isp_ctx_epoch_in_bubble_applied( ctx_isp->substate_activated = CAM_ISP_CTX_ACTIVATED_BUBBLE; CAM_DBG(CAM_ISP, "next substate %d", ctx_isp->substate_activated); end: - req = list_last_entry(&ctx->active_req_list, struct cam_ctx_request, - list); - if (req) - __cam_isp_ctx_update_state_monitor_array(ctx_isp, - CAM_ISP_STATE_CHANGE_TRIGGER_EPOCH, req->request_id); + return 0; } @@ -1023,9 +1069,7 @@ static int __cam_isp_ctx_buf_done_in_bubble_applied( (struct cam_isp_hw_done_event_data *) evt_data; rc = __cam_isp_ctx_handle_buf_done_in_activated_state(ctx_isp, done, 1); - __cam_isp_ctx_update_state_monitor_array(ctx_isp, - CAM_ISP_STATE_CHANGE_TRIGGER_DONE, - ctx_isp->base->req_list->request_id); + return rc; } @@ -1083,9 +1127,6 @@ static int __cam_isp_ctx_handle_error(struct cam_isp_context *ctx_isp, if (error_event_data->enable_reg_dump) cam_isp_ctx_dump_req(req_isp); - __cam_isp_ctx_update_state_monitor_array(ctx_isp, - CAM_ISP_STATE_CHANGE_TRIGGER_ERROR, req_to_dump->request_id); - list_for_each_entry_safe(req, req_temp, &ctx->active_req_list, list) { req_isp = (struct cam_isp_ctx_req *) req->req_priv; @@ -1176,14 +1217,15 @@ move_to_pending: end: do { if (list_empty(&ctx->pending_req_list)) { - error_request_id = ctx_isp->last_applied_req_id + 1; + error_request_id = + ctx_isp->req_info.last_applied_req_id + 1; req_isp = NULL; break; } req = list_first_entry(&ctx->pending_req_list, struct cam_ctx_request, list); req_isp = (struct cam_isp_ctx_req *) req->req_priv; - error_request_id = ctx_isp->last_applied_req_id; + error_request_id = ctx_isp->req_info.last_applied_req_id; if (req_isp->bubble_report) { req_to_report = req; @@ -1201,7 +1243,8 @@ end: list_del_init(&req->list); list_add_tail(&req->list, &ctx->free_req_list); - } while (req->request_id < ctx_isp->last_applied_req_id); + } while (req->request_id < + ctx_isp->req_info.last_applied_req_id); if (ctx->ctx_crm_intf && ctx->ctx_crm_intf->notify_err) { notify.link_hdl = ctx->link_hdl; @@ -1240,8 +1283,8 @@ end: V4L_EVENT_CAM_REQ_MGR_EVENT)) CAM_ERR(CAM_ISP, "Error in notifying the error time for req id:%lld ctx %u", - ctx_isp->last_applied_req_id, - ctx->ctx_id); + ctx_isp->req_info.last_applied_req_id, + ctx->ctx_id); } ctx_isp->substate_activated = CAM_ISP_CTX_ACTIVATED_HW_ERROR; } else { @@ -1278,8 +1321,7 @@ static int __cam_isp_ctx_fs2_sof_in_sof_state( ctx_isp->frame_id++; ctx_isp->sof_timestamp_val = sof_event_data->timestamp; ctx_isp->boot_timestamp = sof_event_data->boot_time; - __cam_isp_ctx_update_state_monitor_array(ctx_isp, - CAM_ISP_STATE_CHANGE_TRIGGER_SOF, req->request_id); + CAM_DBG(CAM_ISP, "frame id: %lld time stamp:0x%llx", ctx_isp->frame_id, ctx_isp->sof_timestamp_val); @@ -1300,9 +1342,12 @@ static int __cam_isp_ctx_fs2_sof_in_sof_state( } list_for_each_entry(req, &ctx->active_req_list, list) { - if (req->request_id > ctx_isp->reported_req_id) { + if (req->request_id > + ctx_isp->req_info.reported_req_id) { request_id = req->request_id; - ctx_isp->reported_req_id = request_id; + ctx_isp->req_info.reported_req_id = request_id; + ctx_isp->req_info.last_reported_id_time_stamp = + jiffies_to_msecs(jiffies); break; } } @@ -1343,8 +1388,10 @@ static int __cam_isp_ctx_fs2_buf_done(struct cam_isp_context *ctx_isp, CAM_DBG(CAM_ISP, "No request, move to SOF"); ctx_isp->substate_activated = CAM_ISP_CTX_ACTIVATED_SOF; - if (ctx_isp->reported_req_id < curr_req_id) { - ctx_isp->reported_req_id = curr_req_id; + if (ctx_isp->req_info.reported_req_id < curr_req_id) { + ctx_isp->req_info.reported_req_id = curr_req_id; + ctx_isp->req_info.last_reported_id_time_stamp = + jiffies_to_msecs(jiffies); __cam_isp_ctx_send_sof_timestamp(ctx_isp, curr_req_id, CAM_REQ_MGR_SOF_EVENT_SUCCESS); @@ -1402,11 +1449,7 @@ static int __cam_isp_ctx_fs2_reg_upd_in_sof(struct cam_isp_context *ctx_isp, CAM_ERR(CAM_ISP, "receive rup in unexpected state"); } - if (req != NULL) { - __cam_isp_ctx_update_state_monitor_array(ctx_isp, - CAM_ISP_STATE_CHANGE_TRIGGER_REG_UPDATE, - req->request_id); - } + end: return rc; } @@ -1451,9 +1494,12 @@ static int __cam_isp_ctx_fs2_reg_upd_in_applied_state( if (ctx->ctx_crm_intf && ctx->ctx_crm_intf->notify_trigger && ctx_isp->active_req_cnt <= 2) { list_for_each_entry(req, &ctx->active_req_list, list) { - if (req->request_id > ctx_isp->reported_req_id) { + if (req->request_id > + ctx_isp->req_info.reported_req_id) { request_id = req->request_id; - ctx_isp->reported_req_id = request_id; + ctx_isp->req_info.reported_req_id = request_id; + ctx_isp->req_info.last_reported_id_time_stamp = + jiffies_to_msecs(jiffies); break; } } @@ -1478,11 +1524,7 @@ static int __cam_isp_ctx_fs2_reg_upd_in_applied_state( CAM_DBG(CAM_ISP, "next substate %d", ctx_isp->substate_activated); end: - if (req != NULL && !rc) { - __cam_isp_ctx_update_state_monitor_array(ctx_isp, - CAM_ISP_STATE_CHANGE_TRIGGER_EPOCH, - req->request_id); - } + return rc; } @@ -1729,19 +1771,19 @@ static int __cam_isp_ctx_apply_req_in_activated_state( } else { spin_lock_bh(&ctx->lock); ctx_isp->substate_activated = next_state; - ctx_isp->last_applied_req_id = apply->request_id; + ctx_isp->req_info.last_applied_req_id = + apply->request_id; + ctx_isp->req_info.last_applied_time_stamp = + jiffies_to_msecs(jiffies); list_del_init(&req->list); list_add_tail(&req->list, &ctx->wait_req_list); CAM_DBG(CAM_ISP, "new substate state %d, applied req %lld", - next_state, ctx_isp->last_applied_req_id); + next_state, + ctx_isp->req_info.last_applied_req_id); spin_unlock_bh(&ctx->lock); } end: - if (ctx_isp != NULL) { - __cam_isp_ctx_update_state_monitor_array(ctx_isp, - CAM_ISP_STATE_CHANGE_TRIGGER_SOF, - ctx->req_list->request_id); - } + return rc; } @@ -1875,6 +1917,23 @@ static int __cam_isp_ctx_flush_req_in_top_state( CAM_DBG(CAM_ISP, "try to flush pending list"); spin_lock_bh(&ctx->lock); rc = __cam_isp_ctx_flush_req(ctx, &ctx->pending_req_list, flush_req); + + if (!list_empty(&ctx->active_req_list)) { + CAM_INFO_RATE_LIMIT_CUSTOM(CAM_ISP, 5, 20, + "ctx:%d last applied id:%lld, reported req id:%lld, buf done id:%lld", + ctx->ctx_id, + ctx_isp->req_info.last_applied_req_id, + ctx_isp->req_info.reported_req_id, + ctx_isp->req_info.last_bufdone_req_id); + CAM_INFO_RATE_LIMIT_CUSTOM(CAM_ISP, 5, 20, + "current time:%u last apply time:%lld, reported req time:%lld, buf done time:%lld", + jiffies_to_msecs(jiffies), + ctx_isp->req_info.last_applied_time_stamp, + ctx_isp->req_info.last_reported_id_time_stamp, + ctx_isp->req_info.last_bufdone_time_stamp); + + __cam_isp_ctx_dump_state_monitor_array(ctx_isp, true); + } spin_unlock_bh(&ctx->lock); atomic_set(&ctx_isp->process_bubble, 0); @@ -2133,8 +2192,10 @@ static int __cam_isp_ctx_rdi_only_sof_in_bubble_applied( list); req_isp = (struct cam_isp_ctx_req *)req->req_priv; req_isp->bubble_detected = true; + CAM_INFO(CAM_ISP, "Ctx:%d Report Bubble flag %d req id:%lld", + ctx->ctx_id, req_isp->bubble_report, req->request_id); + __cam_isp_ctx_dump_state_monitor_array(ctx_isp, true); - CAM_DBG(CAM_ISP, "Report Bubble flag %d", req_isp->bubble_report); if (req_isp->bubble_report && ctx->ctx_crm_intf && ctx->ctx_crm_intf->notify_err) { struct cam_req_mgr_error_notify notify; @@ -2161,9 +2222,11 @@ static int __cam_isp_ctx_rdi_only_sof_in_bubble_applied( req->request_id, ctx_isp->active_req_cnt); if (!req_isp->bubble_report) { - if (req->request_id > ctx_isp->reported_req_id) { + if (req->request_id > ctx_isp->req_info.reported_req_id) { request_id = req->request_id; - ctx_isp->reported_req_id = request_id; + ctx_isp->req_info.reported_req_id = request_id; + ctx_isp->req_info.last_reported_id_time_stamp = + jiffies_to_msecs(jiffies); __cam_isp_ctx_send_sof_timestamp(ctx_isp, request_id, CAM_REQ_MGR_SOF_EVENT_ERROR); } else @@ -2305,8 +2368,11 @@ static int __cam_isp_ctx_rdi_only_reg_upd_in_bubble_applied_state( } else { CAM_ERR(CAM_ISP, "Can not notify SOF to CRM"); } - if (request_id) - ctx_isp->reported_req_id = request_id; + if (request_id) { + ctx_isp->req_info.reported_req_id = request_id; + ctx_isp->req_info.last_reported_id_time_stamp = + jiffies_to_msecs(jiffies); + } __cam_isp_ctx_send_sof_timestamp(ctx_isp, request_id, CAM_REQ_MGR_SOF_EVENT_SUCCESS); @@ -2481,9 +2547,14 @@ static int __cam_isp_ctx_release_hw_in_top_state(struct cam_context *ctx, ctx->last_flush_req = 0; ctx_isp->frame_id = 0; ctx_isp->active_req_cnt = 0; - ctx_isp->reported_req_id = 0; ctx_isp->hw_acquired = false; ctx_isp->init_received = false; + ctx_isp->req_info.reported_req_id = 0; + ctx_isp->req_info.last_applied_req_id = 0; + ctx_isp->req_info.last_bufdone_req_id = 0; + ctx_isp->req_info.last_applied_time_stamp = 0; + ctx_isp->req_info.last_bufdone_time_stamp = 0; + ctx_isp->req_info.last_reported_id_time_stamp = 0; /* * Ideally, we should never have any active request here. @@ -2538,11 +2609,16 @@ static int __cam_isp_ctx_release_dev_in_top_state(struct cam_context *ctx, ctx->last_flush_req = 0; ctx_isp->frame_id = 0; ctx_isp->active_req_cnt = 0; - ctx_isp->reported_req_id = 0; ctx_isp->hw_acquired = false; ctx_isp->init_received = false; ctx_isp->rdi_only_context = false; ctx_isp->split_acquire = false; + ctx_isp->req_info.reported_req_id = 0; + ctx_isp->req_info.last_applied_req_id = 0; + ctx_isp->req_info.last_bufdone_req_id = 0; + ctx_isp->req_info.last_applied_time_stamp = 0; + ctx_isp->req_info.last_bufdone_time_stamp = 0; + ctx_isp->req_info.last_reported_id_time_stamp = 0; /* * Ideally, we should never have any active request here. @@ -3169,7 +3245,7 @@ static int __cam_isp_ctx_start_dev_in_ready(struct cam_context *ctx, atomic_set(&ctx_isp->process_bubble, 0); ctx_isp->frame_id = 0; ctx_isp->active_req_cnt = 0; - ctx_isp->reported_req_id = 0; + ctx_isp->req_info.reported_req_id = 0; ctx_isp->substate_activated = ctx_isp->rdi_only_context ? CAM_ISP_CTX_ACTIVATED_APPLIED : (req_isp->num_fence_map_out) ? CAM_ISP_CTX_ACTIVATED_EPOCH : @@ -3301,7 +3377,13 @@ static int __cam_isp_ctx_stop_dev_in_activated_unlock( } ctx_isp->frame_id = 0; ctx_isp->active_req_cnt = 0; - ctx_isp->reported_req_id = 0; + ctx_isp->req_info.reported_req_id = 0; + ctx_isp->req_info.last_applied_req_id = 0; + ctx_isp->req_info.last_bufdone_req_id = 0; + ctx_isp->req_info.last_applied_time_stamp = 0; + ctx_isp->req_info.last_bufdone_time_stamp = 0; + ctx_isp->req_info.last_reported_id_time_stamp = 0; + atomic_set(&ctx_isp->process_bubble, 0); CAM_DBG(CAM_ISP, "Stop device success next state %d on ctx %u", @@ -3478,8 +3560,9 @@ static int __cam_isp_ctx_apply_req(struct cam_context *ctx, rc = ctx_ops->crm_ops.apply_req(ctx, apply); } else { CAM_ERR_RATE_LIMIT(CAM_ISP, - "No handle function in activated substate %d", - ctx_isp->substate_activated); + "Ctx:%d No handle function in activated substate %d", + ctx->ctx_id, ctx_isp->substate_activated); + __cam_isp_ctx_dump_state_monitor_array(ctx_isp, true); rc = -EFAULT; } @@ -3500,22 +3583,27 @@ static int __cam_isp_ctx_handle_irq_in_activated(void *context, struct cam_context *ctx = (struct cam_context *)context; struct cam_isp_context *ctx_isp = (struct cam_isp_context *)ctx->ctx_priv; + enum cam_isp_ctx_activated_substate curr_state; spin_lock(&ctx->lock); trace_cam_isp_activated_irq(ctx, ctx_isp->substate_activated, evt_id, __cam_isp_ctx_get_event_ts(evt_id, evt_data)); + curr_state = ctx_isp->substate_activated; CAM_DBG(CAM_ISP, "Enter: State %d, Substate %d, evt id %d", ctx->state, ctx_isp->substate_activated, evt_id); irq_ops = &ctx_isp->substate_machine_irq[ctx_isp->substate_activated]; if (irq_ops->irq_ops[evt_id]) { rc = irq_ops->irq_ops[evt_id](ctx_isp, evt_data); } else { - CAM_DBG(CAM_ISP, "No handle function for substate %d", - ctx_isp->substate_activated); - __cam_isp_ctx_dump_state_monitor_array(ctx_isp); + CAM_INFO(CAM_ISP, "Ctx:%d No handle function for substate %d", + ctx->ctx_id, ctx_isp->substate_activated); + __cam_isp_ctx_dump_state_monitor_array(ctx_isp, true); } + if (evt_id != CAM_ISP_HW_EVENT_DONE) + __cam_isp_ctx_update_state_monitor_array(ctx_isp, evt_id, + curr_state, ctx_isp->substate_activated); CAM_DBG(CAM_ISP, "Exit: State %d Substate %d", ctx->state, ctx_isp->substate_activated); @@ -3677,7 +3765,13 @@ int cam_isp_context_init(struct cam_isp_context *ctx, ctx->base = ctx_base; ctx->frame_id = 0; ctx->active_req_cnt = 0; - ctx->reported_req_id = 0; + ctx->req_info.reported_req_id = 0; + ctx->req_info.last_applied_req_id = 0; + ctx->req_info.last_bufdone_req_id = 0; + ctx->req_info.last_applied_time_stamp = 0; + ctx->req_info.last_bufdone_time_stamp = 0; + ctx->req_info.last_reported_id_time_stamp = 0; + ctx->hw_ctx = NULL; ctx->substate_activated = CAM_ISP_CTX_ACTIVATED_SOF; ctx->substate_machine = cam_isp_ctx_activated_state_machine; diff --git a/drivers/media/platform/msm/camera_v3/cam_isp/cam_isp_context.h b/drivers/media/platform/msm/camera_v3/cam_isp/cam_isp_context.h index 4954f2034144..bec84a85391c 100644 --- a/drivers/media/platform/msm/camera_v3/cam_isp/cam_isp_context.h +++ b/drivers/media/platform/msm/camera_v3/cam_isp/cam_isp_context.h @@ -62,20 +62,6 @@ enum cam_isp_ctx_activated_substate { }; /** - * enum cam_isp_state_change_trigger - Different types of ISP events - * - */ -enum cam_isp_state_change_trigger { - CAM_ISP_STATE_CHANGE_TRIGGER_ERROR, - CAM_ISP_STATE_CHANGE_TRIGGER_SOF, - CAM_ISP_STATE_CHANGE_TRIGGER_REG_UPDATE, - CAM_ISP_STATE_CHANGE_TRIGGER_EPOCH, - CAM_ISP_STATE_CHANGE_TRIGGER_EOF, - CAM_ISP_STATE_CHANGE_TRIGGER_DONE, - CAM_ISP_STATE_CHANGE_TRIGGER_MAX -}; - -/** * struct cam_isp_ctx_irq_ops - Function table for handling IRQ callbacks * * @irq_ops: Array of handle function pointers. @@ -125,20 +111,47 @@ struct cam_isp_ctx_req { * debug purposes * *@curr_state: Current sub state that received req - *@req_type: Event type of incoming req - *@req_id: Request id - *@evt_time_stamp Current time stamp + *@next_state: Next sub state that received req + *@hw_event: Hw Event type of incoming req + *@last_reported_id: Last_reported_id to userspace + *@last_applied_req_id Last applied request id to hardware + *@frame_id: Current Frame id + *@evt_time_stamp Current time stamp of this event logged * */ struct cam_isp_context_state_monitor { enum cam_isp_ctx_activated_substate curr_state; - enum cam_isp_state_change_trigger trigger; - uint32_t req_id; + enum cam_isp_ctx_activated_substate next_state; + enum cam_isp_hw_event_type hw_event; + int64_t last_reported_id; + int64_t last_applied_req_id; int64_t frame_id; uint64_t evt_time_stamp; }; /** + * struct cam_isp_context_req_id_info - ISP context request id + * information for last applied, reported and bufdone. + * + *@last_applied_req_id: Last applied request id + *@last_bufdone_req_id: Last bufdone request id + *@reported_req_id: Last reported request id to userspace + *@last_applied_time_stamp: Last applied request time stamp information + *@last_bufdone_time_stamp Last bufdone request time stamp information + *@last_reported_id_time_stamp: Last reported request time stamp information + * + */ + +struct cam_isp_context_req_id_info { + int64_t last_applied_req_id; + int64_t last_bufdone_req_id; + int64_t reported_req_id; + int64_t last_applied_time_stamp; + int64_t last_bufdone_time_stamp; + int64_t last_reported_id_time_stamp; + +}; +/** * struct cam_isp_context - ISP context object * * @base: Common context object pointer @@ -154,11 +167,11 @@ struct cam_isp_context_state_monitor { * @sof_timestamp_val: Captured time stamp value at sof hw event * @boot_timestamp: Boot time stamp for a given req_id * @active_req_cnt: Counter for the active request - * @reported_req_id: Last reported request id * @subscribe_event: The irq event mask that CRM subscribes to, IFE * will invoke CRM cb at those event. - * @last_applied_req_id: Last applied request id * @state_monitor_head: Write index to the state monitoring array + * @req_info Request id information about last applied, + * reported and buf done * @cam_isp_ctx_state_monitor: State monitoring array * @rdi_only_context: Get context type information. * true, if context is rdi only context @@ -183,12 +196,11 @@ struct cam_isp_context { uint64_t sof_timestamp_val; uint64_t boot_timestamp; int32_t active_req_cnt; - int64_t reported_req_id; uint32_t subscribe_event; - int64_t last_applied_req_id; atomic64_t state_monitor_head; struct cam_isp_context_state_monitor cam_isp_ctx_state_monitor[ CAM_ISP_CTX_STATE_MONITOR_MAX_ENTRIES]; + struct cam_isp_context_req_id_info req_info; bool rdi_only_context; bool hw_acquired; bool init_received; diff --git a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c index fe3d2f12a6e2..9b4839261c3e 100644 --- a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c +++ b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c @@ -2637,7 +2637,7 @@ static int cam_ife_mgr_stop_hw(void *hw_mgr_priv, void *stop_hw_args) /* Stop the master CSID path first */ cam_ife_mgr_csid_stop_hw(ctx, &ctx->res_list_ife_csid, - master_base_idx, CAM_CSID_HALT_AT_FRAME_BOUNDARY); + master_base_idx, csid_halt_type); /* stop rest of the CSID paths */ for (i = 0; i < ctx->num_base; i++) { @@ -2647,7 +2647,7 @@ static int cam_ife_mgr_stop_hw(void *hw_mgr_priv, void *stop_hw_args) ctx->base[i].idx, i, master_base_idx); cam_ife_mgr_csid_stop_hw(ctx, &ctx->res_list_ife_csid, - ctx->base[i].idx, CAM_CSID_HALT_AT_FRAME_BOUNDARY); + ctx->base[i].idx, csid_halt_type); } CAM_DBG(CAM_ISP, "Stopping master CID idx %d", master_base_idx); diff --git a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/hw_utils/cam_isp_packet_parser.c b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/hw_utils/cam_isp_packet_parser.c index 0b3c3874a704..5efab9f289dd 100644 --- a/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/hw_utils/cam_isp_packet_parser.c +++ b/drivers/media/platform/msm/camera_v3/cam_isp/isp_hw_mgr/hw_utils/cam_isp_packet_parser.c @@ -467,6 +467,7 @@ int cam_isp_add_io_buffers( int32_t hdl; int mmu_hdl; bool mode, is_buf_secure; + uint64_t req_id; io_cfg = (struct cam_buf_io_cfg *) ((uint8_t *) &prepare->packet->payload + @@ -475,6 +476,7 @@ int cam_isp_add_io_buffers( num_in_buf = 0; io_cfg_used_bytes = 0; prepare->pf_data->packet = prepare->packet; + req_id = prepare->packet->header.request_id; /* Max one hw entries required for each base */ if (prepare->num_hw_update_entries + 1 >= @@ -622,6 +624,23 @@ int cam_isp_add_io_buffers( return rc; } + if (j == 0) { + rc = cam_packet_validate_plane_size( + &io_cfg[i], + plane_id, + size); + if (rc) { + CAM_ERR(CAM_ISP, + "Invalid buffer size, port 0x%x plane %d req_id %llu format %d memh 0x%x", + io_cfg[i].resource_type, + plane_id, + req_id, + io_cfg[i].format, + io_cfg[i].mem_handle[plane_id]); + return -EINVAL; + } + } + /* need to update with offset */ io_addr[plane_id] += io_cfg[i].offsets[plane_id]; diff --git a/drivers/media/platform/msm/camera_v3/cam_jpeg/jpeg_hw/jpeg_enc_hw/jpeg_enc_core.c b/drivers/media/platform/msm/camera_v3/cam_jpeg/jpeg_hw/jpeg_enc_hw/jpeg_enc_core.c index 52907cd6803e..225f859674f1 100644 --- a/drivers/media/platform/msm/camera_v3/cam_jpeg/jpeg_hw/jpeg_enc_hw/jpeg_enc_core.c +++ b/drivers/media/platform/msm/camera_v3/cam_jpeg/jpeg_hw/jpeg_enc_hw/jpeg_enc_core.c @@ -91,6 +91,9 @@ int cam_jpeg_enc_init_hw(void *device_priv, CAM_ERR(CAM_JPEG, "soc enable is failed %d", rc); goto soc_failed; } + spin_lock(&jpeg_enc_dev->hw_lock); + jpeg_enc_dev->hw_state = CAM_HW_STATE_POWER_UP; + spin_unlock(&jpeg_enc_dev->hw_lock); mutex_unlock(&core_info->core_mutex); @@ -140,6 +143,9 @@ int cam_jpeg_enc_deinit_hw(void *device_priv, return -EFAULT; } + spin_lock(&jpeg_enc_dev->hw_lock); + jpeg_enc_dev->hw_state = CAM_HW_STATE_POWER_DOWN; + spin_unlock(&jpeg_enc_dev->hw_lock); rc = cam_jpeg_enc_disable_soc_resources(soc_info); if (rc) CAM_ERR(CAM_JPEG, "soc disable failed %d", rc); @@ -173,12 +179,19 @@ irqreturn_t cam_jpeg_enc_irq(int irq_num, void *data) hw_info = core_info->jpeg_enc_hw_info; mem_base = soc_info->reg_map[0].mem_base; + spin_lock(&jpeg_enc_dev->hw_lock); + if (jpeg_enc_dev->hw_state == CAM_HW_STATE_POWER_DOWN) { + CAM_ERR(CAM_JPEG, "JPEG HW is in off state"); + spin_unlock(&jpeg_enc_dev->hw_lock); + return -EINVAL; + } irq_status = cam_io_r_mb(mem_base + core_info->jpeg_enc_hw_info->reg_offset.int_status); cam_io_w_mb(irq_status, soc_info->reg_map[0].mem_base + core_info->jpeg_enc_hw_info->reg_offset.int_clr); + spin_unlock(&jpeg_enc_dev->hw_lock); CAM_DBG(CAM_JPEG, "irq_num %d irq_status = %x , core_state %d", irq_num, irq_status, core_info->core_state); @@ -268,6 +281,12 @@ int cam_jpeg_enc_reset_hw(void *data, mutex_lock(&core_info->core_mutex); spin_lock(&jpeg_enc_dev->hw_lock); + if (jpeg_enc_dev->hw_state == CAM_HW_STATE_POWER_DOWN) { + CAM_ERR(CAM_JPEG, "JPEG HW is in off state"); + spin_unlock(&jpeg_enc_dev->hw_lock); + mutex_unlock(&core_info->core_mutex); + return -EINVAL; + } if (core_info->core_state == CAM_JPEG_ENC_CORE_RESETTING) { CAM_ERR(CAM_JPEG, "alrady resetting"); spin_unlock(&jpeg_enc_dev->hw_lock); @@ -319,10 +338,18 @@ int cam_jpeg_enc_start_hw(void *data, hw_info = core_info->jpeg_enc_hw_info; mem_base = soc_info->reg_map[0].mem_base; + spin_lock(&jpeg_enc_dev->hw_lock); + if (jpeg_enc_dev->hw_state == CAM_HW_STATE_POWER_DOWN) { + CAM_ERR(CAM_JPEG, "JPEG HW is in off state"); + spin_unlock(&jpeg_enc_dev->hw_lock); + return -EINVAL; + } if (core_info->core_state != CAM_JPEG_ENC_CORE_READY) { CAM_ERR(CAM_JPEG, "Error not ready"); + spin_unlock(&jpeg_enc_dev->hw_lock); return -EINVAL; } + spin_unlock(&jpeg_enc_dev->hw_lock); cam_io_w_mb(hw_info->reg_val.hw_cmd_start, mem_base + hw_info->reg_offset.hw_cmd); @@ -352,6 +379,12 @@ int cam_jpeg_enc_stop_hw(void *data, mutex_lock(&core_info->core_mutex); spin_lock(&jpeg_enc_dev->hw_lock); + if (jpeg_enc_dev->hw_state == CAM_HW_STATE_POWER_DOWN) { + CAM_ERR(CAM_JPEG, "JPEG HW is in off state"); + spin_unlock(&jpeg_enc_dev->hw_lock); + mutex_unlock(&core_info->core_mutex); + return -EINVAL; + } if (core_info->core_state == CAM_JPEG_ENC_CORE_ABORTING) { CAM_ERR(CAM_JPEG, "alrady stopping"); spin_unlock(&jpeg_enc_dev->hw_lock); diff --git a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_sensor/cam_sensor_core.c b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_sensor/cam_sensor_core.c index a2a738d85714..94bc611a9120 100644 --- a/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_sensor/cam_sensor_core.c +++ b/drivers/media/platform/msm/camera_v3/cam_sensor_module/cam_sensor/cam_sensor_core.c @@ -927,6 +927,16 @@ int32_t cam_sensor_driver_cmd(struct cam_sensor_ctrl_t *s_ctrl, } break; case CAM_CONFIG_DEV: { + if (s_ctrl->sensor_state < CAM_SENSOR_ACQUIRE) { + rc = -EINVAL; + CAM_ERR(CAM_SENSOR, + "sensor_id:[0x%x] not acquired to configure [%d] ", + s_ctrl->sensordata->slave_info.sensor_id, + s_ctrl->sensor_state + ); + goto release_mutex; + } + rc = cam_sensor_i2c_pkt_parse(s_ctrl, arg); if (rc < 0) { CAM_ERR(CAM_SENSOR, "Failed i2c pkt parse: %d", rc); diff --git a/drivers/media/platform/msm/camera_v3/cam_smmu/cam_smmu_api.c b/drivers/media/platform/msm/camera_v3/cam_smmu/cam_smmu_api.c index 626473f8769a..77a7204cfe55 100644 --- a/drivers/media/platform/msm/camera_v3/cam_smmu/cam_smmu_api.c +++ b/drivers/media/platform/msm/camera_v3/cam_smmu/cam_smmu_api.c @@ -191,7 +191,7 @@ static struct cam_iommu_cb_set iommu_cb_set; static struct dentry *smmu_dentry; -static bool smmu_fatal_flag; +static bool smmu_fatal_flag = true; static enum dma_data_direction cam_smmu_translate_dir( enum cam_smmu_map_dir dir); diff --git a/drivers/media/platform/msm/camera_v3/cam_sync/cam_sync.c b/drivers/media/platform/msm/camera_v3/cam_sync/cam_sync.c index d4487efbf090..93d39e3c360a 100644 --- a/drivers/media/platform/msm/camera_v3/cam_sync/cam_sync.c +++ b/drivers/media/platform/msm/camera_v3/cam_sync/cam_sync.c @@ -288,6 +288,7 @@ int cam_sync_merge(int32_t *sync_obj, uint32_t num_objs, int32_t *merged_obj) int rc; long idx = 0; bool bit; + int i = 0; if (!sync_obj || !merged_obj) { CAM_ERR(CAM_SYNC, "Invalid pointer(s)"); @@ -305,6 +306,14 @@ int cam_sync_merge(int32_t *sync_obj, uint32_t num_objs, int32_t *merged_obj) return -EINVAL; } + for (i = 0; i < num_objs; i++) { + rc = cam_sync_check_valid(sync_obj[i]); + if (rc) { + CAM_ERR(CAM_SYNC, "Sync_obj[%d] %d valid check fail", + i, sync_obj[i]); + return rc; + } + } do { idx = find_first_zero_bit(sync_dev->bitmap, CAM_SYNC_MAX_OBJS); if (idx >= CAM_SYNC_MAX_OBJS) @@ -376,6 +385,29 @@ int cam_sync_destroy(int32_t sync_obj) return cam_sync_deinit_object(sync_dev->sync_table, sync_obj); } +int cam_sync_check_valid(int32_t sync_obj) +{ + struct sync_table_row *row = NULL; + + if (sync_obj >= CAM_SYNC_MAX_OBJS || sync_obj <= 0) + return -EINVAL; + + row = sync_dev->sync_table + sync_obj; + + if (!test_bit(sync_obj, sync_dev->bitmap)) { + CAM_ERR(CAM_SYNC, "Error: Released sync obj received %d", + sync_obj); + return -EINVAL; + } + + if (row->state == CAM_SYNC_STATE_INVALID) { + CAM_ERR(CAM_SYNC, + "Error: accessing an uninitialized sync obj = %d", + sync_obj); + return -EINVAL; + } + return 0; +} int cam_sync_wait(int32_t sync_obj, uint64_t timeout_ms) { unsigned long timeleft; diff --git a/drivers/media/platform/msm/camera_v3/cam_sync/cam_sync_api.h b/drivers/media/platform/msm/camera_v3/cam_sync/cam_sync_api.h index c735d51fe462..f2f67cb3eb7b 100644 --- a/drivers/media/platform/msm/camera_v3/cam_sync/cam_sync_api.h +++ b/drivers/media/platform/msm/camera_v3/cam_sync/cam_sync_api.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -147,5 +147,14 @@ int cam_sync_destroy(int32_t sync_obj); */ int cam_sync_wait(int32_t sync_obj, uint64_t timeout_ms); +/** + * @brief: Check if sync object is valid + * + * @param sync_obj: int referencing the sync object to be checked + * + * @return 0 upon success, -EINVAL if sync object is in bad state or arguments + * are invalid + */ +int cam_sync_check_valid(int32_t sync_obj); #endif /* __CAM_SYNC_API_H__ */ diff --git a/drivers/media/platform/msm/camera_v3/cam_utils/cam_packet_util.c b/drivers/media/platform/msm/camera_v3/cam_utils/cam_packet_util.c index 0f910c9e8273..3708c212d57b 100644 --- a/drivers/media/platform/msm/camera_v3/cam_utils/cam_packet_util.c +++ b/drivers/media/platform/msm/camera_v3/cam_utils/cam_packet_util.c @@ -353,3 +353,115 @@ rel_cmd_buf: return rc; } + +int32_t cam_packet_validate_plane_size( + struct cam_buf_io_cfg *io_cfg, + int plane_index, + size_t size) +{ + int rc = 0; + uint32_t kmd_plane_size = 0; + uint32_t plane_stride = 0; + uint32_t slice_height = 0; + uint32_t metadata_size = 0; + uint32_t format = io_cfg->format; + uint32_t plane_pixel_size = 0; + + if (plane_index < CAM_PACKET_MAX_PLANES) { + plane_stride = io_cfg->planes[plane_index].plane_stride; + slice_height = io_cfg->planes[plane_index].slice_height; + } + + if (!(plane_stride && slice_height)) { + CAM_ERR(CAM_ISP, + "Invalid values from UMD stride %d, slice height %d", + plane_stride, + slice_height); + return -EINVAL; + } + + switch (format) { + case CAM_FORMAT_MIPI_RAW_6: + case CAM_FORMAT_MIPI_RAW_8: + kmd_plane_size = ((plane_stride * slice_height) + 16 - 1) + / 16 * 16; + break; + case CAM_FORMAT_MIPI_RAW_10: + if (plane_stride % 4 == 0) + kmd_plane_size = ((plane_stride * slice_height) + + 16 - 1) / 16 * 16; + break; + case CAM_FORMAT_MIPI_RAW_12: + if (plane_stride % 2 == 0) + kmd_plane_size = ((plane_stride * slice_height) + + 16 - 1) / 16 * 16; + break; + case CAM_FORMAT_MIPI_RAW_14: + if (plane_stride % 4 == 0) + kmd_plane_size = plane_stride * slice_height * 7 / 4; + break; + case CAM_FORMAT_PLAIN16_8: + case CAM_FORMAT_PLAIN16_10: + case CAM_FORMAT_PLAIN16_12: + case CAM_FORMAT_PLAIN16_14: + case CAM_FORMAT_PLAIN16_16: + case CAM_FORMAT_PLAIN64: + kmd_plane_size = plane_stride * slice_height; + break; + case CAM_FORMAT_NV21: + case CAM_FORMAT_NV12: + if (plane_index < CAM_PACKET_MAX_PLANES) + kmd_plane_size = plane_stride * slice_height; + break; + case CAM_FORMAT_PD10: + if (plane_index < CAM_PACKET_MAX_PLANES) + kmd_plane_size = plane_stride * slice_height; + break; + case CAM_FORMAT_UBWC_NV12: + case CAM_FORMAT_UBWC_NV12_4R: + case CAM_FORMAT_UBWC_TP10: + metadata_size = io_cfg->planes[plane_index].meta_size; + plane_pixel_size = ((plane_stride * slice_height) + + (4096 - 1)) & ~((uint32_t) 4096 - 1); + kmd_plane_size = metadata_size + plane_pixel_size; + break; + case CAM_FORMAT_UBWC_P010: + case CAM_FORMAT_PLAIN32_20: + case CAM_FORMAT_TP10: + case CAM_FORMAT_YUV422: + case CAM_FORMAT_PD8: + case CAM_FORMAT_PLAIN128: + case CAM_FORMAT_ARGB: + case CAM_FORMAT_ARGB_10: + case CAM_FORMAT_ARGB_12: + case CAM_FORMAT_ARGB_14: + case CAM_FORMAT_MIPI_RAW_16: + case CAM_FORMAT_MIPI_RAW_20: + case CAM_FORMAT_QTI_RAW_8: + case CAM_FORMAT_QTI_RAW_10: + case CAM_FORMAT_QTI_RAW_12: + case CAM_FORMAT_QTI_RAW_14: + case CAM_FORMAT_PLAIN8: + case CAM_FORMAT_PLAIN8_SWAP: + case CAM_FORMAT_PLAIN8_10: + case CAM_FORMAT_PLAIN8_10_SWAP: + kmd_plane_size = plane_stride * slice_height; + break; + default: + kmd_plane_size = plane_stride * slice_height; + break; + } + if (!kmd_plane_size || + kmd_plane_size > (size - io_cfg->offsets[plane_index])) { + CAM_ERR(CAM_ISP, + "kmd size: %d umd size: %zu width: %d height: %d stride: %d sliceheight: %d ", + kmd_plane_size, + size, + io_cfg->planes[plane_index].width, + io_cfg->planes[plane_index].height, + plane_stride, + slice_height); + return -EINVAL; + } + return rc; +} diff --git a/drivers/media/platform/msm/camera_v3/cam_utils/cam_packet_util.h b/drivers/media/platform/msm/camera_v3/cam_utils/cam_packet_util.h index 33c07ad89f4e..e49968e6a291 100644 --- a/drivers/media/platform/msm/camera_v3/cam_utils/cam_packet_util.h +++ b/drivers/media/platform/msm/camera_v3/cam_utils/cam_packet_util.h @@ -135,4 +135,20 @@ int cam_packet_util_process_generic_cmd_buffer( struct cam_cmd_buf_desc *cmd_buf, cam_packet_generic_blob_handler blob_handler_cb, void *user_data); +/** + * cam_packet_validate_plane_size() + * + * @brief: Utility function to calculate and validate size of buffer + * required for a format. + * @io_cfg: Contains IO config info + * @plane_index Plane index for which size is to be calculated + * + * @return: Size of buffer + * + */ +int32_t cam_packet_validate_plane_size( + struct cam_buf_io_cfg *io_cfg, + int plane_index, + size_t size); + #endif /* _CAM_PACKET_UTIL_H_ */ |