Loading drivers/media/platform/msm/camera/cam_isp/cam_isp_context.c +61 −22 Original line number Diff line number Diff line Loading @@ -219,7 +219,8 @@ 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) { struct cam_req_mgr_sof_notify notify; int rc = 0; struct cam_req_mgr_trigger_notify notify; struct cam_context *ctx = ctx_isp->base; struct cam_ctx_request *req; uint64_t request_id = 0; Loading @@ -231,15 +232,18 @@ static int __cam_isp_ctx_notify_sof_in_actived_state( * 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 && if (ctx->ctx_crm_intf && ctx->ctx_crm_intf->notify_trigger && ctx_isp->active_req_cnt <= 2) { if (ctx_isp->subscribe_event & CAM_TRIGGER_POINT_SOF) { notify.link_hdl = ctx->link_hdl; notify.dev_hdl = ctx->dev_hdl; notify.frame_id = ctx_isp->frame_id; notify.trigger = CAM_TRIGGER_POINT_SOF; ctx->ctx_crm_intf->notify_sof(¬ify); ctx->ctx_crm_intf->notify_trigger(¬ify); CAM_DBG(CAM_ISP, "Notify CRM SOF frame %lld", ctx_isp->frame_id); } list_for_each_entry(req, &ctx->active_req_list, list) { if (req->request_id > ctx_isp->reported_req_id) { Loading @@ -253,11 +257,39 @@ static int __cam_isp_ctx_notify_sof_in_actived_state( CAM_REQ_MGR_SOF_EVENT_SUCCESS); } else { CAM_ERR(CAM_ISP, "Can not notify SOF to CRM"); rc = -EFAULT; } return 0; } static int __cam_isp_ctx_notify_eof_in_actived_state( struct cam_isp_context *ctx_isp, void *evt_data) { int rc = 0; struct cam_req_mgr_trigger_notify notify; struct cam_context *ctx = ctx_isp->base; if (!(ctx_isp->subscribe_event & CAM_TRIGGER_POINT_EOF)) return rc; /* notify reqmgr with eof signal */ if (ctx->ctx_crm_intf && ctx->ctx_crm_intf->notify_trigger) { notify.link_hdl = ctx->link_hdl; notify.dev_hdl = ctx->dev_hdl; notify.frame_id = ctx_isp->frame_id; notify.trigger = CAM_TRIGGER_POINT_EOF; ctx->ctx_crm_intf->notify_trigger(¬ify); CAM_DBG(CAM_ISP, "Notify CRM EOF frame %lld\n", ctx_isp->frame_id); } else { CAM_ERR(CAM_ISP, "Can not notify EOF to CRM"); rc = -EFAULT; } return rc; } static int __cam_isp_ctx_sof_in_activated_state( struct cam_isp_context *ctx_isp, void *evt_data) Loading Loading @@ -581,7 +613,7 @@ static struct cam_isp_ctx_irq_ops __cam_isp_ctx_sof_in_activated_state, __cam_isp_ctx_reg_upd_in_sof, __cam_isp_ctx_notify_sof_in_actived_state, NULL, __cam_isp_ctx_notify_eof_in_actived_state, NULL, }, }, Loading @@ -592,7 +624,7 @@ static struct cam_isp_ctx_irq_ops __cam_isp_ctx_sof_in_activated_state, __cam_isp_ctx_reg_upd_in_activated_state, __cam_isp_ctx_epoch_in_applied, NULL, __cam_isp_ctx_notify_eof_in_actived_state, __cam_isp_ctx_buf_done_in_applied, }, }, Loading @@ -603,7 +635,7 @@ static struct cam_isp_ctx_irq_ops __cam_isp_ctx_sof_in_epoch, NULL, __cam_isp_ctx_notify_sof_in_actived_state, NULL, __cam_isp_ctx_notify_eof_in_actived_state, __cam_isp_ctx_buf_done_in_epoch, }, }, Loading @@ -614,7 +646,7 @@ static struct cam_isp_ctx_irq_ops __cam_isp_ctx_sof_in_activated_state, NULL, __cam_isp_ctx_notify_sof_in_actived_state, NULL, __cam_isp_ctx_notify_eof_in_actived_state, __cam_isp_ctx_buf_done_in_bubble, }, }, Loading Loading @@ -890,7 +922,7 @@ static int __cam_isp_ctx_rdi_only_sof_in_top_state( { int rc = 0; struct cam_context *ctx = ctx_isp->base; struct cam_req_mgr_sof_notify notify; struct cam_req_mgr_trigger_notify notify; struct cam_isp_hw_sof_event_data *sof_event_data = evt_data; uint64_t request_id = 0; Loading @@ -911,13 +943,14 @@ static int __cam_isp_ctx_rdi_only_sof_in_top_state( * 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 && if (ctx->ctx_crm_intf && ctx->ctx_crm_intf->notify_trigger && 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; notify.trigger = CAM_TRIGGER_POINT_SOF; ctx->ctx_crm_intf->notify_sof(¬ify); ctx->ctx_crm_intf->notify_trigger(¬ify); CAM_DBG(CAM_ISP, "Notify CRM SOF frame %lld", ctx_isp->frame_id); Loading Loading @@ -1037,7 +1070,7 @@ static int __cam_isp_ctx_rdi_only_sof_in_bubble_state( uint32_t i; struct cam_ctx_request *req; struct cam_context *ctx = ctx_isp->base; struct cam_req_mgr_sof_notify notify; struct cam_req_mgr_trigger_notify notify; struct cam_isp_hw_sof_event_data *sof_event_data = evt_data; struct cam_isp_ctx_req *req_isp; uint64_t request_id = 0; Loading Loading @@ -1072,12 +1105,13 @@ static int __cam_isp_ctx_rdi_only_sof_in_bubble_state( } /* notify reqmgr with sof signal */ if (ctx->ctx_crm_intf && ctx->ctx_crm_intf->notify_sof) { if (ctx->ctx_crm_intf && ctx->ctx_crm_intf->notify_trigger) { notify.link_hdl = ctx->link_hdl; notify.dev_hdl = ctx->dev_hdl; notify.frame_id = ctx_isp->frame_id; notify.trigger = CAM_TRIGGER_POINT_SOF; ctx->ctx_crm_intf->notify_sof(¬ify); ctx->ctx_crm_intf->notify_trigger(¬ify); CAM_DBG(CAM_ISP, "Notify CRM SOF frame %lld", ctx_isp->frame_id); Loading Loading @@ -1106,11 +1140,11 @@ static int __cam_isp_ctx_rdi_only_reg_upd_in_bubble_applied_state( struct cam_ctx_request *req; struct cam_context *ctx = ctx_isp->base; struct cam_isp_ctx_req *req_isp; struct cam_req_mgr_sof_notify notify; struct cam_req_mgr_trigger_notify notify; uint64_t request_id = 0; /* notify reqmgr with sof signal*/ if (ctx->ctx_crm_intf && ctx->ctx_crm_intf->notify_sof) { if (ctx->ctx_crm_intf && ctx->ctx_crm_intf->notify_trigger) { if (list_empty(&ctx->pending_req_list)) { CAM_ERR(CAM_ISP, "Reg upd ack with no pending request"); goto error; Loading Loading @@ -1138,8 +1172,9 @@ static int __cam_isp_ctx_rdi_only_reg_upd_in_bubble_applied_state( notify.link_hdl = ctx->link_hdl; notify.dev_hdl = ctx->dev_hdl; notify.frame_id = ctx_isp->frame_id; notify.trigger = CAM_TRIGGER_POINT_SOF; ctx->ctx_crm_intf->notify_sof(¬ify); ctx->ctx_crm_intf->notify_trigger(¬ify); CAM_DBG(CAM_ISP, "Notify CRM SOF frame %lld", ctx_isp->frame_id); } else { Loading Loading @@ -1608,11 +1643,14 @@ static int __cam_isp_ctx_link_in_acquired(struct cam_context *ctx, struct cam_req_mgr_core_dev_link_setup *link) { int rc = 0; struct cam_isp_context *ctx_isp = (struct cam_isp_context *) ctx->ctx_priv; CAM_DBG(CAM_ISP, "Enter........."); ctx->link_hdl = link->link_hdl; ctx->ctx_crm_intf = link->crm_cb; ctx_isp->subscribe_event = link->subscribe_event; /* change state only if we had the init config */ if (!list_empty(&ctx->pending_req_list)) { Loading Loading @@ -1645,6 +1683,7 @@ static int __cam_isp_ctx_get_dev_info_in_acquired(struct cam_context *ctx, strlcpy(dev_info->name, CAM_ISP_DEV_NAME, sizeof(dev_info->name)); dev_info->dev_id = CAM_REQ_MGR_DEVICE_IFE; dev_info->p_delay = 1; dev_info->trigger = CAM_TRIGGER_POINT_SOF; return rc; } Loading drivers/media/platform/msm/camera/cam_isp/cam_isp_context.h +4 −0 Original line number Diff line number Diff line Loading @@ -109,6 +109,9 @@ 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. * */ struct cam_isp_context { struct cam_context *base; Loading @@ -125,6 +128,7 @@ struct cam_isp_context { uint64_t sof_timestamp_val; int32_t active_req_cnt; int64_t reported_req_id; uint32_t subscribe_event; }; /** Loading drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c +153 −46 Original line number Diff line number Diff line Loading @@ -2444,34 +2444,51 @@ static int cam_ife_hw_mgr_handle_reg_update( return 0; } static int cam_ife_hw_mgr_check_epoch_for_dual_vfe( static int cam_ife_hw_mgr_check_irq_for_dual_vfe( struct cam_ife_hw_mgr_ctx *ife_hw_mgr_ctx, uint32_t core_idx0, uint32_t core_idx1) uint32_t core_idx1, uint32_t hw_event_type) { int32_t rc = -1; uint32_t *epoch_cnt = ife_hw_mgr_ctx->epoch_cnt; uint32_t *event_cnt = NULL; if (epoch_cnt[core_idx0] == epoch_cnt[core_idx1]) { switch (hw_event_type) { case CAM_ISP_HW_EVENT_SOF: event_cnt = ife_hw_mgr_ctx->sof_cnt; break; case CAM_ISP_HW_EVENT_REG_UPDATE: event_cnt = ife_hw_mgr_ctx->epoch_cnt; break; case CAM_ISP_HW_EVENT_EOF: event_cnt = ife_hw_mgr_ctx->eof_cnt; break; default: return 0; } epoch_cnt[core_idx0] = 0; epoch_cnt[core_idx1] = 0; if (event_cnt[core_idx0] == event_cnt[core_idx1]) { event_cnt[core_idx0] = 0; event_cnt[core_idx1] = 0; rc = 0; return rc; } if ((epoch_cnt[core_idx0] - epoch_cnt[core_idx1] > 1) || (epoch_cnt[core_idx1] - epoch_cnt[core_idx0] > 1)) { if ((event_cnt[core_idx0] - event_cnt[core_idx1] > 1) || (event_cnt[core_idx1] - event_cnt[core_idx0] > 1)) { CAM_WARN(CAM_ISP, "One of the VFE of dual VFE cound not generate error"); "One of the VFE cound not generate hw event %d", hw_event_type); rc = -1; return rc; } CAM_DBG(CAM_ISP, "Only one core_index has given EPOCH"); CAM_DBG(CAM_ISP, "Only one core_index has given hw event %d", hw_event_type); return rc; } Loading Loading @@ -2562,10 +2579,11 @@ static int cam_ife_hw_mgr_handle_epoch_for_camif_hw_res( core_index0 = hw_res_l->hw_intf->hw_idx; core_index1 = hw_res_r->hw_intf->hw_idx; rc = cam_ife_hw_mgr_check_epoch_for_dual_vfe( rc = cam_ife_hw_mgr_check_irq_for_dual_vfe( ife_hwr_mgr_ctx, core_index0, core_index1); core_index1, evt_payload->evt_id); if (!rc) ife_hwr_irq_epoch_cb( Loading @@ -2588,37 +2606,6 @@ static int cam_ife_hw_mgr_handle_epoch_for_camif_hw_res( return 0; } static int cam_ife_hw_mgr_check_sof_for_dual_vfe( struct cam_ife_hw_mgr_ctx *ife_hwr_mgr_ctx, uint32_t core_idx0, uint32_t core_idx1) { uint32_t *sof_cnt = ife_hwr_mgr_ctx->sof_cnt; int32_t rc = -1; if (sof_cnt[core_idx0] == sof_cnt[core_idx1]) { sof_cnt[core_idx0] = 0; sof_cnt[core_idx1] = 0; rc = 0; return rc; } if ((sof_cnt[core_idx0] - sof_cnt[core_idx1] > 1) || (sof_cnt[core_idx1] - sof_cnt[core_idx0] > 1)) { CAM_ERR(CAM_ISP, "One VFE of dual VFE cound not generate SOF"); rc = -1; return rc; } CAM_INFO(CAM_ISP, "Only one core_index has given SOF"); return rc; } static int cam_ife_hw_mgr_process_camif_sof( struct cam_ife_hw_mgr_res *isp_ife_camif_res, struct cam_ife_hw_mgr_ctx *ife_hwr_mgr_ctx, Loading Loading @@ -2709,8 +2696,8 @@ static int cam_ife_hw_mgr_process_camif_sof( core_index0 = hw_res_l->hw_intf->hw_idx; core_index1 = hw_res_r->hw_intf->hw_idx; rc = cam_ife_hw_mgr_check_sof_for_dual_vfe(ife_hwr_mgr_ctx, core_index0, core_index1); rc = cam_ife_hw_mgr_check_irq_for_dual_vfe(ife_hwr_mgr_ctx, core_index0, core_index1, evt_payload->evt_id); if (!rc) ife_hwr_irq_sof_cb(ife_hwr_mgr_ctx->common.cb_priv, Loading Loading @@ -2803,6 +2790,124 @@ static int cam_ife_hw_mgr_handle_sof( return 0; } static int cam_ife_hw_mgr_handle_eof_for_camif_hw_res( void *handler_priv, void *payload) { int32_t rc = -EINVAL; struct cam_isp_resource_node *hw_res_l = NULL; struct cam_isp_resource_node *hw_res_r = NULL; struct cam_ife_hw_mgr_ctx *ife_hwr_mgr_ctx; struct cam_vfe_top_irq_evt_payload *evt_payload; struct cam_ife_hw_mgr_res *isp_ife_camif_res = NULL; cam_hw_event_cb_func ife_hwr_irq_eof_cb; struct cam_isp_hw_eof_event_data eof_done_event_data; uint32_t core_idx; uint32_t eof_status = 0; uint32_t core_index0; uint32_t core_index1; CAM_DBG(CAM_ISP, "Enter"); ife_hwr_mgr_ctx = handler_priv; evt_payload = payload; if (!evt_payload) { pr_err("%s: no payload\n", __func__); return IRQ_HANDLED; } core_idx = evt_payload->core_index; ife_hwr_irq_eof_cb = ife_hwr_mgr_ctx->common.event_cb[CAM_ISP_HW_EVENT_EOF]; evt_payload->evt_id = CAM_ISP_HW_EVENT_EOF; list_for_each_entry(isp_ife_camif_res, &ife_hwr_mgr_ctx->res_list_ife_src, list) { if ((isp_ife_camif_res->res_type == CAM_IFE_HW_MGR_RES_UNINIT) || (isp_ife_camif_res->res_id != CAM_ISP_HW_VFE_IN_CAMIF)) continue; hw_res_l = isp_ife_camif_res->hw_res[0]; hw_res_r = isp_ife_camif_res->hw_res[1]; CAM_DBG(CAM_ISP, "is_dual_vfe ? = %d", isp_ife_camif_res->is_dual_vfe); switch (isp_ife_camif_res->is_dual_vfe) { /* Handling Single VFE Scenario */ case 0: /* EOF check for Left side VFE */ if (!hw_res_l) { pr_err("%s: VFE Device is NULL\n", __func__); break; } CAM_DBG(CAM_ISP, "curr_core_idx = %d, core idx hw = %d", core_idx, hw_res_l->hw_intf->hw_idx); if (core_idx == hw_res_l->hw_intf->hw_idx) { eof_status = hw_res_l->bottom_half_handler( hw_res_l, evt_payload); if (!eof_status) ife_hwr_irq_eof_cb( ife_hwr_mgr_ctx->common.cb_priv, CAM_ISP_HW_EVENT_EOF, &eof_done_event_data); } break; /* Handling dual VFE Scenario */ case 1: if ((!hw_res_l) || (!hw_res_r)) { CAM_ERR(CAM_ISP, "Dual VFE Device is NULL"); break; } if (core_idx == hw_res_l->hw_intf->hw_idx) { eof_status = hw_res_l->bottom_half_handler( hw_res_l, evt_payload); if (!eof_status) ife_hwr_mgr_ctx->eof_cnt[core_idx]++; } /* EOF check for Right side VFE */ if (core_idx == hw_res_r->hw_intf->hw_idx) { eof_status = hw_res_r->bottom_half_handler( hw_res_r, evt_payload); if (!eof_status) ife_hwr_mgr_ctx->eof_cnt[core_idx]++; } core_index0 = hw_res_l->hw_intf->hw_idx; core_index1 = hw_res_r->hw_intf->hw_idx; rc = cam_ife_hw_mgr_check_irq_for_dual_vfe( ife_hwr_mgr_ctx, core_index0, core_index1, evt_payload->evt_id); if (!rc) ife_hwr_irq_eof_cb( ife_hwr_mgr_ctx->common.cb_priv, CAM_ISP_HW_EVENT_EPOCH, &eof_done_event_data); break; default: CAM_ERR(CAM_ISP, "error with hw_res"); } } CAM_DBG(CAM_ISP, "Exit (eof_status = %d)!", eof_status); return 0; } static int cam_ife_hw_mgr_handle_buf_done_for_hw_res( void *handler_priv, void *payload) Loading Loading @@ -3009,6 +3114,8 @@ int cam_ife_mgr_do_tasklet(void *handler_priv, void *evt_payload_priv) /* EPOCH IRQ */ cam_ife_hw_mgr_handle_epoch_for_camif_hw_res(ife_hwr_mgr_ctx, evt_payload_priv); cam_ife_hw_mgr_handle_eof_for_camif_hw_res(ife_hwr_mgr_ctx, evt_payload_priv); return IRQ_HANDLED; } Loading drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.h +2 −0 Original line number Diff line number Diff line Loading @@ -106,6 +106,7 @@ struct ctx_base_info { * @cdm_cmd cdm base and length request pointer * @sof_cnt sof count value per core, used for dual VFE * @epoch_cnt epoch count value per core, used for dual VFE * @eof_cnt eof count value per core, used for dual VFE * @overflow_pending flat to specify the overflow is pending for the * context * @is_rdi_only_context flag to specify the context has only rdi resource Loading Loading @@ -138,6 +139,7 @@ struct cam_ife_hw_mgr_ctx { uint32_t sof_cnt[CAM_IFE_HW_NUM_MAX]; uint32_t epoch_cnt[CAM_IFE_HW_NUM_MAX]; uint32_t eof_cnt[CAM_IFE_HW_NUM_MAX]; atomic_t overflow_pending; uint32_t is_rdi_only_context; Loading drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe170/cam_vfe170.h +1 −0 Original line number Diff line number Diff line Loading @@ -70,6 +70,7 @@ static struct cam_vfe_camif_reg_data vfe_170_camif_reg_data = { .sof_irq_mask = 0x00000001, .epoch0_irq_mask = 0x00000004, .reg_update_irq_mask = 0x00000010, .eof_irq_mask = 0x00000002, }; struct cam_vfe_top_ver2_reg_offset_module_ctrl lens_170_reg = { Loading Loading
drivers/media/platform/msm/camera/cam_isp/cam_isp_context.c +61 −22 Original line number Diff line number Diff line Loading @@ -219,7 +219,8 @@ 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) { struct cam_req_mgr_sof_notify notify; int rc = 0; struct cam_req_mgr_trigger_notify notify; struct cam_context *ctx = ctx_isp->base; struct cam_ctx_request *req; uint64_t request_id = 0; Loading @@ -231,15 +232,18 @@ static int __cam_isp_ctx_notify_sof_in_actived_state( * 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 && if (ctx->ctx_crm_intf && ctx->ctx_crm_intf->notify_trigger && ctx_isp->active_req_cnt <= 2) { if (ctx_isp->subscribe_event & CAM_TRIGGER_POINT_SOF) { notify.link_hdl = ctx->link_hdl; notify.dev_hdl = ctx->dev_hdl; notify.frame_id = ctx_isp->frame_id; notify.trigger = CAM_TRIGGER_POINT_SOF; ctx->ctx_crm_intf->notify_sof(¬ify); ctx->ctx_crm_intf->notify_trigger(¬ify); CAM_DBG(CAM_ISP, "Notify CRM SOF frame %lld", ctx_isp->frame_id); } list_for_each_entry(req, &ctx->active_req_list, list) { if (req->request_id > ctx_isp->reported_req_id) { Loading @@ -253,11 +257,39 @@ static int __cam_isp_ctx_notify_sof_in_actived_state( CAM_REQ_MGR_SOF_EVENT_SUCCESS); } else { CAM_ERR(CAM_ISP, "Can not notify SOF to CRM"); rc = -EFAULT; } return 0; } static int __cam_isp_ctx_notify_eof_in_actived_state( struct cam_isp_context *ctx_isp, void *evt_data) { int rc = 0; struct cam_req_mgr_trigger_notify notify; struct cam_context *ctx = ctx_isp->base; if (!(ctx_isp->subscribe_event & CAM_TRIGGER_POINT_EOF)) return rc; /* notify reqmgr with eof signal */ if (ctx->ctx_crm_intf && ctx->ctx_crm_intf->notify_trigger) { notify.link_hdl = ctx->link_hdl; notify.dev_hdl = ctx->dev_hdl; notify.frame_id = ctx_isp->frame_id; notify.trigger = CAM_TRIGGER_POINT_EOF; ctx->ctx_crm_intf->notify_trigger(¬ify); CAM_DBG(CAM_ISP, "Notify CRM EOF frame %lld\n", ctx_isp->frame_id); } else { CAM_ERR(CAM_ISP, "Can not notify EOF to CRM"); rc = -EFAULT; } return rc; } static int __cam_isp_ctx_sof_in_activated_state( struct cam_isp_context *ctx_isp, void *evt_data) Loading Loading @@ -581,7 +613,7 @@ static struct cam_isp_ctx_irq_ops __cam_isp_ctx_sof_in_activated_state, __cam_isp_ctx_reg_upd_in_sof, __cam_isp_ctx_notify_sof_in_actived_state, NULL, __cam_isp_ctx_notify_eof_in_actived_state, NULL, }, }, Loading @@ -592,7 +624,7 @@ static struct cam_isp_ctx_irq_ops __cam_isp_ctx_sof_in_activated_state, __cam_isp_ctx_reg_upd_in_activated_state, __cam_isp_ctx_epoch_in_applied, NULL, __cam_isp_ctx_notify_eof_in_actived_state, __cam_isp_ctx_buf_done_in_applied, }, }, Loading @@ -603,7 +635,7 @@ static struct cam_isp_ctx_irq_ops __cam_isp_ctx_sof_in_epoch, NULL, __cam_isp_ctx_notify_sof_in_actived_state, NULL, __cam_isp_ctx_notify_eof_in_actived_state, __cam_isp_ctx_buf_done_in_epoch, }, }, Loading @@ -614,7 +646,7 @@ static struct cam_isp_ctx_irq_ops __cam_isp_ctx_sof_in_activated_state, NULL, __cam_isp_ctx_notify_sof_in_actived_state, NULL, __cam_isp_ctx_notify_eof_in_actived_state, __cam_isp_ctx_buf_done_in_bubble, }, }, Loading Loading @@ -890,7 +922,7 @@ static int __cam_isp_ctx_rdi_only_sof_in_top_state( { int rc = 0; struct cam_context *ctx = ctx_isp->base; struct cam_req_mgr_sof_notify notify; struct cam_req_mgr_trigger_notify notify; struct cam_isp_hw_sof_event_data *sof_event_data = evt_data; uint64_t request_id = 0; Loading @@ -911,13 +943,14 @@ static int __cam_isp_ctx_rdi_only_sof_in_top_state( * 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 && if (ctx->ctx_crm_intf && ctx->ctx_crm_intf->notify_trigger && 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; notify.trigger = CAM_TRIGGER_POINT_SOF; ctx->ctx_crm_intf->notify_sof(¬ify); ctx->ctx_crm_intf->notify_trigger(¬ify); CAM_DBG(CAM_ISP, "Notify CRM SOF frame %lld", ctx_isp->frame_id); Loading Loading @@ -1037,7 +1070,7 @@ static int __cam_isp_ctx_rdi_only_sof_in_bubble_state( uint32_t i; struct cam_ctx_request *req; struct cam_context *ctx = ctx_isp->base; struct cam_req_mgr_sof_notify notify; struct cam_req_mgr_trigger_notify notify; struct cam_isp_hw_sof_event_data *sof_event_data = evt_data; struct cam_isp_ctx_req *req_isp; uint64_t request_id = 0; Loading Loading @@ -1072,12 +1105,13 @@ static int __cam_isp_ctx_rdi_only_sof_in_bubble_state( } /* notify reqmgr with sof signal */ if (ctx->ctx_crm_intf && ctx->ctx_crm_intf->notify_sof) { if (ctx->ctx_crm_intf && ctx->ctx_crm_intf->notify_trigger) { notify.link_hdl = ctx->link_hdl; notify.dev_hdl = ctx->dev_hdl; notify.frame_id = ctx_isp->frame_id; notify.trigger = CAM_TRIGGER_POINT_SOF; ctx->ctx_crm_intf->notify_sof(¬ify); ctx->ctx_crm_intf->notify_trigger(¬ify); CAM_DBG(CAM_ISP, "Notify CRM SOF frame %lld", ctx_isp->frame_id); Loading Loading @@ -1106,11 +1140,11 @@ static int __cam_isp_ctx_rdi_only_reg_upd_in_bubble_applied_state( struct cam_ctx_request *req; struct cam_context *ctx = ctx_isp->base; struct cam_isp_ctx_req *req_isp; struct cam_req_mgr_sof_notify notify; struct cam_req_mgr_trigger_notify notify; uint64_t request_id = 0; /* notify reqmgr with sof signal*/ if (ctx->ctx_crm_intf && ctx->ctx_crm_intf->notify_sof) { if (ctx->ctx_crm_intf && ctx->ctx_crm_intf->notify_trigger) { if (list_empty(&ctx->pending_req_list)) { CAM_ERR(CAM_ISP, "Reg upd ack with no pending request"); goto error; Loading Loading @@ -1138,8 +1172,9 @@ static int __cam_isp_ctx_rdi_only_reg_upd_in_bubble_applied_state( notify.link_hdl = ctx->link_hdl; notify.dev_hdl = ctx->dev_hdl; notify.frame_id = ctx_isp->frame_id; notify.trigger = CAM_TRIGGER_POINT_SOF; ctx->ctx_crm_intf->notify_sof(¬ify); ctx->ctx_crm_intf->notify_trigger(¬ify); CAM_DBG(CAM_ISP, "Notify CRM SOF frame %lld", ctx_isp->frame_id); } else { Loading Loading @@ -1608,11 +1643,14 @@ static int __cam_isp_ctx_link_in_acquired(struct cam_context *ctx, struct cam_req_mgr_core_dev_link_setup *link) { int rc = 0; struct cam_isp_context *ctx_isp = (struct cam_isp_context *) ctx->ctx_priv; CAM_DBG(CAM_ISP, "Enter........."); ctx->link_hdl = link->link_hdl; ctx->ctx_crm_intf = link->crm_cb; ctx_isp->subscribe_event = link->subscribe_event; /* change state only if we had the init config */ if (!list_empty(&ctx->pending_req_list)) { Loading Loading @@ -1645,6 +1683,7 @@ static int __cam_isp_ctx_get_dev_info_in_acquired(struct cam_context *ctx, strlcpy(dev_info->name, CAM_ISP_DEV_NAME, sizeof(dev_info->name)); dev_info->dev_id = CAM_REQ_MGR_DEVICE_IFE; dev_info->p_delay = 1; dev_info->trigger = CAM_TRIGGER_POINT_SOF; return rc; } Loading
drivers/media/platform/msm/camera/cam_isp/cam_isp_context.h +4 −0 Original line number Diff line number Diff line Loading @@ -109,6 +109,9 @@ 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. * */ struct cam_isp_context { struct cam_context *base; Loading @@ -125,6 +128,7 @@ struct cam_isp_context { uint64_t sof_timestamp_val; int32_t active_req_cnt; int64_t reported_req_id; uint32_t subscribe_event; }; /** Loading
drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c +153 −46 Original line number Diff line number Diff line Loading @@ -2444,34 +2444,51 @@ static int cam_ife_hw_mgr_handle_reg_update( return 0; } static int cam_ife_hw_mgr_check_epoch_for_dual_vfe( static int cam_ife_hw_mgr_check_irq_for_dual_vfe( struct cam_ife_hw_mgr_ctx *ife_hw_mgr_ctx, uint32_t core_idx0, uint32_t core_idx1) uint32_t core_idx1, uint32_t hw_event_type) { int32_t rc = -1; uint32_t *epoch_cnt = ife_hw_mgr_ctx->epoch_cnt; uint32_t *event_cnt = NULL; if (epoch_cnt[core_idx0] == epoch_cnt[core_idx1]) { switch (hw_event_type) { case CAM_ISP_HW_EVENT_SOF: event_cnt = ife_hw_mgr_ctx->sof_cnt; break; case CAM_ISP_HW_EVENT_REG_UPDATE: event_cnt = ife_hw_mgr_ctx->epoch_cnt; break; case CAM_ISP_HW_EVENT_EOF: event_cnt = ife_hw_mgr_ctx->eof_cnt; break; default: return 0; } epoch_cnt[core_idx0] = 0; epoch_cnt[core_idx1] = 0; if (event_cnt[core_idx0] == event_cnt[core_idx1]) { event_cnt[core_idx0] = 0; event_cnt[core_idx1] = 0; rc = 0; return rc; } if ((epoch_cnt[core_idx0] - epoch_cnt[core_idx1] > 1) || (epoch_cnt[core_idx1] - epoch_cnt[core_idx0] > 1)) { if ((event_cnt[core_idx0] - event_cnt[core_idx1] > 1) || (event_cnt[core_idx1] - event_cnt[core_idx0] > 1)) { CAM_WARN(CAM_ISP, "One of the VFE of dual VFE cound not generate error"); "One of the VFE cound not generate hw event %d", hw_event_type); rc = -1; return rc; } CAM_DBG(CAM_ISP, "Only one core_index has given EPOCH"); CAM_DBG(CAM_ISP, "Only one core_index has given hw event %d", hw_event_type); return rc; } Loading Loading @@ -2562,10 +2579,11 @@ static int cam_ife_hw_mgr_handle_epoch_for_camif_hw_res( core_index0 = hw_res_l->hw_intf->hw_idx; core_index1 = hw_res_r->hw_intf->hw_idx; rc = cam_ife_hw_mgr_check_epoch_for_dual_vfe( rc = cam_ife_hw_mgr_check_irq_for_dual_vfe( ife_hwr_mgr_ctx, core_index0, core_index1); core_index1, evt_payload->evt_id); if (!rc) ife_hwr_irq_epoch_cb( Loading @@ -2588,37 +2606,6 @@ static int cam_ife_hw_mgr_handle_epoch_for_camif_hw_res( return 0; } static int cam_ife_hw_mgr_check_sof_for_dual_vfe( struct cam_ife_hw_mgr_ctx *ife_hwr_mgr_ctx, uint32_t core_idx0, uint32_t core_idx1) { uint32_t *sof_cnt = ife_hwr_mgr_ctx->sof_cnt; int32_t rc = -1; if (sof_cnt[core_idx0] == sof_cnt[core_idx1]) { sof_cnt[core_idx0] = 0; sof_cnt[core_idx1] = 0; rc = 0; return rc; } if ((sof_cnt[core_idx0] - sof_cnt[core_idx1] > 1) || (sof_cnt[core_idx1] - sof_cnt[core_idx0] > 1)) { CAM_ERR(CAM_ISP, "One VFE of dual VFE cound not generate SOF"); rc = -1; return rc; } CAM_INFO(CAM_ISP, "Only one core_index has given SOF"); return rc; } static int cam_ife_hw_mgr_process_camif_sof( struct cam_ife_hw_mgr_res *isp_ife_camif_res, struct cam_ife_hw_mgr_ctx *ife_hwr_mgr_ctx, Loading Loading @@ -2709,8 +2696,8 @@ static int cam_ife_hw_mgr_process_camif_sof( core_index0 = hw_res_l->hw_intf->hw_idx; core_index1 = hw_res_r->hw_intf->hw_idx; rc = cam_ife_hw_mgr_check_sof_for_dual_vfe(ife_hwr_mgr_ctx, core_index0, core_index1); rc = cam_ife_hw_mgr_check_irq_for_dual_vfe(ife_hwr_mgr_ctx, core_index0, core_index1, evt_payload->evt_id); if (!rc) ife_hwr_irq_sof_cb(ife_hwr_mgr_ctx->common.cb_priv, Loading Loading @@ -2803,6 +2790,124 @@ static int cam_ife_hw_mgr_handle_sof( return 0; } static int cam_ife_hw_mgr_handle_eof_for_camif_hw_res( void *handler_priv, void *payload) { int32_t rc = -EINVAL; struct cam_isp_resource_node *hw_res_l = NULL; struct cam_isp_resource_node *hw_res_r = NULL; struct cam_ife_hw_mgr_ctx *ife_hwr_mgr_ctx; struct cam_vfe_top_irq_evt_payload *evt_payload; struct cam_ife_hw_mgr_res *isp_ife_camif_res = NULL; cam_hw_event_cb_func ife_hwr_irq_eof_cb; struct cam_isp_hw_eof_event_data eof_done_event_data; uint32_t core_idx; uint32_t eof_status = 0; uint32_t core_index0; uint32_t core_index1; CAM_DBG(CAM_ISP, "Enter"); ife_hwr_mgr_ctx = handler_priv; evt_payload = payload; if (!evt_payload) { pr_err("%s: no payload\n", __func__); return IRQ_HANDLED; } core_idx = evt_payload->core_index; ife_hwr_irq_eof_cb = ife_hwr_mgr_ctx->common.event_cb[CAM_ISP_HW_EVENT_EOF]; evt_payload->evt_id = CAM_ISP_HW_EVENT_EOF; list_for_each_entry(isp_ife_camif_res, &ife_hwr_mgr_ctx->res_list_ife_src, list) { if ((isp_ife_camif_res->res_type == CAM_IFE_HW_MGR_RES_UNINIT) || (isp_ife_camif_res->res_id != CAM_ISP_HW_VFE_IN_CAMIF)) continue; hw_res_l = isp_ife_camif_res->hw_res[0]; hw_res_r = isp_ife_camif_res->hw_res[1]; CAM_DBG(CAM_ISP, "is_dual_vfe ? = %d", isp_ife_camif_res->is_dual_vfe); switch (isp_ife_camif_res->is_dual_vfe) { /* Handling Single VFE Scenario */ case 0: /* EOF check for Left side VFE */ if (!hw_res_l) { pr_err("%s: VFE Device is NULL\n", __func__); break; } CAM_DBG(CAM_ISP, "curr_core_idx = %d, core idx hw = %d", core_idx, hw_res_l->hw_intf->hw_idx); if (core_idx == hw_res_l->hw_intf->hw_idx) { eof_status = hw_res_l->bottom_half_handler( hw_res_l, evt_payload); if (!eof_status) ife_hwr_irq_eof_cb( ife_hwr_mgr_ctx->common.cb_priv, CAM_ISP_HW_EVENT_EOF, &eof_done_event_data); } break; /* Handling dual VFE Scenario */ case 1: if ((!hw_res_l) || (!hw_res_r)) { CAM_ERR(CAM_ISP, "Dual VFE Device is NULL"); break; } if (core_idx == hw_res_l->hw_intf->hw_idx) { eof_status = hw_res_l->bottom_half_handler( hw_res_l, evt_payload); if (!eof_status) ife_hwr_mgr_ctx->eof_cnt[core_idx]++; } /* EOF check for Right side VFE */ if (core_idx == hw_res_r->hw_intf->hw_idx) { eof_status = hw_res_r->bottom_half_handler( hw_res_r, evt_payload); if (!eof_status) ife_hwr_mgr_ctx->eof_cnt[core_idx]++; } core_index0 = hw_res_l->hw_intf->hw_idx; core_index1 = hw_res_r->hw_intf->hw_idx; rc = cam_ife_hw_mgr_check_irq_for_dual_vfe( ife_hwr_mgr_ctx, core_index0, core_index1, evt_payload->evt_id); if (!rc) ife_hwr_irq_eof_cb( ife_hwr_mgr_ctx->common.cb_priv, CAM_ISP_HW_EVENT_EPOCH, &eof_done_event_data); break; default: CAM_ERR(CAM_ISP, "error with hw_res"); } } CAM_DBG(CAM_ISP, "Exit (eof_status = %d)!", eof_status); return 0; } static int cam_ife_hw_mgr_handle_buf_done_for_hw_res( void *handler_priv, void *payload) Loading Loading @@ -3009,6 +3114,8 @@ int cam_ife_mgr_do_tasklet(void *handler_priv, void *evt_payload_priv) /* EPOCH IRQ */ cam_ife_hw_mgr_handle_epoch_for_camif_hw_res(ife_hwr_mgr_ctx, evt_payload_priv); cam_ife_hw_mgr_handle_eof_for_camif_hw_res(ife_hwr_mgr_ctx, evt_payload_priv); return IRQ_HANDLED; } Loading
drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.h +2 −0 Original line number Diff line number Diff line Loading @@ -106,6 +106,7 @@ struct ctx_base_info { * @cdm_cmd cdm base and length request pointer * @sof_cnt sof count value per core, used for dual VFE * @epoch_cnt epoch count value per core, used for dual VFE * @eof_cnt eof count value per core, used for dual VFE * @overflow_pending flat to specify the overflow is pending for the * context * @is_rdi_only_context flag to specify the context has only rdi resource Loading Loading @@ -138,6 +139,7 @@ struct cam_ife_hw_mgr_ctx { uint32_t sof_cnt[CAM_IFE_HW_NUM_MAX]; uint32_t epoch_cnt[CAM_IFE_HW_NUM_MAX]; uint32_t eof_cnt[CAM_IFE_HW_NUM_MAX]; atomic_t overflow_pending; uint32_t is_rdi_only_context; Loading
drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe170/cam_vfe170.h +1 −0 Original line number Diff line number Diff line Loading @@ -70,6 +70,7 @@ static struct cam_vfe_camif_reg_data vfe_170_camif_reg_data = { .sof_irq_mask = 0x00000001, .epoch0_irq_mask = 0x00000004, .reg_update_irq_mask = 0x00000010, .eof_irq_mask = 0x00000002, }; struct cam_vfe_top_ver2_reg_offset_module_ctrl lens_170_reg = { Loading