diff --git a/drivers/cam_isp/cam_isp_context.c b/drivers/cam_isp/cam_isp_context.c index 824437bee9..32022f9395 100644 --- a/drivers/cam_isp/cam_isp_context.c +++ b/drivers/cam_isp/cam_isp_context.c @@ -4511,6 +4511,10 @@ static int __cam_isp_ctx_apply_req_in_activated_state( ctx_isp = (struct cam_isp_context *) ctx->ctx_priv; + /* Reset mswitch ref cnt */ + atomic_set(&ctx_isp->mswitch_default_apply_delay_ref_cnt, + ctx_isp->mswitch_default_apply_delay_max_cnt); + if (apply->re_apply) if (apply->request_id <= ctx_isp->last_applied_req_id) { CAM_INFO_RATE_LIMIT(CAM_ISP, @@ -4676,6 +4680,7 @@ static int __cam_isp_ctx_apply_req_in_activated_state( "ctx_id:%d ,Can not apply (req %lld) the configuration, rc %d", ctx->ctx_id, apply->request_id, rc); } + atomic_set(&ctx_isp->apply_in_progress, 0); end: return rc; @@ -4753,29 +4758,100 @@ static int __cam_isp_ctx_apply_req_in_bubble( return rc; } +static void __cam_isp_ctx_find_mup_for_default_settings( + int64_t req_id, struct cam_context *ctx, + struct cam_ctx_request **switch_req) +{ + struct cam_ctx_request *req, *temp_req; + + if (list_empty(&ctx->pending_req_list)) { + CAM_DBG(CAM_ISP, + "Pending list empty, unable to find mup for req: %lld ctx: %u", + req_id, ctx->ctx_id); + return; + } + + list_for_each_entry_safe( + req, temp_req, &ctx->pending_req_list, list) { + if (req->request_id == req_id) { + struct cam_isp_ctx_req *req_isp = (struct cam_isp_ctx_req *)req->req_priv; + + if (req_isp->hw_update_data.mup_en) { + *switch_req = req; + CAM_DBG(CAM_ISP, + "Found mup for last applied max pd req: %lld in ctx: %u", + req_id, ctx->ctx_id); + } + } + } +} + static int __cam_isp_ctx_apply_default_req_settings( struct cam_context *ctx, struct cam_req_mgr_apply_request *apply) { int rc = 0; + bool skip_rup_aup = false; + struct cam_ctx_request *req = NULL; + struct cam_isp_ctx_req *req_isp = NULL; struct cam_isp_context *isp_ctx = (struct cam_isp_context *) ctx->ctx_priv; - struct cam_hw_cmd_args hw_cmd_args; - struct cam_isp_hw_cmd_args isp_hw_cmd_args; + struct cam_hw_cmd_args hw_cmd_args; + struct cam_isp_hw_cmd_args isp_hw_cmd_args; + struct cam_hw_config_args cfg = {0}; - hw_cmd_args.ctxt_to_hw_map = isp_ctx->hw_ctx; - hw_cmd_args.cmd_type = CAM_HW_MGR_CMD_INTERNAL; - isp_hw_cmd_args.cmd_type = - CAM_ISP_HW_MGR_CMD_PROG_DEFAULT_CFG; - hw_cmd_args.u.internal_args = (void *)&isp_hw_cmd_args; + if (isp_ctx->mode_switch_en && isp_ctx->handle_mswitch) { + if ((apply->last_applied_max_pd_req > 0) && + (atomic_dec_and_test(&isp_ctx->mswitch_default_apply_delay_ref_cnt))) { + __cam_isp_ctx_find_mup_for_default_settings( + apply->last_applied_max_pd_req, ctx, &req); + } - rc = ctx->hw_mgr_intf->hw_cmd(ctx->hw_mgr_intf->hw_mgr_priv, + if (req) { + req_isp = (struct cam_isp_ctx_req *)req->req_priv; + + CAM_DBG(CAM_ISP, + "Applying IQ for mode switch req: %lld ctx: %u", + req->request_id, ctx->ctx_id); + cfg.ctxt_to_hw_map = isp_ctx->hw_ctx; + cfg.request_id = req->request_id; + cfg.hw_update_entries = req_isp->cfg; + cfg.num_hw_update_entries = req_isp->num_cfg; + cfg.priv = &req_isp->hw_update_data; + cfg.init_packet = 0; + cfg.reapply_type = CAM_CONFIG_REAPPLY_IQ; + cfg.cdm_reset_before_apply = req_isp->cdm_reset_before_apply; + + rc = ctx->hw_mgr_intf->hw_config(ctx->hw_mgr_intf->hw_mgr_priv, &cfg); + if (rc) { + CAM_ERR(CAM_ISP, + "Failed to apply req: %lld IQ settings in ctx: %u", + req->request_id, ctx->ctx_id); + goto end; + } + skip_rup_aup = true; + } + } + + if (isp_ctx->use_default_apply) { + hw_cmd_args.ctxt_to_hw_map = isp_ctx->hw_ctx; + hw_cmd_args.cmd_type = CAM_HW_MGR_CMD_INTERNAL; + isp_hw_cmd_args.cmd_type = + CAM_ISP_HW_MGR_CMD_PROG_DEFAULT_CFG; + + isp_hw_cmd_args.cmd_data = (void *)&skip_rup_aup; + hw_cmd_args.u.internal_args = (void *)&isp_hw_cmd_args; + + rc = ctx->hw_mgr_intf->hw_cmd(ctx->hw_mgr_intf->hw_mgr_priv, &hw_cmd_args); - if (rc) - CAM_ERR(CAM_ISP, - "Failed to apply default settings rc %d", rc); - else - CAM_DBG(CAM_ISP, "Applied default settings rc %d", rc); + if (rc) + CAM_ERR(CAM_ISP, + "Failed to apply default settings rc %d", rc); + else + CAM_DBG(CAM_ISP, "Applied default settings rc %d ctx: %u", + rc, ctx->ctx_id); + } +end: return rc; } @@ -6939,6 +7015,8 @@ static int __cam_isp_ctx_acquire_hw_v2(struct cam_context *ctx, (param.op_flags & CAM_IFE_CTX_CONSUME_ADDR_EN); ctx_isp->aeb_enabled = (param.op_flags & CAM_IFE_CTX_AEB_EN); + ctx_isp->mode_switch_en = + (param.op_flags & CAM_IFE_CTX_DYNAMIC_SWITCH_EN); /* Query the context bus comp group information */ ctx_isp->vfe_bus_comp_grp = kcalloc(CAM_IFE_BUS_COMP_NUM_MAX, @@ -7206,6 +7284,19 @@ static int __cam_isp_ctx_link_in_acquired(struct cam_context *ctx, ctx_isp->subscribe_event = CAM_TRIGGER_POINT_SOF | CAM_TRIGGER_POINT_EOF; ctx_isp->trigger_id = link->trigger_id; + ctx_isp->mswitch_default_apply_delay_max_cnt = 0; + atomic_set(&ctx_isp->mswitch_default_apply_delay_ref_cnt, 0); + + if ((link->mode_switch_max_delay - CAM_MODESWITCH_DELAY_1) > 0) { + ctx_isp->handle_mswitch = true; + ctx_isp->mswitch_default_apply_delay_max_cnt = + link->mode_switch_max_delay - CAM_MODESWITCH_DELAY_1; + CAM_DBG(CAM_ISP, + "Enabled mode switch handling on ctx: %u max delay cnt: %u", + ctx->ctx_id, ctx_isp->mswitch_default_apply_delay_max_cnt); + atomic_set(&ctx_isp->mswitch_default_apply_delay_ref_cnt, + ctx_isp->mswitch_default_apply_delay_max_cnt); + } /* change state only if we had the init config */ if (ctx_isp->init_received) { @@ -7228,6 +7319,8 @@ static int __cam_isp_ctx_unlink_in_acquired(struct cam_context *ctx, ctx->link_hdl = -1; ctx->ctx_crm_intf = NULL; ctx_isp->trigger_id = -1; + ctx_isp->mswitch_default_apply_delay_max_cnt = 0; + atomic_set(&ctx_isp->mswitch_default_apply_delay_ref_cnt, 0); return rc; } @@ -7240,7 +7333,8 @@ static int __cam_isp_ctx_get_dev_info_in_acquired(struct cam_context *ctx, dev_info->dev_hdl = ctx->dev_hdl; strlcpy(dev_info->name, CAM_ISP_DEV_NAME, sizeof(dev_info->name)); dev_info->dev_id = CAM_REQ_MGR_DEVICE_IFE; - dev_info->p_delay = 1; + dev_info->p_delay = CAM_PIPELINE_DELAY_1; + dev_info->m_delay = CAM_MODESWITCH_DELAY_1; dev_info->trigger = CAM_TRIGGER_POINT_SOF; dev_info->trigger_on = true; @@ -7934,11 +8028,17 @@ static int __cam_isp_ctx_apply_default_settings( if (atomic_read(&ctx_isp->internal_recovery_set)) return __cam_isp_ctx_reset_and_recover(false, ctx); - if (ctx_isp->use_default_apply) { + /* + * Call notify frame skip for static offline cases or + * mode switch cases where IFE mode switch delay differs + * from other devices on the link + */ + if ((ctx_isp->use_default_apply) || + (ctx_isp->mode_switch_en && ctx_isp->handle_mswitch)) { CAM_DBG(CAM_ISP, "Enter: apply req in Substate:%d request _id:%lld ctx:%u on link:0x%x", - ctx_isp->substate_activated, apply->request_id, - ctx->ctx_id, ctx->link_hdl); + ctx_isp->substate_activated, apply->request_id, + ctx->ctx_id, ctx->link_hdl); ctx_ops = &ctx_isp->substate_machine[ ctx_isp->substate_activated]; diff --git a/drivers/cam_isp/cam_isp_context.h b/drivers/cam_isp/cam_isp_context.h index 30decf1a9e..4e8b8a9c7a 100644 --- a/drivers/cam_isp/cam_isp_context.h +++ b/drivers/cam_isp/cam_isp_context.h @@ -303,6 +303,15 @@ struct cam_isp_context_event_record { * @last_applied_jiffies: Record the jiffiest of last applied req * @vfe_bus_comp_grp: Vfe bus comp group record * @sfe_bus_comp_grp: Sfe bus comp group record + * @mswitch_default_apply_delay_max_cnt: Max mode switch delay among all devices connected + * on the same link as this ISP context + * @mswitch_default_apply_delay_ref_cnt: Ref cnt for this context to decide when to apply + * mode switch settings + * @handle_mswitch: Indicates if IFE needs to explicitly handle mode switch + * on frame skip callback from request manager. + * This is decided based on the max mode switch delay published + * by other devices on the link as part of link setup + * @mode_switch_en: Indicates if mode switch is enabled * */ struct cam_isp_context { @@ -366,6 +375,10 @@ struct cam_isp_context { uint64_t last_applied_jiffies; struct cam_isp_context_comp_record *vfe_bus_comp_grp; struct cam_isp_context_comp_record *sfe_bus_comp_grp; + int32_t mswitch_default_apply_delay_max_cnt; + atomic_t mswitch_default_apply_delay_ref_cnt; + bool handle_mswitch; + bool mode_switch_en; }; /** diff --git a/drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c b/drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c index 927fd5f5dc..2ae71b586b 100644 --- a/drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c +++ b/drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c @@ -5517,11 +5517,14 @@ static int cam_ife_mgr_acquire_hw(void *hw_mgr_priv, void *acquire_hw_args) if (ife_ctx->ctx_type == CAM_IFE_CTX_TYPE_CUSTOM) acquire_args->op_flags |= CAM_IFE_CTX_CUSTOM_EN; - if (ife_ctx->ctx_config & - CAM_IFE_CTX_CFG_FRAME_HEADER_TS) + if (ife_ctx->ctx_config & CAM_IFE_CTX_CFG_FRAME_HEADER_TS) acquire_args->op_flags |= CAM_IFE_CTX_FRAME_HEADER_EN; + if (ife_ctx->ctx_config & CAM_IFE_CTX_CFG_DYNAMIC_SWITCH_ON) + acquire_args->op_flags |= + CAM_IFE_CTX_DYNAMIC_SWITCH_EN; + if (ife_ctx->ctx_type == CAM_IFE_CTX_TYPE_SFE) acquire_args->op_flags |= CAM_IFE_CTX_SFE_EN; @@ -12793,9 +12796,19 @@ static int cam_ife_mgr_cmd(void *hw_mgr_priv, void *cmd_args) isp_hw_cmd_args->u.last_cdm_done = ctx->last_cdm_done_req; break; - case CAM_ISP_HW_MGR_CMD_PROG_DEFAULT_CFG: - rc = cam_ife_mgr_prog_default_settings(false, ctx); - break; + case CAM_ISP_HW_MGR_CMD_PROG_DEFAULT_CFG: { + bool skip_rup_aup = false; + + if (!isp_hw_cmd_args->cmd_data) { + CAM_ERR(CAM_ISP, "Invalid cmd data"); + rc = -EINVAL; + break; + } + + skip_rup_aup = *((bool *)isp_hw_cmd_args->cmd_data); + rc = cam_ife_mgr_prog_default_settings((false || skip_rup_aup), ctx); + } + break; case CAM_ISP_HW_MGR_GET_SOF_TS: rc = cam_ife_mgr_cmd_get_sof_timestamp(ctx, &isp_hw_cmd_args->u.sof_ts.curr, diff --git a/drivers/cam_isp/isp_hw_mgr/include/cam_isp_hw_mgr_intf.h b/drivers/cam_isp/isp_hw_mgr/include/cam_isp_hw_mgr_intf.h index 8b9e672a6c..da0ba1ed7d 100644 --- a/drivers/cam_isp/isp_hw_mgr/include/cam_isp_hw_mgr_intf.h +++ b/drivers/cam_isp/isp_hw_mgr/include/cam_isp_hw_mgr_intf.h @@ -46,6 +46,7 @@ #define CAM_IFE_CTX_APPLY_DEFAULT_CFG BIT(3) #define CAM_IFE_CTX_SFE_EN BIT(4) #define CAM_IFE_CTX_AEB_EN BIT(5) +#define CAM_IFE_CTX_DYNAMIC_SWITCH_EN BIT(6) /* * Maximum configuration entry size - This is based on the diff --git a/drivers/cam_req_mgr/cam_req_mgr_core.c b/drivers/cam_req_mgr/cam_req_mgr_core.c index 387c97ac45..8ea78ca0ee 100644 --- a/drivers/cam_req_mgr/cam_req_mgr_core.c +++ b/drivers/cam_req_mgr/cam_req_mgr_core.c @@ -364,10 +364,13 @@ static int __cam_req_mgr_notify_frame_skip( apply_data[pd].req_id; frame_skip.trigger_point = trigger; frame_skip.report_if_bubble = 0; + frame_skip.last_applied_max_pd_req = + link->req.prev_apply_data[link->max_delay].req_id; CAM_DBG(CAM_REQ, - "Notify_frame_skip: link: 0x%x pd %d req_id %lld", - link->link_hdl, pd, apply_data[pd].req_id); + "Notify_frame_skip: link: 0x%x pd %d req_id %lld last_applied %lld", + link->link_hdl, pd, apply_data[pd].req_id, + link->req.prev_apply_data[link->max_delay].req_id); if ((dev->ops) && (dev->ops->notify_frame_skip)) dev->ops->notify_frame_skip(&frame_skip); } @@ -1123,6 +1126,8 @@ static int __cam_req_mgr_send_req(struct cam_req_mgr_core_link *link, link->req.prev_apply_data[pd].req_id; apply_req.trigger_point = trigger; apply_req.report_if_bubble = 0; + apply_req.last_applied_max_pd_req = + link->req.prev_apply_data[link->max_delay].req_id; if ((dev->ops) && (dev->ops->notify_frame_skip)) dev->ops->notify_frame_skip(&apply_req); continue; @@ -1203,6 +1208,8 @@ static int __cam_req_mgr_send_req(struct cam_req_mgr_core_link *link, link->req.prev_apply_data[pd].req_id; apply_req.trigger_point = trigger; apply_req.report_if_bubble = 0; + apply_req.last_applied_max_pd_req = + link->req.prev_apply_data[link->max_delay].req_id; if ((dev->ops) && (dev->ops->notify_frame_skip)) dev->ops->notify_frame_skip(&apply_req); continue; @@ -4147,6 +4154,7 @@ static int __cam_req_mgr_setup_link_info(struct cam_req_mgr_core_link *link, struct cam_req_mgr_connected_device *dev; struct cam_req_mgr_req_tbl *pd_tbl; enum cam_pipeline_delay max_delay; + enum cam_modeswitch_delay max_modeswitch; uint32_t num_trigger_devices = 0; if (link_info->version == VERSION_1) { if (link_info->u.link_info_v1.num_devices > @@ -4167,6 +4175,7 @@ static int __cam_req_mgr_setup_link_info(struct cam_req_mgr_core_link *link, return rc; max_delay = CAM_PIPELINE_DELAY_0; + max_modeswitch = CAM_MODESWITCH_DELAY_0; if (link_info->version == VERSION_1) num_devices = link_info->u.link_info_v1.num_devices; else if (link_info->version == VERSION_2) @@ -4219,6 +4228,12 @@ static int __cam_req_mgr_setup_link_info(struct cam_req_mgr_core_link *link, CAM_PIPELINE_DELAY_0) { CAM_ERR(CAM_CRM, "get device info failed"); goto error; + } else if (dev->dev_info.m_delay >= + CAM_MODESWITCH_DELAY_MAX || + dev->dev_info.m_delay < + CAM_MODESWITCH_DELAY_0) { + CAM_ERR(CAM_CRM, "get mode switch info failed"); + goto error; } else { if (link_info->version == VERSION_1) { CAM_DBG(CAM_CRM, "%x: connected: %s, delay %d", @@ -4234,6 +4249,9 @@ static int __cam_req_mgr_setup_link_info(struct cam_req_mgr_core_link *link, } if (dev->dev_info.p_delay > max_delay) max_delay = dev->dev_info.p_delay; + + if (dev->dev_info.m_delay > max_modeswitch) + max_modeswitch = dev->dev_info.m_delay; } if (dev->dev_info.trigger_on) @@ -4252,6 +4270,7 @@ static int __cam_req_mgr_setup_link_info(struct cam_req_mgr_core_link *link, link_data.link_hdl = link->link_hdl; link_data.crm_cb = &cam_req_mgr_ops; link_data.max_delay = max_delay; + link_data.mode_switch_max_delay = max_modeswitch; if (num_trigger_devices == CAM_REQ_MGR_MAX_TRIGGERS) link->dual_trigger = true; @@ -4304,11 +4323,19 @@ static int __cam_req_mgr_setup_link_info(struct cam_req_mgr_core_link *link, /* Communicate with dev to establish the link */ dev->ops->link_setup(&link_data); + /* Compute max/min pipeline delay */ if (dev->dev_info.p_delay > link->max_delay) link->max_delay = dev->dev_info.p_delay; if (dev->dev_info.p_delay < link->min_delay) link->min_delay = dev->dev_info.p_delay; + + /* Compute max/min modeswitch delay */ + if (dev->dev_info.m_delay > link->max_mswitch_delay) + link->max_mswitch_delay = dev->dev_info.m_delay; + if (dev->dev_info.m_delay < link->min_mswitch_delay) + link->min_mswitch_delay = dev->dev_info.m_delay; } + link->num_devs = num_devices; /* Assign id for pd tables */ diff --git a/drivers/cam_req_mgr/cam_req_mgr_core.h b/drivers/cam_req_mgr/cam_req_mgr_core.h index 01b147d209..83a3f69ffe 100644 --- a/drivers/cam_req_mgr/cam_req_mgr_core.h +++ b/drivers/cam_req_mgr/cam_req_mgr_core.h @@ -1,7 +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. + * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved. */ #ifndef _CAM_REQ_MGR_CORE_H_ #define _CAM_REQ_MGR_CORE_H_ @@ -370,6 +370,8 @@ struct cam_req_mgr_connected_device { * @num_devs : num of connected devices to this link * @max_delay : Max of pipeline delay of all connected devs * @min_delay : Min of pipeline delay of all connected devs + * @max_mswitch_delay : Max of modeswitch delay of all connected devs + * @min_mswitch_delay : Min of modeswitch delay of all connected devs * @workq : Pointer to handle workq related jobs * @pd_mask : each set bit indicates the device with pd equal to * bit position is available. @@ -425,6 +427,8 @@ struct cam_req_mgr_core_link { int32_t num_devs; enum cam_pipeline_delay max_delay; enum cam_pipeline_delay min_delay; + enum cam_modeswitch_delay max_mswitch_delay; + enum cam_modeswitch_delay min_mswitch_delay; struct cam_req_mgr_core_workq *workq; int32_t pd_mask; struct cam_req_mgr_connected_device *l_dev; diff --git a/drivers/cam_req_mgr/cam_req_mgr_interface.h b/drivers/cam_req_mgr/cam_req_mgr_interface.h index 81808a96ca..f41655c619 100644 --- a/drivers/cam_req_mgr/cam_req_mgr_interface.h +++ b/drivers/cam_req_mgr/cam_req_mgr_interface.h @@ -1,7 +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. + * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved. */ #ifndef _CAM_REQ_MGR_INTERFACE_H @@ -115,6 +115,23 @@ enum cam_pipeline_delay { CAM_PIPELINE_DELAY_MAX, }; +/** + * enum cam_modeswitch_delay + * @brief : enumerator for different modeswitch delays in camera + * + * @DELAY_0 : device processed mode switch settings after 0 frame + * @DELAY_1 : device processed mode switch settings after 1 frame + * @DELAY_2 : device processed mode switch settings after 2 frames + * @DELAY_MAX : maximum supported mode switch delay + */ +enum cam_modeswitch_delay { + CAM_MODESWITCH_DELAY_0, + CAM_MODESWITCH_DELAY_1, + CAM_MODESWITCH_DELAY_2, + CAM_MODESWITCH_DELAY_MAX, +}; + + /** * @CAM_TRIGGER_POINT_SOF : Trigger point for Start Of Frame * @CAM_TRIGGER_POINT_EOF : Trigger point for End Of Frame @@ -314,6 +331,7 @@ struct cam_req_mgr_notify_stop { * @name : link link or unlink * @dev_id : device id info * @p_delay : delay between time settings applied and take effect + * @m_delay : delay between time modeswitch settings applied and take effect * @trigger : Trigger point for the client * @trigger_on : This device provides trigger */ @@ -322,6 +340,7 @@ struct cam_req_mgr_device_info { char name[256]; enum cam_req_mgr_device_id dev_id; enum cam_pipeline_delay p_delay; + enum cam_modeswitch_delay m_delay; uint32_t trigger; bool trigger_on; }; @@ -332,6 +351,7 @@ struct cam_req_mgr_device_info { * @link_hdl : link identifier * @dev_hdl : device handle for reference * @max_delay : max pipeline delay on this link + * @mode_switch_max_delay : max modeswitch delay on this link * @crm_cb : callback funcs to communicate with req mgr * @trigger_id : Unique ID provided to the triggering device */ @@ -340,25 +360,29 @@ struct cam_req_mgr_core_dev_link_setup { int32_t link_hdl; int32_t dev_hdl; enum cam_pipeline_delay max_delay; + enum cam_modeswitch_delay mode_switch_max_delay; struct cam_req_mgr_crm_cb *crm_cb; int32_t trigger_id; }; /** * struct cam_req_mgr_apply_request - * @link_hdl : link identifier - * @dev_hdl : device handle for cross check - * @request_id : request id settings to apply - * @report_if_bubble : report to crm if failure in applying - * @trigger_point : the trigger point of this apply - * @re_apply : to skip re_apply for buf_done request - * @recovery : Indicate if it is recovery req + * @link_hdl : link identifier + * @dev_hdl : device handle for cross check + * @request_id : request id settings to apply + * @last_applied_max_pd_req : Last applied request on highest pd device + * -1 is considered invalid + * @report_if_bubble : report to crm if failure in applying + * @trigger_point : the trigger point of this apply + * @re_apply : to skip re_apply for buf_done request + * @recovery : Indicate if it is recovery req * */ struct cam_req_mgr_apply_request { int32_t link_hdl; int32_t dev_hdl; - int64_t request_id; + uint64_t request_id; + int64_t last_applied_max_pd_req; int32_t report_if_bubble; uint32_t trigger_point; bool re_apply; diff --git a/drivers/cam_sensor_module/cam_actuator/cam_actuator_core.c b/drivers/cam_sensor_module/cam_actuator/cam_actuator_core.c index e933accfd4..2b41407414 100644 --- a/drivers/cam_sensor_module/cam_actuator/cam_actuator_core.c +++ b/drivers/cam_sensor_module/cam_actuator/cam_actuator_core.c @@ -1,7 +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. + * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved. */ #include @@ -417,7 +417,8 @@ int32_t cam_actuator_publish_dev_info(struct cam_req_mgr_device_info *info) info->dev_id = CAM_REQ_MGR_DEVICE_ACTUATOR; strlcpy(info->name, CAM_ACTUATOR_NAME, sizeof(info->name)); - info->p_delay = 1; + info->p_delay = CAM_PIPELINE_DELAY_1; + info->m_delay = CAM_MODESWITCH_DELAY_1; info->trigger = CAM_TRIGGER_POINT_SOF; return 0; diff --git a/drivers/cam_sensor_module/cam_flash/cam_flash_core.c b/drivers/cam_sensor_module/cam_flash/cam_flash_core.c index 833e19d853..50b8714f32 100644 --- a/drivers/cam_sensor_module/cam_flash/cam_flash_core.c +++ b/drivers/cam_sensor_module/cam_flash/cam_flash_core.c @@ -1,7 +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. + * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved. */ #include @@ -1791,7 +1791,8 @@ int cam_flash_publish_dev_info(struct cam_req_mgr_device_info *info) { info->dev_id = CAM_REQ_MGR_DEVICE_FLASH; strlcpy(info->name, CAM_FLASH_NAME, sizeof(info->name)); - info->p_delay = CAM_FLASH_PIPELINE_DELAY; + info->p_delay = CAM_PIPELINE_DELAY_1; + info->m_delay = CAM_MODESWITCH_DELAY_1; info->trigger = CAM_TRIGGER_POINT_SOF; return 0; } diff --git a/drivers/cam_sensor_module/cam_sensor/cam_sensor_core.c b/drivers/cam_sensor_module/cam_sensor/cam_sensor_core.c index 70532c4351..3f7fa77ed8 100644 --- a/drivers/cam_sensor_module/cam_sensor/cam_sensor_core.c +++ b/drivers/cam_sensor_module/cam_sensor/cam_sensor_core.c @@ -1,7 +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. + * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved. */ #include @@ -14,6 +14,9 @@ #include "cam_packet_util.h" #include "cam_req_mgr_dev.h" +#define CAM_SENSOR_PIPELINE_DELAY_MASK 0xFF +#define CAM_SENSOR_MODESWITCH_DELAY_SHIFT 8 + extern struct completion *cam_sensor_get_i3c_completion(uint32_t index); static int cam_sensor_notify_v4l2_error_event( @@ -661,6 +664,7 @@ int32_t cam_sensor_update_slave_info(void *probe_info, sensor_probe_info->data_mask; s_ctrl->pipeline_delay = sensor_probe_info->reserved; + s_ctrl->modeswitch_delay = 0; s_ctrl->sensor_probe_addr_type = sensor_probe_info->addr_type; s_ctrl->sensor_probe_data_type = sensor_probe_info->data_type; @@ -673,8 +677,10 @@ int32_t cam_sensor_update_slave_info(void *probe_info, s_ctrl->sensordata->slave_info.sensor_id_mask = sensor_probe_info_v2->data_mask; s_ctrl->pipeline_delay = - sensor_probe_info_v2->pipeline_delay; - + (sensor_probe_info_v2->pipeline_delay & + CAM_SENSOR_PIPELINE_DELAY_MASK); + s_ctrl->modeswitch_delay = (sensor_probe_info_v2->pipeline_delay >> + CAM_SENSOR_MODESWITCH_DELAY_SHIFT); s_ctrl->sensor_probe_addr_type = sensor_probe_info_v2->addr_type; s_ctrl->sensor_probe_data_type = @@ -1552,10 +1558,13 @@ int cam_sensor_publish_dev_info(struct cam_req_mgr_device_info *info) info->dev_id = CAM_REQ_MGR_DEVICE_SENSOR; strlcpy(info->name, CAM_SENSOR_NAME, sizeof(info->name)); - if (s_ctrl->pipeline_delay >= 1 && s_ctrl->pipeline_delay <= 3) + if (s_ctrl->pipeline_delay >= 1 && s_ctrl->pipeline_delay <= 3) { info->p_delay = s_ctrl->pipeline_delay; - else - info->p_delay = 2; + info->m_delay = s_ctrl->modeswitch_delay; + } else { + info->p_delay = CAM_PIPELINE_DELAY_2; + info->m_delay = CAM_MODESWITCH_DELAY_2; + } info->trigger = CAM_TRIGGER_POINT_SOF; return rc; diff --git a/drivers/cam_sensor_module/cam_sensor/cam_sensor_dev.h b/drivers/cam_sensor_module/cam_sensor/cam_sensor_dev.h index bddc91a37b..47469479c8 100644 --- a/drivers/cam_sensor_module/cam_sensor/cam_sensor_dev.h +++ b/drivers/cam_sensor_module/cam_sensor/cam_sensor_dev.h @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2017-2019, 2021 The Linux Foundation. All rights reserved. - * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved. */ #ifndef _CAM_SENSOR_DEV_H_ @@ -106,6 +106,7 @@ struct cam_sensor_dev_res_info { * @bob_pwm_switch: Boolean flag to switch into PWM mode for BoB regulator * @last_flush_req: Last request to flush * @pipeline_delay: Sensor pipeline delay + * @modeswitch_delay: Mode switch delay * @sensor_name: Sensor name * @aon_camera_id: AON Camera ID associated with this sensor * @last_applied_req: Last updated request id @@ -141,6 +142,7 @@ struct cam_sensor_ctrl_t { bool bob_pwm_switch; uint32_t last_flush_req; uint16_t pipeline_delay; + uint16_t modeswitch_delay; char sensor_name[CAM_SENSOR_NAME_MAX_SIZE]; uint8_t aon_camera_id; int64_t last_updated_req;