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",
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);

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,
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) ||

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(
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;

View File

@ -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;

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 */
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);

View File

@ -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];

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);
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);

View File

@ -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);

View File

@ -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);

View File

@ -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;

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
* 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__ */

View File

@ -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;
}

View File

@ -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_ */