Merge "Merge remote-tracking branch 'dev/msm-4.14' into msm-4.9 07/03"
This commit is contained in:
commit
62ad3e5bc0
|
@ -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",
|
||||
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(
|
||||
|
@ -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);
|
||||
|
|
|
@ -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) ||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -61,20 +61,6 @@ enum cam_isp_ctx_activated_substate {
|
|||
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
|
||||
*
|
||||
|
@ -125,19 +111,46 @@ 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
|
||||
*
|
||||
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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;
|
||||
|
||||
if (core_info->core_state != CAM_JPEG_ENC_CORE_READY) {
|
||||
CAM_ERR(CAM_JPEG, "Error not ready");
|
||||
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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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__ */
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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_ */
|
||||
|
|
Loading…
Reference in New Issue