Răsfoiți Sursa

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 <[email protected]>
Signed-off-by: Karthik Anantha Ram <[email protected]>
Mukund Madhusudan Atre 5 ani în urmă
părinte
comite
a6c3698b1f
2 a modificat fișierele cu 104 adăugiri și 14 ștergeri
  1. 91 5
      drivers/cam_req_mgr/cam_req_mgr_core.c
  2. 13 9
      drivers/cam_req_mgr/cam_req_mgr_core.h

+ 91 - 5
drivers/cam_req_mgr/cam_req_mgr_core.c

@@ -443,6 +443,7 @@ static void __cam_req_mgr_flush_req_slot(
 		slot->req_id = -1;
 		slot->req_id = -1;
 		slot->skip_idx = 1;
 		slot->skip_idx = 1;
 		slot->recover = 0;
 		slot->recover = 0;
+		slot->additional_timeout = 0;
 		slot->sync_mode = CAM_REQ_MGR_SYNC_MODE_NO_SYNC;
 		slot->sync_mode = CAM_REQ_MGR_SYNC_MODE_NO_SYNC;
 		slot->status = CRM_SLOT_STATUS_NO_REQ;
 		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->req_id = -1;
 	slot->skip_idx = 0;
 	slot->skip_idx = 0;
 	slot->recover = 0;
 	slot->recover = 0;
+	slot->additional_timeout = 0;
 	slot->sync_mode = CAM_REQ_MGR_SYNC_MODE_NO_SYNC;
 	slot->sync_mode = CAM_REQ_MGR_SYNC_MODE_NO_SYNC;
 	slot->status = CRM_SLOT_STATUS_NO_REQ;
 	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()
  * __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 applied_state, somthign wrong.
 	 * - if in no_req state, no new req
 	 * - 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].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];
 	slot = &in_q->slot[in_q->rd_idx];
 	if (slot->status == CRM_SLOT_STATUS_NO_REQ) {
 	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;
 		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",
 		CAM_DBG(CAM_CRM, "Applied req[%lld] on link[%x] success",
 			slot->req_id, link->link_hdl);
 			slot->req_id, link->link_hdl);
 		spin_lock_bh(&link->link_state_spin_lock);
 		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));
 	memset(&msg, 0, sizeof(msg));
 
 
 	msg.session_hdl = session->session_hdl;
 	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.request_id = 0;
 	msg.u.err_msg.link_hdl   = link->link_hdl;
 	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);
 				mutex_unlock(&link->req.lock);
 				return -EINVAL;
 				return -EINVAL;
 			}
 			}
+			slot->additional_timeout = 0;
 			__cam_req_mgr_in_q_skip_idx(in_q, idx);
 			__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;
 	in_q = link->req.in_q;
 
 
 	CAM_DBG(CAM_CRM,
 	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,
 		sched_req->link_hdl, sched_req->req_id,
 		in_q->wr_idx, sched_req->sync_mode,
 		in_q->wr_idx, sched_req->sync_mode,
-		link->is_master);
+		link->is_master,
+		sched_req->additional_timeout);
 
 
 	mutex_lock(&link->req.lock);
 	mutex_lock(&link->req.lock);
 	slot = &in_q->slot[in_q->wr_idx];
 	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->sync_mode = sched_req->sync_mode;
 	slot->skip_idx = 0;
 	slot->skip_idx = 0;
 	slot->recover = sched_req->bubble_enable;
 	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++;
 	link->open_req_cnt++;
 	__cam_req_mgr_inc_idx(&in_q->wr_idx, 1, in_q->num_slots);
 	__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->req_id = sched_req->req_id;
 	sched->sync_mode = sched_req->sync_mode;
 	sched->sync_mode = sched_req->sync_mode;
 	sched->link_hdl = sched_req->link_hdl;
 	sched->link_hdl = sched_req->link_hdl;
+	sched->additional_timeout = sched_req->additional_timeout;
 	if (session->force_err_recovery == AUTO_RECOVERY) {
 	if (session->force_err_recovery == AUTO_RECOVERY) {
 		sched->bubble_enable = sched_req->bubble_enable;
 		sched->bubble_enable = sched_req->bubble_enable;
 	} else {
 	} else {

+ 13 - 9
drivers/cam_req_mgr/cam_req_mgr_core.h

@@ -13,9 +13,10 @@
 #define CAM_REQ_MGR_MAX_LINKED_DEV     16
 #define CAM_REQ_MGR_MAX_LINKED_DEV     16
 #define MAX_REQ_SLOTS                  48
 #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_DISABLE_RECOVERY  2
 #define FORCE_ENABLE_RECOVERY   1
 #define FORCE_ENABLE_RECOVERY   1
@@ -226,13 +227,15 @@ struct cam_req_mgr_req_tbl {
 /**
 /**
  * struct cam_req_mgr_slot
  * struct cam_req_mgr_slot
  * - Internal Book keeping
  * - 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
  * - 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 {
 struct cam_req_mgr_slot {
 	int32_t               idx;
 	int32_t               idx;
@@ -241,6 +244,7 @@ struct cam_req_mgr_slot {
 	int32_t               recover;
 	int32_t               recover;
 	int64_t               req_id;
 	int64_t               req_id;
 	int32_t               sync_mode;
 	int32_t               sync_mode;
+	int32_t               additional_timeout;
 };
 };
 
 
 /**
 /**