diff --git a/techpack/camera/Makefile b/techpack/camera/Makefile index cb00746debf3..2568ff61c873 100644 --- a/techpack/camera/Makefile +++ b/techpack/camera/Makefile @@ -38,6 +38,10 @@ ifeq ($(CONFIG_ARCH_YUPIK), y) include $(srctree)/techpack/camera/config/yupikcamera.conf endif +ifeq ($(CONFIG_ARCH_SM6150), y) +include $(srctree)/techpack/camera/config/sm6150camera.conf +endif + ifeq ($(CONFIG_ARCH_KONA), y) LINUXINCLUDE += \ -include $(srctree)/techpack/camera/config/konacameraconf.h @@ -83,6 +87,11 @@ LINUXINCLUDE += \ -include $(srctree)/techpack/camera/config/yupikcameraconf.h endif +ifeq ($(CONFIG_ARCH_SM6150), y) +LINUXINCLUDE += \ + -include $(srctree)/techpack/camera/config/sm6150cameraconf.h +endif + endif ifneq (,$(filter $(CONFIG_SPECTRA_CAMERA), y m)) diff --git a/techpack/camera/config/sm6150camera.conf b/techpack/camera/config/sm6150camera.conf new file mode 100644 index 000000000000..66b3a4cd548f --- /dev/null +++ b/techpack/camera/config/sm6150camera.conf @@ -0,0 +1,18 @@ +# SPDX-License-Identifier: GPL-2.0-only +# Copyright (c) 2021, The Linux Foundation. All rights reserved. + +ifeq ($(CONFIG_QGKI),y) +export CONFIG_SPECTRA_CAMERA=m +$(info "QGKI Spectra Camera Building as DLKM") +else +export CONFIG_SPECTRA_CAMERA=m +$(info "GKI Spectra Camera Building as DLKM") +endif + +ifneq (,$(filter $(CONFIG_SPECTRA_CAMERA), y m)) +export CONFIG_SPECTRA_ISP=y +export CONFIG_SPECTRA_SENSOR=y +export CONFIG_SPECTRA_ICP=y +export CONFIG_SPECTRA_JPEG=y +export CONFIG_SPECTRA_CUSTOM=y +endif diff --git a/techpack/camera/config/sm6150cameraconf.h b/techpack/camera/config/sm6150cameraconf.h new file mode 100644 index 000000000000..d736f140093e --- /dev/null +++ b/techpack/camera/config/sm6150cameraconf.h @@ -0,0 +1,12 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2021, The Linux Foundation. All rights reserved. + */ + + +#define CONFIG_SPECTRA_CAMERA 1 +#define CONFIG_SPECTRA_ISP 1 +#define CONFIG_SPECTRA_SENSOR 1 +#define CONFIG_SPECTRA_ICP 1 +#define CONFIG_SPECTRA_JPEG 1 +#define CONFIG_SPECTRA_CUSTOM 1 diff --git a/techpack/camera/drivers/cam_cdm/cam_cdm.h b/techpack/camera/drivers/cam_cdm/cam_cdm.h index dc2c164e0b2c..df19116abab6 100644 --- a/techpack/camera/drivers/cam_cdm/cam_cdm.h +++ b/techpack/camera/drivers/cam_cdm/cam_cdm.h @@ -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. */ #ifndef _CAM_CDM_H_ @@ -68,6 +69,8 @@ #define CAM_CDM_BL_FIFO_LENGTH_MAX_DEFAULT 0x40 #define CAM_CDM_BL_FIFO_LENGTH_CFG_SHIFT 0x10 #define CAM_CDM_BL_FIFO_FLUSH_SHIFT 0x3 +#define CAM_CDM_BL_FIFO_BOUNDARY_CHECK \ + (CAM_CDM_BL_FIFO_LENGTH_MAX_DEFAULT / 2) #define CAM_CDM_BL_FIFO_REQ_SIZE_MAX 0x00 #define CAM_CDM_BL_FIFO_REQ_SIZE_MAX_DIV2 0x01 diff --git a/techpack/camera/drivers/cam_cdm/cam_cdm_core_common.c b/techpack/camera/drivers/cam_cdm/cam_cdm_core_common.c index fd84b8d6866b..6ca94e740013 100644 --- a/techpack/camera/drivers/cam_cdm/cam_cdm_core_common.c +++ b/techpack/camera/drivers/cam_cdm/cam_cdm_core_common.c @@ -180,12 +180,10 @@ void cam_cdm_notify_clients(struct cam_hw_info *cdm_hw, (struct cam_cdm_bl_cb_request_entry *)data; client_idx = CAM_CDM_GET_CLIENT_IDX(node->client_hdl); - mutex_lock(&cdm_hw->hw_mutex); client = core->clients[client_idx]; if ((!client) || (client->handle != node->client_hdl)) { CAM_ERR(CAM_CDM, "Invalid client %pK hdl=%x", client, node->client_hdl); - mutex_unlock(&cdm_hw->hw_mutex); return; } cam_cdm_get_client_refcount(client); @@ -204,7 +202,6 @@ void cam_cdm_notify_clients(struct cam_hw_info *cdm_hw, } mutex_unlock(&client->lock); cam_cdm_put_client_refcount(client); - mutex_unlock(&cdm_hw->hw_mutex); return; } else if (status == CAM_CDM_CB_STATUS_HW_RESET_DONE || status == CAM_CDM_CB_STATUS_HW_FLUSH || @@ -242,7 +239,6 @@ void cam_cdm_notify_clients(struct cam_hw_info *cdm_hw, for (i = 0; i < CAM_PER_CDM_MAX_REGISTERED_CLIENTS; i++) { if (core->clients[i] != NULL) { - mutex_lock(&cdm_hw->hw_mutex); client = core->clients[i]; cam_cdm_get_client_refcount(client); mutex_lock(&client->lock); @@ -265,7 +261,6 @@ void cam_cdm_notify_clients(struct cam_hw_info *cdm_hw, } mutex_unlock(&client->lock); cam_cdm_put_client_refcount(client); - mutex_unlock(&cdm_hw->hw_mutex); } } } diff --git a/techpack/camera/drivers/cam_cdm/cam_cdm_hw_core.c b/techpack/camera/drivers/cam_cdm/cam_cdm_hw_core.c index 37f2a0a10967..901f84c3e034 100644 --- a/techpack/camera/drivers/cam_cdm/cam_cdm_hw_core.c +++ b/techpack/camera/drivers/cam_cdm/cam_cdm_hw_core.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. */ #include @@ -1238,6 +1239,7 @@ static void cam_hw_cdm_work(struct work_struct *work) return; } + mutex_lock(&cdm_hw->hw_mutex); mutex_lock(&core->bl_fifo[fifo_idx].fifo_lock); if (atomic_read(&core->bl_fifo[fifo_idx].work_record)) @@ -1251,6 +1253,7 @@ static void cam_hw_cdm_work(struct work_struct *work) core->arbitration); mutex_unlock(&core->bl_fifo[fifo_idx] .fifo_lock); + mutex_unlock(&cdm_hw->hw_mutex); return; } @@ -1261,26 +1264,30 @@ static void cam_hw_cdm_work(struct work_struct *work) list_for_each_entry_safe(node, tnode, &core->bl_fifo[fifo_idx].bl_request_list, entry) { - if (node->request_type == - CAM_HW_CDM_BL_CB_CLIENT) { - cam_cdm_notify_clients(cdm_hw, - CAM_CDM_CB_STATUS_BL_SUCCESS, - (void *)node); - } else if (node->request_type == - CAM_HW_CDM_BL_CB_INTERNAL) { - CAM_ERR(CAM_CDM, - "Invalid node=%pK %d", - node, - node->request_type); - } - list_del_init(&node->entry); - if (node->bl_tag == payload->irq_data) { + if ((node->bl_tag <= payload->irq_data) || + ((node->bl_tag - payload->irq_data) > + CAM_CDM_BL_FIFO_BOUNDARY_CHECK)) { + if (node->request_type == + CAM_HW_CDM_BL_CB_CLIENT) { + cam_cdm_notify_clients(cdm_hw, + CAM_CDM_CB_STATUS_BL_SUCCESS, + (void *)node); + } else if (node->request_type == + CAM_HW_CDM_BL_CB_INTERNAL) { + CAM_ERR(CAM_CDM, + "Invalid node=%pK %d", + node, + node->request_type); + } + list_del_init(&node->entry); + if (node->bl_tag == payload->irq_data) { + kfree(node); + node = NULL; + break; + } kfree(node); node = NULL; - break; } - kfree(node); - node = NULL; } } else { CAM_INFO(CAM_CDM, @@ -1289,6 +1296,7 @@ static void cam_hw_cdm_work(struct work_struct *work) } mutex_unlock(&core->bl_fifo[payload->fifo_idx] .fifo_lock); + mutex_unlock(&cdm_hw->hw_mutex); } if (payload->irq_status & @@ -1405,9 +1413,9 @@ handle_cdm_pf: cdm_hw->soc_info.index); for (i = 0; i < core->offsets->reg_data->num_bl_fifo; i++) mutex_unlock(&core->bl_fifo[i].fifo_lock); - mutex_unlock(&cdm_hw->hw_mutex); cam_cdm_notify_clients(cdm_hw, CAM_CDM_CB_STATUS_PAGEFAULT, (void *)pf_info->iova); + mutex_unlock(&cdm_hw->hw_mutex); clear_bit(CAM_CDM_ERROR_HW_STATUS, &core->cdm_status); } else { CAM_ERR(CAM_CDM, "Invalid token"); diff --git a/techpack/camera/drivers/cam_core/cam_context_utils.c b/techpack/camera/drivers/cam_core/cam_context_utils.c index cfef68791326..eb1cfc581bb7 100644 --- a/techpack/camera/drivers/cam_core/cam_context_utils.c +++ b/techpack/camera/drivers/cam_core/cam_context_utils.c @@ -457,6 +457,9 @@ int32_t cam_context_prepare_dev_to_hw(struct cam_context *ctx, rc = cam_sync_check_valid( req->in_map_entries[j].sync_id); if (rc) { + spin_lock(&ctx->lock); + list_del_init(&req->list); + spin_unlock(&ctx->lock); CAM_ERR(CAM_CTXT, "invalid in map sync object %d", req->in_map_entries[j].sync_id); diff --git a/techpack/camera/drivers/cam_core/cam_subdev.c b/techpack/camera/drivers/cam_core/cam_subdev.c index cbe1b4ca3336..c1f345fabf1a 100644 --- a/techpack/camera/drivers/cam_core/cam_subdev.c +++ b/techpack/camera/drivers/cam_core/cam_subdev.c @@ -55,8 +55,10 @@ static long cam_subdev_ioctl(struct v4l2_subdev *sd, unsigned int cmd, switch (cmd) { case VIDIOC_CAM_CONTROL: + cam_req_mgr_rwsem_read_op(CAM_SUBDEV_LOCK); rc = cam_node_handle_ioctl(node, (struct cam_control *) arg); + cam_req_mgr_rwsem_read_op(CAM_SUBDEV_UNLOCK); break; case CAM_SD_SHUTDOWN: if (!cam_req_mgr_is_shutdown()) { diff --git a/techpack/camera/drivers/cam_cpas/cam_cpas_hw.c b/techpack/camera/drivers/cam_cpas/cam_cpas_hw.c index 15623b525e55..5aeda25f8415 100644 --- a/techpack/camera/drivers/cam_cpas/cam_cpas_hw.c +++ b/techpack/camera/drivers/cam_cpas/cam_cpas_hw.c @@ -1030,6 +1030,7 @@ static int cam_cpas_util_apply_default_axi_vote( struct cam_cpas *cpas_core = (struct cam_cpas *) cpas_hw->core_info; struct cam_cpas_axi_port *axi_port = NULL; uint64_t mnoc_ab_bw = 0, mnoc_ib_bw = 0; + uint64_t applied_ab_bw = 0, applied_ib_bw = 0; int rc = 0, i = 0; mutex_lock(&cpas_core->tree_lock); @@ -1057,6 +1058,8 @@ static int cam_cpas_util_apply_default_axi_vote( mnoc_ab_bw, mnoc_ib_bw, rc); goto unlock_tree; } + cpas_core->axi_port[i].applied_ab_bw = applied_ab_bw; + cpas_core->axi_port[i].applied_ib_bw = applied_ib_bw; } unlock_tree: diff --git a/techpack/camera/drivers/cam_fd/cam_fd_dev.c b/techpack/camera/drivers/cam_fd/cam_fd_dev.c index a58db056f6fb..e34c9bcc1e0b 100644 --- a/techpack/camera/drivers/cam_fd/cam_fd_dev.c +++ b/techpack/camera/drivers/cam_fd/cam_fd_dev.c @@ -44,8 +44,11 @@ static int cam_fd_dev_open(struct v4l2_subdev *sd, { struct cam_fd_dev *fd_dev = &g_fd_dev; + cam_req_mgr_rwsem_read_op(CAM_SUBDEV_LOCK); + if (!fd_dev->probe_done) { CAM_ERR(CAM_FD, "FD Dev not initialized, fd_dev=%pK", fd_dev); + cam_req_mgr_rwsem_read_op(CAM_SUBDEV_UNLOCK); return -ENODEV; } @@ -54,6 +57,8 @@ static int cam_fd_dev_open(struct v4l2_subdev *sd, CAM_DBG(CAM_FD, "FD Subdev open count %d", fd_dev->open_cnt); mutex_unlock(&fd_dev->lock); + cam_req_mgr_rwsem_read_op(CAM_SUBDEV_UNLOCK); + return 0; } diff --git a/techpack/camera/drivers/cam_icp/cam_icp_subdev.c b/techpack/camera/drivers/cam_icp/cam_icp_subdev.c index 1a3be9b64ad5..a15c726a963d 100644 --- a/techpack/camera/drivers/cam_icp/cam_icp_subdev.c +++ b/techpack/camera/drivers/cam_icp/cam_icp_subdev.c @@ -73,6 +73,8 @@ static int cam_icp_subdev_open(struct v4l2_subdev *sd, struct cam_node *node = v4l2_get_subdevdata(sd); int rc = 0; + cam_req_mgr_rwsem_read_op(CAM_SUBDEV_LOCK); + mutex_lock(&g_icp_dev.icp_lock); if (g_icp_dev.open_cnt >= 1) { CAM_ERR(CAM_ICP, "ICP subdev is already opened"); @@ -95,6 +97,7 @@ static int cam_icp_subdev_open(struct v4l2_subdev *sd, g_icp_dev.open_cnt++; end: mutex_unlock(&g_icp_dev.icp_lock); + cam_req_mgr_rwsem_read_op(CAM_SUBDEV_UNLOCK); return rc; } diff --git a/techpack/camera/drivers/cam_isp/cam_isp_context.c b/techpack/camera/drivers/cam_isp/cam_isp_context.c index acd4c1acad93..f3d454914204 100644 --- a/techpack/camera/drivers/cam_isp/cam_isp_context.c +++ b/techpack/camera/drivers/cam_isp/cam_isp_context.c @@ -3541,6 +3541,19 @@ hw_dump: return rc; } +static int __cam_isp_ctx_flush_req_in_flushed_state( + struct cam_context *ctx, + struct cam_req_mgr_flush_request *flush_req) +{ + if (flush_req->type == CAM_REQ_MGR_FLUSH_TYPE_ALL) { + CAM_INFO(CAM_ISP, "Flush in flushed state req id %lld ctx_id:%d", + flush_req->req_id, ctx->ctx_id); + ctx->last_flush_req = flush_req->req_id; + } + + return 0; +} + static int __cam_isp_ctx_flush_req(struct cam_context *ctx, struct list_head *req_list, struct cam_req_mgr_flush_request *flush_req) { @@ -4106,6 +4119,16 @@ static int __cam_isp_ctx_rdi_only_sof_in_bubble_state( CAM_DBG(CAM_ISP, "CDM callback detected for req: %lld, possible buf_done delay, waiting for buf_done", req->request_id); + if (req_isp->num_fence_map_out == + req_isp->num_deferred_acks) { + __cam_isp_handle_deferred_buf_done(ctx_isp, req, + true, + CAM_SYNC_STATE_SIGNALED_ERROR, + CAM_SYNC_ISP_EVENT_BUBBLE); + + __cam_isp_ctx_handle_buf_done_for_req_list( + ctx_isp, req); + } goto end; } else { CAM_WARN(CAM_ISP, @@ -4292,7 +4315,7 @@ static struct cam_isp_ctx_irq_ops __cam_isp_ctx_rdi_only_sof_in_top_state, __cam_isp_ctx_reg_upd_in_sof, NULL, - NULL, + __cam_isp_ctx_notify_eof_in_activated_state, NULL, }, }, @@ -4303,7 +4326,7 @@ static struct cam_isp_ctx_irq_ops __cam_isp_ctx_rdi_only_sof_in_applied_state, NULL, NULL, - NULL, + __cam_isp_ctx_notify_eof_in_activated_state, __cam_isp_ctx_buf_done_in_applied, }, }, @@ -4314,7 +4337,7 @@ static struct cam_isp_ctx_irq_ops __cam_isp_ctx_rdi_only_sof_in_top_state, NULL, NULL, - NULL, + __cam_isp_ctx_notify_eof_in_activated_state, __cam_isp_ctx_buf_done_in_epoch, }, }, @@ -4325,7 +4348,7 @@ static struct cam_isp_ctx_irq_ops __cam_isp_ctx_rdi_only_sof_in_bubble_state, __cam_isp_ctx_rdi_only_reg_upd_in_bubble_state, NULL, - NULL, + __cam_isp_ctx_notify_eof_in_activated_state, __cam_isp_ctx_buf_done_in_bubble, }, }, @@ -4336,7 +4359,7 @@ static struct cam_isp_ctx_irq_ops __cam_isp_ctx_rdi_only_sof_in_bubble_applied, __cam_isp_ctx_rdi_only_reg_upd_in_bubble_applied_state, NULL, - NULL, + __cam_isp_ctx_notify_eof_in_activated_state, __cam_isp_ctx_buf_done_in_bubble_applied, }, }, @@ -4637,6 +4660,14 @@ static int __cam_isp_ctx_config_dev_in_top_state( packet->header.request_id); rc = -EBADR; goto free_req; + } else if ((packet_opcode == CAM_ISP_PACKET_INIT_DEV) + && (packet->header.request_id <= ctx->last_flush_req) + && ctx->last_flush_req && packet->header.request_id) { + CAM_WARN(CAM_ISP, + "last flushed req is %lld, config dev(init) for req %lld", + ctx->last_flush_req, packet->header.request_id); + rc = -EBADR; + goto free_req; } cfg.packet = packet; @@ -5927,6 +5958,7 @@ static struct cam_ctx_ops .crm_ops = { .unlink = __cam_isp_ctx_unlink_in_ready, .process_evt = __cam_isp_ctx_process_evt, + .flush_req = __cam_isp_ctx_flush_req_in_flushed_state, }, .irq_ops = NULL, .pagefault_ops = cam_isp_context_dump_requests, diff --git a/techpack/camera/drivers/cam_isp/cam_isp_dev.c b/techpack/camera/drivers/cam_isp/cam_isp_dev.c index 9409c1015c6c..d2f8720541e6 100644 --- a/techpack/camera/drivers/cam_isp/cam_isp_dev.c +++ b/techpack/camera/drivers/cam_isp/cam_isp_dev.c @@ -64,10 +64,14 @@ static const struct of_device_id cam_isp_dt_match[] = { static int cam_isp_subdev_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) { + cam_req_mgr_rwsem_read_op(CAM_SUBDEV_LOCK); + mutex_lock(&g_isp_dev.isp_mutex); g_isp_dev.open_cnt++; mutex_unlock(&g_isp_dev.isp_mutex); + cam_req_mgr_rwsem_read_op(CAM_SUBDEV_UNLOCK); + return 0; } diff --git a/techpack/camera/drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c b/techpack/camera/drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c index 487f1eda3457..8af790e2d3b2 100644 --- a/techpack/camera/drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c +++ b/techpack/camera/drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c @@ -7990,6 +7990,14 @@ static int cam_ife_hw_mgr_handle_hw_eof( case CAM_ISP_HW_VFE_IN_RDI1: case CAM_ISP_HW_VFE_IN_RDI2: case CAM_ISP_HW_VFE_IN_RDI3: + if (!ife_hw_mgr_ctx->is_rdi_only_context) + break; + if (atomic_read(&ife_hw_mgr_ctx->overflow_pending)) + break; + ife_hw_irq_eof_cb(ife_hw_mgr_ctx->common.cb_priv, + CAM_ISP_HW_EVENT_EOF, (void *)&eof_done_event_data); + break; + case CAM_ISP_HW_VFE_IN_PDLIB: case CAM_ISP_HW_VFE_IN_LCR: break; diff --git a/techpack/camera/drivers/cam_isp/isp_hw_mgr/cam_tfe_hw_mgr.c b/techpack/camera/drivers/cam_isp/isp_hw_mgr/cam_tfe_hw_mgr.c index 4b33439c44f3..e5342bd95163 100644 --- a/techpack/camera/drivers/cam_isp/isp_hw_mgr/cam_tfe_hw_mgr.c +++ b/techpack/camera/drivers/cam_isp/isp_hw_mgr/cam_tfe_hw_mgr.c @@ -5405,6 +5405,65 @@ end: return 0; } +static int cam_tfe_hw_mgr_handle_hw_dump_info( + void *ctx, + void *evt_info) +{ + struct cam_tfe_hw_mgr_ctx *tfe_hw_mgr_ctx = + (struct cam_tfe_hw_mgr_ctx *)ctx; + struct cam_isp_hw_event_info *event_info = + (struct cam_isp_hw_event_info *)evt_info; + struct cam_isp_hw_mgr_res *hw_mgr_res = NULL; + struct cam_hw_intf *hw_intf; + uint32_t i, out_port_id; + uint64_t dummy_args; + int rc = 0; + + list_for_each_entry(hw_mgr_res, + &tfe_hw_mgr_ctx->res_list_tfe_csid, list) { + for (i = 0; i < CAM_ISP_HW_SPLIT_MAX; i++) { + if (!hw_mgr_res->hw_res[i]) + continue; + hw_intf = hw_mgr_res->hw_res[i]->hw_intf; + if (hw_intf->hw_ops.process_cmd) { + rc = hw_intf->hw_ops.process_cmd( + hw_intf->hw_priv, + CAM_ISP_HW_CMD_CSID_CLOCK_DUMP, + &dummy_args, + sizeof(uint64_t)); + if (rc) + CAM_ERR(CAM_ISP, + "CSID Clock Dump failed"); + } + } + } + + if (event_info->res_type == CAM_ISP_RESOURCE_VFE_OUT) { + out_port_id = event_info->res_id & 0xFF; + if (out_port_id >= CAM_TFE_HW_OUT_RES_MAX) { + CAM_ERR(CAM_ISP, + "Resource out of range"); + goto end; + } + hw_mgr_res = + &tfe_hw_mgr_ctx->res_list_tfe_out[out_port_id]; + for (i = 0; i < CAM_ISP_HW_SPLIT_MAX; i++) { + if (!hw_mgr_res->hw_res[i]) + continue; + hw_intf = hw_mgr_res->hw_res[i]->hw_intf; + if (hw_intf->hw_ops.process_cmd) { + rc = hw_intf->hw_ops.process_cmd( + hw_intf->hw_priv, + CAM_ISP_HW_CMD_DUMP_BUS_INFO, + (void *)event_info, + sizeof(struct cam_isp_hw_event_info)); + } + } + } +end: + return rc; +} + static int cam_tfe_hw_mgr_handle_csid_event( struct cam_isp_hw_event_info *event_info) { @@ -5433,8 +5492,10 @@ static int cam_tfe_hw_mgr_handle_csid_event( } static int cam_tfe_hw_mgr_handle_hw_err( + void *ctx, void *evt_info) { + struct cam_tfe_hw_mgr_ctx *tfe_hw_mgr_ctx; struct cam_isp_hw_event_info *event_info = evt_info; struct cam_isp_hw_error_event_data error_event_data = {0}; struct cam_tfe_hw_event_recovery_data recovery_data = {0}; @@ -5456,6 +5517,18 @@ static int cam_tfe_hw_mgr_handle_hw_err( return rc; } + if (ctx) { + tfe_hw_mgr_ctx = + (struct cam_tfe_hw_mgr_ctx *)ctx; + if (event_info->res_type == + CAM_ISP_RESOURCE_TFE_IN && + !tfe_hw_mgr_ctx->is_rdi_only_context && + event_info->res_id != + CAM_ISP_HW_TFE_IN_CAMIF) + cam_tfe_hw_mgr_handle_hw_dump_info( + tfe_hw_mgr_ctx, event_info); + } + core_idx = event_info->hw_idx; if (g_tfe_hw_mgr.debug_cfg.enable_recovery) @@ -5649,6 +5722,12 @@ static int cam_tfe_hw_mgr_handle_hw_eof( case CAM_ISP_HW_TFE_IN_RDI0: case CAM_ISP_HW_TFE_IN_RDI1: case CAM_ISP_HW_TFE_IN_RDI2: + if (!tfe_hw_mgr_ctx->is_rdi_only_context) + break; + if (atomic_read(&tfe_hw_mgr_ctx->overflow_pending)) + break; + tfe_hw_irq_eof_cb(tfe_hw_mgr_ctx->common.cb_priv, + CAM_ISP_HW_EVENT_EOF, (void *)&eof_done_event_data); break; default: @@ -5732,7 +5811,7 @@ static int cam_tfe_hw_mgr_event_handler( break; case CAM_ISP_HW_EVENT_ERROR: - rc = cam_tfe_hw_mgr_handle_hw_err(evt_info); + rc = cam_tfe_hw_mgr_handle_hw_err(priv, evt_info); break; default: diff --git a/techpack/camera/drivers/cam_isp/isp_hw_mgr/hw_utils/cam_isp_packet_parser.c b/techpack/camera/drivers/cam_isp/isp_hw_mgr/hw_utils/cam_isp_packet_parser.c index 09b0cdb0e881..7357cfd9f77b 100644 --- a/techpack/camera/drivers/cam_isp/isp_hw_mgr/hw_utils/cam_isp_packet_parser.c +++ b/techpack/camera/drivers/cam_isp/isp_hw_mgr/hw_utils/cam_isp_packet_parser.c @@ -124,6 +124,12 @@ static int cam_isp_update_dual_config( cpu_addr += (cmd_desc->offset / 4); dual_config = (struct cam_isp_dual_config *)cpu_addr; + if (dual_config->num_ports > size_isp_out) { + CAM_ERR(CAM_ISP, "num_ports %d more than max_vfe_out_res %d", + dual_config->num_ports, size_isp_out); + return -EINVAL; + } + if ((dual_config->num_ports * sizeof(struct cam_isp_dual_stripe_config)) > (remain_len - offsetof(struct cam_isp_dual_config, stripes))) { @@ -132,14 +138,6 @@ static int cam_isp_update_dual_config( } for (i = 0; i < dual_config->num_ports; i++) { - if (i >= CAM_ISP_IFE_OUT_RES_BASE + size_isp_out) { - CAM_ERR(CAM_ISP, - "failed update for i:%d > size_isp_out:%d", - i, size_isp_out); - rc = -EINVAL; - goto end; - } - hw_mgr_res = &res_list_isp_out[i]; if (!hw_mgr_res) { CAM_ERR(CAM_ISP, diff --git a/techpack/camera/drivers/cam_isp/isp_hw_mgr/isp_hw/ppi_hw/cam_csid_ppi_core.c b/techpack/camera/drivers/cam_isp/isp_hw_mgr/isp_hw/ppi_hw/cam_csid_ppi_core.c index 42a84af64e24..0fa94fc5fde5 100644 --- a/techpack/camera/drivers/cam_isp/isp_hw_mgr/isp_hw/ppi_hw/cam_csid_ppi_core.c +++ b/techpack/camera/drivers/cam_isp/isp_hw_mgr/isp_hw/ppi_hw/cam_csid_ppi_core.c @@ -163,9 +163,7 @@ static int cam_csid_ppi_init_hw(void *hw_priv, void *init_args, { int i, rc = 0; uint32_t num_lanes; - uint32_t lanes[CAM_CSID_PPI_HW_MAX] = {0, 0, 0, 0}; uint32_t cphy; - bool dl0, dl1; uint32_t ppi_cfg_val = 0; struct cam_csid_ppi_hw *ppi_hw; struct cam_hw_info *ppi_hw_info; @@ -180,7 +178,6 @@ static int cam_csid_ppi_init_hw(void *hw_priv, void *init_args, goto end; } - dl0 = dl1 = false; ppi_hw_info = (struct cam_hw_info *)hw_priv; ppi_hw = (struct cam_csid_ppi_hw *)ppi_hw_info->core_info; ppi_reg = ppi_hw->ppi_info->ppi_reg; @@ -195,30 +192,15 @@ static int cam_csid_ppi_init_hw(void *hw_priv, void *init_args, CAM_DBG(CAM_ISP, "lane_cfg 0x%x | num_lanes 0x%x | lane_type 0x%x", ppi_cfg.lane_cfg, num_lanes, cphy); - for (i = 0; i < num_lanes; i++) { - lanes[i] = ppi_cfg.lane_cfg & (0x3 << (4 * i)); - (lanes[i] < 2) ? (dl0 = true) : (dl1 = true); - CAM_DBG(CAM_ISP, "lanes[%d] %d", i, lanes[i]); + if (cphy) { + ppi_cfg_val |= PPI_CFG_CPHY_DLX_SEL(0); + ppi_cfg_val |= PPI_CFG_CPHY_DLX_SEL(1); + } else { + ppi_cfg_val = 0; } - if (num_lanes) { - if (cphy) { - for (i = 0; i < num_lanes; i++) { - ppi_cfg_val |= PPI_CFG_CPHY_DLX_SEL(lanes[i]); - ppi_cfg_val |= PPI_CFG_CPHY_DLX_EN(lanes[i]); - } - } else { - if (dl0) - ppi_cfg_val |= PPI_CFG_CPHY_DLX_EN(0); - if (dl1) - ppi_cfg_val |= PPI_CFG_CPHY_DLX_EN(1); - } - } else { - CAM_ERR(CAM_ISP, - "Number of lanes to enable is cannot be zero"); - rc = -1; - goto end; - } + for (i = 0; i < CAM_CSID_PPI_LANES_MAX; i++) + ppi_cfg_val |= PPI_CFG_CPHY_DLX_EN(i); CAM_DBG(CAM_ISP, "ppi_cfg_val 0x%x", ppi_cfg_val); soc_info = &ppi_hw->hw_info->soc_info; diff --git a/techpack/camera/drivers/cam_isp/isp_hw_mgr/isp_hw/ppi_hw/cam_csid_ppi_core.h b/techpack/camera/drivers/cam_isp/isp_hw_mgr/isp_hw/ppi_hw/cam_csid_ppi_core.h index dc0edf7e50ce..5f8873f529a7 100644 --- a/techpack/camera/drivers/cam_isp/isp_hw_mgr/isp_hw/ppi_hw/cam_csid_ppi_core.h +++ b/techpack/camera/drivers/cam_isp/isp_hw_mgr/isp_hw/ppi_hw/cam_csid_ppi_core.h @@ -25,7 +25,7 @@ /* * Select the PHY (CPHY set '1' or DPHY set '0') */ -#define PPI_CFG_CPHY_DLX_SEL(X) ((X < 2) ? BIT(X) : 0) +#define PPI_CFG_CPHY_DLX_SEL(X) BIT(X) #define PPI_CFG_CPHY_DLX_EN(X) BIT(4+X) diff --git a/techpack/camera/drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_csid_hw/cam_tfe_csid530.h b/techpack/camera/drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_csid_hw/cam_tfe_csid530.h index b0e9dc862c4d..fa54bb4f1c06 100644 --- a/techpack/camera/drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_csid_hw/cam_tfe_csid530.h +++ b/techpack/camera/drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_csid_hw/cam_tfe_csid530.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2019-2021, The Linux Foundation. All rights reserved. */ #ifndef _CAM_TFE_CSID_530_H_ @@ -134,6 +134,7 @@ static struct cam_tfe_csid_csi2_rx_reg_offset .csid_csi2_rx_irq_set_addr = 0x2c, /*CSI2 rx control */ + .phy_sel_base = 1, .csid_csi2_rx_cfg0_addr = 0x100, .csid_csi2_rx_cfg1_addr = 0x104, .csid_csi2_rx_capture_ctrl_addr = 0x108, diff --git a/techpack/camera/drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_csid_hw/cam_tfe_csid_core.c b/techpack/camera/drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_csid_hw/cam_tfe_csid_core.c index 7c86db7b8912..41137cd57efd 100644 --- a/techpack/camera/drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_csid_hw/cam_tfe_csid_core.c +++ b/techpack/camera/drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_csid_hw/cam_tfe_csid_core.c @@ -960,8 +960,14 @@ static int cam_tfe_csid_enable_csi2( cam_io_w_mb(val, soc_info->reg_map[0].mem_base + csid_reg->csi2_reg->csid_csi2_rx_irq_mask_addr); + /* + * There is one to one mapping for ppi index with phy index + * we do not always update phy sel equal to phy number,for some + * targets "phy_sel = phy_num + 1", and for some targets it is + * "phy_sel = phy_num", ppi_index should be updated accordingly + */ + ppi_index = csid_hw->csi2_rx_cfg.phy_sel - csid_reg->csi2_reg->phy_sel_base; - ppi_index = csid_hw->csi2_rx_cfg.phy_sel; if (csid_hw->ppi_hw_intf[ppi_index] && csid_hw->ppi_enable) { ppi_lane_cfg.lane_type = csid_hw->csi2_rx_cfg.lane_type; ppi_lane_cfg.lane_num = csid_hw->csi2_rx_cfg.lane_num; @@ -1005,7 +1011,7 @@ static int cam_tfe_csid_disable_csi2( cam_io_w_mb(0, soc_info->reg_map[0].mem_base + csid_reg->csi2_reg->csid_csi2_rx_cfg1_addr); - ppi_index = csid_hw->csi2_rx_cfg.phy_sel; + ppi_index = csid_hw->csi2_rx_cfg.phy_sel - csid_reg->csi2_reg->phy_sel_base; if (csid_hw->ppi_hw_intf[ppi_index] && csid_hw->ppi_enable) { /* De-Initialize the PPI bridge */ CAM_DBG(CAM_ISP, "ppi_index to de-init %d\n", ppi_index); @@ -2604,6 +2610,19 @@ static int cam_tfe_csid_set_csid_clock( return 0; } +static int cam_tfe_csid_dump_csid_clock( + struct cam_tfe_csid_hw *csid_hw, void *cmd_args) +{ + if (!csid_hw) + return -EINVAL; + + CAM_INFO(CAM_ISP, "CSID:%d clock rate %llu", + csid_hw->hw_intf->hw_idx, + csid_hw->clk_rate); + + return 0; +} + static int cam_tfe_csid_get_csid_clock( struct cam_tfe_csid_hw *csid_hw, void *cmd_args) { @@ -2910,6 +2929,9 @@ static int cam_tfe_csid_process_cmd(void *hw_priv, case CAM_ISP_HW_CMD_CSID_CLOCK_UPDATE: rc = cam_tfe_csid_set_csid_clock(csid_hw, cmd_args); break; + case CAM_ISP_HW_CMD_CSID_CLOCK_DUMP: + rc = cam_tfe_csid_dump_csid_clock(csid_hw, cmd_args); + break; case CAM_TFE_CSID_CMD_GET_REG_DUMP: rc = cam_tfe_csid_get_regdump(csid_hw, cmd_args); break; @@ -3513,9 +3535,23 @@ handle_fatal_error: is_error_irq = true; } - if (is_error_irq || log_en) + if (is_error_irq || log_en) { + CAM_ERR(CAM_ISP, + "CSID %d irq status TOP: 0x%x RX: 0x%x IPP: 0x%x", + csid_hw->hw_intf->hw_idx, + irq_status[TFE_CSID_IRQ_REG_TOP], + irq_status[TFE_CSID_IRQ_REG_RX], + irq_status[TFE_CSID_IRQ_REG_IPP]); + CAM_ERR(CAM_ISP, + "RDI0: 0x%x RDI1: 0x%x RDI2: 0x%x CSID clk:%d", + irq_status[TFE_CSID_IRQ_REG_RDI0], + irq_status[TFE_CSID_IRQ_REG_RDI1], + irq_status[TFE_CSID_IRQ_REG_RDI2], + csid_hw->clk_rate); + cam_tfe_csid_handle_hw_err_irq(csid_hw, CAM_ISP_HW_ERROR_NONE, irq_status); + } if (csid_hw->irq_debug_cnt >= CAM_TFE_CSID_IRQ_SOF_DEBUG_CNT_MAX) { cam_tfe_csid_sof_irq_debug(csid_hw, &sof_irq_debug_en); diff --git a/techpack/camera/drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_csid_hw/cam_tfe_csid_core.h b/techpack/camera/drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_csid_hw/cam_tfe_csid_core.h index b13d4b0473f8..c2e8d343196b 100644 --- a/techpack/camera/drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_csid_hw/cam_tfe_csid_core.h +++ b/techpack/camera/drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_csid_hw/cam_tfe_csid_core.h @@ -185,6 +185,7 @@ struct cam_tfe_csid_csi2_rx_reg_offset { uint32_t csid_csi2_rx_total_crc_err_addr; /*configurations */ + uint32_t phy_sel_base; uint32_t csi2_rst_srb_all; uint32_t csi2_rst_done_shift_val; uint32_t csi2_irq_mask_all; diff --git a/techpack/camera/drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_hw/cam_tfe_core.c b/techpack/camera/drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_hw/cam_tfe_core.c index 74eae1a23ff3..042fe6b892fc 100644 --- a/techpack/camera/drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_hw/cam_tfe_core.c +++ b/techpack/camera/drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_hw/cam_tfe_core.c @@ -444,7 +444,7 @@ static void cam_tfe_log_error_irq_status( "TFE clock rate:%d TFE total bw applied:%lld", top_priv->hw_clk_rate, top_priv->total_bw_applied); - + cam_cpas_log_votes(); } static int cam_tfe_error_irq_bottom_half( diff --git a/techpack/camera/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/cam_vfe_bus_ver2.c b/techpack/camera/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/cam_vfe_bus_ver2.c index 5b33a6ecb0e1..72bc959b6126 100644 --- a/techpack/camera/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/cam_vfe_bus_ver2.c +++ b/techpack/camera/drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/cam_vfe_bus_ver2.c @@ -16,6 +16,7 @@ #include "cam_tasklet_util.h" #include "cam_vfe_bus.h" #include "cam_vfe_bus_ver2.h" +#include "cam_vfe_soc.h" #include "cam_vfe_core.h" #include "cam_debug_util.h" #include "cam_cpas_api.h" @@ -80,6 +81,12 @@ enum cam_vfe_bus_comp_grp_id { CAM_VFE_BUS_COMP_GROUP_ID_5 = 0x5, }; +struct cam_vfe_bus_error_info { + uint32_t bitmask; + uint32_t vfe_output; + char *error_description; +}; + struct cam_vfe_bus_ver2_common_data { uint32_t core_index; void __iomem *mem_base; @@ -99,6 +106,7 @@ struct cam_vfe_bus_ver2_common_data { uint32_t num_sec_out; uint32_t addr_no_sync; cam_hw_mgr_event_cb_func event_cb; + bool is_lite; bool hw_init; bool support_consumed_addr; bool disable_ubwc_comp; @@ -193,6 +201,7 @@ struct cam_vfe_bus_ver2_priv { struct cam_isp_resource_node bus_client[CAM_VFE_BUS_VER2_MAX_CLIENTS]; struct cam_isp_resource_node comp_grp[CAM_VFE_BUS_VER2_COMP_GRP_MAX]; struct cam_isp_resource_node vfe_out[CAM_VFE_BUS_VER2_VFE_OUT_MAX]; + uint32_t vfe_out_map_outtype[CAM_VFE_BUS_VER2_VFE_OUT_MAX]; struct list_head free_comp_grp; struct list_head free_dual_comp_grp; @@ -204,6 +213,138 @@ struct cam_vfe_bus_ver2_priv { uint32_t max_out_res; }; +static const struct cam_vfe_bus_error_info vfe_error_list[] = { + { + .bitmask = 0x80000000, + .vfe_output = CAM_VFE_BUS_VER2_VFE_OUT_FULL_DISP, + .error_description = "DISP C 1:1" + }, + { + .bitmask = 0x40000000, + .vfe_output = CAM_VFE_BUS_VER2_VFE_OUT_FULL_DISP, + .error_description = "DISP Y 1:1" + }, + { + .bitmask = 0x01000000, + .vfe_output = CAM_VFE_BUS_VER2_VFE_OUT_STATS_TL_BG, + .error_description = "STATS TINTLESS BG" + }, + { + .bitmask = 0x00800000, + .vfe_output = CAM_VFE_BUS_VER2_VFE_OUT_STATS_BHIST, + .error_description = "STATS BHIST" + }, + { + .bitmask = 0x00400000, + .vfe_output = CAM_VFE_BUS_VER2_VFE_OUT_STATS_IHIST, + .error_description = "STATS IHIST" + }, + { + .bitmask = 0x00200000, + .vfe_output = CAM_VFE_BUS_VER2_VFE_OUT_STATS_CS, + .error_description = "STATS CS" + }, + { + .bitmask = 0x00100000, + .vfe_output = CAM_VFE_BUS_VER2_VFE_OUT_STATS_RS, + .error_description = "STATS RS" + }, + { + .bitmask = 0x00080000, + .vfe_output = CAM_VFE_BUS_VER2_VFE_OUT_STATS_HDR_BHIST, + .error_description = "STATS HDR BHIST" + }, + { + .bitmask = 0x00040000, + .vfe_output = CAM_VFE_BUS_VER2_VFE_OUT_STATS_BF, + .error_description = "STATS BAF" + }, + { + .bitmask = 0x00020000, + .vfe_output = CAM_VFE_BUS_VER2_VFE_OUT_STATS_AWB_BG, + .error_description = "STATS AWB BG" + }, + { + .bitmask = 0x00010000, + .vfe_output = CAM_VFE_BUS_VER2_VFE_OUT_STATS_HDR_BE, + .error_description = "STATS HDR BE" + }, + { + .bitmask = 0x00004000, + .vfe_output = CAM_VFE_BUS_VER2_VFE_OUT_2PD, + .error_description = "PD" + }, + { + .bitmask = 0x00002000, + .vfe_output = CAM_VFE_BUS_VER2_VFE_OUT_RAW_DUMP, + .error_description = "PIXEL RAW DUMP" + }, + { + .bitmask = 0x00001000, + .vfe_output = CAM_VFE_BUS_VER2_VFE_OUT_FULL, + .error_description = "VID C 1:1" + }, + { + .bitmask = 0x00000800, + .vfe_output = CAM_VFE_BUS_VER2_VFE_OUT_FULL, + .error_description = "VID Y 1:1" + }, + { + .bitmask = 0x00000400, + .vfe_output = CAM_VFE_BUS_VER2_VFE_OUT_FD, + .error_description = "FD C" + }, + { + .bitmask = 0x00000200, + .vfe_output = CAM_VFE_BUS_VER2_VFE_OUT_FD, + .error_description = "FD Y" + }, + { + .bitmask = 0x00000020, + .vfe_output = CAM_VFE_BUS_VER2_VFE_OUT_RDI3, + .error_description = "Full RDI 3" + }, + { + .bitmask = 0x00000010, + .vfe_output = CAM_VFE_BUS_VER2_VFE_OUT_RDI2, + .error_description = "Full RDI 2" + }, + { + .bitmask = 0x00000008, + .vfe_output = CAM_VFE_BUS_VER2_VFE_OUT_RDI1, + .error_description = "Full RDI 1" + }, + { + .bitmask = 0x00000004, + .vfe_output = CAM_VFE_BUS_VER2_VFE_OUT_RDI0, + .error_description = "Full RDI 0" + }, +}; + +static const struct cam_vfe_bus_error_info vfe_lite_error_list[] = { + { + .bitmask = 0x04, + .vfe_output = CAM_VFE_BUS_VER2_VFE_OUT_RDI0, + .error_description = "Lite RDI 0" + }, + { + .bitmask = 0x08, + .vfe_output = CAM_VFE_BUS_VER2_VFE_OUT_RDI1, + .error_description = "Lite RDI 1" + }, + { + .bitmask = 0x10, + .vfe_output = CAM_VFE_BUS_VER2_VFE_OUT_RDI2, + .error_description = "Lite RDI 2" + }, + { + .bitmask = 0x20, + .vfe_output = CAM_VFE_BUS_VER2_VFE_OUT_RDI3, + .error_description = "Lite RDI 3" + } +}; + + static int cam_vfe_bus_process_cmd( struct cam_isp_resource_node *priv, uint32_t cmd_type, void *cmd_args, uint32_t arg_size); @@ -481,6 +622,22 @@ static enum cam_vfe_bus_ver2_vfe_out_type } } +static enum cam_vfe_bus_ver2_vfe_out_type + cam_vfe_bus_ver2_get_out_res_id_and_index( + struct cam_vfe_bus_ver2_priv *bus_priv, + uint32_t res_type, uint32_t *index) +{ + uint32_t vfe_out_type; + + vfe_out_type = cam_vfe_bus_get_out_res_id(res_type); + if (vfe_out_type == CAM_VFE_BUS_VER2_VFE_OUT_MAX) + *index = CAM_VFE_BUS_VER2_VFE_OUT_MAX; + else + *index = bus_priv->vfe_out_map_outtype[vfe_out_type]; + + return vfe_out_type; +} + static int cam_vfe_bus_get_num_wm( enum cam_vfe_bus_ver2_vfe_out_type res_type, uint32_t format) @@ -1440,6 +1597,94 @@ static int cam_vfe_bus_handle_wm_done_bottom_half(void *handler_priv, return rc; } +static int cam_vfe_bus_ver2_print_dimensions( + uint32_t res_id, + struct cam_vfe_bus_ver2_priv *bus_priv) +{ + struct cam_isp_resource_node *rsrc_node = NULL; + struct cam_vfe_bus_ver2_vfe_out_data *rsrc_data = NULL; + struct cam_vfe_bus_ver2_wm_resource_data *wm_data = NULL; + struct cam_vfe_bus_ver2_common_data *common_data = NULL; + int i; + uint32_t addr_status0, addr_status1; + enum cam_vfe_bus_ver2_vfe_out_type vfe_out_res_id = + CAM_VFE_BUS_VER2_VFE_OUT_MAX; + uint32_t outmap_index = CAM_VFE_BUS_VER2_VFE_OUT_MAX; + + if (!bus_priv) { + CAM_ERR(CAM_ISP, "Invalid bus private data, res_id: %d", + res_id); + return -EINVAL; + } + + vfe_out_res_id = cam_vfe_bus_ver2_get_out_res_id_and_index(bus_priv, + res_id, &outmap_index); + + if ((vfe_out_res_id == CAM_VFE_BUS_VER2_VFE_OUT_MAX) || + (outmap_index >= bus_priv->num_out)) { + CAM_WARN_RATE_LIMIT(CAM_ISP, + "target does not support req res id :0x%x outtype:%d index:%d", + res_id, + vfe_out_res_id, outmap_index); + return -EINVAL; + } + + rsrc_node = &bus_priv->vfe_out[outmap_index]; + rsrc_data = rsrc_node->res_priv; + if (!rsrc_data) { + CAM_ERR(CAM_ISP, "VFE out data is null, res_id: %d", + vfe_out_res_id); + return -EINVAL; + } + + for (i = 0; i < rsrc_data->num_wm; i++) { + wm_data = rsrc_data->wm_res[i]->res_priv; + common_data = rsrc_data->common_data; + addr_status0 = cam_io_r_mb(common_data->mem_base + + wm_data->hw_regs->status0); + addr_status1 = cam_io_r_mb(common_data->mem_base + + wm_data->hw_regs->status1); + + CAM_INFO(CAM_ISP, + "VFE:%d WM:%d width:%u height:%u stride:%u x_init:%u en_cfg:%u acquired width:%u height:%u", + wm_data->common_data->core_index, wm_data->index, + wm_data->width, + wm_data->height, + wm_data->stride, wm_data->h_init, + wm_data->en_cfg, + wm_data->acquired_width, + wm_data->acquired_height); + CAM_INFO(CAM_ISP, + "hw:%d WM:%d last consumed address:0x%x last frame addr:0x%x", + common_data->hw_intf->hw_idx, + wm_data->index, + addr_status0, + addr_status1); + } + return 0; +} + +static void cam_vfe_print_violations( + char *error_type, + const struct cam_vfe_bus_error_info *error_list, + uint32_t num_errors, + uint32_t status, + struct cam_vfe_bus_ver2_priv *bus_priv) +{ + int i; + + for (i = 0; i < num_errors; i++) { + if (status & error_list[i].bitmask) { + CAM_INFO(CAM_ISP, "%s: %s violation", + error_list[i].error_description, + error_type); + if (bus_priv != NULL) + cam_vfe_bus_ver2_print_dimensions( + error_list[i].vfe_output, + bus_priv); + } + } +} static int cam_vfe_bus_err_bottom_half(void *handler_priv, void *evt_payload_priv) @@ -1448,7 +1693,10 @@ static int cam_vfe_bus_err_bottom_half(void *handler_priv, struct cam_vfe_bus_ver2_priv *bus_priv = handler_priv; struct cam_vfe_bus_ver2_common_data *common_data; struct cam_isp_hw_event_info evt_info; + const struct cam_vfe_bus_error_info *error_list = NULL; uint32_t val = 0; + uint32_t error_list_size = 0; + uint32_t status = 0; if (!handler_priv || !evt_payload_priv) return -EINVAL; @@ -1459,77 +1707,76 @@ static int cam_vfe_bus_err_bottom_half(void *handler_priv, val = evt_payload->debug_status_0; CAM_ERR(CAM_ISP, "Bus Violation: debug_status_0 = 0x%x", val); - if (val & 0x01) + error_list = common_data->is_lite ? + vfe_lite_error_list : vfe_error_list; + error_list_size = common_data->is_lite ? + ARRAY_SIZE(vfe_lite_error_list) : ARRAY_SIZE(vfe_error_list); + + if (val & 0x00000004) CAM_INFO(CAM_ISP, "RDI 0 violation"); - if (val & 0x02) + if (val & 0x00000008) CAM_INFO(CAM_ISP, "RDI 1 violation"); - if (val & 0x04) + if (val & 0x00000010) CAM_INFO(CAM_ISP, "RDI 2 violation"); - if (val & 0x08) - CAM_INFO(CAM_ISP, "VID Y 1:1 UBWC violation"); + if (val & 0x00000020) + CAM_INFO(CAM_ISP, "RDI 3 violation"); - if (val & 0x010) - CAM_INFO(CAM_ISP, "VID C 1:1 UBWC violation"); - - if (val & 0x020) - CAM_INFO(CAM_ISP, "VID YC 4:1 violation"); - - if (val & 0x040) - CAM_INFO(CAM_ISP, "VID YC 16:1 violation"); - - if (val & 0x080) + if (val & 0x00000200) CAM_INFO(CAM_ISP, "FD Y violation"); - if (val & 0x0100) + if (val & 0x00000400) CAM_INFO(CAM_ISP, "FD C violation"); - if (val & 0x0200) + if (val & 0x00001000) + CAM_INFO(CAM_ISP, "VID C 1:1 UBWC violation"); + + if (val & 0x00000800) + CAM_INFO(CAM_ISP, "VID Y 1:1 UBWC violation"); + + if (val & 0x00002000) CAM_INFO(CAM_ISP, "RAW DUMP violation"); - if (val & 0x0400) + if (val & 0x00004000) CAM_INFO(CAM_ISP, "PDAF violation"); - if (val & 0x0800) + if (val & 0x00010000) CAM_INFO(CAM_ISP, "STATs HDR BE violation"); - if (val & 0x01000) - CAM_INFO(CAM_ISP, "STATs HDR BHIST violation"); - - if (val & 0x02000) - CAM_INFO(CAM_ISP, "STATs TINTLESS BG violation"); - - if (val & 0x04000) - CAM_INFO(CAM_ISP, "STATs BF violation"); - - if (val & 0x08000) + if (val & 0x00020000) CAM_INFO(CAM_ISP, "STATs AWB BG UBWC violation"); - if (val & 0x010000) - CAM_INFO(CAM_ISP, "STATs BHIST violation"); + if (val & 0x00040000) + CAM_INFO(CAM_ISP, "STATs BF violation"); - if (val & 0x020000) + if (val & 0x00080000) + CAM_INFO(CAM_ISP, "STATs HDR BHIST violation"); + + if (val & 0x00100000) CAM_INFO(CAM_ISP, "STATs RS violation"); - if (val & 0x040000) + if (val & 0x00200000) CAM_INFO(CAM_ISP, "STATs CS violation"); - if (val & 0x080000) + if (val & 0x00400000) CAM_INFO(CAM_ISP, "STATs IHIST violation"); - if (val & 0x0100000) + if (val & 0x00800000) + CAM_INFO(CAM_ISP, "STATs BHIST violation"); + + if (val & 0x01000000) + CAM_INFO(CAM_ISP, "STATs TINTLESS BG violation"); + + if (val & 0x40000000) CAM_INFO(CAM_ISP, "DISP Y 1:1 UBWC violation"); - if (val & 0x0200000) + if (val & 0x80000000) CAM_INFO(CAM_ISP, "DISP C 1:1 UBWC violation"); - if (val & 0x0400000) - CAM_INFO(CAM_ISP, "DISP YC 4:1 violation"); - - if (val & 0x0800000) - CAM_INFO(CAM_ISP, "DISP YC 16:1 violation"); + cam_vfe_print_violations("Error", error_list, + error_list_size, status, bus_priv); cam_vfe_bus_put_evt_payload(common_data, &evt_payload); @@ -2550,7 +2797,8 @@ static int cam_vfe_bus_init_vfe_out_resource(uint32_t index, return -EINVAL; } - vfe_out = &ver2_bus_priv->vfe_out[vfe_out_type]; + ver2_bus_priv->vfe_out_map_outtype[vfe_out_type] = index; + vfe_out = &ver2_bus_priv->vfe_out[index]; if (vfe_out->res_state != CAM_ISP_RESOURCE_STATE_UNAVAILABLE || vfe_out->res_priv) { CAM_ERR(CAM_ISP, @@ -3830,6 +4078,7 @@ int cam_vfe_bus_ver2_init( struct cam_vfe_bus_ver2_priv *bus_priv = NULL; struct cam_vfe_bus *vfe_bus_local; struct cam_vfe_bus_ver2_hw_info *ver2_hw_info = bus_hw_info; + struct cam_vfe_soc_private *soc_private = NULL; CAM_DBG(CAM_ISP, "Enter"); @@ -3842,6 +4091,13 @@ int cam_vfe_bus_ver2_init( goto end; } + soc_private = soc_info->soc_private; + if (!soc_private) { + CAM_ERR(CAM_ISP, "Invalid soc_private"); + rc = -ENODEV; + goto end; + } + vfe_bus_local = kzalloc(sizeof(struct cam_vfe_bus), GFP_KERNEL); if (!vfe_bus_local) { CAM_DBG(CAM_ISP, "Failed to alloc for vfe_bus"); @@ -3876,6 +4132,7 @@ int cam_vfe_bus_ver2_init( bus_priv->common_data.support_consumed_addr = ver2_hw_info->support_consumed_addr; bus_priv->common_data.disable_ubwc_comp = false; + bus_priv->common_data.is_lite = soc_private->is_ife_lite; mutex_init(&bus_priv->common_data.bus_mutex); @@ -3909,6 +4166,10 @@ int cam_vfe_bus_ver2_init( } } + for (i = 0; i < CAM_VFE_BUS_VER2_VFE_OUT_MAX; i++) + bus_priv->vfe_out_map_outtype[i] = + CAM_VFE_BUS_VER2_VFE_OUT_MAX; + for (i = 0; i < bus_priv->num_out; i++) { rc = cam_vfe_bus_init_vfe_out_resource(i, bus_priv, bus_hw_info); diff --git a/techpack/camera/drivers/cam_jpeg/cam_jpeg_dev.c b/techpack/camera/drivers/cam_jpeg/cam_jpeg_dev.c index a47476a06144..166db14e75ce 100644 --- a/techpack/camera/drivers/cam_jpeg/cam_jpeg_dev.c +++ b/techpack/camera/drivers/cam_jpeg/cam_jpeg_dev.c @@ -48,11 +48,14 @@ static const struct of_device_id cam_jpeg_dt_match[] = { static int cam_jpeg_subdev_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) { + cam_req_mgr_rwsem_read_op(CAM_SUBDEV_LOCK); mutex_lock(&g_jpeg_dev.jpeg_mutex); g_jpeg_dev.open_cnt++; mutex_unlock(&g_jpeg_dev.jpeg_mutex); + cam_req_mgr_rwsem_read_op(CAM_SUBDEV_UNLOCK); + return 0; } 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 532f6a5a0c1e..4225a33e4f72 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 @@ -761,10 +761,11 @@ static int cam_jpeg_mgr_prepare_hw_update(void *hw_mgr_priv, } if ((packet->num_cmd_buf > 5) || !packet->num_patches || - !packet->num_io_configs) { - CAM_ERR(CAM_JPEG, "wrong number of cmd/patch info: %u %u", - packet->num_cmd_buf, - 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", + packet->num_cmd_buf, packet->num_patches, packet->num_io_configs); return -EINVAL; } diff --git a/techpack/camera/drivers/cam_lrme/cam_lrme_dev.c b/techpack/camera/drivers/cam_lrme/cam_lrme_dev.c index 5055444c3d8a..f46bb25362fe 100644 --- a/techpack/camera/drivers/cam_lrme/cam_lrme_dev.c +++ b/techpack/camera/drivers/cam_lrme/cam_lrme_dev.c @@ -59,9 +59,12 @@ static int cam_lrme_dev_open(struct v4l2_subdev *sd, { struct cam_lrme_dev *lrme_dev = g_lrme_dev; + cam_req_mgr_rwsem_read_op(CAM_SUBDEV_LOCK); + if (!lrme_dev) { CAM_ERR(CAM_LRME, "LRME Dev not initialized, dev=%pK", lrme_dev); + cam_req_mgr_rwsem_read_op(CAM_SUBDEV_UNLOCK); return -ENODEV; } @@ -69,6 +72,8 @@ static int cam_lrme_dev_open(struct v4l2_subdev *sd, lrme_dev->open_cnt++; mutex_unlock(&lrme_dev->lock); + cam_req_mgr_rwsem_read_op(CAM_SUBDEV_UNLOCK); + return 0; } diff --git a/techpack/camera/drivers/cam_ope/cam_ope_subdev.c b/techpack/camera/drivers/cam_ope/cam_ope_subdev.c index a04abe3bcf8c..e4007cbabac0 100644 --- a/techpack/camera/drivers/cam_ope/cam_ope_subdev.c +++ b/techpack/camera/drivers/cam_ope/cam_ope_subdev.c @@ -69,6 +69,8 @@ static int cam_ope_subdev_open(struct v4l2_subdev *sd, struct cam_node *node = v4l2_get_subdevdata(sd); int rc = 0; + cam_req_mgr_rwsem_read_op(CAM_SUBDEV_LOCK); + mutex_lock(&g_ope_dev.ope_lock); if (g_ope_dev.open_cnt >= 1) { CAM_ERR(CAM_OPE, "OPE subdev is already opened"); @@ -92,6 +94,7 @@ static int cam_ope_subdev_open(struct v4l2_subdev *sd, CAM_DBG(CAM_OPE, "OPE HW open success: %d", rc); end: mutex_unlock(&g_ope_dev.ope_lock); + cam_req_mgr_rwsem_read_op(CAM_SUBDEV_UNLOCK); return rc; } 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 978160a6a6ac..b76f97a7461c 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 @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2022, The Linux Foundation. All rights reserved. */ #include @@ -19,6 +19,7 @@ #include #include #include +#include #include "cam_sync_api.h" #include "cam_packet_util.h" @@ -624,8 +625,8 @@ static bool cam_ope_check_req_delay(struct cam_ope_ctx *ctx_data, ts.tv_nsec); if (ts_ns - req_time < - ((OPE_REQUEST_TIMEOUT - - OPE_REQUEST_TIMEOUT / 10) * 1000000)) { + ((ctx_data->req_timer_timeout - + div_u64(ctx_data->req_timer_timeout, 10)) * 1000000)) { CAM_INFO(CAM_OPE, "ctx: %d, ts_ns : %llu", ctx_data->ctx_id, ts_ns); cam_ope_req_timer_reset(ctx_data); @@ -848,7 +849,7 @@ static int cam_ope_start_req_timer(struct cam_ope_ctx *ctx_data) int rc = 0; rc = crm_timer_init(&ctx_data->req_watch_dog, - OPE_REQUEST_TIMEOUT, ctx_data, &cam_ope_req_timer_cb); + ctx_data->req_timer_timeout, ctx_data, &cam_ope_req_timer_cb); if (rc) CAM_ERR(CAM_OPE, "Failed to start timer"); @@ -2626,11 +2627,15 @@ static int cam_ope_mgr_acquire_hw(void *hw_priv, void *hw_acquire_args) goto end; } strlcpy(cdm_acquire->identifier, "ope", sizeof("ope")); - if (ctx->ope_acquire.dev_type == OPE_DEV_TYPE_OPE_RT) + if (ctx->ope_acquire.dev_type == OPE_DEV_TYPE_OPE_RT) { cdm_acquire->priority = CAM_CDM_BL_FIFO_3; + ctx->req_timer_timeout = OPE_REQUEST_RT_TIMEOUT; + } else if (ctx->ope_acquire.dev_type == - OPE_DEV_TYPE_OPE_NRT) + OPE_DEV_TYPE_OPE_NRT) { cdm_acquire->priority = CAM_CDM_BL_FIFO_0; + ctx->req_timer_timeout = OPE_REQUEST_NRT_TIMEOUT; + } else goto free_cdm_acquire; @@ -3300,7 +3305,7 @@ static int cam_ope_mgr_prepare_hw_update(void *hw_priv, CAM_DBG(CAM_REQ, "req_id= %llu ctx_id= %d lrt=%llu", packet->header.request_id, ctx_data->ctx_id, ctx_data->last_req_time); - cam_ope_req_timer_modify(ctx_data, OPE_REQUEST_TIMEOUT); + cam_ope_req_timer_modify(ctx_data, ctx_data->req_timer_timeout); set_bit(request_idx, ctx_data->bitmap); mutex_unlock(&ctx_data->ctx_mutex); @@ -3620,7 +3625,7 @@ static int cam_ope_mgr_hw_dump(void *hw_priv, void *hw_dump_args) cur_ts = ktime_to_timespec64(cur_time); req_ts = ktime_to_timespec64(ctx_data->req_list[idx]->submit_timestamp); - if (diff < (OPE_REQUEST_TIMEOUT * 1000)) { + if (diff < (ctx_data->req_timer_timeout * 1000)) { CAM_INFO(CAM_OPE, "No Error req %llu %ld:%06ld %ld:%06ld", dump_args->request_id, req_ts.tv_sec, diff --git a/techpack/camera/drivers/cam_ope/ope_hw_mgr/cam_ope_hw_mgr.h b/techpack/camera/drivers/cam_ope/ope_hw_mgr/cam_ope_hw_mgr.h index f6206f0c8bf0..9edf1b8ee8ca 100644 --- a/techpack/camera/drivers/cam_ope/ope_hw_mgr/cam_ope_hw_mgr.h +++ b/techpack/camera/drivers/cam_ope/ope_hw_mgr/cam_ope_hw_mgr.h @@ -50,7 +50,7 @@ #define OPE_CMDS OPE_MAX_CMD_BUFS #define CAM_MAX_IN_RES 8 -#define OPE_MAX_CDM_BLS 24 +#define OPE_MAX_CDM_BLS 32 #define CAM_OPE_MAX_PER_PATH_VOTES 6 #define CAM_OPE_BW_CONFIG_UNKNOWN 0 @@ -60,7 +60,8 @@ #define CLK_HW_MAX 0x1 #define OPE_DEVICE_IDLE_TIMEOUT 400 -#define OPE_REQUEST_TIMEOUT 200 +#define OPE_REQUEST_RT_TIMEOUT 200 +#define OPE_REQUEST_NRT_TIMEOUT 400 /** * struct cam_ope_clk_bw_request_v2 @@ -447,6 +448,7 @@ struct cam_ope_cdm { * @clk_watch_dog: Clock watchdog * @clk_watch_dog_reset_counter: Reset counter * @last_flush_req: last flush req for this ctx + * @req_timer_timeout: req timer timeout value */ struct cam_ope_ctx { void *context_priv; @@ -470,6 +472,7 @@ struct cam_ope_ctx { uint32_t clk_watch_dog_reset_counter; uint64_t last_flush_req; bool pf_mid_found; + uint64_t req_timer_timeout; }; /** diff --git a/techpack/camera/drivers/cam_req_mgr/cam_mem_mgr.c b/techpack/camera/drivers/cam_req_mgr/cam_mem_mgr.c index b928c7da46c7..ee227f943272 100644 --- a/techpack/camera/drivers/cam_req_mgr/cam_mem_mgr.c +++ b/techpack/camera/drivers/cam_req_mgr/cam_mem_mgr.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2016-2021, The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. */ #include @@ -758,7 +759,7 @@ int cam_mem_mgr_alloc_and_map(struct cam_mem_mgr_alloc_cmd *cmd) tbl.bufq[idx].kmdvaddr = kvaddr; tbl.bufq[idx].vaddr = hw_vaddr; tbl.bufq[idx].dma_buf = dmabuf; - tbl.bufq[idx].len = cmd->len; + tbl.bufq[idx].len = len; tbl.bufq[idx].num_hdl = cmd->num_hdl; memcpy(tbl.bufq[idx].hdls, cmd->mmu_hdls, sizeof(int32_t) * cmd->num_hdl); diff --git a/techpack/camera/drivers/cam_req_mgr/cam_req_mgr_core.c b/techpack/camera/drivers/cam_req_mgr/cam_req_mgr_core.c index 18dcb1bc2b96..9881516daf3d 100644 --- a/techpack/camera/drivers/cam_req_mgr/cam_req_mgr_core.c +++ b/techpack/camera/drivers/cam_req_mgr/cam_req_mgr_core.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2016-2021, The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. */ #include @@ -1714,20 +1715,20 @@ static int __cam_req_mgr_process_req(struct cam_req_mgr_core_link *link, return -EINVAL; } + mutex_lock(&session->lock); /* - * In case if the wq is scheduled while destroying session - * the session mutex is already taken and will cause a - * dead lock. To avoid further processing check link state - * and exit. + * During session destroy/unlink the link state is updated and session + * mutex is released when flushing the workq. In case the wq is scheduled + * thereafter this API will then check the updated link state and exit */ spin_lock_bh(&link->link_state_spin_lock); if (link->state == CAM_CRM_LINK_STATE_IDLE) { spin_unlock_bh(&link->link_state_spin_lock); + mutex_unlock(&session->lock); return -EPERM; } spin_unlock_bh(&link->link_state_spin_lock); - mutex_lock(&session->lock); in_q = link->req.in_q; /* * Check if new read index, @@ -2281,10 +2282,13 @@ static int __cam_req_mgr_create_subdevs( * */ static void __cam_req_mgr_destroy_subdev( - struct cam_req_mgr_connected_device *l_device) + struct cam_req_mgr_connected_device **l_device) { - kfree(l_device); - l_device = NULL; + CAM_DBG(CAM_CRM, "*l_device %pK", *l_device); + if (*(l_device) != NULL) { + kfree(*(l_device)); + *l_device = NULL; + } } /** @@ -3786,13 +3790,17 @@ end: /** * __cam_req_mgr_unlink() * - * @brief : Unlink devices on a link structure from the session - * @link : Pointer to the link structure + * @brief : Unlink devices on a link structure from the session + * This API is to be invoked with session mutex held + * @session: session of the link + * @link : Pointer to the link structure * * @return: 0 for success, negative for failure * */ -static int __cam_req_mgr_unlink(struct cam_req_mgr_core_link *link) +static int __cam_req_mgr_unlink( + struct cam_req_mgr_core_session *session, + struct cam_req_mgr_core_link *link) { int rc; @@ -3808,19 +3816,21 @@ static int __cam_req_mgr_unlink(struct cam_req_mgr_core_link *link) } mutex_lock(&link->lock); - spin_lock_bh(&link->link_state_spin_lock); /* Destroy timer of link */ crm_timer_exit(&link->watchdog); spin_unlock_bh(&link->link_state_spin_lock); + /* Release session mutex for workq processing */ + mutex_unlock(&session->lock); /* Destroy workq of link */ cam_req_mgr_workq_destroy(&link->workq); - + /* Acquire session mutex after workq flush */ + mutex_lock(&session->lock); /* Cleanup request tables and unlink devices */ __cam_req_mgr_destroy_link_info(link); /* Free memory holding data of linked devs */ - __cam_req_mgr_destroy_subdev(link->l_dev); + __cam_req_mgr_destroy_subdev(&link->l_dev); /* Destroy the link handle */ rc = cam_destroy_device_hdl(link->link_hdl); @@ -3851,12 +3861,15 @@ int cam_req_mgr_destroy_session( mutex_lock(&g_crm_core_dev->crm_lock); cam_session = (struct cam_req_mgr_core_session *) cam_get_device_priv(ses_info->session_hdl); - if (!cam_session) { - CAM_ERR(CAM_CRM, "failed to get session priv"); + if (!cam_session || (cam_session->session_hdl != ses_info->session_hdl)) { + CAM_ERR(CAM_CRM, "session: %s, ses_info->ses_hdl:%x, session->ses_hdl:%x", + CAM_IS_NULL_TO_STR(cam_session), ses_info->session_hdl, + (!cam_session) ? CAM_REQ_MGR_DEFAULT_HDL_VAL : cam_session->session_hdl); rc = -ENOENT; goto end; } + mutex_lock(&cam_session->lock); if (cam_session->num_links) { CAM_DBG(CAM_CRM, "destroy session %x num_active_links %d", @@ -3872,7 +3885,7 @@ int cam_req_mgr_destroy_session( link->link_hdl); /* Ignore return value since session is going away */ link->is_shutdown = is_shutdown; - __cam_req_mgr_unlink(link); + __cam_req_mgr_unlink(cam_session, link); __cam_req_mgr_free_link(link); } } @@ -3921,8 +3934,10 @@ int cam_req_mgr_link(struct cam_req_mgr_ver_info *link_info) /* session hdl's priv data is cam session struct */ cam_session = (struct cam_req_mgr_core_session *) cam_get_device_priv(link_info->u.link_info_v1.session_hdl); - if (!cam_session) { - CAM_DBG(CAM_CRM, "NULL pointer"); + if (!cam_session || (cam_session->session_hdl != link_info->u.link_info_v1.session_hdl)) { + CAM_ERR(CAM_CRM, "session: %s, link_info->ses_hdl:%x, session->ses_hdl:%x", + CAM_IS_NULL_TO_STR(cam_session), link_info->u.link_info_v1.session_hdl, + (!cam_session) ? CAM_REQ_MGR_DEFAULT_HDL_VAL : cam_session->session_hdl); mutex_unlock(&g_crm_core_dev->crm_lock); return -EINVAL; } @@ -3995,7 +4010,7 @@ int cam_req_mgr_link(struct cam_req_mgr_ver_info *link_info) mutex_unlock(&g_crm_core_dev->crm_lock); return rc; setup_failed: - __cam_req_mgr_destroy_subdev(link->l_dev); + __cam_req_mgr_destroy_subdev(&link->l_dev); create_subdev_failed: cam_destroy_device_hdl(link->link_hdl); link_info->u.link_info_v1.link_hdl = -1; @@ -4031,8 +4046,10 @@ int cam_req_mgr_link_v2(struct cam_req_mgr_ver_info *link_info) /* session hdl's priv data is cam session struct */ cam_session = (struct cam_req_mgr_core_session *) cam_get_device_priv(link_info->u.link_info_v2.session_hdl); - if (!cam_session) { - CAM_DBG(CAM_CRM, "NULL pointer"); + if (!cam_session || (cam_session->session_hdl != link_info->u.link_info_v2.session_hdl)) { + CAM_ERR(CAM_CRM, "session: %s, link_info->ses_hdl:%x, session->ses_hdl:%x", + CAM_IS_NULL_TO_STR(cam_session), link_info->u.link_info_v2.session_hdl, + (!cam_session) ? CAM_REQ_MGR_DEFAULT_HDL_VAL : cam_session->session_hdl); mutex_unlock(&g_crm_core_dev->crm_lock); return -EINVAL; } @@ -4111,7 +4128,7 @@ int cam_req_mgr_link_v2(struct cam_req_mgr_ver_info *link_info) mutex_unlock(&g_crm_core_dev->crm_lock); return rc; setup_failed: - __cam_req_mgr_destroy_subdev(link->l_dev); + __cam_req_mgr_destroy_subdev(&link->l_dev); create_subdev_failed: cam_destroy_device_hdl(link->link_hdl); link_info->u.link_info_v2.link_hdl = -1; @@ -4140,21 +4157,26 @@ int cam_req_mgr_unlink(struct cam_req_mgr_unlink_info *unlink_info) /* session hdl's priv data is cam session struct */ cam_session = (struct cam_req_mgr_core_session *) cam_get_device_priv(unlink_info->session_hdl); - if (!cam_session) { - CAM_ERR(CAM_CRM, "NULL pointer"); + if (!cam_session || (cam_session->session_hdl != unlink_info->session_hdl)) { + CAM_ERR(CAM_CRM, "session: %s, unlink_info->ses_hdl:%x, cam_session->ses_hdl:%x", + CAM_IS_NULL_TO_STR(cam_session), unlink_info->session_hdl, + (!cam_session) ? CAM_REQ_MGR_DEFAULT_HDL_VAL : cam_session->session_hdl); mutex_unlock(&g_crm_core_dev->crm_lock); return -EINVAL; } /* link hdl's priv data is core_link struct */ link = cam_get_device_priv(unlink_info->link_hdl); - if (!link) { - CAM_ERR(CAM_CRM, "NULL pointer"); + if (!link || (link->link_hdl != unlink_info->link_hdl)) { + CAM_ERR(CAM_CRM, "link: %s, unlink_info->link_hdl:%x, link->link_hdl:%x", + CAM_IS_NULL_TO_STR(link), unlink_info->link_hdl, + (!link) ? CAM_REQ_MGR_DEFAULT_HDL_VAL : link->link_hdl); rc = -EINVAL; goto done; } - - rc = __cam_req_mgr_unlink(link); + mutex_lock(&cam_session->lock); + rc = __cam_req_mgr_unlink(cam_session, link); + mutex_unlock(&cam_session->lock); /* Free curent link and put back into session's free pool of links */ __cam_req_mgr_unreserve_link(cam_session, link); @@ -4181,8 +4203,10 @@ int cam_req_mgr_schedule_request( mutex_lock(&g_crm_core_dev->crm_lock); link = (struct cam_req_mgr_core_link *) cam_get_device_priv(sched_req->link_hdl); - if (!link) { - CAM_DBG(CAM_CRM, "link ptr NULL %x", sched_req->link_hdl); + if (!link || (link->link_hdl != sched_req->link_hdl)) { + CAM_ERR(CAM_CRM, "link: %s, sched_req->link_hdl:%x, link->link_hdl:%x", + CAM_IS_NULL_TO_STR(link), sched_req->link_hdl, + (!link) ? CAM_REQ_MGR_DEFAULT_HDL_VAL : link->link_hdl); rc = -EINVAL; goto end; } @@ -4266,8 +4290,10 @@ int cam_req_mgr_sync_config( /* session hdl's priv data is cam session struct */ cam_session = (struct cam_req_mgr_core_session *) cam_get_device_priv(sync_info->session_hdl); - if (!cam_session) { - CAM_ERR(CAM_CRM, "NULL pointer"); + if (!cam_session || (cam_session->session_hdl != sync_info->session_hdl)) { + CAM_ERR(CAM_CRM, "session: %s, sync_info->session_hdl:%x, session->ses_hdl:%x", + CAM_IS_NULL_TO_STR(cam_session), sync_info->session_hdl, + (!cam_session) ? CAM_REQ_MGR_DEFAULT_HDL_VAL : cam_session->session_hdl); mutex_unlock(&g_crm_core_dev->crm_lock); return -EINVAL; } @@ -4283,8 +4309,10 @@ int cam_req_mgr_sync_config( } link[i] = cam_get_device_priv(sync_info->link_hdls[i]); - if (!link[i]) { - CAM_ERR(CAM_CRM, "link%d NULL pointer", i); + if (!link[i] || (link[i]->link_hdl != sync_info->link_hdls[i])) { + CAM_ERR(CAM_CRM, "link: %s, sync_info->link_hdl:%x, link->link_hdl:%x", + CAM_IS_NULL_TO_STR(link), sync_info->link_hdls[i], + (!link[i]) ? CAM_REQ_MGR_DEFAULT_HDL_VAL : link[i]->link_hdl); rc = -EINVAL; goto done; } @@ -4360,8 +4388,10 @@ int cam_req_mgr_flush_requests( /* session hdl's priv data is cam session struct */ session = (struct cam_req_mgr_core_session *) cam_get_device_priv(flush_info->session_hdl); - if (!session) { - CAM_ERR(CAM_CRM, "Invalid session %x", flush_info->session_hdl); + if (!session || (session->session_hdl != flush_info->session_hdl)) { + CAM_ERR(CAM_CRM, "session: %s, flush_info->ses_hdl:%x, session->ses_hdl:%x", + CAM_IS_NULL_TO_STR(session), flush_info->session_hdl, + (!session) ? CAM_REQ_MGR_DEFAULT_HDL_VAL : session->session_hdl); rc = -EINVAL; goto end; } @@ -4373,8 +4403,10 @@ int cam_req_mgr_flush_requests( link = (struct cam_req_mgr_core_link *) cam_get_device_priv(flush_info->link_hdl); - if (!link) { - CAM_DBG(CAM_CRM, "link ptr NULL %x", flush_info->link_hdl); + if (!link || (link->link_hdl != flush_info->link_hdl)) { + CAM_ERR(CAM_CRM, "link: %s, flush_info->link_hdl:%x, link->link_hdl:%x", + CAM_IS_NULL_TO_STR(link), flush_info->link_hdl, + (!link) ? CAM_REQ_MGR_DEFAULT_HDL_VAL : link->link_hdl); rc = -EINVAL; goto end; } @@ -4432,9 +4464,10 @@ int cam_req_mgr_link_control(struct cam_req_mgr_link_control *control) for (i = 0; i < control->num_links; i++) { link = (struct cam_req_mgr_core_link *) cam_get_device_priv(control->link_hdls[i]); - if (!link) { - CAM_ERR(CAM_CRM, "Link(%d) is NULL on session 0x%x", - i, control->session_hdl); + if (!link || (link->link_hdl != control->link_hdls[i])) { + CAM_ERR(CAM_CRM, "link: %s, control->link_hdl:%x, link->link_hdl:%x", + CAM_IS_NULL_TO_STR(link), control->link_hdls[i], + (!link) ? CAM_REQ_MGR_DEFAULT_HDL_VAL : link->link_hdl); rc = -EINVAL; break; } @@ -4520,9 +4553,10 @@ int cam_req_mgr_dump_request(struct cam_dump_req_cmd *dump_req) /* session hdl's priv data is cam session struct */ session = (struct cam_req_mgr_core_session *) cam_get_device_priv(dump_req->session_handle); - if (!session) { - CAM_ERR(CAM_CRM, "Invalid session %x", - dump_req->session_handle); + if (!session || (session->session_hdl != dump_req->session_handle)) { + CAM_ERR(CAM_CRM, "session: %s, dump_req->ses_hdl:%x, session->ses_hdl:%x", + CAM_IS_NULL_TO_STR(session), dump_req->session_handle, + (!session) ? CAM_REQ_MGR_DEFAULT_HDL_VAL : session->session_hdl); rc = -EINVAL; goto end; } @@ -4534,8 +4568,10 @@ int cam_req_mgr_dump_request(struct cam_dump_req_cmd *dump_req) link = (struct cam_req_mgr_core_link *) cam_get_device_priv(dump_req->link_hdl); - if (!link) { - CAM_DBG(CAM_CRM, "link ptr NULL %x", dump_req->link_hdl); + if (!link || (link->link_hdl != dump_req->link_hdl)) { + CAM_ERR(CAM_CRM, "link: %s, dump_req->link_hdl:%x, link->link_hdl:%x", + CAM_IS_NULL_TO_STR(link), dump_req->link_hdl, + (!link) ? CAM_REQ_MGR_DEFAULT_HDL_VAL : link->link_hdl); rc = -EINVAL; goto end; } diff --git a/techpack/camera/drivers/cam_req_mgr/cam_req_mgr_core.h b/techpack/camera/drivers/cam_req_mgr/cam_req_mgr_core.h index 8b6edaa3f9ff..6f75677c29c2 100644 --- a/techpack/camera/drivers/cam_req_mgr/cam_req_mgr_core.h +++ b/techpack/camera/drivers/cam_req_mgr/cam_req_mgr_core.h @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2016-2021, The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. */ #ifndef _CAM_REQ_MGR_CORE_H_ #define _CAM_REQ_MGR_CORE_H_ @@ -18,6 +19,7 @@ #define CAM_REQ_MGR_WATCHDOG_TIMEOUT_MAX 50000 #define CAM_REQ_MGR_SCHED_REQ_TIMEOUT 1000 #define CAM_REQ_MGR_SIMULATE_SCHED_REQ 30 +#define CAM_REQ_MGR_DEFAULT_HDL_VAL 0 #define FORCE_DISABLE_RECOVERY 2 #define FORCE_ENABLE_RECOVERY 1 diff --git a/techpack/camera/drivers/cam_req_mgr/cam_req_mgr_dev.c b/techpack/camera/drivers/cam_req_mgr/cam_req_mgr_dev.c index 350c9ea171bf..63e61d160391 100644 --- a/techpack/camera/drivers/cam_req_mgr/cam_req_mgr_dev.c +++ b/techpack/camera/drivers/cam_req_mgr/cam_req_mgr_dev.c @@ -8,6 +8,7 @@ #include #include #include +#include #include @@ -35,6 +36,8 @@ static struct cam_req_mgr_device g_dev; struct kmem_cache *g_cam_req_mgr_timer_cachep; static struct list_head cam_req_mgr_ordered_sd_list; +DECLARE_RWSEM(rwsem_lock); + static struct device_attribute camera_debug_sysfs_attr = __ATTR(debug_node, 0600, NULL, cam_debug_sysfs_node_store); @@ -103,10 +106,29 @@ static void cam_v4l2_device_cleanup(void) g_dev.v4l2_dev = NULL; } + +void cam_req_mgr_rwsem_read_op(enum cam_subdev_rwsem lock) +{ + if (lock == CAM_SUBDEV_LOCK) + down_read(&rwsem_lock); + else if (lock == CAM_SUBDEV_UNLOCK) + up_read(&rwsem_lock); +} + +static void cam_req_mgr_rwsem_write_op(enum cam_subdev_rwsem lock) +{ + if (lock == CAM_SUBDEV_LOCK) + down_write(&rwsem_lock); + else if (lock == CAM_SUBDEV_UNLOCK) + up_write(&rwsem_lock); +} + static int cam_req_mgr_open(struct file *filep) { int rc; + cam_req_mgr_rwsem_write_op(CAM_SUBDEV_LOCK); + mutex_lock(&g_dev.cam_lock); if (g_dev.open_cnt >= 1) { rc = -EALREADY; @@ -133,12 +155,14 @@ static int cam_req_mgr_open(struct file *filep) } mutex_unlock(&g_dev.cam_lock); + cam_req_mgr_rwsem_write_op(CAM_SUBDEV_UNLOCK); return rc; mem_mgr_init_fail: v4l2_fh_release(filep); end: mutex_unlock(&g_dev.cam_lock); + cam_req_mgr_rwsem_write_op(CAM_SUBDEV_UNLOCK); return rc; } @@ -168,10 +192,14 @@ static int cam_req_mgr_close(struct file *filep) CAM_WARN(CAM_CRM, "release invoked associated userspace process has died, open_cnt: %d", g_dev.open_cnt); + + cam_req_mgr_rwsem_write_op(CAM_SUBDEV_LOCK); + mutex_lock(&g_dev.cam_lock); if (g_dev.open_cnt <= 0) { mutex_unlock(&g_dev.cam_lock); + cam_req_mgr_rwsem_write_op(CAM_SUBDEV_UNLOCK); return -EINVAL; } @@ -203,6 +231,8 @@ static int cam_req_mgr_close(struct file *filep) cam_mem_mgr_deinit(); mutex_unlock(&g_dev.cam_lock); + cam_req_mgr_rwsem_write_op(CAM_SUBDEV_UNLOCK); + return 0; } diff --git a/techpack/camera/drivers/cam_req_mgr/cam_req_mgr_util.c b/techpack/camera/drivers/cam_req_mgr/cam_req_mgr_util.c index 00b919fcec30..3c44058d2813 100644 --- a/techpack/camera/drivers/cam_req_mgr/cam_req_mgr_util.c +++ b/techpack/camera/drivers/cam_req_mgr/cam_req_mgr_util.c @@ -15,6 +15,7 @@ #include "cam_req_mgr_util.h" #include "cam_debug_util.h" #include "cam_context.h" +#include "cam_subdev.h" static struct cam_req_mgr_util_hdl_tbl *hdl_tbl; static DEFINE_SPINLOCK(hdl_tbl_lock); @@ -115,7 +116,7 @@ static int32_t cam_get_free_handle_index(void) idx = find_first_zero_bit(hdl_tbl->bitmap, hdl_tbl->bits); if (idx >= CAM_REQ_MGR_MAX_HANDLES_V2 || idx < 0) { - CAM_DBG(CAM_CRM, "idx: %d", idx); + CAM_ERR(CAM_CRM, "No free index found idx: %d", idx); return -ENOSR; } @@ -124,20 +125,6 @@ static int32_t cam_get_free_handle_index(void) return idx; } -void cam_dump_tbl_info(void) -{ - int i; - - for (i = 0; i < CAM_REQ_MGR_MAX_HANDLES_V2; i++) - CAM_INFO(CAM_CRM, - "i: %d session_hdl=0x%x hdl_value=0x%x type=%d state=%d dev_id=0x%llx", - i, hdl_tbl->hdl[i].session_hdl, - hdl_tbl->hdl[i].hdl_value, - hdl_tbl->hdl[i].type, - hdl_tbl->hdl[i].state, - hdl_tbl->hdl[i].dev_id); -} - int32_t cam_create_session_hdl(void *priv) { int idx; @@ -154,7 +141,6 @@ int32_t cam_create_session_hdl(void *priv) idx = cam_get_free_handle_index(); if (idx < 0) { CAM_ERR(CAM_CRM, "Unable to create session handle"); - cam_dump_tbl_info(); spin_unlock_bh(&hdl_tbl_lock); return idx; } @@ -178,6 +164,14 @@ int32_t cam_create_device_hdl(struct cam_create_dev_hdl *hdl_data) int idx; int rand = 0; int32_t handle; + bool crm_active; + + crm_active = cam_req_mgr_is_open(CAM_CRM); + if (!crm_active) { + CAM_ERR(CAM_CRM, "CRM is not ACTIVE"); + spin_unlock_bh(&hdl_tbl_lock); + return -EINVAL; + } spin_lock_bh(&hdl_tbl_lock); if (!hdl_tbl) { @@ -190,7 +184,6 @@ int32_t cam_create_device_hdl(struct cam_create_dev_hdl *hdl_data) if (idx < 0) { CAM_ERR(CAM_CRM, "Unable to create device handle(idx= %d)", idx); - cam_dump_tbl_info(); spin_unlock_bh(&hdl_tbl_lock); return idx; } diff --git a/techpack/camera/drivers/cam_req_mgr/cam_subdev.h b/techpack/camera/drivers/cam_req_mgr/cam_subdev.h index e37d7177c8a3..1e994bc69e33 100644 --- a/techpack/camera/drivers/cam_req_mgr/cam_subdev.h +++ b/techpack/camera/drivers/cam_req_mgr/cam_subdev.h @@ -28,6 +28,11 @@ enum cam_subdev_close_seq_priority { CAM_SD_CLOSE_LOW_PRIORITY }; +enum cam_subdev_rwsem { + CAM_SUBDEV_LOCK = 1, + CAM_SUBDEV_UNLOCK, +}; + /** * struct cam_subdev - describes a camera sub-device * @@ -130,6 +135,15 @@ int cam_register_subdev(struct cam_subdev *sd); */ int cam_unregister_subdev(struct cam_subdev *sd); +/** + * cam_req_mgr_rwsem_read_op() + * + * @brief : API to acquire read semaphore lock to platform framework. + * + * @lock : value indicates to lock or unlock the read lock + */ +void cam_req_mgr_rwsem_read_op(enum cam_subdev_rwsem lock); + /** * cam_req_mgr_is_open() * diff --git a/techpack/camera/drivers/cam_sensor_module/cam_actuator/cam_actuator_core.c b/techpack/camera/drivers/cam_sensor_module/cam_actuator/cam_actuator_core.c index 9c0d7abd043d..722f91e334b3 100644 --- a/techpack/camera/drivers/cam_sensor_module/cam_actuator/cam_actuator_core.c +++ b/techpack/camera/drivers/cam_sensor_module/cam_actuator/cam_actuator_core.c @@ -859,6 +859,11 @@ int32_t cam_actuator_driver_cmd(struct cam_actuator_ctrl_t *a_ctrl, actuator_acq_dev.device_handle = cam_create_device_hdl(&bridge_params); + if (actuator_acq_dev.device_handle <= 0) { + rc = -EFAULT; + CAM_ERR(CAM_ACTUATOR, "Can not create device handle"); + goto release_mutex; + } a_ctrl->bridge_intf.device_hdl = actuator_acq_dev.device_handle; a_ctrl->bridge_intf.session_hdl = actuator_acq_dev.session_handle; 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 210179307a9e..06c02c1932f1 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 @@ -1182,6 +1182,12 @@ int32_t cam_csiphy_core_cfg(void *phy_dev, index = csiphy_dev->acquire_count; csiphy_acq_dev.device_handle = cam_create_device_hdl(&bridge_params); + if (csiphy_acq_dev.device_handle <= 0) { + rc = -EFAULT; + CAM_ERR(CAM_CSIPHY, "Can not create device handle"); + goto release_mutex; + } + csiphy_dev->csiphy_info[index].hdl_data.device_hdl = csiphy_acq_dev.device_handle; csiphy_dev->csiphy_info[index].hdl_data.session_hdl = diff --git a/techpack/camera/drivers/cam_sensor_module/cam_eeprom/cam_eeprom_core.c b/techpack/camera/drivers/cam_sensor_module/cam_eeprom/cam_eeprom_core.c index 8e4270373331..78130f6a66de 100644 --- a/techpack/camera/drivers/cam_sensor_module/cam_eeprom/cam_eeprom_core.c +++ b/techpack/camera/drivers/cam_sensor_module/cam_eeprom/cam_eeprom_core.c @@ -360,6 +360,10 @@ static int32_t cam_eeprom_get_dev_handle(struct cam_eeprom_ctrl_t *e_ctrl, eeprom_acq_dev.device_handle = cam_create_device_hdl(&bridge_params); + if (eeprom_acq_dev.device_handle <= 0) { + CAM_ERR(CAM_EEPROM, "Can not create device handle"); + return -EFAULT; + } e_ctrl->bridge_intf.device_hdl = eeprom_acq_dev.device_handle; e_ctrl->bridge_intf.session_hdl = eeprom_acq_dev.session_handle; diff --git a/techpack/camera/drivers/cam_sensor_module/cam_flash/cam_flash_dev.c b/techpack/camera/drivers/cam_sensor_module/cam_flash/cam_flash_dev.c index b2dd3265da69..cc57a7124ae9 100644 --- a/techpack/camera/drivers/cam_sensor_module/cam_flash/cam_flash_dev.c +++ b/techpack/camera/drivers/cam_sensor_module/cam_flash/cam_flash_dev.c @@ -68,6 +68,11 @@ static int32_t cam_flash_driver_cmd(struct cam_flash_ctrl *fctrl, flash_acq_dev.device_handle = cam_create_device_hdl(&bridge_params); + if (flash_acq_dev.device_handle <= 0) { + rc = -EFAULT; + CAM_ERR(CAM_FLASH, "Can not create device handle"); + goto release_mutex; + } fctrl->bridge_intf.device_hdl = flash_acq_dev.device_handle; fctrl->bridge_intf.session_hdl = @@ -429,6 +434,7 @@ static int cam_flash_component_bind(struct device *dev, return -ENOMEM; fctrl->pdev = pdev; + fctrl->of_node = pdev->dev.of_node; fctrl->soc_info.pdev = pdev; fctrl->soc_info.dev = &pdev->dev; fctrl->soc_info.dev_name = pdev->name; @@ -600,13 +606,18 @@ static int32_t cam_flash_i2c_driver_probe(struct i2c_client *client, { int32_t rc = 0, i = 0; struct cam_flash_ctrl *fctrl; + struct cam_hw_soc_info *soc_info = NULL; - if (client == NULL || id == NULL) { - CAM_ERR(CAM_FLASH, "Invalid Args client: %pK id: %pK", - client, id); + if (client == NULL) { + CAM_ERR(CAM_FLASH, "Invalid Args client: %pK", + client); return -EINVAL; } + if (id == NULL) { + CAM_DBG(CAM_FLASH, "device id is Null"); + } + if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { CAM_ERR(CAM_FLASH, "%s :: i2c_check_functionality failed", client->name); @@ -618,9 +629,9 @@ static int32_t cam_flash_i2c_driver_probe(struct i2c_client *client, if (!fctrl) return -ENOMEM; - i2c_set_clientdata(client, fctrl); - + client->dev.driver_data = fctrl; fctrl->io_master_info.client = client; + fctrl->of_node = client->dev.of_node; fctrl->soc_info.dev = &client->dev; fctrl->soc_info.dev_name = client->name; fctrl->io_master_info.master_type = I2C_MASTER; @@ -631,6 +642,40 @@ static int32_t cam_flash_i2c_driver_probe(struct i2c_client *client, goto free_ctrl; } + rc = cam_flash_init_default_params(fctrl); + if (rc) { + CAM_ERR(CAM_FLASH, + "failed: cam_flash_init_default_params rc %d", + rc); + goto free_ctrl; + } + + soc_info = &fctrl->soc_info; + rc = cam_sensor_util_regulator_powerup(soc_info); + if (rc < 0) { + CAM_ERR(CAM_FLASH, "regulator power up for flash failed %d", + rc); + goto free_ctrl; + } + + if (!soc_info->gpio_data) { + CAM_DBG(CAM_FLASH, "No GPIO found"); + rc = 0; + return rc; + } + + if (!soc_info->gpio_data->cam_gpio_common_tbl_size) { + CAM_DBG(CAM_FLASH, "No GPIO found"); + return -EINVAL; + } + + rc = cam_sensor_util_init_gpio_pin_tbl(soc_info, + &fctrl->power_info.gpio_num_info); + if ((rc < 0) || (!fctrl->power_info.gpio_num_info)) { + CAM_ERR(CAM_FLASH, "No/Error Flash GPIOs"); + goto free_ctrl; + } + rc = cam_flash_init_subdev(fctrl); if (rc) goto free_ctrl; @@ -699,6 +744,7 @@ static struct i2c_driver cam_flash_i2c_driver = { .remove = cam_flash_i2c_driver_remove, .driver = { .name = FLASH_DRIVER_I2C, + .of_match_table = cam_flash_dt_match, }, }; @@ -713,8 +759,9 @@ int32_t cam_flash_init_module(void) } rc = i2c_add_driver(&cam_flash_i2c_driver); - if (rc) + if (rc < 0) CAM_ERR(CAM_FLASH, "i2c_add_driver failed rc: %d", rc); + return rc; } diff --git a/techpack/camera/drivers/cam_sensor_module/cam_flash/cam_flash_soc.c b/techpack/camera/drivers/cam_sensor_module/cam_flash/cam_flash_soc.c index 9ec28e953f8b..9eac7a8b8aaf 100644 --- a/techpack/camera/drivers/cam_sensor_module/cam_flash/cam_flash_soc.c +++ b/techpack/camera/drivers/cam_sensor_module/cam_flash/cam_flash_soc.c @@ -293,7 +293,14 @@ int cam_flash_get_dt_data(struct cam_flash_ctrl *fctrl, rc = -ENOMEM; goto release_soc_res; } - of_node = fctrl->pdev->dev.of_node; + + if (fctrl->of_node == NULL) { + CAM_ERR(CAM_FLASH, "device node is NULL"); + rc = -EINVAL; + goto free_soc_private; + } + + of_node = fctrl->of_node; rc = cam_soc_util_get_dt_properties(soc_info); if (rc) { diff --git a/techpack/camera/drivers/cam_sensor_module/cam_ois/cam_ois_core.c b/techpack/camera/drivers/cam_sensor_module/cam_ois/cam_ois_core.c index 543f7a9f3eb2..b8cc002edb91 100644 --- a/techpack/camera/drivers/cam_sensor_module/cam_ois/cam_ois_core.c +++ b/techpack/camera/drivers/cam_sensor_module/cam_ois/cam_ois_core.c @@ -86,6 +86,10 @@ static int cam_ois_get_dev_handle(struct cam_ois_ctrl_t *o_ctrl, ois_acq_dev.device_handle = cam_create_device_hdl(&bridge_params); + if (ois_acq_dev.device_handle <= 0) { + CAM_ERR(CAM_OIS, "Can not create device handle"); + return -EFAULT; + } o_ctrl->bridge_intf.device_hdl = ois_acq_dev.device_handle; o_ctrl->bridge_intf.session_hdl = ois_acq_dev.session_handle; diff --git a/techpack/camera/drivers/cam_sensor_module/cam_sensor/cam_sensor_core.c b/techpack/camera/drivers/cam_sensor_module/cam_sensor/cam_sensor_core.c index 38846433fd0a..8298f9f81bc6 100644 --- a/techpack/camera/drivers/cam_sensor_module/cam_sensor/cam_sensor_core.c +++ b/techpack/camera/drivers/cam_sensor_module/cam_sensor/cam_sensor_core.c @@ -839,6 +839,11 @@ int32_t cam_sensor_driver_cmd(struct cam_sensor_ctrl_t *s_ctrl, sensor_acq_dev.device_handle = cam_create_device_hdl(&bridge_params); + if (sensor_acq_dev.device_handle <= 0) { + rc = -EFAULT; + CAM_ERR(CAM_SENSOR, "Can not create device handle"); + goto release_mutex; + } s_ctrl->bridge_intf.device_hdl = sensor_acq_dev.device_handle; s_ctrl->bridge_intf.session_hdl = sensor_acq_dev.session_handle; diff --git a/techpack/camera/drivers/cam_sensor_module/cam_sensor_io/cam_sensor_qup_i2c.c b/techpack/camera/drivers/cam_sensor_module/cam_sensor_io/cam_sensor_qup_i2c.c index 38af4f74bedb..17bcb0867abb 100644 --- a/techpack/camera/drivers/cam_sensor_module/cam_sensor_io/cam_sensor_qup_i2c.c +++ b/techpack/camera/drivers/cam_sensor_module/cam_sensor_io/cam_sensor_qup_i2c.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved. */ #include "cam_sensor_cmn_header.h" @@ -31,9 +31,14 @@ static int32_t cam_qup_i2c_rxdata( }, }; rc = i2c_transfer(dev_client->adapter, msgs, 2); - if (rc < 0) + if (rc < 0) { CAM_ERR(CAM_SENSOR, "failed 0x%x", saddr); - return rc; + return rc; + } + /* Returns negative errno */ + /* else the number of messages executed. */ + /* So positive values are not errors. */ + return 0; } @@ -52,9 +57,14 @@ static int32_t cam_qup_i2c_txdata( }, }; rc = i2c_transfer(dev_client->client->adapter, msg, 1); - if (rc < 0) + if (rc < 0) { CAM_ERR(CAM_SENSOR, "failed 0x%x", saddr); - return rc; + return rc; + } + /* Returns negative errno, */ + /* else the number of messages executed. */ + /* So positive values are not errors. */ + return 0; } int32_t cam_qup_i2c_read(struct i2c_client *client, diff --git a/techpack/camera/drivers/cam_sensor_module/cam_sensor_utils/cam_sensor_util.c b/techpack/camera/drivers/cam_sensor_module/cam_sensor_utils/cam_sensor_util.c index 771ca38fa6d8..a8bad02a0247 100644 --- a/techpack/camera/drivers/cam_sensor_module/cam_sensor_utils/cam_sensor_util.c +++ b/techpack/camera/drivers/cam_sensor_module/cam_sensor_utils/cam_sensor_util.c @@ -74,11 +74,11 @@ int32_t cam_sensor_util_regulator_powerup(struct cam_hw_soc_info *soc_info) if (IS_ERR_OR_NULL(soc_info->rgltr[i])) { rc = PTR_ERR(soc_info->rgltr[i]); rc = rc ? rc : -EINVAL; - CAM_ERR(CAM_ACTUATOR, "get failed for regulator %s %d", + CAM_ERR(CAM_SENSOR, "get failed for regulator %s %d", soc_info->rgltr_name[i], rc); return rc; } - CAM_DBG(CAM_ACTUATOR, "get for regulator %s", + CAM_DBG(CAM_SENSOR, "get for regulator %s", soc_info->rgltr_name[i]); } diff --git a/techpack/camera/drivers/cam_utils/cam_debug_util.h b/techpack/camera/drivers/cam_utils/cam_debug_util.h index 5232501525d1..28fc4c2399a2 100644 --- a/techpack/camera/drivers/cam_utils/cam_debug_util.h +++ b/techpack/camera/drivers/cam_utils/cam_debug_util.h @@ -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. */ #ifndef _CAM_DEBUG_UTIL_H_ @@ -8,6 +9,8 @@ #include +#define CAM_IS_NULL_TO_STR(ptr) ((ptr) ? "Non-NULL" : "NULL") + /* Module IDs used for debug logging */ #define CAM_CDM (1 << 0) #define CAM_CORE (1 << 1) diff --git a/techpack/camera/include/uapi/camera/media/cam_ope.h b/techpack/camera/include/uapi/camera/media/cam_ope.h index d9badbcdff3d..b6a9a41d8dfe 100644 --- a/techpack/camera/include/uapi/camera/media/cam_ope.h +++ b/techpack/camera/include/uapi/camera/media/cam_ope.h @@ -73,7 +73,7 @@ #define OPE_MAX_IO_BUFS (OPE_OUT_RES_MAX + OPE_IN_RES_MAX) #define OPE_MAX_PASS 1 #define OPE_MAX_PLANES 2 -#define OPE_MAX_STRIPES 48 +#define OPE_MAX_STRIPES 64 #define OPE_MAX_BATCH_SIZE 16 /**