msm: camera: common: Enhance seamless switch support
Mode switch delay is an inherent property of a sensor. Similarly IFE has a static switch delay of 1. For sensors with switch delay > 1 need special handling on certain occasions. It is possible that switch settings was applied to sensor, and on the next frame if there is a flash inject delay or a packet delay, sensor & IFE are bound to go out of sync. To address such cases, IFE will decide if it needs to apply MUP on a dropped frame or not, along with any corresponding IQ settings. CRs-Fixed: 3320774 Change-Id: I355fa0f8b767d44bd3fb87c91b3cbf56fb9c3933 Signed-off-by: Karthik Anantha Ram <quic_kartanan@quicinc.com>
This commit is contained in:

committed by
Camera Software Integration

parent
06142d3894
commit
a5b60b58b2
@@ -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,19 +4758,87 @@ 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_config_args cfg = {0};
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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,
|
||||
@@ -4774,8 +4847,11 @@ static int __cam_isp_ctx_apply_default_req_settings(
|
||||
CAM_ERR(CAM_ISP,
|
||||
"Failed to apply default settings rc %d", rc);
|
||||
else
|
||||
CAM_DBG(CAM_ISP, "Applied default settings rc %d", rc);
|
||||
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,7 +8028,13 @@ 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,
|
||||
|
@@ -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;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@@ -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,8 +12796,18 @@ 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);
|
||||
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,
|
||||
|
@@ -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
|
||||
|
@@ -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 */
|
||||
|
@@ -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;
|
||||
|
@@ -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,6 +360,7 @@ 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;
|
||||
};
|
||||
@@ -349,6 +370,8 @@ struct cam_req_mgr_core_dev_link_setup {
|
||||
* @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
|
||||
@@ -358,7 +381,8 @@ struct cam_req_mgr_core_dev_link_setup {
|
||||
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;
|
||||
|
@@ -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 <linux/module.h>
|
||||
@@ -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;
|
||||
|
@@ -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 <linux/module.h>
|
||||
@@ -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;
|
||||
}
|
||||
|
@@ -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 <linux/module.h>
|
||||
@@ -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;
|
||||
|
@@ -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;
|
||||
|
Reference in New Issue
Block a user