Loading drivers/media/platform/msm/camera/cam_isp/cam_isp_context.c +170 −23 Original line number Diff line number Diff line Loading @@ -26,6 +26,97 @@ static const char isp_dev_name[] = "isp"; #define INC_STATE_MONITOR_HEAD(head) \ (atomic64_add_return(1, head) % \ CAM_ISP_CTX_STATE_MONITOR_MAX_ENTRIES) 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) { 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; ctx_isp->cam_isp_ctx_state_monitor[iterator].evt_time_stamp = jiffies_to_msecs(jiffies); } static const char *__cam_isp_ctx_substate_val_to_type( uint32_t type) { switch (type) { case CAM_ISP_CTX_ACTIVATED_SOF: return "SOF"; case CAM_ISP_CTX_ACTIVATED_APPLIED: return "APPLIED"; case CAM_ISP_CTX_ACTIVATED_EPOCH: return "EPOCH"; case CAM_ISP_CTX_ACTIVATED_BUBBLE: return "BUBBLE"; case CAM_ISP_CTX_ACTIVATED_BUBBLE_APPLIED: return "BUBBLE_APPLIED"; case CAM_ISP_CTX_ACTIVATED_HALT: return "HALT"; default: return "CAM_ISP_CTX_INVALID_STATE"; } } static const char *__cam_isp_hw_evt_val_to_type( uint32_t evt_id) { switch (evt_id) { case CAM_ISP_STATE_CHANGE_TRIGGER_ERROR: return "ERROR"; case CAM_ISP_STATE_CHANGE_TRIGGER_SOF: return "SOF"; case CAM_ISP_STATE_CHANGE_TRIGGER_REG_UPDATE: return "REG_UPDATE"; case CAM_ISP_STATE_CHANGE_TRIGGER_EPOCH: return "EPOCH"; case CAM_ISP_STATE_CHANGE_TRIGGER_EOF: return "EOF"; case CAM_ISP_STATE_CHANGE_TRIGGER_DONE: return "DONE"; default: return "CAM_ISP_EVENT_INVALID"; } } static void __cam_isp_ctx_dump_state_monitor_array( struct cam_isp_context *ctx_isp) { int i = 0; uint64_t state_head = 0; uint64_t index; state_head = atomic64_read(&ctx_isp->state_monitor_head); CAM_ERR_RATE_LIMIT(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)); } } static int __cam_isp_ctx_enqueue_request_in_order( struct cam_context *ctx, struct cam_ctx_request *req) { Loading Loading @@ -134,46 +225,46 @@ static int __cam_isp_ctx_enqueue_init_request( return rc; } static const char *__cam_isp_resource_handle_id_to_type (uint32_t resource_handle) static const char *__cam_isp_resource_handle_id_to_type( uint32_t resource_handle) { switch (resource_handle) { case CAM_ISP_IFE_OUT_RES_FULL: return "CAM_ISP_IFE_OUT_RES_FULL"; return "FULL"; case CAM_ISP_IFE_OUT_RES_DS4: return "CAM_ISP_IFE_OUT_RES_DS4"; return "DS4"; case CAM_ISP_IFE_OUT_RES_DS16: return "CAM_ISP_IFE_OUT_RES_DS16"; return "DS16"; case CAM_ISP_IFE_OUT_RES_RAW_DUMP: return "CAM_ISP_IFE_OUT_RES_RAW_DUMP"; return "RAW_DUMP"; case CAM_ISP_IFE_OUT_RES_FD: return "CAM_ISP_IFE_OUT_RES_FD"; return "FD"; case CAM_ISP_IFE_OUT_RES_PDAF: return "CAM_ISP_IFE_OUT_RES_PDAF"; return "PDAF"; case CAM_ISP_IFE_OUT_RES_RDI_0: return "CAM_ISP_IFE_OUT_RES_RDI_0"; return "RDI_0"; case CAM_ISP_IFE_OUT_RES_RDI_1: return "CAM_ISP_IFE_OUT_RES_RDI_1"; return "RDI_1"; case CAM_ISP_IFE_OUT_RES_RDI_2: return "CAM_ISP_IFE_OUT_RES_RDI_2"; return "RDI_2"; case CAM_ISP_IFE_OUT_RES_RDI_3: return "CAM_ISP_IFE_OUT_RES_RDI_3"; return "RDI_3"; case CAM_ISP_IFE_OUT_RES_STATS_HDR_BE: return "CAM_ISP_IFE_OUT_RES_STATS_HDR_BE"; return "STATS_HDR_BE"; case CAM_ISP_IFE_OUT_RES_STATS_HDR_BHIST: return "CAM_ISP_IFE_OUT_RES_STATS_HDR_BHIST"; return "STATS_HDR_BHIST"; case CAM_ISP_IFE_OUT_RES_STATS_TL_BG: return "CAM_ISP_IFE_OUT_RES_STATS_TL_BG"; return "STATS_TL_BG"; case CAM_ISP_IFE_OUT_RES_STATS_BF: return "CAM_ISP_IFE_OUT_RES_STATS_BF"; return "STATS_BF"; case CAM_ISP_IFE_OUT_RES_STATS_AWB_BG: return "CAM_ISP_IFE_OUT_RES_STATS_AWB_BG"; return "STATS_AWB_BG"; case CAM_ISP_IFE_OUT_RES_STATS_BHIST: return "CAM_ISP_IFE_OUT_RES_STATS_BHIST"; return "STATS_BHIST"; case CAM_ISP_IFE_OUT_RES_STATS_RS: return "CAM_ISP_IFE_OUT_RES_STATS_RS"; return "STATS_RS"; case CAM_ISP_IFE_OUT_RES_STATS_CS: return "CAM_ISP_IFE_OUT_RES_STATS_CS"; return "STATS_CS"; default: return "CAM_ISP_Invalid_Resource_Type"; } Loading Loading @@ -350,6 +441,9 @@ static int __cam_isp_ctx_handle_buf_done_in_activated_state( } 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; } Loading Loading @@ -510,6 +604,11 @@ static int __cam_isp_ctx_sof_in_activated_state( { int rc = 0; struct cam_isp_hw_sof_event_data *sof_event_data = evt_data; struct cam_ctx_request *req; struct cam_context *ctx = ctx_isp->base; req = list_last_entry(&ctx->pending_req_list, struct cam_ctx_request, list); if (!evt_data) { CAM_ERR(CAM_ISP, "in valid sof event data"); Loading @@ -518,6 +617,8 @@ static int __cam_isp_ctx_sof_in_activated_state( ctx_isp->frame_id++; ctx_isp->sof_timestamp_val = sof_event_data->timestamp; __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); Loading @@ -528,11 +629,11 @@ static int __cam_isp_ctx_reg_upd_in_sof(struct cam_isp_context *ctx_isp, void *evt_data) { int rc = 0; struct cam_ctx_request *req; struct cam_ctx_request *req = NULL; struct cam_isp_ctx_req *req_isp; struct cam_context *ctx = ctx_isp->base; if (ctx->state != CAM_CTX_ACTIVATED) { if (ctx->state != CAM_CTX_ACTIVATED && ctx_isp->frame_id > 1) { CAM_DBG(CAM_ISP, "invalid RUP"); goto end; } Loading Loading @@ -560,6 +661,11 @@ static int __cam_isp_ctx_reg_upd_in_sof(struct cam_isp_context *ctx_isp, CAM_ISP_CTX_ACTIVATED_EPOCH; } } 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; } Loading Loading @@ -627,6 +733,15 @@ 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; } Loading @@ -649,6 +764,7 @@ 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"); Loading @@ -663,6 +779,10 @@ 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); __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); Loading Loading @@ -761,6 +881,10 @@ 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); __cam_isp_ctx_update_state_monitor_array(ctx_isp, CAM_ISP_STATE_CHANGE_TRIGGER_EPOCH, req->request_id); return 0; } Loading @@ -772,6 +896,9 @@ 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; } Loading Loading @@ -894,6 +1021,14 @@ static int __cam_isp_ctx_handle_error(struct cam_isp_context *ctx_isp, rc = -EFAULT; } list_del_init(&req->list); list_add(&req->list, &ctx->pending_req_list); /* might need to check if active list is empty */ if (req != NULL) { __cam_isp_ctx_update_state_monitor_array(ctx_isp, CAM_ISP_STATE_CHANGE_TRIGGER_ERROR, req->request_id); } CAM_DBG(CAM_ISP, "Exit"); return rc; } Loading Loading @@ -1014,7 +1149,7 @@ static int __cam_isp_ctx_apply_req_in_activated_state( struct cam_ctx_request *active_req; struct cam_isp_ctx_req *req_isp; struct cam_isp_ctx_req *active_req_isp; struct cam_isp_context *ctx_isp; struct cam_isp_context *ctx_isp = NULL; struct cam_hw_config_args cfg; if (list_empty(&ctx->pending_req_list)) { Loading Loading @@ -1088,6 +1223,11 @@ static int __cam_isp_ctx_apply_req_in_activated_state( 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; } Loading Loading @@ -2439,6 +2579,7 @@ static int __cam_isp_ctx_handle_irq_in_activated(void *context, } 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_DBG(CAM_ISP, "Exit: State %d Substate %d", ctx->state, ctx_isp->substate_activated); Loading Loading @@ -2552,6 +2693,12 @@ int cam_isp_context_init(struct cam_isp_context *ctx, ctx_base->state_machine = cam_isp_ctx_top_state_machine; ctx_base->ctx_priv = ctx; /* initializing current state for error logging */ for (i = 0; i < CAM_ISP_CTX_STATE_MONITOR_MAX_ENTRIES; i++) { ctx->cam_isp_ctx_state_monitor[i].curr_state = CAM_ISP_CTX_ACTIVATED_MAX; } atomic64_set(&ctx->state_monitor_head, -1); err: return rc; } Loading drivers/media/platform/msm/camera/cam_isp/cam_isp_context.h +60 −18 Original line number Diff line number Diff line Loading @@ -28,11 +28,16 @@ #define CAM_ISP_CTX_RES_MAX 20 /* * Maxiimum configuration entry size - This is based on the * Maximum configuration entry size - This is based on the * worst case DUAL IFE use case plus some margin. */ #define CAM_ISP_CTX_CFG_MAX 22 /* * Maximum entries in state monitoring array for error logging */ #define CAM_ISP_CTX_STATE_MONITOR_MAX_ENTRIES 20 /* forward declaration */ struct cam_isp_context; Loading @@ -56,6 +61,19 @@ 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 Loading Loading @@ -100,6 +118,25 @@ struct cam_isp_ctx_req { struct cam_isp_prepare_hw_update_data hw_update_data; }; /** * struct cam_isp_context_state_monitor - ISP context state * monitoring for * 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 * */ 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; int64_t frame_id; uint64_t evt_time_stamp; }; /** * struct cam_isp_context - ISP context object * Loading @@ -114,10 +151,12 @@ struct cam_isp_ctx_req { * @sof_timestamp_val: Captured time stamp value at sof hw event * @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. * @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 * @frame_skip_count: Number of frame to skip before change state * @state_monitor_head: Write index to the state monitoring array * @cam_isp_ctx_state_monitor: State monitoring array * */ struct cam_isp_context { Loading @@ -138,6 +177,9 @@ struct cam_isp_context { uint32_t subscribe_event; int64_t last_applied_req_id; uint32_t frame_skip_count; atomic64_t state_monitor_head; struct cam_isp_context_state_monitor cam_isp_ctx_state_monitor[ CAM_ISP_CTX_STATE_MONITOR_MAX_ENTRIES]; }; /** Loading Loading
drivers/media/platform/msm/camera/cam_isp/cam_isp_context.c +170 −23 Original line number Diff line number Diff line Loading @@ -26,6 +26,97 @@ static const char isp_dev_name[] = "isp"; #define INC_STATE_MONITOR_HEAD(head) \ (atomic64_add_return(1, head) % \ CAM_ISP_CTX_STATE_MONITOR_MAX_ENTRIES) 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) { 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; ctx_isp->cam_isp_ctx_state_monitor[iterator].evt_time_stamp = jiffies_to_msecs(jiffies); } static const char *__cam_isp_ctx_substate_val_to_type( uint32_t type) { switch (type) { case CAM_ISP_CTX_ACTIVATED_SOF: return "SOF"; case CAM_ISP_CTX_ACTIVATED_APPLIED: return "APPLIED"; case CAM_ISP_CTX_ACTIVATED_EPOCH: return "EPOCH"; case CAM_ISP_CTX_ACTIVATED_BUBBLE: return "BUBBLE"; case CAM_ISP_CTX_ACTIVATED_BUBBLE_APPLIED: return "BUBBLE_APPLIED"; case CAM_ISP_CTX_ACTIVATED_HALT: return "HALT"; default: return "CAM_ISP_CTX_INVALID_STATE"; } } static const char *__cam_isp_hw_evt_val_to_type( uint32_t evt_id) { switch (evt_id) { case CAM_ISP_STATE_CHANGE_TRIGGER_ERROR: return "ERROR"; case CAM_ISP_STATE_CHANGE_TRIGGER_SOF: return "SOF"; case CAM_ISP_STATE_CHANGE_TRIGGER_REG_UPDATE: return "REG_UPDATE"; case CAM_ISP_STATE_CHANGE_TRIGGER_EPOCH: return "EPOCH"; case CAM_ISP_STATE_CHANGE_TRIGGER_EOF: return "EOF"; case CAM_ISP_STATE_CHANGE_TRIGGER_DONE: return "DONE"; default: return "CAM_ISP_EVENT_INVALID"; } } static void __cam_isp_ctx_dump_state_monitor_array( struct cam_isp_context *ctx_isp) { int i = 0; uint64_t state_head = 0; uint64_t index; state_head = atomic64_read(&ctx_isp->state_monitor_head); CAM_ERR_RATE_LIMIT(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)); } } static int __cam_isp_ctx_enqueue_request_in_order( struct cam_context *ctx, struct cam_ctx_request *req) { Loading Loading @@ -134,46 +225,46 @@ static int __cam_isp_ctx_enqueue_init_request( return rc; } static const char *__cam_isp_resource_handle_id_to_type (uint32_t resource_handle) static const char *__cam_isp_resource_handle_id_to_type( uint32_t resource_handle) { switch (resource_handle) { case CAM_ISP_IFE_OUT_RES_FULL: return "CAM_ISP_IFE_OUT_RES_FULL"; return "FULL"; case CAM_ISP_IFE_OUT_RES_DS4: return "CAM_ISP_IFE_OUT_RES_DS4"; return "DS4"; case CAM_ISP_IFE_OUT_RES_DS16: return "CAM_ISP_IFE_OUT_RES_DS16"; return "DS16"; case CAM_ISP_IFE_OUT_RES_RAW_DUMP: return "CAM_ISP_IFE_OUT_RES_RAW_DUMP"; return "RAW_DUMP"; case CAM_ISP_IFE_OUT_RES_FD: return "CAM_ISP_IFE_OUT_RES_FD"; return "FD"; case CAM_ISP_IFE_OUT_RES_PDAF: return "CAM_ISP_IFE_OUT_RES_PDAF"; return "PDAF"; case CAM_ISP_IFE_OUT_RES_RDI_0: return "CAM_ISP_IFE_OUT_RES_RDI_0"; return "RDI_0"; case CAM_ISP_IFE_OUT_RES_RDI_1: return "CAM_ISP_IFE_OUT_RES_RDI_1"; return "RDI_1"; case CAM_ISP_IFE_OUT_RES_RDI_2: return "CAM_ISP_IFE_OUT_RES_RDI_2"; return "RDI_2"; case CAM_ISP_IFE_OUT_RES_RDI_3: return "CAM_ISP_IFE_OUT_RES_RDI_3"; return "RDI_3"; case CAM_ISP_IFE_OUT_RES_STATS_HDR_BE: return "CAM_ISP_IFE_OUT_RES_STATS_HDR_BE"; return "STATS_HDR_BE"; case CAM_ISP_IFE_OUT_RES_STATS_HDR_BHIST: return "CAM_ISP_IFE_OUT_RES_STATS_HDR_BHIST"; return "STATS_HDR_BHIST"; case CAM_ISP_IFE_OUT_RES_STATS_TL_BG: return "CAM_ISP_IFE_OUT_RES_STATS_TL_BG"; return "STATS_TL_BG"; case CAM_ISP_IFE_OUT_RES_STATS_BF: return "CAM_ISP_IFE_OUT_RES_STATS_BF"; return "STATS_BF"; case CAM_ISP_IFE_OUT_RES_STATS_AWB_BG: return "CAM_ISP_IFE_OUT_RES_STATS_AWB_BG"; return "STATS_AWB_BG"; case CAM_ISP_IFE_OUT_RES_STATS_BHIST: return "CAM_ISP_IFE_OUT_RES_STATS_BHIST"; return "STATS_BHIST"; case CAM_ISP_IFE_OUT_RES_STATS_RS: return "CAM_ISP_IFE_OUT_RES_STATS_RS"; return "STATS_RS"; case CAM_ISP_IFE_OUT_RES_STATS_CS: return "CAM_ISP_IFE_OUT_RES_STATS_CS"; return "STATS_CS"; default: return "CAM_ISP_Invalid_Resource_Type"; } Loading Loading @@ -350,6 +441,9 @@ static int __cam_isp_ctx_handle_buf_done_in_activated_state( } 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; } Loading Loading @@ -510,6 +604,11 @@ static int __cam_isp_ctx_sof_in_activated_state( { int rc = 0; struct cam_isp_hw_sof_event_data *sof_event_data = evt_data; struct cam_ctx_request *req; struct cam_context *ctx = ctx_isp->base; req = list_last_entry(&ctx->pending_req_list, struct cam_ctx_request, list); if (!evt_data) { CAM_ERR(CAM_ISP, "in valid sof event data"); Loading @@ -518,6 +617,8 @@ static int __cam_isp_ctx_sof_in_activated_state( ctx_isp->frame_id++; ctx_isp->sof_timestamp_val = sof_event_data->timestamp; __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); Loading @@ -528,11 +629,11 @@ static int __cam_isp_ctx_reg_upd_in_sof(struct cam_isp_context *ctx_isp, void *evt_data) { int rc = 0; struct cam_ctx_request *req; struct cam_ctx_request *req = NULL; struct cam_isp_ctx_req *req_isp; struct cam_context *ctx = ctx_isp->base; if (ctx->state != CAM_CTX_ACTIVATED) { if (ctx->state != CAM_CTX_ACTIVATED && ctx_isp->frame_id > 1) { CAM_DBG(CAM_ISP, "invalid RUP"); goto end; } Loading Loading @@ -560,6 +661,11 @@ static int __cam_isp_ctx_reg_upd_in_sof(struct cam_isp_context *ctx_isp, CAM_ISP_CTX_ACTIVATED_EPOCH; } } 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; } Loading Loading @@ -627,6 +733,15 @@ 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; } Loading @@ -649,6 +764,7 @@ 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"); Loading @@ -663,6 +779,10 @@ 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); __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); Loading Loading @@ -761,6 +881,10 @@ 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); __cam_isp_ctx_update_state_monitor_array(ctx_isp, CAM_ISP_STATE_CHANGE_TRIGGER_EPOCH, req->request_id); return 0; } Loading @@ -772,6 +896,9 @@ 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; } Loading Loading @@ -894,6 +1021,14 @@ static int __cam_isp_ctx_handle_error(struct cam_isp_context *ctx_isp, rc = -EFAULT; } list_del_init(&req->list); list_add(&req->list, &ctx->pending_req_list); /* might need to check if active list is empty */ if (req != NULL) { __cam_isp_ctx_update_state_monitor_array(ctx_isp, CAM_ISP_STATE_CHANGE_TRIGGER_ERROR, req->request_id); } CAM_DBG(CAM_ISP, "Exit"); return rc; } Loading Loading @@ -1014,7 +1149,7 @@ static int __cam_isp_ctx_apply_req_in_activated_state( struct cam_ctx_request *active_req; struct cam_isp_ctx_req *req_isp; struct cam_isp_ctx_req *active_req_isp; struct cam_isp_context *ctx_isp; struct cam_isp_context *ctx_isp = NULL; struct cam_hw_config_args cfg; if (list_empty(&ctx->pending_req_list)) { Loading Loading @@ -1088,6 +1223,11 @@ static int __cam_isp_ctx_apply_req_in_activated_state( 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; } Loading Loading @@ -2439,6 +2579,7 @@ static int __cam_isp_ctx_handle_irq_in_activated(void *context, } 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_DBG(CAM_ISP, "Exit: State %d Substate %d", ctx->state, ctx_isp->substate_activated); Loading Loading @@ -2552,6 +2693,12 @@ int cam_isp_context_init(struct cam_isp_context *ctx, ctx_base->state_machine = cam_isp_ctx_top_state_machine; ctx_base->ctx_priv = ctx; /* initializing current state for error logging */ for (i = 0; i < CAM_ISP_CTX_STATE_MONITOR_MAX_ENTRIES; i++) { ctx->cam_isp_ctx_state_monitor[i].curr_state = CAM_ISP_CTX_ACTIVATED_MAX; } atomic64_set(&ctx->state_monitor_head, -1); err: return rc; } Loading
drivers/media/platform/msm/camera/cam_isp/cam_isp_context.h +60 −18 Original line number Diff line number Diff line Loading @@ -28,11 +28,16 @@ #define CAM_ISP_CTX_RES_MAX 20 /* * Maxiimum configuration entry size - This is based on the * Maximum configuration entry size - This is based on the * worst case DUAL IFE use case plus some margin. */ #define CAM_ISP_CTX_CFG_MAX 22 /* * Maximum entries in state monitoring array for error logging */ #define CAM_ISP_CTX_STATE_MONITOR_MAX_ENTRIES 20 /* forward declaration */ struct cam_isp_context; Loading @@ -56,6 +61,19 @@ 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 Loading Loading @@ -100,6 +118,25 @@ struct cam_isp_ctx_req { struct cam_isp_prepare_hw_update_data hw_update_data; }; /** * struct cam_isp_context_state_monitor - ISP context state * monitoring for * 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 * */ 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; int64_t frame_id; uint64_t evt_time_stamp; }; /** * struct cam_isp_context - ISP context object * Loading @@ -114,10 +151,12 @@ struct cam_isp_ctx_req { * @sof_timestamp_val: Captured time stamp value at sof hw event * @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. * @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 * @frame_skip_count: Number of frame to skip before change state * @state_monitor_head: Write index to the state monitoring array * @cam_isp_ctx_state_monitor: State monitoring array * */ struct cam_isp_context { Loading @@ -138,6 +177,9 @@ struct cam_isp_context { uint32_t subscribe_event; int64_t last_applied_req_id; uint32_t frame_skip_count; atomic64_t state_monitor_head; struct cam_isp_context_state_monitor cam_isp_ctx_state_monitor[ CAM_ISP_CTX_STATE_MONITOR_MAX_ENTRIES]; }; /** Loading