Loading drivers/media/platform/msm/camera/cam_isp/cam_isp_context.c +127 −46 Original line number Diff line number Diff line Loading @@ -99,12 +99,39 @@ static int __cam_isp_ctx_handle_buf_done_in_activated_state( if (req_isp->num_acked == req_isp->num_fence_map_out) { list_del_init(&req->list); list_add_tail(&req->list, &ctx->free_req_list); ctx_isp->active_req_cnt--; CDBG("%s: Move active request %lld to free list(cnt = %d)\n", __func__, req->request_id, ctx_isp->active_req_cnt); } end: return rc; } static void __cam_isp_ctx_send_sof_timestamp( struct cam_isp_context *ctx_isp, uint64_t request_id, uint32_t sof_event_status) { struct cam_req_mgr_message req_msg; req_msg.session_hdl = ctx_isp->base->session_hdl; req_msg.u.frame_msg.frame_id = ctx_isp->frame_id; req_msg.u.frame_msg.request_id = request_id; req_msg.u.frame_msg.timestamp = ctx_isp->sof_timestamp_val; req_msg.u.frame_msg.link_hdl = ctx_isp->base->link_hdl; req_msg.u.frame_msg.sof_status = sof_event_status; CDBG("%s: request id:%lld frame number:%lld SOF time stamp:0x%llx\n", __func__, request_id, ctx_isp->frame_id, ctx_isp->sof_timestamp_val); CDBG("%s sof status:%d\n", __func__, sof_event_status); if (cam_req_mgr_notify_frame_message(&req_msg, V4L_EVENT_CAM_REQ_MGR_SOF, V4L_EVENT_CAM_REQ_MGR_EVENT)) pr_err("%s: Error in notifying the sof time for req id:%lld\n", __func__, request_id); } static int __cam_isp_ctx_reg_upd_in_activated_state( struct cam_isp_context *ctx_isp, void *evt_data) { Loading @@ -123,12 +150,15 @@ static int __cam_isp_ctx_reg_upd_in_activated_state( req_isp = (struct cam_isp_ctx_req *) req->req_priv; if (req_isp->num_fence_map_out != 0) { CDBG("%s: move request %lld to active list\n", __func__, req->request_id); list_add_tail(&req->list, &ctx->active_req_list); ctx_isp->active_req_cnt++; CDBG("%s: move request %lld to active list(cnt = %d)\n", __func__, req->request_id, ctx_isp->active_req_cnt); } else { /* no io config, so the request is completed. */ list_add_tail(&req->list, &ctx->free_req_list); CDBG("%s: move active request %lld to free list(cnt = %d)\n", __func__, req->request_id, ctx_isp->active_req_cnt); } /* Loading @@ -145,12 +175,20 @@ static int __cam_isp_ctx_reg_upd_in_activated_state( static int __cam_isp_ctx_notify_sof_in_actived_state( struct cam_isp_context *ctx_isp, void *evt_data) { int rc = 0; struct cam_req_mgr_sof_notify notify; struct cam_context *ctx = ctx_isp->base; struct cam_ctx_request *req; uint64_t request_id = 0; /* notify reqmgr with sof signal */ if (ctx->ctx_crm_intf && ctx->ctx_crm_intf->notify_sof) { /* * notify reqmgr with sof signal. Note, due to scheduling delay * we can run into situation that two active requests has already * be in the active queue while we try to do the notification. * In this case, we need to skip the current notification. This * helps the state machine to catch up the delay. */ if (ctx->ctx_crm_intf && ctx->ctx_crm_intf->notify_sof && ctx_isp->active_req_cnt <= 2) { notify.link_hdl = ctx->link_hdl; notify.dev_hdl = ctx->dev_hdl; notify.frame_id = ctx_isp->frame_id; Loading @@ -158,21 +196,40 @@ static int __cam_isp_ctx_notify_sof_in_actived_state( ctx->ctx_crm_intf->notify_sof(¬ify); CDBG("%s: Notify CRM SOF frame %lld\n", __func__, ctx_isp->frame_id); list_for_each_entry(req, &ctx->active_req_list, list) { if (req->request_id > ctx_isp->reported_req_id) { request_id = req->request_id; ctx_isp->reported_req_id = request_id; break; } } __cam_isp_ctx_send_sof_timestamp(ctx_isp, request_id, CAM_REQ_MGR_SOF_EVENT_SUCCESS); } else { pr_err("%s: Can not notify SOF to CRM\n", __func__); } return rc; return 0; } static int __cam_isp_ctx_sof_in_sof(struct cam_isp_context *ctx_isp, void *evt_data) static int __cam_isp_ctx_sof_in_activated_state( struct cam_isp_context *ctx_isp, void *evt_data) { int rc = 0; struct cam_isp_hw_sof_event_data *sof_event_data = evt_data; if (!evt_data) { pr_err("%s: in valid sof event data\n", __func__); return -EINVAL; } CDBG("%s: Enter\n", __func__); ctx_isp->frame_id++; ctx_isp->sof_timestamp_val = sof_event_data->timestamp; CDBG("%s: frame id: %lld time stamp:0x%llx\n", __func__, ctx_isp->frame_id, ctx_isp->sof_timestamp_val); return rc; } Loading @@ -199,11 +256,15 @@ static int __cam_isp_ctx_reg_upd_in_sof(struct cam_isp_context *ctx_isp, struct cam_ctx_request, list); list_del_init(&req->list); req_isp = (struct cam_isp_ctx_req *) req->req_priv; if (req_isp->num_fence_map_out == req_isp->num_acked) if (req_isp->num_fence_map_out == req_isp->num_acked) { list_add_tail(&req->list, &ctx->free_req_list); else { } else { /* need to handle the buf done */ list_add_tail(&req->list, &ctx->active_req_list); ctx_isp->active_req_cnt++; CDBG("%s: move request %lld to active list(cnt = %d)\n", __func__, req->request_id, ctx_isp->active_req_cnt); ctx_isp->substate_activated = CAM_ISP_CTX_ACTIVATED_EPOCH; } Loading @@ -215,10 +276,10 @@ static int __cam_isp_ctx_reg_upd_in_sof(struct cam_isp_context *ctx_isp, static int __cam_isp_ctx_epoch_in_applied(struct cam_isp_context *ctx_isp, void *evt_data) { int rc = 0; struct cam_ctx_request *req; struct cam_isp_ctx_req *req_isp; struct cam_context *ctx = ctx_isp->base; uint64_t request_id = 0; if (list_empty(&ctx->pending_req_list)) { /* Loading @@ -227,6 +288,11 @@ static int __cam_isp_ctx_epoch_in_applied(struct cam_isp_context *ctx_isp, */ pr_err("%s: No pending request\n", __func__); ctx_isp->substate_activated = CAM_ISP_CTX_ACTIVATED_SOF; /* Send SOF event as empty frame*/ __cam_isp_ctx_send_sof_timestamp(ctx_isp, request_id, CAM_REQ_MGR_SOF_EVENT_SUCCESS); goto end; } Loading @@ -253,14 +319,21 @@ 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); ctx_isp->active_req_cnt++; CDBG("%s: move request %lld to active list(cnt = %d)\n", __func__, req->request_id, ctx_isp->active_req_cnt); req_isp->bubble_report = 0; } request_id = req->request_id; __cam_isp_ctx_send_sof_timestamp(ctx_isp, request_id, CAM_REQ_MGR_SOF_EVENT_ERROR); ctx_isp->substate_activated = CAM_ISP_CTX_ACTIVATED_BUBBLE; CDBG("%s: next substate %d\n", __func__, ctx_isp->substate_activated); end: return rc; return 0; } Loading @@ -281,13 +354,21 @@ 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; if (!evt_data) { pr_err("%s: in valid sof event data\n", __func__); return -EINVAL; } ctx_isp->frame_id++; ctx_isp->sof_timestamp_val = sof_event_data->timestamp; if (list_empty(&ctx->active_req_list)) ctx_isp->substate_activated = CAM_ISP_CTX_ACTIVATED_SOF; else CDBG("%s: Still need to wait for the buf done\n", __func__); CDBG("%s: next substate %d\n", __func__, ctx_isp->substate_activated); Loading @@ -305,14 +386,6 @@ static int __cam_isp_ctx_buf_done_in_epoch(struct cam_isp_context *ctx_isp, return rc; } static int __cam_isp_ctx_sof_in_bubble(struct cam_isp_context *ctx_isp, void *evt_data) { ctx_isp->frame_id++; return 0; } static int __cam_isp_ctx_buf_done_in_bubble( struct cam_isp_context *ctx_isp, void *evt_data) { Loading @@ -324,20 +397,13 @@ static int __cam_isp_ctx_buf_done_in_bubble( return rc; } static int __cam_isp_ctx_sof_in_bubble_applied( struct cam_isp_context *ctx_isp, void *evt_data) { ctx_isp->frame_id++; return 0; } static int __cam_isp_ctx_epoch_in_bubble_applied( struct cam_isp_context *ctx_isp, void *evt_data) { struct cam_ctx_request *req; struct cam_isp_ctx_req *req_isp; struct cam_context *ctx = ctx_isp->base; uint64_t request_id = 0; /* * This means we missed the reg upd ack. So we need to Loading @@ -350,6 +416,9 @@ static int __cam_isp_ctx_epoch_in_bubble_applied( * Just go back to the bubble state. */ pr_err("%s: No pending request.\n", __func__); __cam_isp_ctx_send_sof_timestamp(ctx_isp, request_id, CAM_REQ_MGR_SOF_EVENT_SUCCESS); ctx_isp->substate_activated = CAM_ISP_CTX_ACTIVATED_BUBBLE; goto end; } Loading @@ -376,9 +445,16 @@ static int __cam_isp_ctx_epoch_in_bubble_applied( */ list_del_init(&req->list); list_add_tail(&req->list, &ctx->active_req_list); ctx_isp->active_req_cnt++; CDBG("%s: move request %lld to active list(cnt = %d)\n", __func__, req->request_id, ctx_isp->active_req_cnt); req_isp->bubble_report = 0; } request_id = req->request_id; __cam_isp_ctx_send_sof_timestamp(ctx_isp, request_id, CAM_REQ_MGR_SOF_EVENT_ERROR); ctx_isp->substate_activated = CAM_ISP_CTX_ACTIVATED_BUBBLE; CDBG("%s: next substate %d\n", __func__, ctx_isp->substate_activated); end: Loading Loading @@ -457,7 +533,7 @@ static struct cam_isp_ctx_irq_ops { .irq_ops = { NULL, __cam_isp_ctx_sof_in_sof, __cam_isp_ctx_sof_in_activated_state, __cam_isp_ctx_reg_upd_in_sof, __cam_isp_ctx_notify_sof_in_actived_state, NULL, Loading @@ -468,7 +544,7 @@ static struct cam_isp_ctx_irq_ops { .irq_ops = { __cam_isp_ctx_handle_error, __cam_isp_ctx_sof_in_sof, __cam_isp_ctx_sof_in_activated_state, __cam_isp_ctx_reg_upd_in_activated_state, __cam_isp_ctx_epoch_in_applied, NULL, Loading @@ -490,7 +566,7 @@ static struct cam_isp_ctx_irq_ops { .irq_ops = { NULL, __cam_isp_ctx_sof_in_bubble, __cam_isp_ctx_sof_in_activated_state, NULL, __cam_isp_ctx_notify_sof_in_actived_state, NULL, Loading @@ -501,7 +577,7 @@ static struct cam_isp_ctx_irq_ops { .irq_ops = { NULL, __cam_isp_ctx_sof_in_bubble_applied, __cam_isp_ctx_sof_in_activated_state, __cam_isp_ctx_reg_upd_in_activated_state, __cam_isp_ctx_epoch_in_bubble_applied, NULL, Loading @@ -518,7 +594,6 @@ static int __cam_isp_ctx_apply_req_in_activated_state( uint32_t next_state) { int rc = 0; int cnt = 0; struct cam_ctx_request *req; struct cam_isp_ctx_req *req_isp; struct cam_isp_context *ctx_isp; Loading @@ -537,14 +612,13 @@ static int __cam_isp_ctx_apply_req_in_activated_state( * The maximum number of request allowed to be outstanding is 2. * */ list_for_each_entry(req, &ctx->active_req_list, list) { if (++cnt > 2) { pr_err_ratelimited("%s: Apply failed due to congest\n", __func__); ctx_isp = (struct cam_isp_context *) ctx->ctx_priv; if (ctx_isp->active_req_cnt >= 2) { CDBG("%s: Reject apply request due to congestion(cnt = %d)\n", __func__, ctx_isp->active_req_cnt); rc = -EFAULT; goto end; } } req = list_first_entry(&ctx->pending_req_list, struct cam_ctx_request, list); Loading @@ -560,7 +634,6 @@ static int __cam_isp_ctx_apply_req_in_activated_state( CDBG("%s: Apply request %lld\n", __func__, req->request_id); req_isp = (struct cam_isp_ctx_req *) req->req_priv; ctx_isp = (struct cam_isp_context *) ctx->ctx_priv; req_isp->bubble_report = apply->report_if_bubble; Loading Loading @@ -786,6 +859,8 @@ static int __cam_isp_ctx_release_dev_in_top_state(struct cam_context *ctx, ctx->link_hdl = 0; ctx->ctx_crm_intf = NULL; ctx_isp->frame_id = 0; ctx_isp->active_req_cnt = 0; ctx_isp->reported_req_id = 0; /* * Ideally, we should never have any active request here. Loading Loading @@ -855,7 +930,7 @@ static int __cam_isp_ctx_config_dev_in_top_state( CDBG("%s: packet address is 0x%llx\n", __func__, packet_addr); CDBG("%s: packet with length %zu, offset 0x%llx\n", __func__, len, cmd->offset); CDBG("%s: Packet request id 0x%llx\n", __func__, CDBG("%s: Packet request id %lld\n", __func__, packet->header.request_id); CDBG("%s: Packet size 0x%x\n", __func__, packet->header.size); CDBG("%s: packet op %d\n", __func__, packet->header.op_code); Loading Loading @@ -1121,6 +1196,8 @@ static int __cam_isp_ctx_start_dev_in_ready(struct cam_context *ctx, arg.num_hw_update_entries = req_isp->num_cfg; ctx_isp->frame_id = 0; ctx_isp->active_req_cnt = 0; ctx_isp->reported_req_id = 0; ctx_isp->substate_activated = CAM_ISP_CTX_ACTIVATED_SOF; /* Loading Loading @@ -1209,6 +1286,8 @@ static int __cam_isp_ctx_stop_dev_in_activated_unlock( list_add_tail(&req->list, &ctx->free_req_list); } ctx_isp->frame_id = 0; ctx_isp->active_req_cnt = 0; ctx_isp->reported_req_id = 0; CDBG("%s: next state %d", __func__, ctx->state); return rc; Loading Loading @@ -1259,8 +1338,8 @@ static int __cam_isp_ctx_apply_req(struct cam_context *ctx, struct cam_isp_context *ctx_isp = (struct cam_isp_context *) ctx->ctx_priv; CDBG("%s: Enter: apply req in Substate %d\n", __func__, ctx_isp->substate_activated); CDBG("%s: Enter: apply req in Substate %d request _id:%lld\n", __func__, ctx_isp->substate_activated, apply->request_id); if (ctx_isp->substate_machine[ctx_isp->substate_activated]. crm_ops.apply_req) { rc = ctx_isp->substate_machine[ctx_isp->substate_activated]. Loading Loading @@ -1383,6 +1462,8 @@ 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->hw_ctx = NULL; ctx->substate_activated = CAM_ISP_CTX_ACTIVATED_SOF; ctx->substate_machine = cam_isp_ctx_activated_state_machine; Loading drivers/media/platform/msm/camera/cam_isp/cam_isp_context.h +6 −1 Original line number Diff line number Diff line Loading @@ -106,7 +106,9 @@ struct cam_isp_ctx_req { * @req_base: Common request object storage * @req_isp: ISP private request object storage * @hw_ctx: HW object returned by the acquire device command * * @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 */ struct cam_isp_context { struct cam_context *base; Loading @@ -120,6 +122,9 @@ struct cam_isp_context { struct cam_isp_ctx_req req_isp[CAM_CTX_REQ_MAX]; void *hw_ctx; uint64_t sof_timestamp_val; int32_t active_req_cnt; int64_t reported_req_id; }; /** Loading drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c +63 −3 Original line number Diff line number Diff line Loading @@ -1982,6 +1982,57 @@ static int cam_ife_mgr_prepare_hw_update(void *hw_mgr_priv, return rc; } static int cam_ife_mgr_cmd_get_sof_timestamp( struct cam_ife_hw_mgr_ctx *ife_ctx, uint64_t *time_stamp) { int rc = -EINVAL; uint32_t i; struct cam_ife_hw_mgr_res *hw_mgr_res; struct cam_hw_intf *hw_intf; struct cam_csid_get_time_stamp_args csid_get_time; list_for_each_entry(hw_mgr_res, &ife_ctx->res_list_ife_csid, list) { for (i = 0; i < CAM_ISP_HW_SPLIT_MAX; i++) { if (!hw_mgr_res->hw_res[i] || (i == CAM_ISP_HW_SPLIT_RIGHT)) continue; /* * Get the SOF time stamp from left resource only. * Left resource is master for dual vfe case and * Rdi only context case left resource only hold * the RDI resource */ hw_intf = hw_mgr_res->hw_res[i]->hw_intf; if (hw_intf->hw_ops.process_cmd) { csid_get_time.node_res = hw_mgr_res->hw_res[i]; rc = hw_intf->hw_ops.process_cmd( hw_intf->hw_priv, CAM_IFE_CSID_CMD_GET_TIME_STAMP, &csid_get_time, sizeof( struct cam_csid_get_time_stamp_args)); if (!rc) *time_stamp = csid_get_time.time_stamp_val; /* * Single VFE case, Get the time stamp from available * one csid hw in the context * Dual VFE case, get the time stamp from master(left) * would be sufficient */ goto end; } } } end: if (rc) pr_err("%s:error in getting sof time stamp\n", __func__); return rc; } static int cam_ife_mgr_process_recovery_cb(void *priv, void *data) { int32_t rc = 0; Loading Loading @@ -2572,12 +2623,17 @@ static int cam_ife_hw_mgr_handle_sof_for_camif_hw_res( if (core_idx == hw_res_l->hw_intf->hw_idx) { sof_status = hw_res_l->bottom_half_handler( hw_res_l, evt_payload); if (!sof_status) if (!sof_status) { cam_ife_mgr_cmd_get_sof_timestamp( ife_hwr_mgr_ctx, &sof_done_event_data.timestamp); ife_hwr_irq_sof_cb( ife_hwr_mgr_ctx->common.cb_priv, CAM_ISP_HW_EVENT_SOF, &sof_done_event_data); } } break; Loading Loading @@ -2623,12 +2679,16 @@ static int cam_ife_hw_mgr_handle_sof_for_camif_hw_res( rc = cam_ife_hw_mgr_check_sof_for_dual_vfe( ife_hwr_mgr_ctx, core_index0, core_index1); if (!rc) if (!rc) { cam_ife_mgr_cmd_get_sof_timestamp( ife_hwr_mgr_ctx, &sof_done_event_data.timestamp); ife_hwr_irq_sof_cb( ife_hwr_mgr_ctx->common.cb_priv, CAM_ISP_HW_EVENT_SOF, &sof_done_event_data); } break; default: Loading drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/include/cam_isp_hw_mgr_intf.h +12 −12 Original line number Diff line number Diff line Loading @@ -50,32 +50,32 @@ enum cam_isp_hw_err_type { /** * struct cam_isp_hw_sof_event_data - Event payload for CAM_HW_EVENT_SOF * * @timestamp: Timestamp for the buf done event * @timestamp: Time stamp for the sof event * */ struct cam_isp_hw_sof_event_data { struct timeval timestamp; uint64_t timestamp; }; /** * struct cam_isp_hw_reg_update_event_data - Event payload for * CAM_HW_EVENT_REG_UPDATE * * @timestamp: Timestamp for the buf done event * @timestamp: Time stamp for the reg update event * */ struct cam_isp_hw_reg_update_event_data { struct timeval timestamp; uint64_t timestamp; }; /** * struct cam_isp_hw_epoch_event_data - Event payload for CAM_HW_EVENT_EPOCH * * @timestamp: Timestamp for the buf done event * @timestamp: Time stamp for the epoch event * */ struct cam_isp_hw_epoch_event_data { struct timeval timestamp; uint64_t timestamp; }; /** Loading @@ -90,29 +90,29 @@ struct cam_isp_hw_done_event_data { uint32_t num_handles; uint32_t resource_handle[ CAM_NUM_OUT_PER_COMP_IRQ_MAX]; struct timeval timestamp; uint64_t timestamp; }; /** * struct cam_isp_hw_eof_event_data - Event payload for CAM_HW_EVENT_EOF * * @timestamp: Timestamp for the buf done event * @timestamp: Timestamp for the eof event * */ struct cam_isp_hw_eof_event_data { struct timeval timestamp; uint64_t timestamp; }; /** * struct cam_isp_hw_error_event_data - Event payload for CAM_HW_EVENT_ERROR * * @error_type: error type for the error event * @timestamp: Timestamp for the buf done event * @error_type: Error type for the error event * @timestamp: Timestamp for the error event * */ struct cam_isp_hw_error_event_data { uint32_t error_type; struct timeval timestamp; uint64_t timestamp; }; /** Loading drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.c +8 −2 Original line number Diff line number Diff line Loading @@ -1150,6 +1150,10 @@ static int cam_ife_csid_init_config_ipp_path( cam_io_w_mb(val, soc_info->reg_map[0].mem_base + csid_reg->ipp_reg->csid_ipp_cfg0_addr); /* select the post irq sub sample strobe for time stamp capture */ cam_io_w_mb(CSID_TIMESTAMP_STB_POST_IRQ, soc_info->reg_map[0].mem_base + csid_reg->ipp_reg->csid_ipp_cfg1_addr); if (path_data->crop_enable) { val = ((path_data->width + path_data->start_pixel) & 0xFFFF << Loading Loading @@ -1435,6 +1439,10 @@ static int cam_ife_csid_init_config_rdi_path( cam_io_w_mb(val, soc_info->reg_map[0].mem_base + csid_reg->rdi_reg[id]->csid_rdi_cfg0_addr); /* select the post irq sub sample strobe for time stamp capture */ cam_io_w_mb(CSID_TIMESTAMP_STB_POST_IRQ, soc_info->reg_map[0].mem_base + csid_reg->rdi_reg[id]->csid_rdi_cfg1_addr); if (path_data->crop_enable) { val = ((path_data->width + path_data->start_pixel) & 0xFFFF << Loading Loading @@ -2220,7 +2228,6 @@ static int cam_ife_csid_process_cmd(void *hw_priv, csid_hw_info = (struct cam_hw_info *)hw_priv; csid_hw = (struct cam_ife_csid_hw *)csid_hw_info->core_info; mutex_lock(&csid_hw->hw_info->hw_mutex); switch (cmd_type) { case CAM_IFE_CSID_CMD_GET_TIME_STAMP: rc = cam_ife_csid_get_time_stamp(csid_hw, cmd_args); Loading @@ -2231,7 +2238,6 @@ static int cam_ife_csid_process_cmd(void *hw_priv, rc = -EINVAL; break; } mutex_unlock(&csid_hw->hw_info->hw_mutex); return rc; Loading Loading
drivers/media/platform/msm/camera/cam_isp/cam_isp_context.c +127 −46 Original line number Diff line number Diff line Loading @@ -99,12 +99,39 @@ static int __cam_isp_ctx_handle_buf_done_in_activated_state( if (req_isp->num_acked == req_isp->num_fence_map_out) { list_del_init(&req->list); list_add_tail(&req->list, &ctx->free_req_list); ctx_isp->active_req_cnt--; CDBG("%s: Move active request %lld to free list(cnt = %d)\n", __func__, req->request_id, ctx_isp->active_req_cnt); } end: return rc; } static void __cam_isp_ctx_send_sof_timestamp( struct cam_isp_context *ctx_isp, uint64_t request_id, uint32_t sof_event_status) { struct cam_req_mgr_message req_msg; req_msg.session_hdl = ctx_isp->base->session_hdl; req_msg.u.frame_msg.frame_id = ctx_isp->frame_id; req_msg.u.frame_msg.request_id = request_id; req_msg.u.frame_msg.timestamp = ctx_isp->sof_timestamp_val; req_msg.u.frame_msg.link_hdl = ctx_isp->base->link_hdl; req_msg.u.frame_msg.sof_status = sof_event_status; CDBG("%s: request id:%lld frame number:%lld SOF time stamp:0x%llx\n", __func__, request_id, ctx_isp->frame_id, ctx_isp->sof_timestamp_val); CDBG("%s sof status:%d\n", __func__, sof_event_status); if (cam_req_mgr_notify_frame_message(&req_msg, V4L_EVENT_CAM_REQ_MGR_SOF, V4L_EVENT_CAM_REQ_MGR_EVENT)) pr_err("%s: Error in notifying the sof time for req id:%lld\n", __func__, request_id); } static int __cam_isp_ctx_reg_upd_in_activated_state( struct cam_isp_context *ctx_isp, void *evt_data) { Loading @@ -123,12 +150,15 @@ static int __cam_isp_ctx_reg_upd_in_activated_state( req_isp = (struct cam_isp_ctx_req *) req->req_priv; if (req_isp->num_fence_map_out != 0) { CDBG("%s: move request %lld to active list\n", __func__, req->request_id); list_add_tail(&req->list, &ctx->active_req_list); ctx_isp->active_req_cnt++; CDBG("%s: move request %lld to active list(cnt = %d)\n", __func__, req->request_id, ctx_isp->active_req_cnt); } else { /* no io config, so the request is completed. */ list_add_tail(&req->list, &ctx->free_req_list); CDBG("%s: move active request %lld to free list(cnt = %d)\n", __func__, req->request_id, ctx_isp->active_req_cnt); } /* Loading @@ -145,12 +175,20 @@ static int __cam_isp_ctx_reg_upd_in_activated_state( static int __cam_isp_ctx_notify_sof_in_actived_state( struct cam_isp_context *ctx_isp, void *evt_data) { int rc = 0; struct cam_req_mgr_sof_notify notify; struct cam_context *ctx = ctx_isp->base; struct cam_ctx_request *req; uint64_t request_id = 0; /* notify reqmgr with sof signal */ if (ctx->ctx_crm_intf && ctx->ctx_crm_intf->notify_sof) { /* * notify reqmgr with sof signal. Note, due to scheduling delay * we can run into situation that two active requests has already * be in the active queue while we try to do the notification. * In this case, we need to skip the current notification. This * helps the state machine to catch up the delay. */ if (ctx->ctx_crm_intf && ctx->ctx_crm_intf->notify_sof && ctx_isp->active_req_cnt <= 2) { notify.link_hdl = ctx->link_hdl; notify.dev_hdl = ctx->dev_hdl; notify.frame_id = ctx_isp->frame_id; Loading @@ -158,21 +196,40 @@ static int __cam_isp_ctx_notify_sof_in_actived_state( ctx->ctx_crm_intf->notify_sof(¬ify); CDBG("%s: Notify CRM SOF frame %lld\n", __func__, ctx_isp->frame_id); list_for_each_entry(req, &ctx->active_req_list, list) { if (req->request_id > ctx_isp->reported_req_id) { request_id = req->request_id; ctx_isp->reported_req_id = request_id; break; } } __cam_isp_ctx_send_sof_timestamp(ctx_isp, request_id, CAM_REQ_MGR_SOF_EVENT_SUCCESS); } else { pr_err("%s: Can not notify SOF to CRM\n", __func__); } return rc; return 0; } static int __cam_isp_ctx_sof_in_sof(struct cam_isp_context *ctx_isp, void *evt_data) static int __cam_isp_ctx_sof_in_activated_state( struct cam_isp_context *ctx_isp, void *evt_data) { int rc = 0; struct cam_isp_hw_sof_event_data *sof_event_data = evt_data; if (!evt_data) { pr_err("%s: in valid sof event data\n", __func__); return -EINVAL; } CDBG("%s: Enter\n", __func__); ctx_isp->frame_id++; ctx_isp->sof_timestamp_val = sof_event_data->timestamp; CDBG("%s: frame id: %lld time stamp:0x%llx\n", __func__, ctx_isp->frame_id, ctx_isp->sof_timestamp_val); return rc; } Loading @@ -199,11 +256,15 @@ static int __cam_isp_ctx_reg_upd_in_sof(struct cam_isp_context *ctx_isp, struct cam_ctx_request, list); list_del_init(&req->list); req_isp = (struct cam_isp_ctx_req *) req->req_priv; if (req_isp->num_fence_map_out == req_isp->num_acked) if (req_isp->num_fence_map_out == req_isp->num_acked) { list_add_tail(&req->list, &ctx->free_req_list); else { } else { /* need to handle the buf done */ list_add_tail(&req->list, &ctx->active_req_list); ctx_isp->active_req_cnt++; CDBG("%s: move request %lld to active list(cnt = %d)\n", __func__, req->request_id, ctx_isp->active_req_cnt); ctx_isp->substate_activated = CAM_ISP_CTX_ACTIVATED_EPOCH; } Loading @@ -215,10 +276,10 @@ static int __cam_isp_ctx_reg_upd_in_sof(struct cam_isp_context *ctx_isp, static int __cam_isp_ctx_epoch_in_applied(struct cam_isp_context *ctx_isp, void *evt_data) { int rc = 0; struct cam_ctx_request *req; struct cam_isp_ctx_req *req_isp; struct cam_context *ctx = ctx_isp->base; uint64_t request_id = 0; if (list_empty(&ctx->pending_req_list)) { /* Loading @@ -227,6 +288,11 @@ static int __cam_isp_ctx_epoch_in_applied(struct cam_isp_context *ctx_isp, */ pr_err("%s: No pending request\n", __func__); ctx_isp->substate_activated = CAM_ISP_CTX_ACTIVATED_SOF; /* Send SOF event as empty frame*/ __cam_isp_ctx_send_sof_timestamp(ctx_isp, request_id, CAM_REQ_MGR_SOF_EVENT_SUCCESS); goto end; } Loading @@ -253,14 +319,21 @@ 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); ctx_isp->active_req_cnt++; CDBG("%s: move request %lld to active list(cnt = %d)\n", __func__, req->request_id, ctx_isp->active_req_cnt); req_isp->bubble_report = 0; } request_id = req->request_id; __cam_isp_ctx_send_sof_timestamp(ctx_isp, request_id, CAM_REQ_MGR_SOF_EVENT_ERROR); ctx_isp->substate_activated = CAM_ISP_CTX_ACTIVATED_BUBBLE; CDBG("%s: next substate %d\n", __func__, ctx_isp->substate_activated); end: return rc; return 0; } Loading @@ -281,13 +354,21 @@ 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; if (!evt_data) { pr_err("%s: in valid sof event data\n", __func__); return -EINVAL; } ctx_isp->frame_id++; ctx_isp->sof_timestamp_val = sof_event_data->timestamp; if (list_empty(&ctx->active_req_list)) ctx_isp->substate_activated = CAM_ISP_CTX_ACTIVATED_SOF; else CDBG("%s: Still need to wait for the buf done\n", __func__); CDBG("%s: next substate %d\n", __func__, ctx_isp->substate_activated); Loading @@ -305,14 +386,6 @@ static int __cam_isp_ctx_buf_done_in_epoch(struct cam_isp_context *ctx_isp, return rc; } static int __cam_isp_ctx_sof_in_bubble(struct cam_isp_context *ctx_isp, void *evt_data) { ctx_isp->frame_id++; return 0; } static int __cam_isp_ctx_buf_done_in_bubble( struct cam_isp_context *ctx_isp, void *evt_data) { Loading @@ -324,20 +397,13 @@ static int __cam_isp_ctx_buf_done_in_bubble( return rc; } static int __cam_isp_ctx_sof_in_bubble_applied( struct cam_isp_context *ctx_isp, void *evt_data) { ctx_isp->frame_id++; return 0; } static int __cam_isp_ctx_epoch_in_bubble_applied( struct cam_isp_context *ctx_isp, void *evt_data) { struct cam_ctx_request *req; struct cam_isp_ctx_req *req_isp; struct cam_context *ctx = ctx_isp->base; uint64_t request_id = 0; /* * This means we missed the reg upd ack. So we need to Loading @@ -350,6 +416,9 @@ static int __cam_isp_ctx_epoch_in_bubble_applied( * Just go back to the bubble state. */ pr_err("%s: No pending request.\n", __func__); __cam_isp_ctx_send_sof_timestamp(ctx_isp, request_id, CAM_REQ_MGR_SOF_EVENT_SUCCESS); ctx_isp->substate_activated = CAM_ISP_CTX_ACTIVATED_BUBBLE; goto end; } Loading @@ -376,9 +445,16 @@ static int __cam_isp_ctx_epoch_in_bubble_applied( */ list_del_init(&req->list); list_add_tail(&req->list, &ctx->active_req_list); ctx_isp->active_req_cnt++; CDBG("%s: move request %lld to active list(cnt = %d)\n", __func__, req->request_id, ctx_isp->active_req_cnt); req_isp->bubble_report = 0; } request_id = req->request_id; __cam_isp_ctx_send_sof_timestamp(ctx_isp, request_id, CAM_REQ_MGR_SOF_EVENT_ERROR); ctx_isp->substate_activated = CAM_ISP_CTX_ACTIVATED_BUBBLE; CDBG("%s: next substate %d\n", __func__, ctx_isp->substate_activated); end: Loading Loading @@ -457,7 +533,7 @@ static struct cam_isp_ctx_irq_ops { .irq_ops = { NULL, __cam_isp_ctx_sof_in_sof, __cam_isp_ctx_sof_in_activated_state, __cam_isp_ctx_reg_upd_in_sof, __cam_isp_ctx_notify_sof_in_actived_state, NULL, Loading @@ -468,7 +544,7 @@ static struct cam_isp_ctx_irq_ops { .irq_ops = { __cam_isp_ctx_handle_error, __cam_isp_ctx_sof_in_sof, __cam_isp_ctx_sof_in_activated_state, __cam_isp_ctx_reg_upd_in_activated_state, __cam_isp_ctx_epoch_in_applied, NULL, Loading @@ -490,7 +566,7 @@ static struct cam_isp_ctx_irq_ops { .irq_ops = { NULL, __cam_isp_ctx_sof_in_bubble, __cam_isp_ctx_sof_in_activated_state, NULL, __cam_isp_ctx_notify_sof_in_actived_state, NULL, Loading @@ -501,7 +577,7 @@ static struct cam_isp_ctx_irq_ops { .irq_ops = { NULL, __cam_isp_ctx_sof_in_bubble_applied, __cam_isp_ctx_sof_in_activated_state, __cam_isp_ctx_reg_upd_in_activated_state, __cam_isp_ctx_epoch_in_bubble_applied, NULL, Loading @@ -518,7 +594,6 @@ static int __cam_isp_ctx_apply_req_in_activated_state( uint32_t next_state) { int rc = 0; int cnt = 0; struct cam_ctx_request *req; struct cam_isp_ctx_req *req_isp; struct cam_isp_context *ctx_isp; Loading @@ -537,14 +612,13 @@ static int __cam_isp_ctx_apply_req_in_activated_state( * The maximum number of request allowed to be outstanding is 2. * */ list_for_each_entry(req, &ctx->active_req_list, list) { if (++cnt > 2) { pr_err_ratelimited("%s: Apply failed due to congest\n", __func__); ctx_isp = (struct cam_isp_context *) ctx->ctx_priv; if (ctx_isp->active_req_cnt >= 2) { CDBG("%s: Reject apply request due to congestion(cnt = %d)\n", __func__, ctx_isp->active_req_cnt); rc = -EFAULT; goto end; } } req = list_first_entry(&ctx->pending_req_list, struct cam_ctx_request, list); Loading @@ -560,7 +634,6 @@ static int __cam_isp_ctx_apply_req_in_activated_state( CDBG("%s: Apply request %lld\n", __func__, req->request_id); req_isp = (struct cam_isp_ctx_req *) req->req_priv; ctx_isp = (struct cam_isp_context *) ctx->ctx_priv; req_isp->bubble_report = apply->report_if_bubble; Loading Loading @@ -786,6 +859,8 @@ static int __cam_isp_ctx_release_dev_in_top_state(struct cam_context *ctx, ctx->link_hdl = 0; ctx->ctx_crm_intf = NULL; ctx_isp->frame_id = 0; ctx_isp->active_req_cnt = 0; ctx_isp->reported_req_id = 0; /* * Ideally, we should never have any active request here. Loading Loading @@ -855,7 +930,7 @@ static int __cam_isp_ctx_config_dev_in_top_state( CDBG("%s: packet address is 0x%llx\n", __func__, packet_addr); CDBG("%s: packet with length %zu, offset 0x%llx\n", __func__, len, cmd->offset); CDBG("%s: Packet request id 0x%llx\n", __func__, CDBG("%s: Packet request id %lld\n", __func__, packet->header.request_id); CDBG("%s: Packet size 0x%x\n", __func__, packet->header.size); CDBG("%s: packet op %d\n", __func__, packet->header.op_code); Loading Loading @@ -1121,6 +1196,8 @@ static int __cam_isp_ctx_start_dev_in_ready(struct cam_context *ctx, arg.num_hw_update_entries = req_isp->num_cfg; ctx_isp->frame_id = 0; ctx_isp->active_req_cnt = 0; ctx_isp->reported_req_id = 0; ctx_isp->substate_activated = CAM_ISP_CTX_ACTIVATED_SOF; /* Loading Loading @@ -1209,6 +1286,8 @@ static int __cam_isp_ctx_stop_dev_in_activated_unlock( list_add_tail(&req->list, &ctx->free_req_list); } ctx_isp->frame_id = 0; ctx_isp->active_req_cnt = 0; ctx_isp->reported_req_id = 0; CDBG("%s: next state %d", __func__, ctx->state); return rc; Loading Loading @@ -1259,8 +1338,8 @@ static int __cam_isp_ctx_apply_req(struct cam_context *ctx, struct cam_isp_context *ctx_isp = (struct cam_isp_context *) ctx->ctx_priv; CDBG("%s: Enter: apply req in Substate %d\n", __func__, ctx_isp->substate_activated); CDBG("%s: Enter: apply req in Substate %d request _id:%lld\n", __func__, ctx_isp->substate_activated, apply->request_id); if (ctx_isp->substate_machine[ctx_isp->substate_activated]. crm_ops.apply_req) { rc = ctx_isp->substate_machine[ctx_isp->substate_activated]. Loading Loading @@ -1383,6 +1462,8 @@ 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->hw_ctx = NULL; ctx->substate_activated = CAM_ISP_CTX_ACTIVATED_SOF; ctx->substate_machine = cam_isp_ctx_activated_state_machine; Loading
drivers/media/platform/msm/camera/cam_isp/cam_isp_context.h +6 −1 Original line number Diff line number Diff line Loading @@ -106,7 +106,9 @@ struct cam_isp_ctx_req { * @req_base: Common request object storage * @req_isp: ISP private request object storage * @hw_ctx: HW object returned by the acquire device command * * @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 */ struct cam_isp_context { struct cam_context *base; Loading @@ -120,6 +122,9 @@ struct cam_isp_context { struct cam_isp_ctx_req req_isp[CAM_CTX_REQ_MAX]; void *hw_ctx; uint64_t sof_timestamp_val; int32_t active_req_cnt; int64_t reported_req_id; }; /** Loading
drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c +63 −3 Original line number Diff line number Diff line Loading @@ -1982,6 +1982,57 @@ static int cam_ife_mgr_prepare_hw_update(void *hw_mgr_priv, return rc; } static int cam_ife_mgr_cmd_get_sof_timestamp( struct cam_ife_hw_mgr_ctx *ife_ctx, uint64_t *time_stamp) { int rc = -EINVAL; uint32_t i; struct cam_ife_hw_mgr_res *hw_mgr_res; struct cam_hw_intf *hw_intf; struct cam_csid_get_time_stamp_args csid_get_time; list_for_each_entry(hw_mgr_res, &ife_ctx->res_list_ife_csid, list) { for (i = 0; i < CAM_ISP_HW_SPLIT_MAX; i++) { if (!hw_mgr_res->hw_res[i] || (i == CAM_ISP_HW_SPLIT_RIGHT)) continue; /* * Get the SOF time stamp from left resource only. * Left resource is master for dual vfe case and * Rdi only context case left resource only hold * the RDI resource */ hw_intf = hw_mgr_res->hw_res[i]->hw_intf; if (hw_intf->hw_ops.process_cmd) { csid_get_time.node_res = hw_mgr_res->hw_res[i]; rc = hw_intf->hw_ops.process_cmd( hw_intf->hw_priv, CAM_IFE_CSID_CMD_GET_TIME_STAMP, &csid_get_time, sizeof( struct cam_csid_get_time_stamp_args)); if (!rc) *time_stamp = csid_get_time.time_stamp_val; /* * Single VFE case, Get the time stamp from available * one csid hw in the context * Dual VFE case, get the time stamp from master(left) * would be sufficient */ goto end; } } } end: if (rc) pr_err("%s:error in getting sof time stamp\n", __func__); return rc; } static int cam_ife_mgr_process_recovery_cb(void *priv, void *data) { int32_t rc = 0; Loading Loading @@ -2572,12 +2623,17 @@ static int cam_ife_hw_mgr_handle_sof_for_camif_hw_res( if (core_idx == hw_res_l->hw_intf->hw_idx) { sof_status = hw_res_l->bottom_half_handler( hw_res_l, evt_payload); if (!sof_status) if (!sof_status) { cam_ife_mgr_cmd_get_sof_timestamp( ife_hwr_mgr_ctx, &sof_done_event_data.timestamp); ife_hwr_irq_sof_cb( ife_hwr_mgr_ctx->common.cb_priv, CAM_ISP_HW_EVENT_SOF, &sof_done_event_data); } } break; Loading Loading @@ -2623,12 +2679,16 @@ static int cam_ife_hw_mgr_handle_sof_for_camif_hw_res( rc = cam_ife_hw_mgr_check_sof_for_dual_vfe( ife_hwr_mgr_ctx, core_index0, core_index1); if (!rc) if (!rc) { cam_ife_mgr_cmd_get_sof_timestamp( ife_hwr_mgr_ctx, &sof_done_event_data.timestamp); ife_hwr_irq_sof_cb( ife_hwr_mgr_ctx->common.cb_priv, CAM_ISP_HW_EVENT_SOF, &sof_done_event_data); } break; default: Loading
drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/include/cam_isp_hw_mgr_intf.h +12 −12 Original line number Diff line number Diff line Loading @@ -50,32 +50,32 @@ enum cam_isp_hw_err_type { /** * struct cam_isp_hw_sof_event_data - Event payload for CAM_HW_EVENT_SOF * * @timestamp: Timestamp for the buf done event * @timestamp: Time stamp for the sof event * */ struct cam_isp_hw_sof_event_data { struct timeval timestamp; uint64_t timestamp; }; /** * struct cam_isp_hw_reg_update_event_data - Event payload for * CAM_HW_EVENT_REG_UPDATE * * @timestamp: Timestamp for the buf done event * @timestamp: Time stamp for the reg update event * */ struct cam_isp_hw_reg_update_event_data { struct timeval timestamp; uint64_t timestamp; }; /** * struct cam_isp_hw_epoch_event_data - Event payload for CAM_HW_EVENT_EPOCH * * @timestamp: Timestamp for the buf done event * @timestamp: Time stamp for the epoch event * */ struct cam_isp_hw_epoch_event_data { struct timeval timestamp; uint64_t timestamp; }; /** Loading @@ -90,29 +90,29 @@ struct cam_isp_hw_done_event_data { uint32_t num_handles; uint32_t resource_handle[ CAM_NUM_OUT_PER_COMP_IRQ_MAX]; struct timeval timestamp; uint64_t timestamp; }; /** * struct cam_isp_hw_eof_event_data - Event payload for CAM_HW_EVENT_EOF * * @timestamp: Timestamp for the buf done event * @timestamp: Timestamp for the eof event * */ struct cam_isp_hw_eof_event_data { struct timeval timestamp; uint64_t timestamp; }; /** * struct cam_isp_hw_error_event_data - Event payload for CAM_HW_EVENT_ERROR * * @error_type: error type for the error event * @timestamp: Timestamp for the buf done event * @error_type: Error type for the error event * @timestamp: Timestamp for the error event * */ struct cam_isp_hw_error_event_data { uint32_t error_type; struct timeval timestamp; uint64_t timestamp; }; /** Loading
drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_core.c +8 −2 Original line number Diff line number Diff line Loading @@ -1150,6 +1150,10 @@ static int cam_ife_csid_init_config_ipp_path( cam_io_w_mb(val, soc_info->reg_map[0].mem_base + csid_reg->ipp_reg->csid_ipp_cfg0_addr); /* select the post irq sub sample strobe for time stamp capture */ cam_io_w_mb(CSID_TIMESTAMP_STB_POST_IRQ, soc_info->reg_map[0].mem_base + csid_reg->ipp_reg->csid_ipp_cfg1_addr); if (path_data->crop_enable) { val = ((path_data->width + path_data->start_pixel) & 0xFFFF << Loading Loading @@ -1435,6 +1439,10 @@ static int cam_ife_csid_init_config_rdi_path( cam_io_w_mb(val, soc_info->reg_map[0].mem_base + csid_reg->rdi_reg[id]->csid_rdi_cfg0_addr); /* select the post irq sub sample strobe for time stamp capture */ cam_io_w_mb(CSID_TIMESTAMP_STB_POST_IRQ, soc_info->reg_map[0].mem_base + csid_reg->rdi_reg[id]->csid_rdi_cfg1_addr); if (path_data->crop_enable) { val = ((path_data->width + path_data->start_pixel) & 0xFFFF << Loading Loading @@ -2220,7 +2228,6 @@ static int cam_ife_csid_process_cmd(void *hw_priv, csid_hw_info = (struct cam_hw_info *)hw_priv; csid_hw = (struct cam_ife_csid_hw *)csid_hw_info->core_info; mutex_lock(&csid_hw->hw_info->hw_mutex); switch (cmd_type) { case CAM_IFE_CSID_CMD_GET_TIME_STAMP: rc = cam_ife_csid_get_time_stamp(csid_hw, cmd_args); Loading @@ -2231,7 +2238,6 @@ static int cam_ife_csid_process_cmd(void *hw_priv, rc = -EINVAL; break; } mutex_unlock(&csid_hw->hw_info->hw_mutex); return rc; Loading