msm: camera: reqmgr: Add support for dual trigger
Currently CRM waits for a single trigger to apply settings for all the devices on a given link. This change provides provision for CRM to wait on two triggers prior to applying a given setting. CRs-Fixed: 2627065 Change-Id: If6e4c9281cfd1bf1a8ffa369daee060d79f3c39e Signed-off-by: Karthik Anantha Ram <kartanan@codeaurora.org>
Dieser Commit ist enthalten in:
@@ -1313,6 +1313,7 @@ static int __cam_isp_ctx_notify_sof_in_activated_state(
|
||||
notify.trigger = CAM_TRIGGER_POINT_SOF;
|
||||
notify.req_id = ctx_isp->req_info.last_bufdone_req_id;
|
||||
notify.sof_timestamp_val = ctx_isp->sof_timestamp_val;
|
||||
notify.trigger_id = ctx_isp->trigger_id;
|
||||
|
||||
ctx->ctx_crm_intf->notify_trigger(¬ify);
|
||||
CAM_DBG(CAM_ISP, "Notify CRM SOF frame %lld ctx %u",
|
||||
@@ -4517,6 +4518,7 @@ static int __cam_isp_ctx_link_in_acquired(struct cam_context *ctx,
|
||||
ctx->link_hdl = link->link_hdl;
|
||||
ctx->ctx_crm_intf = link->crm_cb;
|
||||
ctx_isp->subscribe_event = link->subscribe_event;
|
||||
ctx_isp->trigger_id = link->trigger_id;
|
||||
|
||||
/* change state only if we had the init config */
|
||||
if (ctx_isp->init_received) {
|
||||
@@ -4533,9 +4535,12 @@ static int __cam_isp_ctx_unlink_in_acquired(struct cam_context *ctx,
|
||||
struct cam_req_mgr_core_dev_link_setup *unlink)
|
||||
{
|
||||
int rc = 0;
|
||||
struct cam_isp_context *ctx_isp =
|
||||
(struct cam_isp_context *) ctx->ctx_priv;
|
||||
|
||||
ctx->link_hdl = -1;
|
||||
ctx->ctx_crm_intf = NULL;
|
||||
ctx_isp->trigger_id = -1;
|
||||
|
||||
return rc;
|
||||
}
|
||||
@@ -4550,6 +4555,7 @@ static int __cam_isp_ctx_get_dev_info_in_acquired(struct cam_context *ctx,
|
||||
dev_info->dev_id = CAM_REQ_MGR_DEVICE_IFE;
|
||||
dev_info->p_delay = 1;
|
||||
dev_info->trigger = CAM_TRIGGER_POINT_SOF;
|
||||
dev_info->trigger_on = true;
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
@@ -258,6 +258,7 @@ struct cam_isp_context_event_record {
|
||||
* @rxd_epoch: Indicate whether epoch has been received. Used to
|
||||
* decide whether to apply request in offline ctx
|
||||
* @workq: Worker thread for offline ife
|
||||
* @trigger_id: ID provided by CRM for each ctx on the link
|
||||
*
|
||||
*/
|
||||
struct cam_isp_context {
|
||||
@@ -300,6 +301,7 @@ struct cam_isp_context {
|
||||
uint32_t isp_device_type;
|
||||
atomic_t rxd_epoch;
|
||||
struct cam_req_mgr_core_workq *workq;
|
||||
int32_t trigger_id;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@@ -40,6 +40,9 @@ void cam_req_mgr_core_link_reset(struct cam_req_mgr_core_link *link)
|
||||
link->open_req_cnt = 0;
|
||||
link->last_flush_id = 0;
|
||||
link->initial_sync_req = -1;
|
||||
link->dual_trigger = false;
|
||||
link->trigger_cnt[0] = 0;
|
||||
link->trigger_cnt[1] = 0;
|
||||
link->in_msync_mode = false;
|
||||
link->retry_cnt = 0;
|
||||
link->is_shutdown = false;
|
||||
@@ -2760,6 +2763,33 @@ end:
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int __cam_req_mgr_check_for_dual_trigger(
|
||||
struct cam_req_mgr_core_link *link)
|
||||
{
|
||||
int rc = -EAGAIN;
|
||||
|
||||
if (link->trigger_cnt[0] == link->trigger_cnt[1]) {
|
||||
link->trigger_cnt[0] = 0;
|
||||
link->trigger_cnt[1] = 0;
|
||||
rc = 0;
|
||||
return rc;
|
||||
}
|
||||
|
||||
if ((link->trigger_cnt[0] &&
|
||||
(link->trigger_cnt[0] - link->trigger_cnt[1] > 1)) ||
|
||||
(link->trigger_cnt[1] &&
|
||||
(link->trigger_cnt[1] - link->trigger_cnt[0] > 1))) {
|
||||
|
||||
CAM_ERR(CAM_CRM,
|
||||
"One of the devices could not generate trigger");
|
||||
return rc;
|
||||
}
|
||||
|
||||
CAM_DBG(CAM_CRM, "Only one device has generated trigger");
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* cam_req_mgr_cb_notify_timer()
|
||||
*
|
||||
@@ -2878,7 +2908,7 @@ end:
|
||||
static int cam_req_mgr_cb_notify_trigger(
|
||||
struct cam_req_mgr_trigger_notify *trigger_data)
|
||||
{
|
||||
int rc = 0;
|
||||
int32_t rc = 0, trigger_id = 0;
|
||||
struct crm_workq_task *task = NULL;
|
||||
struct cam_req_mgr_core_link *link = NULL;
|
||||
struct cam_req_mgr_trigger_notify *notify_trigger;
|
||||
@@ -2898,6 +2928,8 @@ static int cam_req_mgr_cb_notify_trigger(
|
||||
goto end;
|
||||
}
|
||||
|
||||
trigger_id = trigger_data->trigger_id;
|
||||
|
||||
spin_lock_bh(&link->link_state_spin_lock);
|
||||
if (link->state < CAM_CRM_LINK_STATE_READY) {
|
||||
CAM_WARN(CAM_CRM, "invalid link state:%d", link->state);
|
||||
@@ -2909,6 +2941,23 @@ static int cam_req_mgr_cb_notify_trigger(
|
||||
if ((link->watchdog) && (link->watchdog->pause_timer))
|
||||
link->watchdog->pause_timer = false;
|
||||
|
||||
if (link->dual_trigger) {
|
||||
if ((trigger_id >= 0) && (trigger_id <
|
||||
CAM_REQ_MGR_MAX_TRIGGERS)) {
|
||||
link->trigger_cnt[trigger_id]++;
|
||||
rc = __cam_req_mgr_check_for_dual_trigger(link);
|
||||
if (rc) {
|
||||
spin_unlock_bh(&link->link_state_spin_lock);
|
||||
goto end;
|
||||
}
|
||||
} else {
|
||||
CAM_ERR(CAM_CRM, "trigger_id invalid %d", trigger_id);
|
||||
rc = -EINVAL;
|
||||
spin_unlock_bh(&link->link_state_spin_lock);
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
crm_timer_reset(link->watchdog);
|
||||
spin_unlock_bh(&link->link_state_spin_lock);
|
||||
|
||||
@@ -2963,16 +3012,18 @@ static int __cam_req_mgr_setup_link_info(struct cam_req_mgr_core_link *link,
|
||||
struct cam_req_mgr_req_tbl *pd_tbl;
|
||||
enum cam_pipeline_delay max_delay;
|
||||
uint32_t subscribe_event = 0;
|
||||
uint32_t num_trigger_devices = 0;
|
||||
if (link_info->version == VERSION_1) {
|
||||
if (link_info->u.link_info_v1.num_devices >
|
||||
CAM_REQ_MGR_MAX_HANDLES)
|
||||
return -EPERM;
|
||||
}
|
||||
}
|
||||
else if (link_info->version == VERSION_2) {
|
||||
if (link_info->u.link_info_v2.num_devices >
|
||||
CAM_REQ_MGR_MAX_HANDLES_V2)
|
||||
return -EPERM;
|
||||
}
|
||||
}
|
||||
|
||||
mutex_init(&link->req.lock);
|
||||
CAM_DBG(CAM_CRM, "LOCK_DBG in_q lock %pK", &link->req.lock);
|
||||
link->req.num_tbl = 0;
|
||||
@@ -3052,6 +3103,17 @@ static int __cam_req_mgr_setup_link_info(struct cam_req_mgr_core_link *link,
|
||||
|
||||
subscribe_event |= (uint32_t)dev->dev_info.trigger;
|
||||
}
|
||||
|
||||
if (dev->dev_info.trigger_on)
|
||||
num_trigger_devices++;
|
||||
}
|
||||
|
||||
if (num_trigger_devices > CAM_REQ_MGR_MAX_TRIGGERS) {
|
||||
CAM_ERR(CAM_CRM,
|
||||
"Unsupported number of trigger devices %u",
|
||||
num_trigger_devices);
|
||||
rc = -EINVAL;
|
||||
goto error;
|
||||
}
|
||||
|
||||
link->subscribe_event = subscribe_event;
|
||||
@@ -3060,7 +3122,10 @@ static int __cam_req_mgr_setup_link_info(struct cam_req_mgr_core_link *link,
|
||||
link_data.crm_cb = &cam_req_mgr_ops;
|
||||
link_data.max_delay = max_delay;
|
||||
link_data.subscribe_event = subscribe_event;
|
||||
if (num_trigger_devices == CAM_REQ_MGR_MAX_TRIGGERS)
|
||||
link->dual_trigger = true;
|
||||
|
||||
num_trigger_devices = 0;
|
||||
for (i = 0; i < num_devices; i++) {
|
||||
dev = &link->l_dev[i];
|
||||
|
||||
@@ -3100,6 +3165,12 @@ static int __cam_req_mgr_setup_link_info(struct cam_req_mgr_core_link *link,
|
||||
CAM_DBG(CAM_CRM, "dev_bit %u name %s pd %u mask %d",
|
||||
dev->dev_bit, dev->dev_info.name, pd_tbl->pd,
|
||||
pd_tbl->dev_mask);
|
||||
link_data.trigger_id = -1;
|
||||
if ((dev->dev_info.trigger_on) && (link->dual_trigger)) {
|
||||
link_data.trigger_id = num_trigger_devices;
|
||||
num_trigger_devices++;
|
||||
}
|
||||
|
||||
/* Communicate with dev to establish the link */
|
||||
dev->ops->link_setup(&link_data);
|
||||
|
||||
|
@@ -37,6 +37,7 @@
|
||||
|
||||
#define VERSION_1 1
|
||||
#define VERSION_2 2
|
||||
#define CAM_REQ_MGR_MAX_TRIGGERS 2
|
||||
|
||||
/**
|
||||
* enum crm_workq_task_type
|
||||
@@ -344,6 +345,9 @@ struct cam_req_mgr_connected_device {
|
||||
* as part of shutdown.
|
||||
* @sof_timestamp_value : SOF timestamp value
|
||||
* @prev_sof_timestamp : Previous SOF timestamp value
|
||||
* @dual_trigger : Links needs to wait for two triggers prior to
|
||||
* applying the settings
|
||||
* @trigger_cnt : trigger count value per device initiating the trigger
|
||||
*/
|
||||
struct cam_req_mgr_core_link {
|
||||
int32_t link_hdl;
|
||||
@@ -374,6 +378,9 @@ struct cam_req_mgr_core_link {
|
||||
bool is_shutdown;
|
||||
uint64_t sof_timestamp;
|
||||
uint64_t prev_sof_timestamp;
|
||||
bool dual_trigger;
|
||||
uint32_t trigger_cnt[CAM_REQ_MGR_MAX_TRIGGERS];
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
|
@@ -210,6 +210,7 @@ enum cam_req_mgr_link_evt_type {
|
||||
* only to the devices which subscribe to this point.
|
||||
* @sof_timestamp_val: Captured time stamp value at sof hw event
|
||||
* @req_id : req id which returned buf_done
|
||||
* @trigger_id: ID to differentiate between the trigger devices
|
||||
*/
|
||||
struct cam_req_mgr_trigger_notify {
|
||||
int32_t link_hdl;
|
||||
@@ -218,6 +219,7 @@ struct cam_req_mgr_trigger_notify {
|
||||
uint32_t trigger;
|
||||
uint64_t sof_timestamp_val;
|
||||
uint64_t req_id;
|
||||
int32_t trigger_id;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -286,6 +288,7 @@ struct cam_req_mgr_notify_stop {
|
||||
* @dev_id : device id info
|
||||
* @p_delay : delay between time settings applied and take effect
|
||||
* @trigger : Trigger point for the client
|
||||
* @trigger_on : This device provides trigger
|
||||
*/
|
||||
struct cam_req_mgr_device_info {
|
||||
int32_t dev_hdl;
|
||||
@@ -293,6 +296,7 @@ struct cam_req_mgr_device_info {
|
||||
enum cam_req_mgr_device_id dev_id;
|
||||
enum cam_pipeline_delay p_delay;
|
||||
uint32_t trigger;
|
||||
bool trigger_on;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -303,6 +307,7 @@ struct cam_req_mgr_device_info {
|
||||
* @max_delay : max pipeline delay on this link
|
||||
* @crm_cb : callback funcs to communicate with req mgr
|
||||
* @subscribe_event : the mask of trigger points this link subscribes
|
||||
* @trigger_id : Unique ID provided to the triggering device
|
||||
*/
|
||||
struct cam_req_mgr_core_dev_link_setup {
|
||||
int32_t link_enable;
|
||||
@@ -311,6 +316,7 @@ struct cam_req_mgr_core_dev_link_setup {
|
||||
enum cam_pipeline_delay max_delay;
|
||||
struct cam_req_mgr_crm_cb *crm_cb;
|
||||
uint32_t subscribe_event;
|
||||
int32_t trigger_id;
|
||||
};
|
||||
|
||||
/**
|
||||
|
In neuem Issue referenzieren
Einen Benutzer sperren