msm: camera: reqmgr: Add support to modify timer for long exposure

In case of long exposure shots, watchdog timer needs to be modified
according to the requested value to avoid trigger. Add support for
modifying timer value and changing it back to normal.

CRs-Fixed: 2530691
Change-Id: I97bdd92d2ed461066bbf746bc6293094a444f8a5
Signed-off-by: Mukund Madhusudan Atre <matre@codeaurora.org>
Signed-off-by: Karthik Anantha Ram <kartanan@codeaurora.org>
This commit is contained in:
Mukund Madhusudan Atre 2019-10-18 16:25:36 -07:00 коммит произвёл Gerrit - the friendly Code Review server
Родитель 17ea11cdec
Коммит a6c3698b1f
2 изменённых файлов: 104 добавлений и 14 удалений

Просмотреть файл

@ -443,6 +443,7 @@ static void __cam_req_mgr_flush_req_slot(
slot->req_id = -1;
slot->skip_idx = 1;
slot->recover = 0;
slot->additional_timeout = 0;
slot->sync_mode = CAM_REQ_MGR_SYNC_MODE_NO_SYNC;
slot->status = CRM_SLOT_STATUS_NO_REQ;
@ -486,6 +487,7 @@ static void __cam_req_mgr_reset_req_slot(struct cam_req_mgr_core_link *link,
slot->req_id = -1;
slot->skip_idx = 0;
slot->recover = 0;
slot->additional_timeout = 0;
slot->sync_mode = CAM_REQ_MGR_SYNC_MODE_NO_SYNC;
slot->status = CRM_SLOT_STATUS_NO_REQ;
@ -499,6 +501,66 @@ static void __cam_req_mgr_reset_req_slot(struct cam_req_mgr_core_link *link,
}
}
/**
* __cam_req_mgr_validate_crm_wd_timer()
*
* @brief : Validate/modify the wd timer based on associated
* timeout with the request
* @link : link pointer
*
*/
static void __cam_req_mgr_validate_crm_wd_timer(
struct cam_req_mgr_core_link *link)
{
int idx = 0;
int next_frame_timeout = 0, current_frame_timeout = 0;
struct cam_req_mgr_req_queue *in_q = link->req.in_q;
idx = in_q->rd_idx;
__cam_req_mgr_dec_idx(
&idx, (link->max_delay - 1),
in_q->num_slots);
next_frame_timeout = in_q->slot[idx].additional_timeout;
CAM_DBG(CAM_CRM,
"rd_idx: %d idx: %d next_frame_timeout: %d ms",
in_q->rd_idx, idx, next_frame_timeout);
idx = in_q->rd_idx;
__cam_req_mgr_dec_idx(
&idx, link->max_delay,
in_q->num_slots);
current_frame_timeout = in_q->slot[idx].additional_timeout;
CAM_DBG(CAM_CRM,
"rd_idx: %d idx: %d current_frame_timeout: %d ms",
in_q->rd_idx, idx, current_frame_timeout);
if ((next_frame_timeout + CAM_REQ_MGR_WATCHDOG_TIMEOUT) >
link->watchdog->expires) {
CAM_DBG(CAM_CRM,
"Modifying wd timer expiry from %d ms to %d ms",
link->watchdog->expires,
(next_frame_timeout + CAM_REQ_MGR_WATCHDOG_TIMEOUT));
crm_timer_modify(link->watchdog,
next_frame_timeout +
CAM_REQ_MGR_WATCHDOG_TIMEOUT);
} else if (current_frame_timeout) {
CAM_DBG(CAM_CRM,
"Reset wd timer to current frame from %d ms to %d ms",
link->watchdog->expires,
(current_frame_timeout + CAM_REQ_MGR_WATCHDOG_TIMEOUT));
crm_timer_modify(link->watchdog,
current_frame_timeout +
CAM_REQ_MGR_WATCHDOG_TIMEOUT);
} else if (link->watchdog->expires >
CAM_REQ_MGR_WATCHDOG_TIMEOUT) {
CAM_DBG(CAM_CRM,
"Reset wd timer to default from %d ms to %d ms",
link->watchdog->expires, CAM_REQ_MGR_WATCHDOG_TIMEOUT);
crm_timer_modify(link->watchdog,
CAM_REQ_MGR_WATCHDOG_TIMEOUT);
}
}
/**
* __cam_req_mgr_check_for_lower_pd_devices()
*
@ -1275,9 +1337,11 @@ static int __cam_req_mgr_process_req(struct cam_req_mgr_core_link *link,
* - if in applied_state, somthign wrong.
* - if in no_req state, no new req
*/
CAM_DBG(CAM_REQ, "SOF Req[%lld] idx %d req_status %d link_hdl %x",
CAM_DBG(CAM_REQ,
"SOF Req[%lld] idx %d req_status %d link_hdl %x wd_timeout %d ms",
in_q->slot[in_q->rd_idx].req_id, in_q->rd_idx,
in_q->slot[in_q->rd_idx].status, link->link_hdl);
in_q->slot[in_q->rd_idx].status, link->link_hdl,
in_q->slot[in_q->rd_idx].additional_timeout);
slot = &in_q->slot[in_q->rd_idx];
if (slot->status == CRM_SLOT_STATUS_NO_REQ) {
@ -1393,6 +1457,9 @@ static int __cam_req_mgr_process_req(struct cam_req_mgr_core_link *link,
link->trigger_mask |= trigger;
/* Check for any long exposure settings */
__cam_req_mgr_validate_crm_wd_timer(link);
CAM_DBG(CAM_CRM, "Applied req[%lld] on link[%x] success",
slot->req_id, link->link_hdl);
spin_lock_bh(&link->link_state_spin_lock);
@ -1641,7 +1708,7 @@ static int __cam_req_mgr_process_sof_freeze(void *priv, void *data)
memset(&msg, 0, sizeof(msg));
msg.session_hdl = session->session_hdl;
msg.u.err_msg.error_type = CAM_REQ_MGR_ERROR_TYPE_RECOVERY;
msg.u.err_msg.error_type = CAM_REQ_MGR_ERROR_TYPE_SOF_FREEZE;
msg.u.err_msg.request_id = 0;
msg.u.err_msg.link_hdl = link->link_hdl;
@ -2030,6 +2097,7 @@ int cam_req_mgr_process_flush_req(void *priv, void *data)
mutex_unlock(&link->req.lock);
return -EINVAL;
}
slot->additional_timeout = 0;
__cam_req_mgr_in_q_skip_idx(in_q, idx);
}
}
@ -2081,10 +2149,11 @@ int cam_req_mgr_process_sched_req(void *priv, void *data)
in_q = link->req.in_q;
CAM_DBG(CAM_CRM,
"link_hdl %x req_id %lld at slot %d sync_mode %d is_master:%d",
"link_hdl %x req_id %lld at slot %d sync_mode %d is_master %d exp_timeout_val %d ms",
sched_req->link_hdl, sched_req->req_id,
in_q->wr_idx, sched_req->sync_mode,
link->is_master);
link->is_master,
sched_req->additional_timeout);
mutex_lock(&link->req.lock);
slot = &in_q->slot[in_q->wr_idx];
@ -2098,6 +2167,22 @@ int cam_req_mgr_process_sched_req(void *priv, void *data)
slot->sync_mode = sched_req->sync_mode;
slot->skip_idx = 0;
slot->recover = sched_req->bubble_enable;
if (sched_req->additional_timeout < 0) {
CAM_WARN(CAM_CRM,
"Requested timeout is invalid [%dms]",
sched_req->additional_timeout);
slot->additional_timeout = 0;
} else if (sched_req->additional_timeout >
CAM_REQ_MGR_WATCHDOG_TIMEOUT_MAX) {
CAM_WARN(CAM_CRM,
"Requested timeout [%dms] max supported timeout [%dms] resetting to max",
sched_req->additional_timeout,
CAM_REQ_MGR_WATCHDOG_TIMEOUT_MAX);
slot->additional_timeout = CAM_REQ_MGR_WATCHDOG_TIMEOUT_MAX;
} else {
slot->additional_timeout = sched_req->additional_timeout;
}
link->open_req_cnt++;
__cam_req_mgr_inc_idx(&in_q->wr_idx, 1, in_q->num_slots);
@ -3261,6 +3346,7 @@ int cam_req_mgr_schedule_request(
sched->req_id = sched_req->req_id;
sched->sync_mode = sched_req->sync_mode;
sched->link_hdl = sched_req->link_hdl;
sched->additional_timeout = sched_req->additional_timeout;
if (session->force_err_recovery == AUTO_RECOVERY) {
sched->bubble_enable = sched_req->bubble_enable;
} else {

Просмотреть файл

@ -13,9 +13,10 @@
#define CAM_REQ_MGR_MAX_LINKED_DEV 16
#define MAX_REQ_SLOTS 48
#define CAM_REQ_MGR_WATCHDOG_TIMEOUT 5000
#define CAM_REQ_MGR_SCHED_REQ_TIMEOUT 1000
#define CAM_REQ_MGR_SIMULATE_SCHED_REQ 30
#define CAM_REQ_MGR_WATCHDOG_TIMEOUT 1000
#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 FORCE_DISABLE_RECOVERY 2
#define FORCE_ENABLE_RECOVERY 1
@ -226,13 +227,15 @@ struct cam_req_mgr_req_tbl {
/**
* struct cam_req_mgr_slot
* - Internal Book keeping
* @idx : slot index
* @skip_idx : if req id in this slot needs to be skipped/not applied
* @status : state machine for life cycle of a slot
* @idx : slot index
* @skip_idx : if req id in this slot needs to be skipped/not applied
* @status : state machine for life cycle of a slot
* - members updated due to external events
* @recover : if user enabled recovery for this request.
* @req_id : mask tracking which all devices have request ready
* @sync_mode : Sync mode in which req id in this slot has to applied
* @recover : if user enabled recovery for this request.
* @req_id : mask tracking which all devices have request ready
* @sync_mode : Sync mode in which req id in this slot has to applied
* @additional_timeout : Adjusted watchdog timeout value associated with
* this request
*/
struct cam_req_mgr_slot {
int32_t idx;
@ -241,6 +244,7 @@ struct cam_req_mgr_slot {
int32_t recover;
int64_t req_id;
int32_t sync_mode;
int32_t additional_timeout;
};
/**