Эх сурвалжийг харах

msm: camera: reqmgr: SAT switch latency optimization

To optimize SAT switch latency, Link handles will be passed along
with OpenRequest so that KMD can get sync link info per request and
UMD don't need to wait all pending requests to be done before activing
new links.

CRs-Fixed: 3094388
Change-Id: Ia52a95d9eaf444bd982a288bacf1e62b276130f2
Signed-off-by: Stark Lin <[email protected]>
Signed-off-by: Depeng Shao <[email protected]>
Stark Lin 3 жил өмнө
parent
commit
38c78b4c8d

+ 93 - 143
drivers/cam_req_mgr/cam_req_mgr_core.c

@@ -660,7 +660,8 @@ static void __cam_req_mgr_tbl_set_all_skip_cnt(
 static void __cam_req_mgr_flush_req_slot(
 	struct cam_req_mgr_core_link *link)
 {
-	int                           idx = 0;
+	int                           i;
+	int                           idx;
 	struct cam_req_mgr_slot      *slot;
 	struct cam_req_mgr_req_tbl   *tbl;
 	struct cam_req_mgr_req_queue *in_q = link->req.in_q;
@@ -679,6 +680,9 @@ static void __cam_req_mgr_flush_req_slot(
 		slot->additional_timeout = 0;
 		slot->sync_mode = CAM_REQ_MGR_SYNC_MODE_NO_SYNC;
 		slot->status = CRM_SLOT_STATUS_NO_REQ;
+		slot->num_sync_links = 0;
+		for (i = 0; i < MAXIMUM_LINKS_PER_SESSION - 1; i++)
+			slot->sync_link_hdls[i] = 0;
 
 		/* Reset all pd table slot */
 		while (tbl != NULL) {
@@ -714,6 +718,7 @@ static void __cam_req_mgr_flush_req_slot(
 static void __cam_req_mgr_reset_req_slot(struct cam_req_mgr_core_link *link,
 	int32_t idx)
 {
+	int                           i;
 	struct cam_req_mgr_slot      *slot;
 	struct cam_req_mgr_req_tbl   *tbl = link->req.l_tbl;
 	struct cam_req_mgr_req_queue *in_q = link->req.in_q;
@@ -735,6 +740,9 @@ static void __cam_req_mgr_reset_req_slot(struct cam_req_mgr_core_link *link,
 	slot->recovery_counter = 0;
 	slot->sync_mode = CAM_REQ_MGR_SYNC_MODE_NO_SYNC;
 	slot->status = CRM_SLOT_STATUS_NO_REQ;
+	slot->num_sync_links = 0;
+	for (i = 0; i < MAXIMUM_LINKS_PER_SESSION - 1; i++)
+		slot->sync_link_hdls[i] = 0;
 
 	/* Reset all pd table slot */
 	while (tbl != NULL) {
@@ -1717,6 +1725,8 @@ static int __cam_req_mgr_check_multi_sync_link_ready(
 	uint32_t trigger)
 {
 	int i, rc = 0;
+	struct cam_req_mgr_core_link
+		*sync_link[MAXIMUM_LINKS_PER_SESSION - 1];
 
 	if (link->state == CAM_CRM_LINK_STATE_IDLE) {
 		CAM_ERR(CAM_CRM, "link hdl %x is in idle state",
@@ -1724,17 +1734,20 @@ static int __cam_req_mgr_check_multi_sync_link_ready(
 		return -EINVAL;
 	}
 
-	for (i = 0; i < link->num_sync_links; i++) {
-		if (link->sync_link[i]) {
-			if (link->sync_link[i]->state ==
+	for (i = 0; i < slot->num_sync_links; i++) {
+		sync_link[i] = (struct cam_req_mgr_core_link *)
+			cam_get_device_priv(slot->sync_link_hdls[i]);
+
+		if (sync_link[i]) {
+			if (sync_link[i]->state ==
 				CAM_CRM_LINK_STATE_IDLE) {
 				CAM_ERR(CAM_CRM, "sync link hdl %x is idle",
-					link->sync_link[i]->link_hdl);
+					sync_link[i]->link_hdl);
 				return -EINVAL;
 			}
-			if (link->max_delay == link->sync_link[i]->max_delay) {
+			if (link->max_delay == sync_link[i]->max_delay) {
 				rc = __cam_req_mgr_check_sync_req_is_ready(
-						link, link->sync_link[i],
+						link, sync_link[i],
 						slot, trigger);
 				if (rc < 0) {
 					CAM_DBG(CAM_CRM, "link %x not ready",
@@ -1742,11 +1755,11 @@ static int __cam_req_mgr_check_multi_sync_link_ready(
 					return rc;
 				}
 			} else if (link->max_delay >
-					link->sync_link[i]->max_delay) {
+					sync_link[i]->max_delay) {
 				link->is_master = true;
-				link->sync_link[i]->is_master = false;
+				sync_link[i]->is_master = false;
 				rc = __cam_req_mgr_check_sync_for_mslave(
-					link, link->sync_link[i], slot);
+					link, sync_link[i], slot);
 				if (rc < 0) {
 					CAM_DBG(CAM_CRM, "link%x not ready",
 						link->link_hdl);
@@ -1754,9 +1767,9 @@ static int __cam_req_mgr_check_multi_sync_link_ready(
 				}
 			} else {
 				link->is_master = false;
-				link->sync_link[i]->is_master = true;
+				sync_link[i]->is_master = true;
 				rc = __cam_req_mgr_check_sync_for_mslave(
-						link, link->sync_link[i], slot);
+						link, sync_link[i], slot);
 				if (rc < 0) {
 					CAM_DBG(CAM_CRM, "link %x not ready",
 						link->link_hdl);
@@ -1942,8 +1955,8 @@ static int __cam_req_mgr_process_req(struct cam_req_mgr_core_link *link,
 
 	if (slot->status != CRM_SLOT_STATUS_REQ_READY) {
 		if (slot->sync_mode == CAM_REQ_MGR_SYNC_MODE_SYNC) {
-			rc = __cam_req_mgr_check_multi_sync_link_ready(
-				link, slot, trigger);
+			rc = __cam_req_mgr_check_multi_sync_link_ready(link, slot,
+				trigger);
 		} else {
 			if (link->in_msync_mode) {
 				CAM_DBG(CAM_CRM,
@@ -2835,12 +2848,12 @@ int cam_req_mgr_process_flush_req(void *priv, void *data)
  */
 int cam_req_mgr_process_sched_req(void *priv, void *data)
 {
-	int                               rc = 0, i;
-	struct cam_req_mgr_sched_request *sched_req = NULL;
-	struct cam_req_mgr_core_link     *link = NULL;
-	struct cam_req_mgr_req_queue     *in_q = NULL;
-	struct cam_req_mgr_slot          *slot = NULL;
-	struct crm_task_payload          *task_data = NULL;
+	int                                  rc = 0, i, sync_idx = 0;
+	struct cam_req_mgr_sched_request_v2 *sched_req = NULL;
+	struct cam_req_mgr_core_link        *link = NULL;
+	struct cam_req_mgr_req_queue        *in_q = NULL;
+	struct cam_req_mgr_slot             *slot = NULL;
+	struct crm_task_payload             *task_data = NULL;
 
 	if (!data || !priv) {
 		CAM_ERR(CAM_CRM, "input args NULL %pK %pK", data, priv);
@@ -2849,7 +2862,7 @@ int cam_req_mgr_process_sched_req(void *priv, void *data)
 	}
 	link = (struct cam_req_mgr_core_link *)priv;
 	task_data = (struct crm_task_payload *)data;
-	sched_req  = (struct cam_req_mgr_sched_request *)&task_data->u;
+	sched_req  = (struct cam_req_mgr_sched_request_v2 *)&task_data->u;
 	in_q = link->req.in_q;
 
 	CAM_DBG(CAM_CRM,
@@ -2871,6 +2884,7 @@ 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]",
@@ -2883,9 +2897,19 @@ int cam_req_mgr_process_sched_req(void *priv, void *data)
 			sched_req->additional_timeout,
 			CAM_REQ_MGR_WATCHDOG_TIMEOUT_MAX);
 		slot->additional_timeout = CAM_REQ_MGR_WATCHDOG_TIMEOUT_MAX;
-	} else {
+	} else
 		slot->additional_timeout = sched_req->additional_timeout;
+
+	for (i = 0; i < sched_req->num_links; i++) {
+		if (link->link_hdl != sched_req->link_hdls[i]) {
+			slot->sync_link_hdls[sync_idx] = sched_req->link_hdls[i];
+			CAM_DBG(CAM_REQ, "link:0x%x req:%lld sync_link[%d]:0x%x",
+				link->link_hdl, slot->req_id, sync_idx,
+				slot->sync_link_hdls[sync_idx]);
+			sync_idx++;
+		}
 	}
+	slot->num_sync_links = sync_idx;
 
 	link->open_req_cnt++;
 	CAM_DBG(CAM_REQ, "Open_req_cnt: %u after scheduling req: %d",
@@ -4595,20 +4619,18 @@ done:
 }
 
 int cam_req_mgr_schedule_request(
-			struct cam_req_mgr_sched_request *sched_req)
+	struct cam_req_mgr_sched_request_v2 *sched_req)
 {
-	int                               rc = 0;
-	struct cam_req_mgr_core_link     *link = NULL;
-	struct cam_req_mgr_core_session  *session = NULL;
-	struct cam_req_mgr_sched_request *sched;
-	struct crm_task_payload           task_data;
-
-	if (!sched_req) {
-		CAM_ERR(CAM_CRM, "csl_req is NULL");
-		return -EINVAL;
-	}
+	int                                  i = 0;
+	int                                  rc = 0;
+	struct cam_req_mgr_core_link        *link = NULL;
+	struct cam_req_mgr_core_session     *session = NULL;
+	struct crm_task_payload              task_data;
+	struct cam_req_mgr_sched_request_v2 *sched;
+	struct cam_req_mgr_core_link        *sync_links[MAXIMUM_LINKS_PER_SESSION];
 
 	mutex_lock(&g_crm_core_dev->crm_lock);
+
 	link = (struct cam_req_mgr_core_link *)
 		cam_get_device_priv(sched_req->link_hdl);
 	if (!link || (link->link_hdl != sched_req->link_hdl)) {
@@ -4637,15 +4659,17 @@ int cam_req_mgr_schedule_request(
 	if (sched_req->req_id > link->last_flush_id)
 		link->last_flush_id = 0;
 
-	CAM_DBG(CAM_CRM, "link 0x%x req %lld, sync_mode %d",
-		sched_req->link_hdl, sched_req->req_id, sched_req->sync_mode);
+	CAM_DBG(CAM_CRM, "link 0x%x req %lld, sync_mode %d num_links %d",
+		sched_req->link_hdl, sched_req->req_id, sched_req->sync_mode,
+		sched_req->num_links);
 
 	task_data.type = CRM_WORKQ_TASK_SCHED_REQ;
-	sched = (struct cam_req_mgr_sched_request *)&task_data.u;
+	sched = (struct cam_req_mgr_sched_request_v2 *)&task_data.u;
 	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 {
@@ -4653,121 +4677,47 @@ int cam_req_mgr_schedule_request(
 		(session->force_err_recovery == FORCE_ENABLE_RECOVERY) ? 1 : 0;
 	}
 
-	rc = cam_req_mgr_process_sched_req(link, &task_data);
-
-	CAM_DBG(CAM_REQ, "Open req %lld on link 0x%x with sync_mode %d",
-		sched_req->req_id, sched_req->link_hdl, sched_req->sync_mode);
-end:
-	mutex_unlock(&g_crm_core_dev->crm_lock);
-	return rc;
-}
-
-int cam_req_mgr_sync_config(
-	struct cam_req_mgr_sync_mode *sync_info)
-{
-	int                              i, j, rc = 0;
-	int                              sync_idx = 0;
-	struct cam_req_mgr_core_session *cam_session;
-	struct cam_req_mgr_core_link    *link[MAX_LINKS_PER_SESSION];
-
-	if (!sync_info) {
-		CAM_ERR(CAM_CRM, "NULL pointer");
-		return -EINVAL;
-	}
-
-	if ((sync_info->num_links < 0) ||
-		(sync_info->num_links >
-		MAX_LINKS_PER_SESSION)) {
-		CAM_ERR(CAM_CRM, "Invalid num links %d", sync_info->num_links);
-		return -EINVAL;
-	}
-
-	if ((sync_info->sync_mode != CAM_REQ_MGR_SYNC_MODE_SYNC) &&
-		(sync_info->sync_mode != CAM_REQ_MGR_SYNC_MODE_NO_SYNC)) {
-		CAM_ERR(CAM_CRM, "Invalid sync mode %d", sync_info->sync_mode);
-		return -EINVAL;
-	}
-
-	if ((!sync_info->link_hdls[0]) || (!sync_info->link_hdls[1])) {
-		CAM_WARN(CAM_CRM, "Invalid link handles 0x%x 0x%x",
-			sync_info->link_hdls[0], sync_info->link_hdls[1]);
-		return -EINVAL;
-	}
-
-	mutex_lock(&g_crm_core_dev->crm_lock);
-	/* session hdl's priv data is cam session struct */
-	cam_session = (struct cam_req_mgr_core_session *)
-		cam_get_device_priv(sync_info->session_hdl);
-	if (!cam_session || (cam_session->session_hdl != sync_info->session_hdl)) {
-		CAM_ERR(CAM_CRM, "session: %s, sync_info->session_hdl:%x, session->ses_hdl:%x",
-			CAM_IS_NULL_TO_STR(cam_session), sync_info->session_hdl,
-			(!cam_session) ? CAM_REQ_MGR_DEFAULT_HDL_VAL : cam_session->session_hdl);
-		mutex_unlock(&g_crm_core_dev->crm_lock);
-		return -EINVAL;
-	}
-
-	mutex_lock(&cam_session->lock);
-
-	for (i = 0; i < sync_info->num_links; i++) {
-
-		if (!sync_info->link_hdls[i]) {
-			CAM_ERR(CAM_CRM, "link handle %d is null", i);
+	if (sched_req->sync_mode == CAM_REQ_MGR_SYNC_MODE_SYNC) {
+		if ((sched_req->num_links <= 0) &&
+			(sched_req->num_links > MAXIMUM_LINKS_PER_SESSION)) {
+			CAM_ERR(CAM_CRM, "link:0x%x req:%lld invalid num_links:%d",
+				link->link_hdl, sched_req->req_id, sched_req->num_links);
 			rc = -EINVAL;
-			goto done;
+			goto end;
 		}
 
-		link[i] = cam_get_device_priv(sync_info->link_hdls[i]);
-		if (!link[i] || (link[i]->link_hdl != sync_info->link_hdls[i])) {
-			CAM_ERR(CAM_CRM, "link: %s, sync_info->link_hdl:%x, link->link_hdl:%x",
-				CAM_IS_NULL_TO_STR(link), sync_info->link_hdls[i],
-				(!link[i]) ? CAM_REQ_MGR_DEFAULT_HDL_VAL : link[i]->link_hdl);
-			rc = -EINVAL;
-			goto done;
-		}
+		for (i = 0; i < sched_req->num_links; i++) {
+			if (!sched_req->link_hdls[i]) {
+				CAM_ERR(CAM_CRM, "link handle %d in sched_req is null", i);
+				rc = -EINVAL;
+				goto end;
+			}
 
-		link[i]->sync_link_sof_skip = false;
-		link[i]->is_master = false;
-		link[i]->in_msync_mode = false;
-		link[i]->initial_sync_req = -1;
-		link[i]->num_sync_links = 0;
-
-		for (j = 0; j < sync_info->num_links-1; j++)
-			link[i]->sync_link[j] = NULL;
-	}
-
-	if (sync_info->sync_mode == CAM_REQ_MGR_SYNC_MODE_SYNC) {
-		for (i = 0; i < sync_info->num_links; i++) {
-			j = 0;
-			sync_idx = 0;
-			CAM_DBG(CAM_REQ, "link %x adds sync link:",
-				link[i]->link_hdl);
-			while (j < sync_info->num_links) {
-				if (i != j) {
-					link[i]->sync_link[sync_idx++] =
-						link[j];
-					link[i]->num_sync_links++;
-					CAM_DBG(CAM_REQ, "sync_link[%d] : %x",
-						sync_idx-1, link[j]->link_hdl);
-				}
-				j++;
+			sync_links[i] = (struct cam_req_mgr_core_link *)
+				cam_get_device_priv(sched_req->link_hdls[i]);
+			if (!sync_links[i] ||
+				(sync_links[i]->link_hdl != sched_req->link_hdls[i])) {
+				CAM_ERR(CAM_CRM,
+					"Invalid sync link, sync link[%d]: %s sched_req->link_hdl: %x sync_links->link_hdl: 0x%x",
+					i, CAM_IS_NULL_TO_STR(sync_links[i]),
+					sched_req->link_hdls[i],
+					((!sync_links[i]) ? CAM_REQ_MGR_DEFAULT_HDL_VAL :
+					sync_links[i]->link_hdl));
+				rc = -EINVAL;
+				goto end;
 			}
-			link[i]->initial_skip = true;
-			link[i]->sof_timestamp = 0;
-		}
-	} else {
-		for (j = 0; j < sync_info->num_links; j++) {
-			link[j]->initial_skip = true;
-			link[j]->sof_timestamp = 0;
+
+			sched->link_hdls[i] = sched_req->link_hdls[i];
 		}
-	}
+		sched->num_links = sched_req->num_links;
+	} else
+		sched->num_links = 0;
 
-	cam_session->sync_mode = sync_info->sync_mode;
-	CAM_DBG(CAM_REQ,
-		"Sync config completed on %d links with sync_mode %d",
-		sync_info->num_links, sync_info->sync_mode);
+	rc = cam_req_mgr_process_sched_req(link, &task_data);
 
-done:
-	mutex_unlock(&cam_session->lock);
+	CAM_DBG(CAM_REQ, "Open req %lld on link 0x%x with sync_mode %d",
+		sched_req->req_id, sched_req->link_hdl, sched_req->sync_mode);
+end:
 	mutex_unlock(&g_crm_core_dev->crm_lock);
 	return rc;
 }

+ 7 - 10
drivers/cam_req_mgr/cam_req_mgr_core.h

@@ -90,7 +90,7 @@ enum crm_workq_task_type {
 struct crm_task_payload {
 	enum crm_workq_task_type type;
 	union {
-		struct cam_req_mgr_sched_request        sched_req;
+		struct cam_req_mgr_sched_request_v2     sched_req;
 		struct cam_req_mgr_flush_info           flush_info;
 		struct cam_req_mgr_add_request          dev_req;
 		struct cam_req_mgr_send_request         send_req;
@@ -285,6 +285,8 @@ struct cam_req_mgr_req_tbl {
  * @additional_timeout : Adjusted watchdog timeout value associated with
  * this request
  * @recovery_counter   : Internal recovery counter
+ * @num_sync_links     : Num of sync links
+ * @sync_link_hdls     : Array of sync link handles
  */
 struct cam_req_mgr_slot {
 	int32_t               idx;
@@ -295,6 +297,8 @@ struct cam_req_mgr_slot {
 	int32_t               sync_mode;
 	int32_t               additional_timeout;
 	int32_t               recovery_counter;
+	int32_t               num_sync_links;
+	int32_t               sync_link_hdls[MAXIMUM_LINKS_PER_SESSION - 1];
 };
 
 /**
@@ -637,16 +641,9 @@ int cam_req_mgr_unlink(struct cam_req_mgr_unlink_info *unlink_info);
 /**
  * cam_req_mgr_schedule_request()
  * @brief: Request is scheduled
- * @sched_req: request id, session and link id info, bubble recovery info
+ * @sched_req: request id, session, link id info, bubble recovery info and sync info
  */
-int cam_req_mgr_schedule_request(struct cam_req_mgr_sched_request *sched_req);
-
-/**
- * cam_req_mgr_sync_mode_setup()
- * @brief: sync for links in a session
- * @sync_info: session, links info and master link info
- */
-int cam_req_mgr_sync_config(struct cam_req_mgr_sync_mode *sync_info);
+int cam_req_mgr_schedule_request(struct cam_req_mgr_sched_request_v2 *sched_req);
 
 /**
  * cam_req_mgr_flush_requests()

+ 11 - 19
drivers/cam_req_mgr/cam_req_mgr_dev.c

@@ -444,15 +444,15 @@ static long cam_private_ioctl(struct file *file, void *fh,
 		}
 		break;
 
-	case CAM_REQ_MGR_SCHED_REQ: {
-		struct cam_req_mgr_sched_request sched_req;
+	case CAM_REQ_MGR_SCHED_REQ_V2: {
+		struct cam_req_mgr_sched_request_v2 sched_req;
 
 		if (k_ioctl->size != sizeof(sched_req))
 			return -EINVAL;
 
 		if (copy_from_user(&sched_req,
 			u64_to_user_ptr(k_ioctl->handle),
-			sizeof(struct cam_req_mgr_sched_request))) {
+			sizeof(struct cam_req_mgr_sched_request_v2))) {
 			return -EFAULT;
 		}
 
@@ -476,21 +476,6 @@ static long cam_private_ioctl(struct file *file, void *fh,
 		}
 		break;
 
-	case CAM_REQ_MGR_SYNC_MODE: {
-		struct cam_req_mgr_sync_mode sync_info;
-
-		if (k_ioctl->size != sizeof(sync_info))
-			return -EINVAL;
-
-		if (copy_from_user(&sync_info,
-			u64_to_user_ptr(k_ioctl->handle),
-			sizeof(struct cam_req_mgr_sync_mode))) {
-			return -EFAULT;
-		}
-
-		rc = cam_req_mgr_sync_config(&sync_info);
-		}
-		break;
 	case CAM_REQ_MGR_ALLOC_BUF: {
 		struct cam_mem_mgr_alloc_cmd cmd;
 		struct cam_mem_mgr_alloc_cmd_v2 cmd_v2 = {0};
@@ -694,8 +679,15 @@ static long cam_private_ioctl(struct file *file, void *fh,
 		rc = cam_req_mgr_link_properties(&cmd);
 		}
 		break;
+	/* Deprecated Opcodes */
+	case CAM_REQ_MGR_SCHED_REQ:
+	case CAM_REQ_MGR_SYNC_MODE:
+		rc = -EBADRQC;
+		CAM_ERR(CAM_CRM, "Unsupported Opcode: %d", k_ioctl->op_code);
+		break;
 	default:
-		return -ENOIOCTLCMD;
+		CAM_ERR(CAM_CRM, "Invalid Opcode %d", k_ioctl->op_code);
+		rc = -ENOIOCTLCMD;
 	}
 
 	return rc;