Loading drivers/media/platform/msm/camera/cam_isp/cam_isp_context.c +375 −9 Original line number Diff line number Diff line Loading @@ -1228,6 +1228,236 @@ static int __cam_isp_ctx_handle_error(struct cam_isp_context *ctx_isp, return rc; } static int __cam_isp_ctx_fs2_sof_in_sof_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; struct cam_ctx_request *req; struct cam_context *ctx = ctx_isp->base; struct cam_req_mgr_trigger_notify notify; uint64_t request_id = 0; 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"); return -EINVAL; } ctx_isp->frame_id++; ctx_isp->sof_timestamp_val = sof_event_data->timestamp; ctx_isp->boot_timestamp = sof_event_data->boot_time; __cam_isp_ctx_update_state_monitor_array(ctx_isp, CAM_ISP_STATE_CHANGE_TRIGGER_SOF, req->request_id); CAM_DBG(CAM_ISP, "frame id: %lld time stamp:0x%llx", ctx_isp->frame_id, ctx_isp->sof_timestamp_val); if (!(list_empty(&ctx->wait_req_list))) goto end; 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_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) { 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 { CAM_ERR_RATE_LIMIT(CAM_ISP, "Can not notify SOF to CRM"); rc = -EFAULT; } end: return rc; } static int __cam_isp_ctx_fs2_buf_done(struct cam_isp_context *ctx_isp, void *evt_data) { int rc = 0; struct cam_isp_hw_done_event_data *done = (struct cam_isp_hw_done_event_data *) evt_data; struct cam_context *ctx = ctx_isp->base; int prev_active_req_cnt = 0; int curr_req_id = 0; struct cam_ctx_request *req; prev_active_req_cnt = ctx_isp->active_req_cnt; req = list_first_entry(&ctx->active_req_list, struct cam_ctx_request, list); if (req) curr_req_id = req->request_id; rc = __cam_isp_ctx_handle_buf_done_in_activated_state(ctx_isp, done, 0); if (prev_active_req_cnt == ctx_isp->active_req_cnt + 1) { if (list_empty(&ctx->wait_req_list) && list_empty(&ctx->active_req_list)) { CAM_DBG(CAM_ISP, "No request, move to SOF"); ctx_isp->substate_activated = CAM_ISP_CTX_ACTIVATED_SOF; if (ctx_isp->reported_req_id < curr_req_id) { ctx_isp->reported_req_id = curr_req_id; __cam_isp_ctx_send_sof_timestamp(ctx_isp, curr_req_id, CAM_REQ_MGR_SOF_EVENT_SUCCESS); } } } return rc; } static int __cam_isp_ctx_fs2_buf_done_in_epoch(struct cam_isp_context *ctx_isp, void *evt_data) { int rc = 0; rc = __cam_isp_ctx_fs2_buf_done(ctx_isp, evt_data); return rc; } static int __cam_isp_ctx_fs2_buf_done_in_applied( struct cam_isp_context *ctx_isp, void *evt_data) { int rc = 0; rc = __cam_isp_ctx_fs2_buf_done(ctx_isp, evt_data); return rc; } static int __cam_isp_ctx_fs2_reg_upd_in_sof(struct cam_isp_context *ctx_isp, void *evt_data) { int rc = 0; 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 && ctx_isp->frame_id > 1) { CAM_DBG(CAM_ISP, "invalid RUP"); goto end; } /* * This is for the first update. The initial setting will * cause the reg_upd in the first frame. */ if (!list_empty(&ctx->wait_req_list)) { req = list_first_entry(&ctx->wait_req_list, 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) list_add_tail(&req->list, &ctx->free_req_list); else CAM_ERR(CAM_ISP, "receive rup in unexpected state"); } if (req != NULL) { __cam_isp_ctx_update_state_monitor_array(ctx_isp, CAM_ISP_STATE_CHANGE_TRIGGER_REG_UPDATE, req->request_id); } end: return rc; } static int __cam_isp_ctx_fs2_reg_upd_in_applied_state( struct cam_isp_context *ctx_isp, void *evt_data) { int rc = 0; struct cam_ctx_request *req = NULL; struct cam_context *ctx = ctx_isp->base; struct cam_isp_ctx_req *req_isp; struct cam_req_mgr_trigger_notify notify; uint64_t request_id = 0; if (list_empty(&ctx->wait_req_list)) { CAM_ERR(CAM_ISP, "Reg upd ack with no waiting request"); goto end; } req = list_first_entry(&ctx->wait_req_list, 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 != 0) { list_add_tail(&req->list, &ctx->active_req_list); ctx_isp->active_req_cnt++; CAM_DBG(CAM_REQ, "move request %lld to active list(cnt = %d)", 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); } /* * This function only called directly from applied and bubble applied * state so change substate here. */ ctx_isp->substate_activated = CAM_ISP_CTX_ACTIVATED_EPOCH; if (req_isp->num_fence_map_out != 1) goto end; if (ctx->ctx_crm_intf && ctx->ctx_crm_intf->notify_trigger && ctx_isp->active_req_cnt <= 2) { list_for_each_entry(req, &ctx->active_req_list, list) { if (req->request_id > ctx_isp->reported_req_id) { 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); 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_trigger(¬ify); CAM_DBG(CAM_ISP, "Notify CRM SOF frame %lld", ctx_isp->frame_id); } } else { CAM_ERR_RATE_LIMIT(CAM_ISP, "Can not notify SOF to CRM"); rc = -EFAULT; } CAM_DBG(CAM_ISP, "next substate %d", ctx_isp->substate_activated); end: if (req != NULL && !rc) { __cam_isp_ctx_update_state_monitor_array(ctx_isp, CAM_ISP_STATE_CHANGE_TRIGGER_EPOCH, req->request_id); } return rc; } static struct cam_isp_ctx_irq_ops cam_isp_ctx_activated_state_machine_irq[CAM_ISP_CTX_ACTIVATED_MAX] = { /* SOF */ Loading Loading @@ -1301,6 +1531,79 @@ static struct cam_isp_ctx_irq_ops }, }; static struct cam_isp_ctx_irq_ops cam_isp_ctx_fs2_state_machine_irq[CAM_ISP_CTX_ACTIVATED_MAX] = { /* SOF */ { .irq_ops = { __cam_isp_ctx_handle_error, __cam_isp_ctx_fs2_sof_in_sof_state, __cam_isp_ctx_fs2_reg_upd_in_sof, __cam_isp_ctx_fs2_sof_in_sof_state, __cam_isp_ctx_notify_eof_in_activated_state, NULL, }, }, /* APPLIED */ { .irq_ops = { __cam_isp_ctx_handle_error, __cam_isp_ctx_sof_in_activated_state, __cam_isp_ctx_fs2_reg_upd_in_applied_state, __cam_isp_ctx_epoch_in_applied, __cam_isp_ctx_notify_eof_in_activated_state, __cam_isp_ctx_fs2_buf_done_in_applied, }, }, /* EPOCH */ { .irq_ops = { __cam_isp_ctx_handle_error, __cam_isp_ctx_sof_in_epoch, __cam_isp_ctx_reg_upd_in_epoch_state, __cam_isp_ctx_notify_sof_in_activated_state, __cam_isp_ctx_notify_eof_in_activated_state, __cam_isp_ctx_fs2_buf_done_in_epoch, }, }, /* BUBBLE */ { .irq_ops = { __cam_isp_ctx_handle_error, __cam_isp_ctx_sof_in_activated_state, NULL, __cam_isp_ctx_notify_sof_in_activated_state, __cam_isp_ctx_notify_eof_in_activated_state, __cam_isp_ctx_buf_done_in_bubble, }, }, /* Bubble Applied */ { .irq_ops = { __cam_isp_ctx_handle_error, __cam_isp_ctx_sof_in_activated_state, __cam_isp_ctx_reg_upd_in_activated_state, __cam_isp_ctx_epoch_in_bubble_applied, NULL, __cam_isp_ctx_buf_done_in_bubble_applied, }, }, /* HW ERROR */ { .irq_ops = { NULL, __cam_isp_ctx_sof_in_activated_state, __cam_isp_ctx_reg_upd_in_hw_error, NULL, NULL, NULL, }, }, /* HALT */ { }, }; static int __cam_isp_ctx_apply_req_in_activated_state( struct cam_context *ctx, struct cam_req_mgr_apply_request *apply, uint32_t next_state) Loading Loading @@ -1620,6 +1923,58 @@ static struct cam_ctx_ops }, }; static struct cam_ctx_ops cam_isp_ctx_fs2_state_machine[CAM_ISP_CTX_ACTIVATED_MAX] = { /* SOF */ { .ioctl_ops = {}, .crm_ops = { .apply_req = __cam_isp_ctx_apply_req_in_sof, }, .irq_ops = NULL, }, /* APPLIED */ { .ioctl_ops = {}, .crm_ops = {}, .irq_ops = NULL, }, /* EPOCH */ { .ioctl_ops = {}, .crm_ops = { .apply_req = __cam_isp_ctx_apply_req_in_epoch, }, .irq_ops = NULL, }, /* BUBBLE */ { .ioctl_ops = {}, .crm_ops = { .apply_req = __cam_isp_ctx_apply_req_in_bubble, }, .irq_ops = NULL, }, /* Bubble Applied */ { .ioctl_ops = {}, .crm_ops = {}, .irq_ops = NULL, }, /* HW ERROR */ { .ioctl_ops = {}, .crm_ops = {}, .irq_ops = NULL, }, /* HALT */ { .ioctl_ops = {}, .crm_ops = {}, .irq_ops = NULL, }, }; static int __cam_isp_ctx_rdi_only_sof_in_top_state( struct cam_isp_context *ctx_isp, void *evt_data) { Loading Loading @@ -2424,7 +2779,7 @@ static int __cam_isp_ctx_acquire_dev_in_available(struct cam_context *ctx, /* Query the context has rdi only resource */ hw_cmd_args.ctxt_to_hw_map = param.ctxt_to_hw_map; hw_cmd_args.cmd_type = CAM_HW_MGR_CMD_INTERNAL; isp_hw_cmd_args.cmd_type = CAM_ISP_HW_MGR_CMD_IS_RDI_ONLY_CONTEXT; isp_hw_cmd_args.cmd_type = CAM_ISP_HW_MGR_CMD_CTX_TYPE; hw_cmd_args.u.internal_args = (void *)&isp_hw_cmd_args; rc = ctx->hw_mgr_intf->hw_cmd(ctx->hw_mgr_intf->hw_mgr_priv, &hw_cmd_args); Loading @@ -2433,7 +2788,7 @@ static int __cam_isp_ctx_acquire_dev_in_available(struct cam_context *ctx, goto free_hw; } if (isp_hw_cmd_args.u.is_rdi_only_context) { if (isp_hw_cmd_args.u.ctx_type == CAM_ISP_CTX_RDI) { /* * this context has rdi only resource assign rdi only * state machine Loading @@ -2444,6 +2799,13 @@ static int __cam_isp_ctx_acquire_dev_in_available(struct cam_context *ctx, cam_isp_ctx_rdi_only_activated_state_machine_irq; ctx_isp->substate_machine = cam_isp_ctx_rdi_only_activated_state_machine; ctx_isp->rdi_only_context = true; } else if (isp_hw_cmd_args.u.ctx_type == CAM_ISP_CTX_FS2) { CAM_DBG(CAM_ISP, "FS2 Session has PIX ,RD and RDI"); ctx_isp->substate_machine_irq = cam_isp_ctx_fs2_state_machine_irq; ctx_isp->substate_machine = cam_isp_ctx_fs2_state_machine; } else { CAM_DBG(CAM_ISP, "Session has PIX or PIX and RDI resources"); ctx_isp->substate_machine_irq = Loading @@ -2452,7 +2814,6 @@ static int __cam_isp_ctx_acquire_dev_in_available(struct cam_context *ctx, cam_isp_ctx_activated_state_machine; } ctx_isp->rdi_only_context = isp_hw_cmd_args.u.is_rdi_only_context; ctx_isp->hw_ctx = param.ctxt_to_hw_map; ctx_isp->hw_acquired = true; ctx_isp->split_acquire = false; Loading Loading @@ -2570,7 +2931,7 @@ static int __cam_isp_ctx_acquire_hw_v1(struct cam_context *ctx, /* Query the context has rdi only resource */ hw_cmd_args.ctxt_to_hw_map = param.ctxt_to_hw_map; hw_cmd_args.cmd_type = CAM_HW_MGR_CMD_INTERNAL; isp_hw_cmd_args.cmd_type = CAM_ISP_HW_MGR_CMD_IS_RDI_ONLY_CONTEXT; isp_hw_cmd_args.cmd_type = CAM_ISP_HW_MGR_CMD_CTX_TYPE; hw_cmd_args.u.internal_args = (void *)&isp_hw_cmd_args; rc = ctx->hw_mgr_intf->hw_cmd(ctx->hw_mgr_intf->hw_mgr_priv, &hw_cmd_args); Loading @@ -2579,7 +2940,7 @@ static int __cam_isp_ctx_acquire_hw_v1(struct cam_context *ctx, goto free_hw; } if (isp_hw_cmd_args.u.is_rdi_only_context) { if (isp_hw_cmd_args.u.ctx_type == CAM_ISP_CTX_RDI) { /* * this context has rdi only resource assign rdi only * state machine Loading @@ -2590,6 +2951,13 @@ static int __cam_isp_ctx_acquire_hw_v1(struct cam_context *ctx, cam_isp_ctx_rdi_only_activated_state_machine_irq; ctx_isp->substate_machine = cam_isp_ctx_rdi_only_activated_state_machine; ctx_isp->rdi_only_context = true; } else if (isp_hw_cmd_args.u.ctx_type == CAM_ISP_CTX_FS2) { CAM_DBG(CAM_ISP, "FS2 Session has PIX ,RD and RDI"); ctx_isp->substate_machine_irq = cam_isp_ctx_fs2_state_machine_irq; ctx_isp->substate_machine = cam_isp_ctx_fs2_state_machine; } else { CAM_DBG(CAM_ISP, "Session has PIX or PIX and RDI resources"); ctx_isp->substate_machine_irq = Loading @@ -2598,16 +2966,14 @@ static int __cam_isp_ctx_acquire_hw_v1(struct cam_context *ctx, cam_isp_ctx_activated_state_machine; } ctx_isp->rdi_only_context = isp_hw_cmd_args.u.is_rdi_only_context; ctx_isp->hw_ctx = param.ctxt_to_hw_map; ctx_isp->hw_acquired = true; ctx->ctxt_to_hw_map = param.ctxt_to_hw_map; trace_cam_context_state("ISP", ctx); CAM_DBG(CAM_ISP, "Acquire success on session_hdl 0x%xs RDI only %d ctx %u", ctx->session_hdl, (isp_hw_cmd_args.u.is_rdi_only_context ? 1 : 0), ctx->ctx_id); "Acquire success on session_hdl 0x%xs ctx_type %d ctx_id %u", ctx->session_hdl, isp_hw_cmd_args.u.ctx_type, ctx->ctx_id); kfree(acquire_hw_info); return rc; Loading drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c +16 −10 Original line number Diff line number Diff line Loading @@ -2228,7 +2228,8 @@ static int cam_isp_blob_bw_update( if (!hw_mgr_res->hw_res[i]) continue; if (hw_mgr_res->res_id == CAM_ISP_HW_VFE_IN_CAMIF) if ((hw_mgr_res->res_id == CAM_ISP_HW_VFE_IN_CAMIF) || (hw_mgr_res->res_id == CAM_ISP_HW_VFE_IN_RD)) if (i == CAM_ISP_HW_SPLIT_LEFT) { if (camif_l_bw_updated) continue; Loading Loading @@ -3599,6 +3600,7 @@ static int cam_isp_packet_generic_blob_handler(void *user_data, CAM_ERR(CAM_ISP, "FS Update Failed rc: %d", rc); } break; default: CAM_WARN(CAM_ISP, "Invalid blob type %d", blob_type); break; Loading Loading @@ -3904,12 +3906,6 @@ static int cam_ife_mgr_cmd(void *hw_mgr_priv, void *cmd_args) hw_cmd_args->u.internal_args; switch (isp_hw_cmd_args->cmd_type) { case CAM_ISP_HW_MGR_CMD_IS_RDI_ONLY_CONTEXT: if (ctx->is_rdi_only_context) isp_hw_cmd_args->u.is_rdi_only_context = 1; else isp_hw_cmd_args->u.is_rdi_only_context = 0; break; case CAM_ISP_HW_MGR_CMD_PAUSE_HW: cam_ife_mgr_pause_hw(ctx); break; Loading @@ -3920,6 +3916,14 @@ static int cam_ife_mgr_cmd(void *hw_mgr_priv, void *cmd_args) cam_ife_mgr_sof_irq_debug(ctx, isp_hw_cmd_args->u.sof_irq_enable); break; case CAM_ISP_HW_MGR_CMD_CTX_TYPE: if (ctx->is_fe_enable) isp_hw_cmd_args->u.ctx_type = CAM_ISP_CTX_FS2; else if (ctx->is_rdi_only_context) isp_hw_cmd_args->u.ctx_type = CAM_ISP_CTX_RDI; else isp_hw_cmd_args->u.ctx_type = CAM_ISP_CTX_PIX; break; default: CAM_ERR(CAM_ISP, "Invalid HW mgr command:0x%x", hw_cmd_args->cmd_type); Loading Loading @@ -4472,7 +4476,8 @@ static int cam_ife_hw_mgr_handle_reg_update( rup_status = hw_res->bottom_half_handler( hw_res, evt_payload); if (!ife_hwr_mgr_ctx->is_rdi_only_context) if (ife_hwr_mgr_ctx->is_rdi_only_context == 0 && ife_hwr_mgr_ctx->is_fe_enable == false) continue; if (atomic_read(&ife_hwr_mgr_ctx->overflow_pending)) Loading Loading @@ -4815,7 +4820,8 @@ static int cam_ife_hw_mgr_handle_sof( hw_res, evt_payload); /* check if it is rdi only context */ if (ife_hw_mgr_ctx->is_rdi_only_context) { if (ife_hw_mgr_ctx->is_fe_enable || ife_hw_mgr_ctx->is_rdi_only_context) { if (!sof_status && !sof_sent) { cam_ife_mgr_cmd_get_sof_timestamp( ife_hw_mgr_ctx, Loading @@ -4826,7 +4832,7 @@ static int cam_ife_hw_mgr_handle_sof( ife_hw_mgr_ctx->common.cb_priv, CAM_ISP_HW_EVENT_SOF, &sof_done_event_data); CAM_DBG(CAM_ISP, "sof_status = %d", CAM_DBG(CAM_ISP, "RDI sof_status = %d", sof_status); sof_sent = true; Loading drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/include/cam_isp_hw_mgr_intf.h +11 −3 Original line number Diff line number Diff line Loading @@ -199,20 +199,28 @@ enum cam_isp_hw_mgr_command { CAM_ISP_HW_MGR_CMD_PAUSE_HW, CAM_ISP_HW_MGR_CMD_RESUME_HW, CAM_ISP_HW_MGR_CMD_SOF_DEBUG, CAM_ISP_HW_MGR_CMD_CTX_TYPE, CAM_ISP_HW_MGR_CMD_MAX, }; enum cam_isp_ctx_type { CAM_ISP_CTX_FS2 = 1, CAM_ISP_CTX_RDI, CAM_ISP_CTX_PIX, CAM_ISP_CTX_MAX, }; /** * struct cam_isp_hw_cmd_args - Payload for hw manager command * * @cmd_type HW command type * @get_context Get context type information * @sof_irq_enable To debug if SOF irq is enabled * @ctx_type RDI_ONLY, PIX and RDI, or FS2 */ struct cam_isp_hw_cmd_args { uint32_t cmd_type; union { uint32_t is_rdi_only_context; uint32_t sof_irq_enable; uint32_t ctx_type; } u; }; Loading drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_core.c +6 −1 Original line number Diff line number Diff line Loading @@ -36,6 +36,11 @@ static uint32_t camif_irq_reg_mask[CAM_IFE_IRQ_REGISTERS_MAX] = { 0x00000000, }; static uint32_t camif_fe_irq_reg_mask[CAM_IFE_IRQ_REGISTERS_MAX] = { 0x10000056, 0x00000000, }; static uint32_t camif_irq_err_reg_mask[CAM_IFE_IRQ_REGISTERS_MAX] = { 0x0003FC00, 0xEFFF7EBC, Loading Loading @@ -606,7 +611,7 @@ int cam_vfe_start(void *hw_priv, void *start_args, uint32_t arg_size) cam_irq_controller_subscribe_irq( core_info->vfe_irq_controller, CAM_IRQ_PRIORITY_1, camif_irq_reg_mask, camif_fe_irq_reg_mask, &core_info->irq_payload, cam_vfe_irq_top_half, cam_ife_mgr_do_tasklet, Loading Loading
drivers/media/platform/msm/camera/cam_isp/cam_isp_context.c +375 −9 Original line number Diff line number Diff line Loading @@ -1228,6 +1228,236 @@ static int __cam_isp_ctx_handle_error(struct cam_isp_context *ctx_isp, return rc; } static int __cam_isp_ctx_fs2_sof_in_sof_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; struct cam_ctx_request *req; struct cam_context *ctx = ctx_isp->base; struct cam_req_mgr_trigger_notify notify; uint64_t request_id = 0; 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"); return -EINVAL; } ctx_isp->frame_id++; ctx_isp->sof_timestamp_val = sof_event_data->timestamp; ctx_isp->boot_timestamp = sof_event_data->boot_time; __cam_isp_ctx_update_state_monitor_array(ctx_isp, CAM_ISP_STATE_CHANGE_TRIGGER_SOF, req->request_id); CAM_DBG(CAM_ISP, "frame id: %lld time stamp:0x%llx", ctx_isp->frame_id, ctx_isp->sof_timestamp_val); if (!(list_empty(&ctx->wait_req_list))) goto end; 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_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) { 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 { CAM_ERR_RATE_LIMIT(CAM_ISP, "Can not notify SOF to CRM"); rc = -EFAULT; } end: return rc; } static int __cam_isp_ctx_fs2_buf_done(struct cam_isp_context *ctx_isp, void *evt_data) { int rc = 0; struct cam_isp_hw_done_event_data *done = (struct cam_isp_hw_done_event_data *) evt_data; struct cam_context *ctx = ctx_isp->base; int prev_active_req_cnt = 0; int curr_req_id = 0; struct cam_ctx_request *req; prev_active_req_cnt = ctx_isp->active_req_cnt; req = list_first_entry(&ctx->active_req_list, struct cam_ctx_request, list); if (req) curr_req_id = req->request_id; rc = __cam_isp_ctx_handle_buf_done_in_activated_state(ctx_isp, done, 0); if (prev_active_req_cnt == ctx_isp->active_req_cnt + 1) { if (list_empty(&ctx->wait_req_list) && list_empty(&ctx->active_req_list)) { CAM_DBG(CAM_ISP, "No request, move to SOF"); ctx_isp->substate_activated = CAM_ISP_CTX_ACTIVATED_SOF; if (ctx_isp->reported_req_id < curr_req_id) { ctx_isp->reported_req_id = curr_req_id; __cam_isp_ctx_send_sof_timestamp(ctx_isp, curr_req_id, CAM_REQ_MGR_SOF_EVENT_SUCCESS); } } } return rc; } static int __cam_isp_ctx_fs2_buf_done_in_epoch(struct cam_isp_context *ctx_isp, void *evt_data) { int rc = 0; rc = __cam_isp_ctx_fs2_buf_done(ctx_isp, evt_data); return rc; } static int __cam_isp_ctx_fs2_buf_done_in_applied( struct cam_isp_context *ctx_isp, void *evt_data) { int rc = 0; rc = __cam_isp_ctx_fs2_buf_done(ctx_isp, evt_data); return rc; } static int __cam_isp_ctx_fs2_reg_upd_in_sof(struct cam_isp_context *ctx_isp, void *evt_data) { int rc = 0; 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 && ctx_isp->frame_id > 1) { CAM_DBG(CAM_ISP, "invalid RUP"); goto end; } /* * This is for the first update. The initial setting will * cause the reg_upd in the first frame. */ if (!list_empty(&ctx->wait_req_list)) { req = list_first_entry(&ctx->wait_req_list, 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) list_add_tail(&req->list, &ctx->free_req_list); else CAM_ERR(CAM_ISP, "receive rup in unexpected state"); } if (req != NULL) { __cam_isp_ctx_update_state_monitor_array(ctx_isp, CAM_ISP_STATE_CHANGE_TRIGGER_REG_UPDATE, req->request_id); } end: return rc; } static int __cam_isp_ctx_fs2_reg_upd_in_applied_state( struct cam_isp_context *ctx_isp, void *evt_data) { int rc = 0; struct cam_ctx_request *req = NULL; struct cam_context *ctx = ctx_isp->base; struct cam_isp_ctx_req *req_isp; struct cam_req_mgr_trigger_notify notify; uint64_t request_id = 0; if (list_empty(&ctx->wait_req_list)) { CAM_ERR(CAM_ISP, "Reg upd ack with no waiting request"); goto end; } req = list_first_entry(&ctx->wait_req_list, 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 != 0) { list_add_tail(&req->list, &ctx->active_req_list); ctx_isp->active_req_cnt++; CAM_DBG(CAM_REQ, "move request %lld to active list(cnt = %d)", 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); } /* * This function only called directly from applied and bubble applied * state so change substate here. */ ctx_isp->substate_activated = CAM_ISP_CTX_ACTIVATED_EPOCH; if (req_isp->num_fence_map_out != 1) goto end; if (ctx->ctx_crm_intf && ctx->ctx_crm_intf->notify_trigger && ctx_isp->active_req_cnt <= 2) { list_for_each_entry(req, &ctx->active_req_list, list) { if (req->request_id > ctx_isp->reported_req_id) { 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); 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_trigger(¬ify); CAM_DBG(CAM_ISP, "Notify CRM SOF frame %lld", ctx_isp->frame_id); } } else { CAM_ERR_RATE_LIMIT(CAM_ISP, "Can not notify SOF to CRM"); rc = -EFAULT; } CAM_DBG(CAM_ISP, "next substate %d", ctx_isp->substate_activated); end: if (req != NULL && !rc) { __cam_isp_ctx_update_state_monitor_array(ctx_isp, CAM_ISP_STATE_CHANGE_TRIGGER_EPOCH, req->request_id); } return rc; } static struct cam_isp_ctx_irq_ops cam_isp_ctx_activated_state_machine_irq[CAM_ISP_CTX_ACTIVATED_MAX] = { /* SOF */ Loading Loading @@ -1301,6 +1531,79 @@ static struct cam_isp_ctx_irq_ops }, }; static struct cam_isp_ctx_irq_ops cam_isp_ctx_fs2_state_machine_irq[CAM_ISP_CTX_ACTIVATED_MAX] = { /* SOF */ { .irq_ops = { __cam_isp_ctx_handle_error, __cam_isp_ctx_fs2_sof_in_sof_state, __cam_isp_ctx_fs2_reg_upd_in_sof, __cam_isp_ctx_fs2_sof_in_sof_state, __cam_isp_ctx_notify_eof_in_activated_state, NULL, }, }, /* APPLIED */ { .irq_ops = { __cam_isp_ctx_handle_error, __cam_isp_ctx_sof_in_activated_state, __cam_isp_ctx_fs2_reg_upd_in_applied_state, __cam_isp_ctx_epoch_in_applied, __cam_isp_ctx_notify_eof_in_activated_state, __cam_isp_ctx_fs2_buf_done_in_applied, }, }, /* EPOCH */ { .irq_ops = { __cam_isp_ctx_handle_error, __cam_isp_ctx_sof_in_epoch, __cam_isp_ctx_reg_upd_in_epoch_state, __cam_isp_ctx_notify_sof_in_activated_state, __cam_isp_ctx_notify_eof_in_activated_state, __cam_isp_ctx_fs2_buf_done_in_epoch, }, }, /* BUBBLE */ { .irq_ops = { __cam_isp_ctx_handle_error, __cam_isp_ctx_sof_in_activated_state, NULL, __cam_isp_ctx_notify_sof_in_activated_state, __cam_isp_ctx_notify_eof_in_activated_state, __cam_isp_ctx_buf_done_in_bubble, }, }, /* Bubble Applied */ { .irq_ops = { __cam_isp_ctx_handle_error, __cam_isp_ctx_sof_in_activated_state, __cam_isp_ctx_reg_upd_in_activated_state, __cam_isp_ctx_epoch_in_bubble_applied, NULL, __cam_isp_ctx_buf_done_in_bubble_applied, }, }, /* HW ERROR */ { .irq_ops = { NULL, __cam_isp_ctx_sof_in_activated_state, __cam_isp_ctx_reg_upd_in_hw_error, NULL, NULL, NULL, }, }, /* HALT */ { }, }; static int __cam_isp_ctx_apply_req_in_activated_state( struct cam_context *ctx, struct cam_req_mgr_apply_request *apply, uint32_t next_state) Loading Loading @@ -1620,6 +1923,58 @@ static struct cam_ctx_ops }, }; static struct cam_ctx_ops cam_isp_ctx_fs2_state_machine[CAM_ISP_CTX_ACTIVATED_MAX] = { /* SOF */ { .ioctl_ops = {}, .crm_ops = { .apply_req = __cam_isp_ctx_apply_req_in_sof, }, .irq_ops = NULL, }, /* APPLIED */ { .ioctl_ops = {}, .crm_ops = {}, .irq_ops = NULL, }, /* EPOCH */ { .ioctl_ops = {}, .crm_ops = { .apply_req = __cam_isp_ctx_apply_req_in_epoch, }, .irq_ops = NULL, }, /* BUBBLE */ { .ioctl_ops = {}, .crm_ops = { .apply_req = __cam_isp_ctx_apply_req_in_bubble, }, .irq_ops = NULL, }, /* Bubble Applied */ { .ioctl_ops = {}, .crm_ops = {}, .irq_ops = NULL, }, /* HW ERROR */ { .ioctl_ops = {}, .crm_ops = {}, .irq_ops = NULL, }, /* HALT */ { .ioctl_ops = {}, .crm_ops = {}, .irq_ops = NULL, }, }; static int __cam_isp_ctx_rdi_only_sof_in_top_state( struct cam_isp_context *ctx_isp, void *evt_data) { Loading Loading @@ -2424,7 +2779,7 @@ static int __cam_isp_ctx_acquire_dev_in_available(struct cam_context *ctx, /* Query the context has rdi only resource */ hw_cmd_args.ctxt_to_hw_map = param.ctxt_to_hw_map; hw_cmd_args.cmd_type = CAM_HW_MGR_CMD_INTERNAL; isp_hw_cmd_args.cmd_type = CAM_ISP_HW_MGR_CMD_IS_RDI_ONLY_CONTEXT; isp_hw_cmd_args.cmd_type = CAM_ISP_HW_MGR_CMD_CTX_TYPE; hw_cmd_args.u.internal_args = (void *)&isp_hw_cmd_args; rc = ctx->hw_mgr_intf->hw_cmd(ctx->hw_mgr_intf->hw_mgr_priv, &hw_cmd_args); Loading @@ -2433,7 +2788,7 @@ static int __cam_isp_ctx_acquire_dev_in_available(struct cam_context *ctx, goto free_hw; } if (isp_hw_cmd_args.u.is_rdi_only_context) { if (isp_hw_cmd_args.u.ctx_type == CAM_ISP_CTX_RDI) { /* * this context has rdi only resource assign rdi only * state machine Loading @@ -2444,6 +2799,13 @@ static int __cam_isp_ctx_acquire_dev_in_available(struct cam_context *ctx, cam_isp_ctx_rdi_only_activated_state_machine_irq; ctx_isp->substate_machine = cam_isp_ctx_rdi_only_activated_state_machine; ctx_isp->rdi_only_context = true; } else if (isp_hw_cmd_args.u.ctx_type == CAM_ISP_CTX_FS2) { CAM_DBG(CAM_ISP, "FS2 Session has PIX ,RD and RDI"); ctx_isp->substate_machine_irq = cam_isp_ctx_fs2_state_machine_irq; ctx_isp->substate_machine = cam_isp_ctx_fs2_state_machine; } else { CAM_DBG(CAM_ISP, "Session has PIX or PIX and RDI resources"); ctx_isp->substate_machine_irq = Loading @@ -2452,7 +2814,6 @@ static int __cam_isp_ctx_acquire_dev_in_available(struct cam_context *ctx, cam_isp_ctx_activated_state_machine; } ctx_isp->rdi_only_context = isp_hw_cmd_args.u.is_rdi_only_context; ctx_isp->hw_ctx = param.ctxt_to_hw_map; ctx_isp->hw_acquired = true; ctx_isp->split_acquire = false; Loading Loading @@ -2570,7 +2931,7 @@ static int __cam_isp_ctx_acquire_hw_v1(struct cam_context *ctx, /* Query the context has rdi only resource */ hw_cmd_args.ctxt_to_hw_map = param.ctxt_to_hw_map; hw_cmd_args.cmd_type = CAM_HW_MGR_CMD_INTERNAL; isp_hw_cmd_args.cmd_type = CAM_ISP_HW_MGR_CMD_IS_RDI_ONLY_CONTEXT; isp_hw_cmd_args.cmd_type = CAM_ISP_HW_MGR_CMD_CTX_TYPE; hw_cmd_args.u.internal_args = (void *)&isp_hw_cmd_args; rc = ctx->hw_mgr_intf->hw_cmd(ctx->hw_mgr_intf->hw_mgr_priv, &hw_cmd_args); Loading @@ -2579,7 +2940,7 @@ static int __cam_isp_ctx_acquire_hw_v1(struct cam_context *ctx, goto free_hw; } if (isp_hw_cmd_args.u.is_rdi_only_context) { if (isp_hw_cmd_args.u.ctx_type == CAM_ISP_CTX_RDI) { /* * this context has rdi only resource assign rdi only * state machine Loading @@ -2590,6 +2951,13 @@ static int __cam_isp_ctx_acquire_hw_v1(struct cam_context *ctx, cam_isp_ctx_rdi_only_activated_state_machine_irq; ctx_isp->substate_machine = cam_isp_ctx_rdi_only_activated_state_machine; ctx_isp->rdi_only_context = true; } else if (isp_hw_cmd_args.u.ctx_type == CAM_ISP_CTX_FS2) { CAM_DBG(CAM_ISP, "FS2 Session has PIX ,RD and RDI"); ctx_isp->substate_machine_irq = cam_isp_ctx_fs2_state_machine_irq; ctx_isp->substate_machine = cam_isp_ctx_fs2_state_machine; } else { CAM_DBG(CAM_ISP, "Session has PIX or PIX and RDI resources"); ctx_isp->substate_machine_irq = Loading @@ -2598,16 +2966,14 @@ static int __cam_isp_ctx_acquire_hw_v1(struct cam_context *ctx, cam_isp_ctx_activated_state_machine; } ctx_isp->rdi_only_context = isp_hw_cmd_args.u.is_rdi_only_context; ctx_isp->hw_ctx = param.ctxt_to_hw_map; ctx_isp->hw_acquired = true; ctx->ctxt_to_hw_map = param.ctxt_to_hw_map; trace_cam_context_state("ISP", ctx); CAM_DBG(CAM_ISP, "Acquire success on session_hdl 0x%xs RDI only %d ctx %u", ctx->session_hdl, (isp_hw_cmd_args.u.is_rdi_only_context ? 1 : 0), ctx->ctx_id); "Acquire success on session_hdl 0x%xs ctx_type %d ctx_id %u", ctx->session_hdl, isp_hw_cmd_args.u.ctx_type, ctx->ctx_id); kfree(acquire_hw_info); return rc; Loading
drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c +16 −10 Original line number Diff line number Diff line Loading @@ -2228,7 +2228,8 @@ static int cam_isp_blob_bw_update( if (!hw_mgr_res->hw_res[i]) continue; if (hw_mgr_res->res_id == CAM_ISP_HW_VFE_IN_CAMIF) if ((hw_mgr_res->res_id == CAM_ISP_HW_VFE_IN_CAMIF) || (hw_mgr_res->res_id == CAM_ISP_HW_VFE_IN_RD)) if (i == CAM_ISP_HW_SPLIT_LEFT) { if (camif_l_bw_updated) continue; Loading Loading @@ -3599,6 +3600,7 @@ static int cam_isp_packet_generic_blob_handler(void *user_data, CAM_ERR(CAM_ISP, "FS Update Failed rc: %d", rc); } break; default: CAM_WARN(CAM_ISP, "Invalid blob type %d", blob_type); break; Loading Loading @@ -3904,12 +3906,6 @@ static int cam_ife_mgr_cmd(void *hw_mgr_priv, void *cmd_args) hw_cmd_args->u.internal_args; switch (isp_hw_cmd_args->cmd_type) { case CAM_ISP_HW_MGR_CMD_IS_RDI_ONLY_CONTEXT: if (ctx->is_rdi_only_context) isp_hw_cmd_args->u.is_rdi_only_context = 1; else isp_hw_cmd_args->u.is_rdi_only_context = 0; break; case CAM_ISP_HW_MGR_CMD_PAUSE_HW: cam_ife_mgr_pause_hw(ctx); break; Loading @@ -3920,6 +3916,14 @@ static int cam_ife_mgr_cmd(void *hw_mgr_priv, void *cmd_args) cam_ife_mgr_sof_irq_debug(ctx, isp_hw_cmd_args->u.sof_irq_enable); break; case CAM_ISP_HW_MGR_CMD_CTX_TYPE: if (ctx->is_fe_enable) isp_hw_cmd_args->u.ctx_type = CAM_ISP_CTX_FS2; else if (ctx->is_rdi_only_context) isp_hw_cmd_args->u.ctx_type = CAM_ISP_CTX_RDI; else isp_hw_cmd_args->u.ctx_type = CAM_ISP_CTX_PIX; break; default: CAM_ERR(CAM_ISP, "Invalid HW mgr command:0x%x", hw_cmd_args->cmd_type); Loading Loading @@ -4472,7 +4476,8 @@ static int cam_ife_hw_mgr_handle_reg_update( rup_status = hw_res->bottom_half_handler( hw_res, evt_payload); if (!ife_hwr_mgr_ctx->is_rdi_only_context) if (ife_hwr_mgr_ctx->is_rdi_only_context == 0 && ife_hwr_mgr_ctx->is_fe_enable == false) continue; if (atomic_read(&ife_hwr_mgr_ctx->overflow_pending)) Loading Loading @@ -4815,7 +4820,8 @@ static int cam_ife_hw_mgr_handle_sof( hw_res, evt_payload); /* check if it is rdi only context */ if (ife_hw_mgr_ctx->is_rdi_only_context) { if (ife_hw_mgr_ctx->is_fe_enable || ife_hw_mgr_ctx->is_rdi_only_context) { if (!sof_status && !sof_sent) { cam_ife_mgr_cmd_get_sof_timestamp( ife_hw_mgr_ctx, Loading @@ -4826,7 +4832,7 @@ static int cam_ife_hw_mgr_handle_sof( ife_hw_mgr_ctx->common.cb_priv, CAM_ISP_HW_EVENT_SOF, &sof_done_event_data); CAM_DBG(CAM_ISP, "sof_status = %d", CAM_DBG(CAM_ISP, "RDI sof_status = %d", sof_status); sof_sent = true; Loading
drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/include/cam_isp_hw_mgr_intf.h +11 −3 Original line number Diff line number Diff line Loading @@ -199,20 +199,28 @@ enum cam_isp_hw_mgr_command { CAM_ISP_HW_MGR_CMD_PAUSE_HW, CAM_ISP_HW_MGR_CMD_RESUME_HW, CAM_ISP_HW_MGR_CMD_SOF_DEBUG, CAM_ISP_HW_MGR_CMD_CTX_TYPE, CAM_ISP_HW_MGR_CMD_MAX, }; enum cam_isp_ctx_type { CAM_ISP_CTX_FS2 = 1, CAM_ISP_CTX_RDI, CAM_ISP_CTX_PIX, CAM_ISP_CTX_MAX, }; /** * struct cam_isp_hw_cmd_args - Payload for hw manager command * * @cmd_type HW command type * @get_context Get context type information * @sof_irq_enable To debug if SOF irq is enabled * @ctx_type RDI_ONLY, PIX and RDI, or FS2 */ struct cam_isp_hw_cmd_args { uint32_t cmd_type; union { uint32_t is_rdi_only_context; uint32_t sof_irq_enable; uint32_t ctx_type; } u; }; Loading
drivers/media/platform/msm/camera/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_core.c +6 −1 Original line number Diff line number Diff line Loading @@ -36,6 +36,11 @@ static uint32_t camif_irq_reg_mask[CAM_IFE_IRQ_REGISTERS_MAX] = { 0x00000000, }; static uint32_t camif_fe_irq_reg_mask[CAM_IFE_IRQ_REGISTERS_MAX] = { 0x10000056, 0x00000000, }; static uint32_t camif_irq_err_reg_mask[CAM_IFE_IRQ_REGISTERS_MAX] = { 0x0003FC00, 0xEFFF7EBC, Loading Loading @@ -606,7 +611,7 @@ int cam_vfe_start(void *hw_priv, void *start_args, uint32_t arg_size) cam_irq_controller_subscribe_irq( core_info->vfe_irq_controller, CAM_IRQ_PRIORITY_1, camif_irq_reg_mask, camif_fe_irq_reg_mask, &core_info->irq_payload, cam_vfe_irq_top_half, cam_ife_mgr_do_tasklet, Loading