msm: camera: reqmgr: Add notify frame skip interface
This change adds support to notify frame skip when CRM not ready to apply a normal setting. Sensor and custom device also want to update the HW settings in some conditions even if a frame is skipped. CRs-Fixed: 2691642 Change-Id: Ibd2b22655d0f6b6c90663df75a0f5fad8565e918 Signed-off-by: Depeng Shao <depengs@codeaurora.org>
这个提交包含在:
@@ -21,6 +21,8 @@ static struct cam_req_mgr_core_link g_links[MAXIMUM_LINKS_PER_SESSION];
|
||||
|
||||
void cam_req_mgr_core_link_reset(struct cam_req_mgr_core_link *link)
|
||||
{
|
||||
uint32_t pd = 0;
|
||||
|
||||
link->link_hdl = 0;
|
||||
link->num_devs = 0;
|
||||
link->max_delay = CAM_PIPELINE_DELAY_0;
|
||||
@@ -49,9 +51,13 @@ void cam_req_mgr_core_link_reset(struct cam_req_mgr_core_link *link)
|
||||
link->initial_skip = true;
|
||||
link->sof_timestamp = 0;
|
||||
link->prev_sof_timestamp = 0;
|
||||
link->enable_apply_default = false;
|
||||
link->skip_init_frame = false;
|
||||
atomic_set(&link->eof_event_cnt, 0);
|
||||
|
||||
for (pd = 0; pd < CAM_PIPELINE_DELAY_MAX; pd++) {
|
||||
link->req.apply_data[pd].req_id = -1;
|
||||
link->req.prev_apply_data[pd].req_id = -1;
|
||||
}
|
||||
}
|
||||
|
||||
void cam_req_mgr_handle_core_shutdown(void)
|
||||
@@ -212,32 +218,77 @@ static void __cam_req_mgr_find_dev_name(
|
||||
}
|
||||
|
||||
/**
|
||||
* __cam_req_mgr_apply_default()
|
||||
* __cam_req_mgr_notify_frame_skip()
|
||||
*
|
||||
* @brief : Apply default settings to all devices
|
||||
* @brief : Notify all devices of frame skipping
|
||||
* @link : link on which we are applying these settings
|
||||
*
|
||||
*/
|
||||
static void __cam_req_mgr_apply_default(
|
||||
struct cam_req_mgr_core_link *link)
|
||||
static int __cam_req_mgr_notify_frame_skip(
|
||||
struct cam_req_mgr_core_link *link,
|
||||
uint32_t trigger)
|
||||
{
|
||||
int i;
|
||||
struct cam_req_mgr_apply_request apply_req;
|
||||
int rc = 0, i, pd, idx;
|
||||
struct cam_req_mgr_apply_request frame_skip;
|
||||
struct cam_req_mgr_apply *apply_data = NULL;
|
||||
struct cam_req_mgr_connected_device *dev = NULL;
|
||||
struct cam_req_mgr_tbl_slot *slot = NULL;
|
||||
|
||||
if (!link->enable_apply_default)
|
||||
return;
|
||||
apply_data = link->req.prev_apply_data;
|
||||
|
||||
for (i = 0; i < link->num_devs; i++) {
|
||||
dev = &link->l_dev[i];
|
||||
apply_req.request_id = 0;
|
||||
apply_req.dev_hdl = dev->dev_hdl;
|
||||
apply_req.link_hdl = link->link_hdl;
|
||||
apply_req.trigger_point = 0;
|
||||
apply_req.report_if_bubble = 0;
|
||||
if (dev->ops && dev->ops->apply_default)
|
||||
dev->ops->apply_default(&apply_req);
|
||||
if (!dev)
|
||||
continue;
|
||||
|
||||
pd = dev->dev_info.p_delay;
|
||||
if (pd >= CAM_PIPELINE_DELAY_MAX) {
|
||||
CAM_WARN(CAM_CRM, "pd %d greater than max",
|
||||
pd);
|
||||
continue;
|
||||
}
|
||||
|
||||
idx = apply_data[pd].idx;
|
||||
slot = &dev->pd_tbl->slot[idx];
|
||||
|
||||
if ((slot->ops.dev_hdl == dev->dev_hdl) &&
|
||||
(slot->ops.is_applied)) {
|
||||
slot->ops.is_applied = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* If apply_at_eof is enabled do not apply at SOF
|
||||
* e.x. Flash device
|
||||
*/
|
||||
if ((trigger == CAM_TRIGGER_POINT_SOF) &&
|
||||
(dev->dev_hdl == slot->ops.dev_hdl) &&
|
||||
(slot->ops.apply_at_eof))
|
||||
continue;
|
||||
|
||||
/*
|
||||
* If apply_at_eof is not enabled ignore EOF
|
||||
*/
|
||||
if ((trigger == CAM_TRIGGER_POINT_EOF) &&
|
||||
(dev->dev_hdl == slot->ops.dev_hdl) &&
|
||||
(!slot->ops.apply_at_eof))
|
||||
continue;
|
||||
|
||||
frame_skip.dev_hdl = dev->dev_hdl;
|
||||
frame_skip.link_hdl = link->link_hdl;
|
||||
frame_skip.request_id =
|
||||
apply_data[pd].req_id;
|
||||
frame_skip.trigger_point = trigger;
|
||||
frame_skip.report_if_bubble = 0;
|
||||
|
||||
CAM_DBG(CAM_REQ,
|
||||
"Notify_frame_skip: pd %d req_id %lld",
|
||||
link->link_hdl, pd, apply_data[pd].req_id);
|
||||
if ((dev->ops) && (dev->ops->notify_frame_skip))
|
||||
dev->ops->notify_frame_skip(&frame_skip);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -716,6 +767,7 @@ static int __cam_req_mgr_send_req(struct cam_req_mgr_core_link *link,
|
||||
struct cam_req_mgr_apply_request apply_req;
|
||||
struct cam_req_mgr_link_evt_data evt_data;
|
||||
struct cam_req_mgr_tbl_slot *slot = NULL;
|
||||
struct cam_req_mgr_apply *apply_data = NULL;
|
||||
|
||||
apply_req.link_hdl = link->link_hdl;
|
||||
apply_req.report_if_bubble = 0;
|
||||
@@ -725,6 +777,8 @@ static int __cam_req_mgr_send_req(struct cam_req_mgr_core_link *link,
|
||||
apply_req.re_apply = true;
|
||||
}
|
||||
|
||||
apply_data = link->req.apply_data;
|
||||
|
||||
/*
|
||||
* This For loop is to address the special operation requested
|
||||
* by device
|
||||
@@ -740,7 +794,7 @@ static int __cam_req_mgr_send_req(struct cam_req_mgr_core_link *link,
|
||||
continue;
|
||||
}
|
||||
|
||||
idx = link->req.apply_data[pd].idx;
|
||||
idx = apply_data[pd].idx;
|
||||
slot = &dev->pd_tbl->slot[idx];
|
||||
|
||||
if (slot->ops.dev_hdl < 0) {
|
||||
@@ -772,20 +826,21 @@ static int __cam_req_mgr_send_req(struct cam_req_mgr_core_link *link,
|
||||
if ((trigger == CAM_TRIGGER_POINT_EOF) &&
|
||||
(!slot->ops.apply_at_eof)) {
|
||||
CAM_DBG(CAM_CRM, "NO EOF DATA FOR REQ: %llu",
|
||||
link->req.apply_data[pd].req_id);
|
||||
apply_data[pd].req_id);
|
||||
break;
|
||||
}
|
||||
|
||||
apply_req.dev_hdl = dev->dev_hdl;
|
||||
apply_req.request_id =
|
||||
link->req.apply_data[pd].req_id;
|
||||
apply_data[pd].req_id;
|
||||
apply_req.trigger_point = trigger;
|
||||
if ((dev->ops) && (dev->ops->apply_req) &&
|
||||
(!slot->ops.is_applied)) {
|
||||
rc = dev->ops->apply_req(&apply_req);
|
||||
if (rc) {
|
||||
*failed_dev = dev;
|
||||
__cam_req_mgr_apply_default(link);
|
||||
__cam_req_mgr_notify_frame_skip(link,
|
||||
trigger);
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
@@ -801,7 +856,8 @@ static int __cam_req_mgr_send_req(struct cam_req_mgr_core_link *link,
|
||||
CAM_DBG(CAM_REQ,
|
||||
"SEND: link_hdl: %x pd: %d req_id %lld",
|
||||
link->link_hdl, pd, apply_req.request_id);
|
||||
__cam_req_mgr_apply_default(link);
|
||||
__cam_req_mgr_notify_frame_skip(link,
|
||||
trigger);
|
||||
return -EAGAIN;
|
||||
} else if ((trigger == CAM_TRIGGER_POINT_EOF) &&
|
||||
(slot->ops.apply_at_eof)) {
|
||||
@@ -810,7 +866,7 @@ static int __cam_req_mgr_send_req(struct cam_req_mgr_core_link *link,
|
||||
atomic_dec(&link->eof_event_cnt);
|
||||
CAM_DBG(CAM_REQ,
|
||||
"Req_id: %llu eof_event_cnt : %d",
|
||||
link->req.apply_data[pd].req_id,
|
||||
apply_data[pd].req_id,
|
||||
link->eof_event_cnt);
|
||||
return 0;
|
||||
}
|
||||
@@ -830,27 +886,27 @@ static int __cam_req_mgr_send_req(struct cam_req_mgr_core_link *link,
|
||||
if (!(dev->dev_info.trigger & trigger))
|
||||
continue;
|
||||
|
||||
if (link->req.apply_data[pd].skip_idx ||
|
||||
(link->req.apply_data[pd].req_id < 0)) {
|
||||
if (apply_data[pd].skip_idx ||
|
||||
(apply_data[pd].req_id < 0)) {
|
||||
CAM_DBG(CAM_CRM,
|
||||
"dev %s skip %d req_id %lld",
|
||||
dev->dev_info.name,
|
||||
link->req.apply_data[pd].skip_idx,
|
||||
link->req.apply_data[pd].req_id);
|
||||
apply_data[pd].skip_idx,
|
||||
apply_data[pd].req_id);
|
||||
apply_req.dev_hdl = dev->dev_hdl;
|
||||
apply_req.request_id = 0;
|
||||
apply_req.request_id =
|
||||
link->req.prev_apply_data[pd].req_id;
|
||||
apply_req.trigger_point = 0;
|
||||
apply_req.report_if_bubble = 0;
|
||||
if ((link->enable_apply_default) &&
|
||||
(dev->ops) && (dev->ops->apply_default))
|
||||
dev->ops->apply_default(&apply_req);
|
||||
if ((dev->ops) && (dev->ops->notify_frame_skip))
|
||||
dev->ops->notify_frame_skip(&apply_req);
|
||||
continue;
|
||||
}
|
||||
|
||||
apply_req.dev_hdl = dev->dev_hdl;
|
||||
apply_req.request_id =
|
||||
link->req.apply_data[pd].req_id;
|
||||
idx = link->req.apply_data[pd].idx;
|
||||
apply_data[pd].req_id;
|
||||
idx = apply_data[pd].idx;
|
||||
slot = &dev->pd_tbl->slot[idx];
|
||||
apply_req.report_if_bubble =
|
||||
in_q->slot[idx].recover;
|
||||
@@ -880,7 +936,7 @@ static int __cam_req_mgr_send_req(struct cam_req_mgr_core_link *link,
|
||||
|
||||
apply_req.trigger_point = trigger;
|
||||
CAM_DBG(CAM_REQ,
|
||||
"SEND: link_hdl: %x pd %d req_id %lld",
|
||||
"SEND: %d link_hdl: %x pd %d req_id %lld",
|
||||
link->link_hdl, pd, apply_req.request_id);
|
||||
if (dev->ops && dev->ops->apply_req) {
|
||||
rc = dev->ops->apply_req(&apply_req);
|
||||
@@ -906,8 +962,13 @@ static int __cam_req_mgr_send_req(struct cam_req_mgr_core_link *link,
|
||||
if (dev->ops && dev->ops->process_evt)
|
||||
dev->ops->process_evt(&evt_data);
|
||||
}
|
||||
__cam_req_mgr_apply_default(link);
|
||||
__cam_req_mgr_notify_frame_skip(link, trigger);
|
||||
} else {
|
||||
memcpy(link->req.prev_apply_data, link->req.apply_data,
|
||||
CAM_PIPELINE_DELAY_MAX *
|
||||
sizeof(struct cam_req_mgr_apply));
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -1598,7 +1659,7 @@ static int __cam_req_mgr_process_req(struct cam_req_mgr_core_link *link,
|
||||
rc = -EPERM;
|
||||
}
|
||||
spin_unlock_bh(&link->link_state_spin_lock);
|
||||
__cam_req_mgr_apply_default(link);
|
||||
__cam_req_mgr_notify_frame_skip(link, trigger);
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
@@ -2197,38 +2258,6 @@ static void __cam_req_mgr_unreserve_link(
|
||||
|
||||
/* Workqueue context processing section */
|
||||
|
||||
/**
|
||||
* cam_req_mgr_process_send_req()
|
||||
*
|
||||
* @brief: This runs in workque thread context. Call core funcs to send
|
||||
* apply request id to drivers.
|
||||
* @priv : link information.
|
||||
* @data : contains information about frame_id, link etc.
|
||||
*
|
||||
* @return: 0 on success.
|
||||
*/
|
||||
int cam_req_mgr_process_send_req(void *priv, void *data)
|
||||
{
|
||||
int rc = 0;
|
||||
struct cam_req_mgr_core_link *link = NULL;
|
||||
struct cam_req_mgr_send_request *send_req = NULL;
|
||||
struct cam_req_mgr_req_queue *in_q = NULL;
|
||||
struct cam_req_mgr_connected_device *dev;
|
||||
|
||||
if (!data || !priv) {
|
||||
CAM_ERR(CAM_CRM, "input args NULL %pK %pK", data, priv);
|
||||
rc = -EINVAL;
|
||||
goto end;
|
||||
}
|
||||
link = (struct cam_req_mgr_core_link *)priv;
|
||||
send_req = (struct cam_req_mgr_send_request *)data;
|
||||
in_q = send_req->in_q;
|
||||
|
||||
rc = __cam_req_mgr_send_req(link, in_q, CAM_TRIGGER_POINT_SOF, &dev);
|
||||
end:
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* cam_req_mgr_process_flush_req()
|
||||
*
|
||||
@@ -2242,6 +2271,7 @@ end:
|
||||
int cam_req_mgr_process_flush_req(void *priv, void *data)
|
||||
{
|
||||
int rc = 0, i = 0, idx = -1;
|
||||
uint32_t pd = 0;
|
||||
struct cam_req_mgr_flush_info *flush_info = NULL;
|
||||
struct cam_req_mgr_core_link *link = NULL;
|
||||
struct cam_req_mgr_req_queue *in_q = NULL;
|
||||
@@ -2306,6 +2336,12 @@ int cam_req_mgr_process_flush_req(void *priv, void *data)
|
||||
if (device->ops && device->ops->flush_req)
|
||||
rc = device->ops->flush_req(&flush_req);
|
||||
}
|
||||
|
||||
for (pd = 0; pd < CAM_PIPELINE_DELAY_MAX; pd++) {
|
||||
link->req.apply_data[pd].req_id = -1;
|
||||
link->req.prev_apply_data[pd].req_id = -1;
|
||||
}
|
||||
|
||||
complete(&link->workq_comp);
|
||||
mutex_unlock(&link->req.lock);
|
||||
|
||||
@@ -3297,9 +3333,6 @@ 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.enable_apply_default)
|
||||
link->enable_apply_default = true;
|
||||
|
||||
subscribe_event |= (uint32_t)dev->dev_info.trigger;
|
||||
}
|
||||
|
||||
|
@@ -281,17 +281,20 @@ struct cam_req_mgr_req_queue {
|
||||
|
||||
/**
|
||||
* struct cam_req_mgr_req_data
|
||||
* @in_q : Poiner to Input request queue
|
||||
* @l_tbl : unique pd request tables.
|
||||
* @num_tbl : how many unique pd value devices are present
|
||||
* @apply_data : Holds information about request id for a request
|
||||
* @lock : mutex lock protecting request data ops.
|
||||
* @in_q : Poiner to Input request queue
|
||||
* @l_tbl : unique pd request tables.
|
||||
* @num_tbl : how many unique pd value devices are present
|
||||
* @apply_data : Holds information about request id for a request
|
||||
* @prev_apply_data : Holds information about request id for a previous
|
||||
* applied request
|
||||
* @lock : mutex lock protecting request data ops.
|
||||
*/
|
||||
struct cam_req_mgr_req_data {
|
||||
struct cam_req_mgr_req_queue *in_q;
|
||||
struct cam_req_mgr_req_tbl *l_tbl;
|
||||
int32_t num_tbl;
|
||||
struct cam_req_mgr_apply apply_data[CAM_PIPELINE_DELAY_MAX];
|
||||
struct cam_req_mgr_apply prev_apply_data[CAM_PIPELINE_DELAY_MAX];
|
||||
struct mutex lock;
|
||||
};
|
||||
|
||||
@@ -365,10 +368,6 @@ struct cam_req_mgr_connected_device {
|
||||
* applying the settings
|
||||
* @trigger_cnt : trigger count value per device initiating the trigger
|
||||
* @eof_event_cnt : Atomic variable to track the number of EOF requests
|
||||
* @enable_apply_default : Link will apply a default settings to devices on
|
||||
* frames where actual settings are not available.
|
||||
* This will account for all devices irrespective of
|
||||
* pipeline delay
|
||||
* @skip_init_frame : skip initial frames crm_wd_timer validation in the
|
||||
* case of long exposure use case
|
||||
*/
|
||||
@@ -404,7 +403,6 @@ struct cam_req_mgr_core_link {
|
||||
bool dual_trigger;
|
||||
uint32_t trigger_cnt[CAM_REQ_MGR_MAX_TRIGGERS];
|
||||
atomic_t eof_event_cnt;
|
||||
bool enable_apply_default;
|
||||
bool skip_init_frame;
|
||||
};
|
||||
|
||||
|
@@ -44,17 +44,20 @@ typedef int (*cam_req_mgr_notify_stop)(struct cam_req_mgr_notify_stop *);
|
||||
/**
|
||||
* @brief: cam req mgr to camera device drivers
|
||||
*
|
||||
* @cam_req_mgr_get_dev_info: to fetch details about device linked
|
||||
* @cam_req_mgr_link_setup : to establish link with device for a session
|
||||
* @cam_req_mgr_apply_req : CRM asks device to apply certain request id
|
||||
* @cam_req_mgr_flush_req : Flush or cancel request
|
||||
* cam_req_mgr_process_evt : generic events
|
||||
* @cam_req_mgr_dump_req : dump request
|
||||
* @cam_req_mgr_get_dev_info : to fetch details about device linked
|
||||
* @cam_req_mgr_link_setup : to establish link with device for a session
|
||||
* @cam_req_mgr_apply_req : CRM asks device to apply certain request id
|
||||
* @cam_req_mgr_notify_frame_skip: CRM asks device to apply setting for
|
||||
* frame skip
|
||||
* @cam_req_mgr_flush_req : Flush or cancel request
|
||||
* cam_req_mgr_process_evt : generic events
|
||||
* @cam_req_mgr_dump_req : dump request
|
||||
*/
|
||||
typedef int (*cam_req_mgr_get_dev_info) (struct cam_req_mgr_device_info *);
|
||||
typedef int (*cam_req_mgr_link_setup)(struct cam_req_mgr_core_dev_link_setup *);
|
||||
typedef int (*cam_req_mgr_apply_req)(struct cam_req_mgr_apply_request *);
|
||||
typedef int (*cam_req_mgr_apply_default)(struct cam_req_mgr_apply_request *);
|
||||
typedef int (*cam_req_mgr_notify_frame_skip)(
|
||||
struct cam_req_mgr_apply_request *);
|
||||
typedef int (*cam_req_mgr_flush_req)(struct cam_req_mgr_flush_request *);
|
||||
typedef int (*cam_req_mgr_process_evt)(struct cam_req_mgr_link_evt_data *);
|
||||
typedef int (*cam_req_mgr_dump_req)(struct cam_req_mgr_dump_info *);
|
||||
@@ -79,22 +82,22 @@ struct cam_req_mgr_crm_cb {
|
||||
/**
|
||||
* @brief : cam_req_mgr_kmd_ops - func table
|
||||
*
|
||||
* @get_dev_info : payload to fetch device details
|
||||
* @link_setup : payload to establish link with device
|
||||
* @apply_req : payload to apply request id on a device linked
|
||||
* @apply_default: payload to trigger default apply settings
|
||||
* @flush_req : payload to flush request
|
||||
* @process_evt : payload to generic event
|
||||
* @dump_req : payload to dump request
|
||||
* @get_dev_info : payload to fetch device details
|
||||
* @link_setup : payload to establish link with device
|
||||
* @apply_req : payload to apply request id on a device linked
|
||||
* @notify_frame_skip: payload to notify frame skip
|
||||
* @flush_req : payload to flush request
|
||||
* @process_evt : payload to generic event
|
||||
* @dump_req : payload to dump request
|
||||
*/
|
||||
struct cam_req_mgr_kmd_ops {
|
||||
cam_req_mgr_get_dev_info get_dev_info;
|
||||
cam_req_mgr_link_setup link_setup;
|
||||
cam_req_mgr_apply_req apply_req;
|
||||
cam_req_mgr_apply_default apply_default;
|
||||
cam_req_mgr_flush_req flush_req;
|
||||
cam_req_mgr_process_evt process_evt;
|
||||
cam_req_mgr_dump_req dump_req;
|
||||
cam_req_mgr_get_dev_info get_dev_info;
|
||||
cam_req_mgr_link_setup link_setup;
|
||||
cam_req_mgr_apply_req apply_req;
|
||||
cam_req_mgr_notify_frame_skip notify_frame_skip;
|
||||
cam_req_mgr_flush_req flush_req;
|
||||
cam_req_mgr_process_evt process_evt;
|
||||
cam_req_mgr_dump_req dump_req;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -296,9 +299,6 @@ struct cam_req_mgr_notify_stop {
|
||||
* @p_delay : delay between time settings applied and take effect
|
||||
* @trigger : Trigger point for the client
|
||||
* @trigger_on : This device provides trigger
|
||||
* @enable_apply_default : Device requests CRM to apply default
|
||||
* settings for devices on a link if actual
|
||||
* settings for a given frame is not available
|
||||
*/
|
||||
struct cam_req_mgr_device_info {
|
||||
int32_t dev_hdl;
|
||||
@@ -307,7 +307,6 @@ struct cam_req_mgr_device_info {
|
||||
enum cam_pipeline_delay p_delay;
|
||||
uint32_t trigger;
|
||||
bool trigger_on;
|
||||
bool enable_apply_default;
|
||||
};
|
||||
|
||||
/**
|
||||
|
在新工单中引用
屏蔽一个用户