diff --git a/techpack/camera/drivers/cam_fd/fd_hw_mgr/cam_fd_hw_mgr.c b/techpack/camera/drivers/cam_fd/fd_hw_mgr/cam_fd_hw_mgr.c index 3035982861ee..33566f8fb403 100644 --- a/techpack/camera/drivers/cam_fd/fd_hw_mgr/cam_fd_hw_mgr.c +++ b/techpack/camera/drivers/cam_fd/fd_hw_mgr/cam_fd_hw_mgr.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. */ #include @@ -54,7 +55,7 @@ static int cam_fd_mgr_util_packet_validate(struct cam_packet *packet, } /* All buffers must come through io config, do not support patching */ - if (packet->num_patches || !packet->num_io_configs) { + if (packet->num_patches || !packet->num_io_configs || !packet->num_cmd_buf) { CAM_ERR(CAM_FD, "wrong number of cmd/patch info: %u %u", packet->num_cmd_buf, packet->num_patches); return -EINVAL; diff --git a/techpack/camera/drivers/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c b/techpack/camera/drivers/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c index d6a1ecee86f9..a6ef5560594e 100644 --- a/techpack/camera/drivers/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c +++ b/techpack/camera/drivers/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c @@ -4189,13 +4189,13 @@ static int cam_icp_mgr_pkt_validation(struct cam_packet *packet) return -EINVAL; } - if (packet->num_io_configs > IPE_IO_IMAGES_MAX) { + if (!packet->num_io_configs || packet->num_io_configs > IPE_IO_IMAGES_MAX) { CAM_ERR(CAM_ICP, "Invalid number of io configs: %d %d", IPE_IO_IMAGES_MAX, packet->num_io_configs); return -EINVAL; } - if (packet->num_cmd_buf > CAM_ICP_CTX_MAX_CMD_BUFFERS) { + if (!packet->num_cmd_buf || packet->num_cmd_buf > CAM_ICP_CTX_MAX_CMD_BUFFERS) { CAM_ERR(CAM_ICP, "Invalid number of cmd buffers: %d %d", CAM_ICP_CTX_MAX_CMD_BUFFERS, packet->num_cmd_buf); return -EINVAL; diff --git a/techpack/camera/drivers/cam_isp/cam_isp_context.c b/techpack/camera/drivers/cam_isp/cam_isp_context.c index f3d454914204..dcb3570340a4 100644 --- a/techpack/camera/drivers/cam_isp/cam_isp_context.c +++ b/techpack/camera/drivers/cam_isp/cam_isp_context.c @@ -894,6 +894,33 @@ static int __cam_isp_ctx_handle_buf_done_for_req_list( return rc; } +static int __cam_isp_ctx_handle_early_buf_done( + struct cam_isp_context *ctx_isp, + struct cam_ctx_request *req) +{ + int i, rc = 0; + + struct cam_isp_ctx_req *req_isp = (struct cam_isp_ctx_req *) req->req_priv; + struct cam_context *ctx = ctx_isp->base; + + for (i = 0; i < req_isp->num_fence_map_out; i++) { + if (req_isp->early_fence_map_index[i] == 1) { + rc = cam_sync_signal(req_isp->fence_map_out[i].sync_id, + CAM_SYNC_STATE_SIGNALED_SUCCESS, + CAM_SYNC_COMMON_EVENT_SUCCESS); + req_isp->early_fence_map_index[i] = 0; + req_isp->fence_map_out[i].sync_id = -1; + CAM_DBG(CAM_ISP, + "Sync :req %lld res 0x%x fd 0x%x idx %d ctx %u", + req->request_id, + req_isp->fence_map_out[i].resource_handle, + req_isp->fence_map_out[i].sync_id, i, + ctx->ctx_id); + req_isp->flag_sync_set = true; + } + } + return rc; +} static int __cam_isp_ctx_handle_buf_done_for_request( struct cam_isp_context *ctx_isp, struct cam_ctx_request *req, @@ -968,6 +995,13 @@ static int __cam_isp_ctx_handle_buf_done_for_request( } if (!req_isp->bubble_detected) { + /* Signal fence for early bufdones got during reapply of a bubble req*/ + if ((req_isp->num_acked != 0) && (!req_isp->flag_sync_set)) { + rc = __cam_isp_ctx_handle_early_buf_done(ctx_isp, req); + if (rc) + CAM_ERR(CAM_ISP, "Sync early bufdone failed rc=%d", rc); + } + CAM_DBG(CAM_ISP, "Sync with success: req %lld res 0x%x fd 0x%x, ctx %u, Bad_frame %u", req->request_id, @@ -1017,18 +1051,19 @@ static int __cam_isp_ctx_handle_buf_done_for_request( */ req_isp->num_acked++; CAM_DBG(CAM_ISP, - "buf done with bubble state %d recovery %d", - bubble_state, req_isp->bubble_report); + "buf done with bubble state %d recovery %d num_acked %d ctx %u", + bubble_state, req_isp->bubble_report, + req_isp->num_acked, ctx->ctx_id); continue; } - CAM_DBG(CAM_ISP, "req %lld, reset sync id 0x%x ctx %u", - req->request_id, - req_isp->fence_map_out[j].sync_id, ctx->ctx_id); if (!rc) { req_isp->num_acked++; req_isp->fence_map_out[j].sync_id = -1; } + CAM_DBG(CAM_ISP, "rc %d num_acked %d req %lld, reset sync id 0x%x ctx %u", + rc, req_isp->num_acked, req->request_id, + req_isp->fence_map_out[j].sync_id, ctx->ctx_id); if ((ctx_isp->use_frame_header_ts) && (req_isp->hw_update_data.frame_header_res_id == @@ -1275,8 +1310,10 @@ static int __cam_isp_ctx_handle_buf_done_for_request_verify_addr( */ req_isp->num_acked++; CAM_DBG(CAM_ISP, - "buf done with bubble state %d recovery %d", - bubble_state, req_isp->bubble_report); + "num_acked %d buf done with bubble state %d recovery %d ctx %d", + req_isp->num_acked, bubble_state, + req_isp->bubble_report, + ctx->ctx_id); /* Process deferred buf_done acks */ if (req_isp->num_deferred_acks) @@ -1288,13 +1325,13 @@ static int __cam_isp_ctx_handle_buf_done_for_request_verify_addr( continue; } - CAM_DBG(CAM_ISP, "req %lld, reset sync id 0x%x ctx %u", - req->request_id, - req_isp->fence_map_out[j].sync_id, ctx->ctx_id); if (!rc) { req_isp->num_acked++; req_isp->fence_map_out[j].sync_id = -1; } + CAM_DBG(CAM_ISP, "num_acked %d req %lld, reset sync id 0x%x ctx %u", + req_isp->num_acked, req->request_id, + req_isp->fence_map_out[j].sync_id, ctx->ctx_id); if ((ctx_isp->use_frame_header_ts) && (req_isp->hw_update_data.frame_header_res_id == @@ -1329,9 +1366,60 @@ static int __cam_isp_ctx_handle_buf_done( struct cam_ctx_request *req; struct cam_context *ctx = ctx_isp->base; struct cam_isp_hw_done_event_data done_next_req; + int i, j; if (list_empty(&ctx->active_req_list)) { CAM_WARN(CAM_ISP, "Buf done with no active request"); + + if (!list_empty(&ctx->wait_req_list)) { + struct cam_isp_ctx_req *req_isp; + + req = list_first_entry(&ctx->wait_req_list, + struct cam_ctx_request, list); + + if (ctx_isp->last_applied_req_id != + ctx_isp->last_bufdone_err_apply_req_id) { + CAM_WARN(CAM_ISP, + "Buf done with req %llu in wait list apply id:%lld last err id:%lld", + req->request_id, + ctx_isp->last_applied_req_id, + ctx_isp->last_bufdone_err_apply_req_id); + ctx_isp->last_bufdone_err_apply_req_id = + ctx_isp->last_applied_req_id; + } + + req_isp = (struct cam_isp_ctx_req *) req->req_priv; + + /* + * do not signal the fence as this request may go into + * Bubble state eventually. + */ + for (i = 0; i < done->num_handles; i++) { + for (j = 0; j < req_isp->num_fence_map_out; j++) { + if (done->resource_handle[i] == + req_isp->fence_map_out[j].resource_handle) { + req_isp->num_acked++; + /* + * save the fence map out index for signalling + * fence during re-apply of bubble request. + */ + req_isp->early_fence_map_index[j]++; + + CAM_WARN(CAM_ISP, "Early done req %lld res 0x%x", + req->request_id, + done->resource_handle[i]); + + CAM_WARN(CAM_ISP, "ctx %u ack %d total %d idx %d", + ctx->ctx_id, + req_isp->num_acked, + req_isp->num_fence_map_out, j); + break; + } + } + } + } else { + CAM_WARN(CAM_ISP, "Buf done with no request in wait as well"); + } return 0; } @@ -2031,6 +2119,7 @@ static int __cam_isp_ctx_epoch_in_applied(struct cam_isp_context *ctx_isp, void *evt_data) { uint64_t request_id = 0; + uint32_t i; uint32_t sof_event_status = CAM_REQ_MGR_SOF_EVENT_SUCCESS; struct cam_req_mgr_trigger_notify notify; struct cam_ctx_request *req; @@ -2068,6 +2157,10 @@ static int __cam_isp_ctx_epoch_in_applied(struct cam_isp_context *ctx_isp, req_isp->reapply = true; req_isp->cdm_reset_before_apply = false; + /* reset early_fence_map_index array */ + for (i = 0; i < req_isp->num_fence_map_out; i++) + req_isp->early_fence_map_index[i] = 0; + CAM_INFO_RATE_LIMIT(CAM_ISP, "ctx:%d Report Bubble flag %d req id:%lld", ctx->ctx_id, req_isp->bubble_report, req->request_id); if (req_isp->bubble_report && ctx->ctx_crm_intf && @@ -3128,7 +3221,7 @@ static int __cam_isp_ctx_apply_req_in_activated_state( struct cam_context *ctx, struct cam_req_mgr_apply_request *apply, enum cam_isp_ctx_activated_substate next_state) { - int rc = 0; + int rc = 0, i; struct cam_ctx_request *req; struct cam_ctx_request *active_req = NULL; struct cam_isp_ctx_req *req_isp; @@ -3225,6 +3318,12 @@ static int __cam_isp_ctx_apply_req_in_activated_state( } req_isp->bubble_report = apply->report_if_bubble; + /* reset early_fence_map_index */ + for (i = 0; i < req_isp->num_fence_map_out; i++) + req_isp->early_fence_map_index[i] = 0; + + req_isp->flag_sync_set = false; + cfg.ctxt_to_hw_map = ctx_isp->hw_ctx; cfg.request_id = req->request_id; cfg.hw_update_entries = req_isp->cfg; @@ -4305,6 +4404,65 @@ error: return 0; } +static int __cam_isp_ctx_rdi_only_reg_upd_in_applied_state( + struct cam_isp_context *ctx_isp, void *evt_data) +{ + struct cam_ctx_request *req = NULL; + struct cam_context *ctx = ctx_isp->base; + struct cam_isp_ctx_req *req_isp; + 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; + } + ctx_isp->substate_activated = CAM_ISP_CTX_ACTIVATED_EPOCH; + + 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; + + request_id = (req_isp->hw_update_data.packet_opcode_type == + CAM_ISP_PACKET_INIT_DEV) ? 0 : req->request_id; + + if (req_isp->num_fence_map_out != 0) { + list_add_tail(&req->list, &ctx->active_req_list); + ctx_isp->active_req_cnt++; + request_id = req->request_id; + CAM_DBG(CAM_REQ, + "move request %lld to active list(cnt = %d), ctx %u", + req->request_id, ctx_isp->active_req_cnt, ctx->ctx_id); + __cam_isp_ctx_update_event_record(ctx_isp, + CAM_ISP_CTX_EVENT_RUP, req); + } else { + /* no io config, so the request is completed. */ + list_add_tail(&req->list, &ctx->free_req_list); + CAM_DBG(CAM_ISP, + "move active request %lld to free list(cnt = %d), ctx %u", + req->request_id, ctx_isp->active_req_cnt, ctx->ctx_id); + } + + CAM_DBG(CAM_ISP, "next Substate[%s]", + __cam_isp_ctx_substate_val_to_type( + ctx_isp->substate_activated)); + + __cam_isp_ctx_update_event_record(ctx_isp, + CAM_ISP_CTX_EVENT_RUP, req); + + return 0; +end: + __cam_isp_ctx_update_event_record(ctx_isp, + CAM_ISP_CTX_EVENT_RUP, NULL); + /* + * There is no request in the pending list, move the sub state machine + * to SOF sub state + */ + ctx_isp->substate_activated = CAM_ISP_CTX_ACTIVATED_SOF; + return 0; +} + static struct cam_isp_ctx_irq_ops cam_isp_ctx_rdi_only_activated_state_machine_irq [CAM_ISP_CTX_ACTIVATED_MAX] = { @@ -4324,7 +4482,7 @@ static struct cam_isp_ctx_irq_ops .irq_ops = { __cam_isp_ctx_handle_error, __cam_isp_ctx_rdi_only_sof_in_applied_state, - NULL, + __cam_isp_ctx_rdi_only_reg_upd_in_applied_state, NULL, __cam_isp_ctx_notify_eof_in_activated_state, __cam_isp_ctx_buf_done_in_applied, diff --git a/techpack/camera/drivers/cam_isp/cam_isp_context.h b/techpack/camera/drivers/cam_isp/cam_isp_context.h index 108dc096d897..e216852cdbc5 100644 --- a/techpack/camera/drivers/cam_isp/cam_isp_context.h +++ b/techpack/camera/drivers/cam_isp/cam_isp_context.h @@ -143,6 +143,10 @@ struct cam_isp_ctx_irq_ops { * @num_acked: Count to track acked entried for output. * If count equals the number of fence out, it means * the request has been completed. + * @early_fence_map_index Array which stores fence map out index for resource + * which early buf done is received. + * @flag_sync_set Flags to track if early bufdone fence are signalled + * or not * @num_deferred_acks: Number of buf_dones/acks that are deferred to * handle or signalled in special scenarios. * Increment this count instead of num_acked and @@ -163,12 +167,13 @@ struct cam_isp_ctx_req { struct cam_ctx_request *base; struct cam_hw_update_entry cfg[CAM_ISP_CTX_CFG_MAX]; uint32_t num_cfg; - struct cam_hw_fence_map_entry fence_map_out - [CAM_ISP_CTX_RES_MAX]; + struct cam_hw_fence_map_entry fence_map_out[CAM_ISP_CTX_RES_MAX]; uint32_t num_fence_map_out; struct cam_hw_fence_map_entry fence_map_in[CAM_ISP_CTX_RES_MAX]; uint32_t num_fence_map_in; uint32_t num_acked; + uint32_t early_fence_map_index[CAM_ISP_CTX_RES_MAX]; + bool flag_sync_set; uint32_t num_deferred_acks; uint32_t deferred_fence_map_index[CAM_ISP_CTX_RES_MAX]; int32_t bubble_report; diff --git a/techpack/camera/drivers/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.c b/techpack/camera/drivers/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.c index 5d72d910ad37..a7580fc0a205 100644 --- a/techpack/camera/drivers/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.c +++ b/techpack/camera/drivers/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. */ #include @@ -769,8 +769,9 @@ static int cam_jpeg_mgr_prepare_hw_update(void *hw_mgr_priv, return rc; } - if ((packet->num_cmd_buf > 5) || !packet->num_patches || - !packet->num_io_configs || + if (!packet->num_cmd_buf || + (packet->num_cmd_buf > 5) || + !packet->num_patches || !packet->num_io_configs || (packet->num_io_configs > CAM_JPEG_IMAGE_MAX)) { CAM_ERR(CAM_JPEG, "wrong number of cmd/patch/io_configs info: %u %u %u", diff --git a/techpack/camera/drivers/cam_lrme/lrme_hw_mgr/cam_lrme_hw_mgr.c b/techpack/camera/drivers/cam_lrme/lrme_hw_mgr/cam_lrme_hw_mgr.c index d878271403d1..53ca5442e03f 100644 --- a/techpack/camera/drivers/cam_lrme/lrme_hw_mgr/cam_lrme_hw_mgr.c +++ b/techpack/camera/drivers/cam_lrme/lrme_hw_mgr/cam_lrme_hw_mgr.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. */ #include @@ -113,6 +114,11 @@ static int cam_lrme_mgr_util_packet_validate(struct cam_packet *packet, return -EINVAL; } + if (!packet->num_cmd_buf) { + CAM_ERR(CAM_LRME, "no cmd bufs"); + return -EINVAL; + } + cmd_desc = (struct cam_cmd_buf_desc *)((uint8_t *)&packet->payload + packet->cmd_buf_offset); diff --git a/techpack/camera/drivers/cam_ope/ope_hw_mgr/cam_ope_hw_mgr.c b/techpack/camera/drivers/cam_ope/ope_hw_mgr/cam_ope_hw_mgr.c index b76f97a7461c..9f16f0f48084 100644 --- a/techpack/camera/drivers/cam_ope/ope_hw_mgr/cam_ope_hw_mgr.c +++ b/techpack/camera/drivers/cam_ope/ope_hw_mgr/cam_ope_hw_mgr.c @@ -2379,13 +2379,15 @@ static int cam_ope_mgr_pkt_validation(struct cam_packet *packet) return -EINVAL; } - if (packet->num_io_configs > OPE_MAX_IO_BUFS) { + if (!packet->num_io_configs || + packet->num_io_configs > OPE_MAX_IO_BUFS) { CAM_ERR(CAM_OPE, "Invalid number of io configs: %d %d", OPE_MAX_IO_BUFS, packet->num_io_configs); return -EINVAL; } - if (packet->num_cmd_buf > OPE_PACKET_MAX_CMD_BUFS) { + if (!packet->num_cmd_buf || + packet->num_cmd_buf > OPE_PACKET_MAX_CMD_BUFS) { CAM_ERR(CAM_OPE, "Invalid number of cmd buffers: %d %d", OPE_PACKET_MAX_CMD_BUFS, packet->num_cmd_buf); return -EINVAL; diff --git a/techpack/camera/drivers/cam_sensor_module/cam_csiphy/cam_csiphy_core.c b/techpack/camera/drivers/cam_sensor_module/cam_csiphy/cam_csiphy_core.c index 06c02c1932f1..c1a2a53c9d10 100644 --- a/techpack/camera/drivers/cam_sensor_module/cam_csiphy/cam_csiphy_core.c +++ b/techpack/camera/drivers/cam_sensor_module/cam_csiphy/cam_csiphy_core.c @@ -393,9 +393,21 @@ int32_t cam_cmd_buf_parser(struct csiphy_device *csiphy_dev, return rc; } - cmd_desc = (struct cam_cmd_buf_desc *) - ((uint32_t *)&csl_packet->payload + - csl_packet->cmd_buf_offset / 4); + if (csl_packet->num_cmd_buf) + cmd_desc = (struct cam_cmd_buf_desc *) + ((uint32_t *)&csl_packet->payload + + csl_packet->cmd_buf_offset / 4); + else { + CAM_ERR(CAM_CSIPHY, "num_cmd_buffers = %d", csl_packet->num_cmd_buf); + rc = -EINVAL; + return rc; + } + + rc = cam_packet_util_validate_cmd_desc(cmd_desc); + if (rc) { + CAM_ERR(CAM_CSIPHY, "Invalid cmd desc ret: %d", rc); + return rc; + } rc = cam_mem_get_cpu_buf(cmd_desc->mem_handle, &generic_ptr, &len); diff --git a/techpack/camera/drivers/cam_utils/cam_packet_util.c b/techpack/camera/drivers/cam_utils/cam_packet_util.c index ebcd36cd4e11..ba0c93086c55 100644 --- a/techpack/camera/drivers/cam_utils/cam_packet_util.c +++ b/techpack/camera/drivers/cam_utils/cam_packet_util.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. */ #include @@ -40,6 +41,12 @@ int cam_packet_util_get_cmd_mem_addr(int handle, uint32_t **buf_addr, int cam_packet_util_validate_cmd_desc(struct cam_cmd_buf_desc *cmd_desc) { + + if (!cmd_desc) { + CAM_ERR(CAM_UTIL, "Invalid cmd desc"); + return -EINVAL; + } + if ((cmd_desc->length > cmd_desc->size) || (cmd_desc->mem_handle <= 0)) { CAM_ERR(CAM_UTIL, "invalid cmd arg %d %d %d %d", @@ -80,6 +87,7 @@ int cam_packet_util_validate_packet(struct cam_packet *packet, pkt_wo_payload = offsetof(struct cam_packet, payload); if ((!packet->header.size) || + ((size_t)packet->header.size <= pkt_wo_payload) || ((pkt_wo_payload + (size_t)packet->cmd_buf_offset + sum_cmd_desc) > (size_t)packet->header.size) || ((pkt_wo_payload + (size_t)packet->io_configs_offset + @@ -109,6 +117,11 @@ int cam_packet_util_get_kmd_buffer(struct cam_packet *packet, return -EINVAL; } + if (!packet->num_cmd_buf) { + CAM_ERR(CAM_UTIL, "Invalid num_cmd_buf = %d", packet->num_cmd_buf); + return -EINVAL; + } + if ((packet->kmd_cmd_buf_index < 0) || (packet->kmd_cmd_buf_index >= packet->num_cmd_buf)) { CAM_ERR(CAM_UTIL, "Invalid kmd buf index: %d",