Merge "Merge remote-tracking branch 'dev/msm-4.14' into msm-4.9 07/03"

This commit is contained in:
Linux Build Service Account 2019-08-09 12:36:50 -07:00 committed by Gerrit - the friendly Code Review server
commit 62ad3e5bc0
13 changed files with 503 additions and 149 deletions

View File

@ -461,6 +461,17 @@ int32_t cam_context_prepare_dev_to_hw(struct cam_context *ctx,
"[%s][%d] : Moving req[%llu] from free_list to pending_list", "[%s][%d] : Moving req[%llu] from free_list to pending_list",
ctx->dev_name, ctx->ctx_id, req->request_id); 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++) { for (j = 0; j < req->num_in_map_entries; j++) {
cam_context_getref(ctx); cam_context_getref(ctx);
rc = cam_sync_register_callback( rc = cam_sync_register_callback(
@ -482,7 +493,9 @@ int32_t cam_context_prepare_dev_to_hw(struct cam_context *ctx,
ctx->dev_name, ctx->ctx_id, ctx->dev_name, ctx->ctx_id,
req->request_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", CAM_DBG(CAM_CTXT, "register in fence cb: %d ret = %d",
req->in_map_entries[j].sync_id, rc); 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; return rc;
put_ctx_ref:
for (--j; j >= 0; j--)
cam_context_putref(ctx);
put_ref: put_ref:
for (--i; i >= 0; i--) { for (--i; i >= 0; i--) {
rc = cam_sync_put_obj_ref(req->out_map_entries[i].sync_id); rc = cam_sync_put_obj_ref(req->out_map_entries[i].sync_id);

View File

@ -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, rc = cam_common_util_get_string_index(soc_private->client_name,
soc_private->num_clients, client_name, &client_indx); 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]); mutex_lock(&cpas_core->client_mutex[client_indx]);
if (rc || !CAM_CPAS_CLIENT_VALID(client_indx) || if (rc || !CAM_CPAS_CLIENT_VALID(client_indx) ||

View File

@ -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( static void __cam_isp_ctx_update_state_monitor_array(
struct cam_isp_context *ctx_isp, struct cam_isp_context *ctx_isp,
enum cam_isp_state_change_trigger trigger_type, enum cam_isp_hw_event_type hw_event,
uint32_t req_id) enum cam_isp_ctx_activated_substate curr_state,
enum cam_isp_ctx_activated_substate next_state)
{ {
int iterator = 0; int iterator = 0;
iterator = INC_STATE_MONITOR_HEAD(&ctx_isp->state_monitor_head); iterator = INC_STATE_MONITOR_HEAD(&ctx_isp->state_monitor_head);
ctx_isp->cam_isp_ctx_state_monitor[iterator].curr_state = ctx_isp->cam_isp_ctx_state_monitor[iterator].curr_state =
ctx_isp->substate_activated; curr_state;
ctx_isp->cam_isp_ctx_state_monitor[iterator].trigger = ctx_isp->cam_isp_ctx_state_monitor[iterator].next_state =
trigger_type; next_state;
ctx_isp->cam_isp_ctx_state_monitor[iterator].req_id = ctx_isp->cam_isp_ctx_state_monitor[iterator].hw_event =
req_id; 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 = ctx_isp->cam_isp_ctx_state_monitor[iterator].evt_time_stamp =
jiffies_to_msecs(jiffies); jiffies_to_msecs(jiffies);
} }
@ -79,17 +87,17 @@ static const char *__cam_isp_hw_evt_val_to_type(
uint32_t evt_id) uint32_t evt_id)
{ {
switch (evt_id) { switch (evt_id) {
case CAM_ISP_STATE_CHANGE_TRIGGER_ERROR: case CAM_ISP_HW_EVENT_ERROR:
return "ERROR"; return "ERROR";
case CAM_ISP_STATE_CHANGE_TRIGGER_SOF: case CAM_ISP_HW_EVENT_SOF:
return "SOF"; return "SOF";
case CAM_ISP_STATE_CHANGE_TRIGGER_REG_UPDATE: case CAM_ISP_HW_EVENT_REG_UPDATE:
return "REG_UPDATE"; return "REG_UPDATE";
case CAM_ISP_STATE_CHANGE_TRIGGER_EPOCH: case CAM_ISP_HW_EVENT_EPOCH:
return "EPOCH"; return "EPOCH";
case CAM_ISP_STATE_CHANGE_TRIGGER_EOF: case CAM_ISP_HW_EVENT_EOF:
return "EOF"; return "EOF";
case CAM_ISP_STATE_CHANGE_TRIGGER_DONE: case CAM_ISP_HW_EVENT_DONE:
return "DONE"; return "DONE";
default: default:
return "CAM_ISP_EVENT_INVALID"; 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( 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; int i = 0;
uint64_t state_head = 0; uint64_t state_head = 0;
uint64_t index; uint64_t index;
struct cam_isp_context_state_monitor *ctx_monitor;
state_head = atomic64_read(&ctx_isp->state_monitor_head); 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; for (i = CAM_ISP_CTX_STATE_MONITOR_MAX_ENTRIES - 1; i >= 0;
i--) { i--) {
index = (((state_head - i) + index = (((state_head - i) +
CAM_ISP_CTX_STATE_MONITOR_MAX_ENTRIES) % CAM_ISP_CTX_STATE_MONITOR_MAX_ENTRIES) %
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]", if (log_rate_limit) {
ctx_isp->cam_isp_ctx_state_monitor[index].evt_time_stamp, CAM_INFO_RATE_LIMIT_CUSTOM(CAM_ISP, 5, 20,
ctx_isp->cam_isp_ctx_state_monitor[index].req_id, "time[%lld] last reported req_id[%lld] frame id[%lld] applied id[%lld] current state[%s] next state[%s] hw_event[%s]",
__cam_isp_ctx_substate_val_to_type( ctx_monitor[index].evt_time_stamp,
ctx_isp->cam_isp_ctx_state_monitor[index].curr_state), ctx_monitor[index].last_reported_id,
__cam_isp_hw_evt_val_to_type( ctx_monitor[index].frame_id,
ctx_isp->cam_isp_ctx_state_monitor[index].trigger)); 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; struct cam_context *ctx = ctx_isp->base;
if (list_empty(&ctx->active_req_list)) { 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; goto end;
} }
@ -508,6 +545,10 @@ static int __cam_isp_ctx_handle_buf_done_in_activated_state(
CAM_DBG(CAM_REQ, CAM_DBG(CAM_REQ,
"Move active request %lld to pending list(cnt = %d) [bubble recovery], ctx %u", "Move active request %lld to pending list(cnt = %d) [bubble recovery], ctx %u",
req->request_id, ctx_isp->active_req_cnt, ctx->ctx_id); 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 { } else {
list_del_init(&req->list); list_del_init(&req->list);
list_add_tail(&req->list, &ctx->free_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, CAM_DBG(CAM_REQ,
"Move active request %lld to free list(cnt = %d) [all fences done], ctx %u", "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); 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: 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; 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) { 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; 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; 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) if (ctx_isp->substate_activated == CAM_ISP_CTX_ACTIVATED_BUBBLE)
request_id = 0; 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_isp_ctx_send_sof_timestamp(ctx_isp, request_id,
CAM_REQ_MGR_SOF_EVENT_SUCCESS); CAM_REQ_MGR_SOF_EVENT_SUCCESS);
} else { } else {
@ -742,8 +801,7 @@ static int __cam_isp_ctx_sof_in_activated_state(
ctx_isp->frame_id++; ctx_isp->frame_id++;
ctx_isp->sof_timestamp_val = sof_event_data->timestamp; ctx_isp->sof_timestamp_val = sof_event_data->timestamp;
ctx_isp->boot_timestamp = sof_event_data->boot_time; 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", 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); 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, CAM_ERR(CAM_ISP,
"receive rup in unexpected state"); "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: end:
return rc; 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. * If no wait req in epoch, this is an error case.
* The recovery is to go back to sof state * 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; ctx_isp->substate_activated = CAM_ISP_CTX_ACTIVATED_SOF;
/* Send SOF event as empty frame*/ /* 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 = (struct cam_isp_ctx_req *)req->req_priv;
req_isp->bubble_detected = true; 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 && if (req_isp->bubble_report && ctx->ctx_crm_intf &&
ctx->ctx_crm_intf->notify_err) { ctx->ctx_crm_intf->notify_err) {
struct cam_req_mgr_error_notify notify; 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_del_init(&req->list);
list_add_tail(&req->list, &ctx->active_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; 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_isp_ctx_send_sof_timestamp(ctx_isp, request_id,
CAM_REQ_MGR_SOF_EVENT_ERROR); 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", CAM_DBG(CAM_ISP, "next substate %d",
ctx_isp->substate_activated); ctx_isp->substate_activated);
end: 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; return 0;
} }
@ -884,7 +935,6 @@ static int __cam_isp_ctx_sof_in_epoch(struct cam_isp_context *ctx_isp,
int rc = 0; int rc = 0;
struct cam_context *ctx = ctx_isp->base; struct cam_context *ctx = ctx_isp->base;
struct cam_isp_hw_sof_event_data *sof_event_data = evt_data; struct cam_isp_hw_sof_event_data *sof_event_data = evt_data;
struct cam_ctx_request *req;
if (!evt_data) { if (!evt_data) {
CAM_ERR(CAM_ISP, "in valid sof event 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 else
CAM_DBG(CAM_ISP, "Still need to wait for the buf done"); 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", CAM_DBG(CAM_ISP, "next substate %d",
ctx_isp->substate_activated); 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. * If no pending req in epoch, this is an error case.
* Just go back to the bubble state. * 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_isp_ctx_send_sof_timestamp(ctx_isp, request_id,
CAM_REQ_MGR_SOF_EVENT_SUCCESS); CAM_REQ_MGR_SOF_EVENT_SUCCESS);
@ -964,6 +1009,9 @@ static int __cam_isp_ctx_epoch_in_bubble_applied(
list); list);
req_isp = (struct cam_isp_ctx_req *)req->req_priv; req_isp = (struct cam_isp_ctx_req *)req->req_priv;
req_isp->bubble_detected = true; 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 && if (req_isp->bubble_report && ctx->ctx_crm_intf &&
ctx->ctx_crm_intf->notify_err) { 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); list_add_tail(&req->list, &ctx->active_req_list);
if (!req_isp->bubble_report) { 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; 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_isp_ctx_send_sof_timestamp(ctx_isp, request_id,
CAM_REQ_MGR_SOF_EVENT_ERROR); CAM_REQ_MGR_SOF_EVENT_ERROR);
} else } else
@ -1007,11 +1057,7 @@ static int __cam_isp_ctx_epoch_in_bubble_applied(
ctx_isp->substate_activated = CAM_ISP_CTX_ACTIVATED_BUBBLE; ctx_isp->substate_activated = CAM_ISP_CTX_ACTIVATED_BUBBLE;
CAM_DBG(CAM_ISP, "next substate %d", ctx_isp->substate_activated); CAM_DBG(CAM_ISP, "next substate %d", ctx_isp->substate_activated);
end: 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; 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; (struct cam_isp_hw_done_event_data *) evt_data;
rc = __cam_isp_ctx_handle_buf_done_in_activated_state(ctx_isp, done, 1); 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; 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) if (error_event_data->enable_reg_dump)
cam_isp_ctx_dump_req(req_isp); 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, list_for_each_entry_safe(req, req_temp,
&ctx->active_req_list, list) { &ctx->active_req_list, list) {
req_isp = (struct cam_isp_ctx_req *) req->req_priv; req_isp = (struct cam_isp_ctx_req *) req->req_priv;
@ -1176,14 +1217,15 @@ move_to_pending:
end: end:
do { do {
if (list_empty(&ctx->pending_req_list)) { 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; req_isp = NULL;
break; break;
} }
req = list_first_entry(&ctx->pending_req_list, req = list_first_entry(&ctx->pending_req_list,
struct cam_ctx_request, list); struct cam_ctx_request, list);
req_isp = (struct cam_isp_ctx_req *) req->req_priv; 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) { if (req_isp->bubble_report) {
req_to_report = req; req_to_report = req;
@ -1201,7 +1243,8 @@ end:
list_del_init(&req->list); list_del_init(&req->list);
list_add_tail(&req->list, &ctx->free_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) { if (ctx->ctx_crm_intf && ctx->ctx_crm_intf->notify_err) {
notify.link_hdl = ctx->link_hdl; notify.link_hdl = ctx->link_hdl;
@ -1240,8 +1283,8 @@ end:
V4L_EVENT_CAM_REQ_MGR_EVENT)) V4L_EVENT_CAM_REQ_MGR_EVENT))
CAM_ERR(CAM_ISP, CAM_ERR(CAM_ISP,
"Error in notifying the error time for req id:%lld ctx %u", "Error in notifying the error time for req id:%lld ctx %u",
ctx_isp->last_applied_req_id, ctx_isp->req_info.last_applied_req_id,
ctx->ctx_id); ctx->ctx_id);
} }
ctx_isp->substate_activated = CAM_ISP_CTX_ACTIVATED_HW_ERROR; ctx_isp->substate_activated = CAM_ISP_CTX_ACTIVATED_HW_ERROR;
} else { } else {
@ -1278,8 +1321,7 @@ static int __cam_isp_ctx_fs2_sof_in_sof_state(
ctx_isp->frame_id++; ctx_isp->frame_id++;
ctx_isp->sof_timestamp_val = sof_event_data->timestamp; ctx_isp->sof_timestamp_val = sof_event_data->timestamp;
ctx_isp->boot_timestamp = sof_event_data->boot_time; 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", CAM_DBG(CAM_ISP, "frame id: %lld time stamp:0x%llx",
ctx_isp->frame_id, ctx_isp->sof_timestamp_val); 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) { 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; 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; 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"); CAM_DBG(CAM_ISP, "No request, move to SOF");
ctx_isp->substate_activated = ctx_isp->substate_activated =
CAM_ISP_CTX_ACTIVATED_SOF; CAM_ISP_CTX_ACTIVATED_SOF;
if (ctx_isp->reported_req_id < curr_req_id) { if (ctx_isp->req_info.reported_req_id < curr_req_id) {
ctx_isp->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, __cam_isp_ctx_send_sof_timestamp(ctx_isp,
curr_req_id, curr_req_id,
CAM_REQ_MGR_SOF_EVENT_SUCCESS); 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, CAM_ERR(CAM_ISP,
"receive rup in unexpected state"); "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: end:
return rc; 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 && if (ctx->ctx_crm_intf && ctx->ctx_crm_intf->notify_trigger &&
ctx_isp->active_req_cnt <= 2) { ctx_isp->active_req_cnt <= 2) {
list_for_each_entry(req, &ctx->active_req_list, list) { 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; 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; 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); CAM_DBG(CAM_ISP, "next substate %d", ctx_isp->substate_activated);
end: 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; return rc;
} }
@ -1729,19 +1771,19 @@ static int __cam_isp_ctx_apply_req_in_activated_state(
} else { } else {
spin_lock_bh(&ctx->lock); spin_lock_bh(&ctx->lock);
ctx_isp->substate_activated = next_state; 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_del_init(&req->list);
list_add_tail(&req->list, &ctx->wait_req_list); list_add_tail(&req->list, &ctx->wait_req_list);
CAM_DBG(CAM_ISP, "new substate state %d, applied req %lld", 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); spin_unlock_bh(&ctx->lock);
} }
end: 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; 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"); CAM_DBG(CAM_ISP, "try to flush pending list");
spin_lock_bh(&ctx->lock); spin_lock_bh(&ctx->lock);
rc = __cam_isp_ctx_flush_req(ctx, &ctx->pending_req_list, flush_req); 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); spin_unlock_bh(&ctx->lock);
atomic_set(&ctx_isp->process_bubble, 0); atomic_set(&ctx_isp->process_bubble, 0);
@ -2133,8 +2192,10 @@ static int __cam_isp_ctx_rdi_only_sof_in_bubble_applied(
list); list);
req_isp = (struct cam_isp_ctx_req *)req->req_priv; req_isp = (struct cam_isp_ctx_req *)req->req_priv;
req_isp->bubble_detected = true; 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 && if (req_isp->bubble_report && ctx->ctx_crm_intf &&
ctx->ctx_crm_intf->notify_err) { ctx->ctx_crm_intf->notify_err) {
struct cam_req_mgr_error_notify notify; 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); req->request_id, ctx_isp->active_req_cnt);
if (!req_isp->bubble_report) { 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; 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_isp_ctx_send_sof_timestamp(ctx_isp, request_id,
CAM_REQ_MGR_SOF_EVENT_ERROR); CAM_REQ_MGR_SOF_EVENT_ERROR);
} else } else
@ -2305,8 +2368,11 @@ static int __cam_isp_ctx_rdi_only_reg_upd_in_bubble_applied_state(
} else { } else {
CAM_ERR(CAM_ISP, "Can not notify SOF to CRM"); CAM_ERR(CAM_ISP, "Can not notify SOF to CRM");
} }
if (request_id) if (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_isp_ctx_send_sof_timestamp(ctx_isp, request_id,
CAM_REQ_MGR_SOF_EVENT_SUCCESS); 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->last_flush_req = 0;
ctx_isp->frame_id = 0; ctx_isp->frame_id = 0;
ctx_isp->active_req_cnt = 0; ctx_isp->active_req_cnt = 0;
ctx_isp->reported_req_id = 0;
ctx_isp->hw_acquired = false; ctx_isp->hw_acquired = false;
ctx_isp->init_received = 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. * 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->last_flush_req = 0;
ctx_isp->frame_id = 0; ctx_isp->frame_id = 0;
ctx_isp->active_req_cnt = 0; ctx_isp->active_req_cnt = 0;
ctx_isp->reported_req_id = 0;
ctx_isp->hw_acquired = false; ctx_isp->hw_acquired = false;
ctx_isp->init_received = false; ctx_isp->init_received = false;
ctx_isp->rdi_only_context = false; ctx_isp->rdi_only_context = false;
ctx_isp->split_acquire = 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. * 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); atomic_set(&ctx_isp->process_bubble, 0);
ctx_isp->frame_id = 0; ctx_isp->frame_id = 0;
ctx_isp->active_req_cnt = 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 ? ctx_isp->substate_activated = ctx_isp->rdi_only_context ?
CAM_ISP_CTX_ACTIVATED_APPLIED : CAM_ISP_CTX_ACTIVATED_APPLIED :
(req_isp->num_fence_map_out) ? CAM_ISP_CTX_ACTIVATED_EPOCH : (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->frame_id = 0;
ctx_isp->active_req_cnt = 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); atomic_set(&ctx_isp->process_bubble, 0);
CAM_DBG(CAM_ISP, "Stop device success next state %d on ctx %u", 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); rc = ctx_ops->crm_ops.apply_req(ctx, apply);
} else { } else {
CAM_ERR_RATE_LIMIT(CAM_ISP, CAM_ERR_RATE_LIMIT(CAM_ISP,
"No handle function in activated substate %d", "Ctx:%d No handle function in activated substate %d",
ctx_isp->substate_activated); ctx->ctx_id, ctx_isp->substate_activated);
__cam_isp_ctx_dump_state_monitor_array(ctx_isp, true);
rc = -EFAULT; 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_context *ctx = (struct cam_context *)context;
struct cam_isp_context *ctx_isp = struct cam_isp_context *ctx_isp =
(struct cam_isp_context *)ctx->ctx_priv; (struct cam_isp_context *)ctx->ctx_priv;
enum cam_isp_ctx_activated_substate curr_state;
spin_lock(&ctx->lock); spin_lock(&ctx->lock);
trace_cam_isp_activated_irq(ctx, ctx_isp->substate_activated, evt_id, trace_cam_isp_activated_irq(ctx, ctx_isp->substate_activated, evt_id,
__cam_isp_ctx_get_event_ts(evt_id, evt_data)); __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", CAM_DBG(CAM_ISP, "Enter: State %d, Substate %d, evt id %d",
ctx->state, ctx_isp->substate_activated, evt_id); ctx->state, ctx_isp->substate_activated, evt_id);
irq_ops = &ctx_isp->substate_machine_irq[ctx_isp->substate_activated]; irq_ops = &ctx_isp->substate_machine_irq[ctx_isp->substate_activated];
if (irq_ops->irq_ops[evt_id]) { if (irq_ops->irq_ops[evt_id]) {
rc = irq_ops->irq_ops[evt_id](ctx_isp, evt_data); rc = irq_ops->irq_ops[evt_id](ctx_isp, evt_data);
} else { } else {
CAM_DBG(CAM_ISP, "No handle function for substate %d", CAM_INFO(CAM_ISP, "Ctx:%d No handle function for substate %d",
ctx_isp->substate_activated); ctx->ctx_id, ctx_isp->substate_activated);
__cam_isp_ctx_dump_state_monitor_array(ctx_isp); __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", CAM_DBG(CAM_ISP, "Exit: State %d Substate %d",
ctx->state, ctx_isp->substate_activated); 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->base = ctx_base;
ctx->frame_id = 0; ctx->frame_id = 0;
ctx->active_req_cnt = 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->hw_ctx = NULL;
ctx->substate_activated = CAM_ISP_CTX_ACTIVATED_SOF; ctx->substate_activated = CAM_ISP_CTX_ACTIVATED_SOF;
ctx->substate_machine = cam_isp_ctx_activated_state_machine; ctx->substate_machine = cam_isp_ctx_activated_state_machine;

View File

@ -61,20 +61,6 @@ enum cam_isp_ctx_activated_substate {
CAM_ISP_CTX_ACTIVATED_MAX, CAM_ISP_CTX_ACTIVATED_MAX,
}; };
/**
* 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 * struct cam_isp_ctx_irq_ops - Function table for handling IRQ callbacks
* *
@ -125,19 +111,46 @@ struct cam_isp_ctx_req {
* debug purposes * debug purposes
* *
*@curr_state: Current sub state that received req *@curr_state: Current sub state that received req
*@req_type: Event type of incoming req *@next_state: Next sub state that received req
*@req_id: Request id *@hw_event: Hw Event type of incoming req
*@evt_time_stamp Current time stamp *@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 { struct cam_isp_context_state_monitor {
enum cam_isp_ctx_activated_substate curr_state; enum cam_isp_ctx_activated_substate curr_state;
enum cam_isp_state_change_trigger trigger; enum cam_isp_ctx_activated_substate next_state;
uint32_t req_id; enum cam_isp_hw_event_type hw_event;
int64_t last_reported_id;
int64_t last_applied_req_id;
int64_t frame_id; int64_t frame_id;
uint64_t evt_time_stamp; 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 * struct cam_isp_context - ISP context object
* *
@ -154,11 +167,11 @@ struct cam_isp_context_state_monitor {
* @sof_timestamp_val: Captured time stamp value at sof hw event * @sof_timestamp_val: Captured time stamp value at sof hw event
* @boot_timestamp: Boot time stamp for a given req_id * @boot_timestamp: Boot time stamp for a given req_id
* @active_req_cnt: Counter for the active request * @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 * @subscribe_event: The irq event mask that CRM subscribes to, IFE
* will invoke CRM cb at those event. * 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 * @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 * @cam_isp_ctx_state_monitor: State monitoring array
* @rdi_only_context: Get context type information. * @rdi_only_context: Get context type information.
* true, if context is rdi only context * true, if context is rdi only context
@ -183,12 +196,11 @@ struct cam_isp_context {
uint64_t sof_timestamp_val; uint64_t sof_timestamp_val;
uint64_t boot_timestamp; uint64_t boot_timestamp;
int32_t active_req_cnt; int32_t active_req_cnt;
int64_t reported_req_id;
uint32_t subscribe_event; uint32_t subscribe_event;
int64_t last_applied_req_id;
atomic64_t state_monitor_head; atomic64_t state_monitor_head;
struct cam_isp_context_state_monitor cam_isp_ctx_state_monitor[ struct cam_isp_context_state_monitor cam_isp_ctx_state_monitor[
CAM_ISP_CTX_STATE_MONITOR_MAX_ENTRIES]; CAM_ISP_CTX_STATE_MONITOR_MAX_ENTRIES];
struct cam_isp_context_req_id_info req_info;
bool rdi_only_context; bool rdi_only_context;
bool hw_acquired; bool hw_acquired;
bool init_received; bool init_received;

View File

@ -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 */ /* Stop the master CSID path first */
cam_ife_mgr_csid_stop_hw(ctx, &ctx->res_list_ife_csid, 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 */ /* stop rest of the CSID paths */
for (i = 0; i < ctx->num_base; i++) { 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); ctx->base[i].idx, i, master_base_idx);
cam_ife_mgr_csid_stop_hw(ctx, &ctx->res_list_ife_csid, 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); CAM_DBG(CAM_ISP, "Stopping master CID idx %d", master_base_idx);

View File

@ -467,6 +467,7 @@ int cam_isp_add_io_buffers(
int32_t hdl; int32_t hdl;
int mmu_hdl; int mmu_hdl;
bool mode, is_buf_secure; bool mode, is_buf_secure;
uint64_t req_id;
io_cfg = (struct cam_buf_io_cfg *) ((uint8_t *) io_cfg = (struct cam_buf_io_cfg *) ((uint8_t *)
&prepare->packet->payload + &prepare->packet->payload +
@ -475,6 +476,7 @@ int cam_isp_add_io_buffers(
num_in_buf = 0; num_in_buf = 0;
io_cfg_used_bytes = 0; io_cfg_used_bytes = 0;
prepare->pf_data->packet = prepare->packet; prepare->pf_data->packet = prepare->packet;
req_id = prepare->packet->header.request_id;
/* Max one hw entries required for each base */ /* Max one hw entries required for each base */
if (prepare->num_hw_update_entries + 1 >= if (prepare->num_hw_update_entries + 1 >=
@ -622,6 +624,23 @@ int cam_isp_add_io_buffers(
return rc; 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 */ /* need to update with offset */
io_addr[plane_id] += io_addr[plane_id] +=
io_cfg[i].offsets[plane_id]; io_cfg[i].offsets[plane_id];

View File

@ -91,6 +91,9 @@ int cam_jpeg_enc_init_hw(void *device_priv,
CAM_ERR(CAM_JPEG, "soc enable is failed %d", rc); CAM_ERR(CAM_JPEG, "soc enable is failed %d", rc);
goto soc_failed; 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); mutex_unlock(&core_info->core_mutex);
@ -140,6 +143,9 @@ int cam_jpeg_enc_deinit_hw(void *device_priv,
return -EFAULT; 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); rc = cam_jpeg_enc_disable_soc_resources(soc_info);
if (rc) if (rc)
CAM_ERR(CAM_JPEG, "soc disable failed %d", 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; hw_info = core_info->jpeg_enc_hw_info;
mem_base = soc_info->reg_map[0].mem_base; 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 + irq_status = cam_io_r_mb(mem_base +
core_info->jpeg_enc_hw_info->reg_offset.int_status); core_info->jpeg_enc_hw_info->reg_offset.int_status);
cam_io_w_mb(irq_status, cam_io_w_mb(irq_status,
soc_info->reg_map[0].mem_base + soc_info->reg_map[0].mem_base +
core_info->jpeg_enc_hw_info->reg_offset.int_clr); 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", CAM_DBG(CAM_JPEG, "irq_num %d irq_status = %x , core_state %d",
irq_num, irq_status, core_info->core_state); 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); mutex_lock(&core_info->core_mutex);
spin_lock(&jpeg_enc_dev->hw_lock); 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) { if (core_info->core_state == CAM_JPEG_ENC_CORE_RESETTING) {
CAM_ERR(CAM_JPEG, "alrady resetting"); CAM_ERR(CAM_JPEG, "alrady resetting");
spin_unlock(&jpeg_enc_dev->hw_lock); 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; hw_info = core_info->jpeg_enc_hw_info;
mem_base = soc_info->reg_map[0].mem_base; mem_base = soc_info->reg_map[0].mem_base;
if (core_info->core_state != CAM_JPEG_ENC_CORE_READY) { spin_lock(&jpeg_enc_dev->hw_lock);
CAM_ERR(CAM_JPEG, "Error not ready"); 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; 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, cam_io_w_mb(hw_info->reg_val.hw_cmd_start,
mem_base + hw_info->reg_offset.hw_cmd); 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); mutex_lock(&core_info->core_mutex);
spin_lock(&jpeg_enc_dev->hw_lock); 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) { if (core_info->core_state == CAM_JPEG_ENC_CORE_ABORTING) {
CAM_ERR(CAM_JPEG, "alrady stopping"); CAM_ERR(CAM_JPEG, "alrady stopping");
spin_unlock(&jpeg_enc_dev->hw_lock); spin_unlock(&jpeg_enc_dev->hw_lock);

View File

@ -927,6 +927,16 @@ int32_t cam_sensor_driver_cmd(struct cam_sensor_ctrl_t *s_ctrl,
} }
break; break;
case CAM_CONFIG_DEV: { 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); rc = cam_sensor_i2c_pkt_parse(s_ctrl, arg);
if (rc < 0) { if (rc < 0) {
CAM_ERR(CAM_SENSOR, "Failed i2c pkt parse: %d", rc); CAM_ERR(CAM_SENSOR, "Failed i2c pkt parse: %d", rc);

View File

@ -191,7 +191,7 @@ static struct cam_iommu_cb_set iommu_cb_set;
static struct dentry *smmu_dentry; 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( static enum dma_data_direction cam_smmu_translate_dir(
enum cam_smmu_map_dir dir); enum cam_smmu_map_dir dir);

View File

@ -288,6 +288,7 @@ int cam_sync_merge(int32_t *sync_obj, uint32_t num_objs, int32_t *merged_obj)
int rc; int rc;
long idx = 0; long idx = 0;
bool bit; bool bit;
int i = 0;
if (!sync_obj || !merged_obj) { if (!sync_obj || !merged_obj) {
CAM_ERR(CAM_SYNC, "Invalid pointer(s)"); 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; 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 { do {
idx = find_first_zero_bit(sync_dev->bitmap, CAM_SYNC_MAX_OBJS); idx = find_first_zero_bit(sync_dev->bitmap, CAM_SYNC_MAX_OBJS);
if (idx >= 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); 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) int cam_sync_wait(int32_t sync_obj, uint64_t timeout_ms)
{ {
unsigned long timeleft; unsigned long timeleft;

View File

@ -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 * 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 * 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); 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__ */ #endif /* __CAM_SYNC_API_H__ */

View File

@ -353,3 +353,115 @@ rel_cmd_buf:
return rc; 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;
}

View File

@ -135,4 +135,20 @@ int cam_packet_util_process_generic_cmd_buffer(
struct cam_cmd_buf_desc *cmd_buf, struct cam_cmd_buf_desc *cmd_buf,
cam_packet_generic_blob_handler blob_handler_cb, void *user_data); 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_ */ #endif /* _CAM_PACKET_UTIL_H_ */