Browse Source

msm: camera: isp: Change master slave combination for dual IFE

For some targets, there is a requirement to have the lower IFE
as master. Current implementation selects the higher IFE as
the master.
This commit changes the acquire logic to reserve the lower IFE
first and then the higher IFE as slave. This logic is for dual
ife use cases. For single IFE use case, acquire logic is not
changed.
Also, removes the hard coded check for master hw index
during the irq  handling. Stores the master hw index
in ife hardware manager context and check against it.

Change-Id: Ifd3a28e80a0a4d16e3d9278b7ed61290c620ec79
CRs-Fixed: 2582959
Signed-off-by: Gaurav Jindal <[email protected]>
Signed-off-by: Vishalsingh Hajeri <[email protected]>
Gaurav Jindal 5 năm trước cách đây
mục cha
commit
7d7ed34560

+ 89 - 65
drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c

@@ -1004,7 +1004,7 @@ static int cam_ife_hw_mgr_acquire_res_bus_rd(
 					/*TBD */
 					vfe_acquire.vfe_out.is_master     = 1;
 					vfe_acquire.vfe_out.dual_slave_core =
-						(hw_intf->hw_idx == 0) ? 1 : 0;
+					ife_ctx->slave_hw_idx;
 				} else {
 					vfe_acquire.vfe_out.is_master   = 0;
 					vfe_acquire.vfe_out.dual_slave_core =
@@ -1015,7 +1015,7 @@ static int cam_ife_hw_mgr_acquire_res_bus_rd(
 					CAM_ISP_HW_SPLIT_RIGHT;
 				vfe_acquire.vfe_out.is_master       = 0;
 				vfe_acquire.vfe_out.dual_slave_core =
-					(hw_intf->hw_idx == 0) ? 1 : 0;
+					ife_ctx->master_hw_idx;
 			}
 			rc = hw_intf->hw_ops.reserve(hw_intf->hw_priv,
 				&vfe_acquire,
@@ -1197,7 +1197,7 @@ static int cam_ife_hw_mgr_acquire_res_ife_out_pixel(
 					/*TBD */
 					vfe_acquire.vfe_out.is_master     = 1;
 					vfe_acquire.vfe_out.dual_slave_core =
-						(hw_intf->hw_idx == 0) ? 1 : 0;
+						ife_ctx->slave_hw_idx;
 				} else {
 					vfe_acquire.vfe_out.is_master   = 0;
 					vfe_acquire.vfe_out.dual_slave_core =
@@ -1208,9 +1208,8 @@ static int cam_ife_hw_mgr_acquire_res_ife_out_pixel(
 					CAM_ISP_HW_SPLIT_RIGHT;
 				vfe_acquire.vfe_out.is_master       = 0;
 				vfe_acquire.vfe_out.dual_slave_core =
-					(hw_intf->hw_idx == 0) ? 1 : 0;
+					ife_ctx->master_hw_idx;
 			}
-
 			rc = hw_intf->hw_ops.reserve(hw_intf->hw_priv,
 				&vfe_acquire,
 				sizeof(struct cam_vfe_acquire_args));
@@ -1643,6 +1642,54 @@ err:
 	return rc;
 }
 
+static int cam_ife_hw_mgr_acquire_csid_hw(
+	struct cam_ife_hw_mgr *ife_hw_mgr,
+	struct cam_csid_hw_reserve_resource_args  *csid_acquire,
+	bool is_start_lower_idx)
+{
+	int i;
+	int rc = -EINVAL;
+	struct cam_hw_intf  *hw_intf;
+
+	if (!ife_hw_mgr || !csid_acquire) {
+		CAM_ERR(CAM_ISP,
+			"Invalid args ife hw mgr %pK csid_acquire %pK",
+			ife_hw_mgr, csid_acquire);
+		return -EINVAL;
+	}
+
+	if (is_start_lower_idx) {
+		for (i =  0; i < CAM_IFE_CSID_HW_NUM_MAX; i++) {
+			if (!ife_hw_mgr->csid_devices[i])
+				continue;
+
+			hw_intf = ife_hw_mgr->csid_devices[i];
+			rc = hw_intf->hw_ops.reserve(hw_intf->hw_priv,
+				csid_acquire,
+				sizeof(struct
+					cam_csid_hw_reserve_resource_args));
+			if (!rc)
+				return rc;
+		}
+		return rc;
+	}
+
+	for (i = CAM_IFE_CSID_HW_NUM_MAX - 1; i >= 0; i--) {
+		if (!ife_hw_mgr->csid_devices[i])
+			continue;
+
+		hw_intf = ife_hw_mgr->csid_devices[i];
+		rc = hw_intf->hw_ops.reserve(hw_intf->hw_priv,
+			csid_acquire,
+			sizeof(struct
+				cam_csid_hw_reserve_resource_args));
+		if (!rc)
+			return rc;
+	}
+
+	return rc;
+}
+
 static int cam_ife_mgr_acquire_cid_res(
 	struct cam_ife_hw_mgr_ctx           *ife_ctx,
 	struct cam_isp_in_port_generic_info *in_port,
@@ -1735,52 +1782,21 @@ static int cam_ife_mgr_acquire_cid_res(
 	}
 
 	/* Acquire Left if not already acquired */
-	if (ife_ctx->is_fe_enable) {
-		for (i = 0; i < CAM_IFE_CSID_HW_NUM_MAX; i++) {
-			if (!ife_hw_mgr->csid_devices[i])
-				continue;
-
-			hw_intf = ife_hw_mgr->csid_devices[i];
-			rc = hw_intf->hw_ops.reserve(hw_intf->hw_priv,
-				&csid_acquire, sizeof(csid_acquire));
-			if (rc)
-				continue;
-			else {
-				cid_res_temp->hw_res[acquired_cnt++] =
-					csid_acquire.node_res;
-				break;
-			}
-		}
-		if (i == CAM_IFE_CSID_HW_NUM_MAX || !csid_acquire.node_res) {
-			CAM_ERR(CAM_ISP,
-				"Can not acquire ife cid resource for path %d",
-				path_res_id);
-			goto put_res;
-		}
-	} else {
-		for (i = CAM_IFE_CSID_HW_NUM_MAX - 1; i >= 0; i--) {
-			if (!ife_hw_mgr->csid_devices[i])
-				continue;
+	/* For dual IFE cases, start acquiring the lower idx first */
+	if (ife_ctx->is_fe_enable || in_port->usage_type)
+		rc = cam_ife_hw_mgr_acquire_csid_hw(ife_hw_mgr,
+			&csid_acquire, true);
+	else
+		rc = cam_ife_hw_mgr_acquire_csid_hw(ife_hw_mgr,
+			&csid_acquire, false);
 
-			hw_intf = ife_hw_mgr->csid_devices[i];
-			rc = hw_intf->hw_ops.reserve(hw_intf->hw_priv,
-				&csid_acquire, sizeof(csid_acquire));
-			if (rc)
-				continue;
-			else {
-				cid_res_temp->hw_res[acquired_cnt++] =
-					csid_acquire.node_res;
-				break;
-			}
-		}
-		if (i == -1 || !csid_acquire.node_res) {
-			CAM_ERR(CAM_ISP,
-				"Can not acquire ife cid resource for path %d",
-				path_res_id);
-			goto put_res;
-		}
+	if (rc || !csid_acquire.node_res) {
+		CAM_ERR(CAM_ISP,
+			"Can not acquire ife cid resource for path %d",
+			path_res_id);
+		goto put_res;
 	}
-
+	cid_res_temp->hw_res[acquired_cnt++] = csid_acquire.node_res;
 
 acquire_successful:
 	CAM_DBG(CAM_ISP, "CID left acquired success is_dual %d",
@@ -1791,7 +1807,9 @@ acquire_successful:
 	cid_res_temp->res_id = csid_acquire.node_res->res_id;
 	cid_res_temp->is_dual_vfe = in_port->usage_type;
 	ife_ctx->is_dual = (bool)in_port->usage_type;
-
+	if (ife_ctx->is_dual)
+		ife_ctx->master_hw_idx =
+			cid_res_temp->hw_res[0]->hw_intf->hw_idx;
 	if (in_port->num_out_res)
 		cid_res_temp->is_secure = out_port->secure_mode;
 
@@ -1828,6 +1846,8 @@ acquire_successful:
 			goto end;
 		}
 		cid_res_temp->hw_res[1] = csid_acquire.node_res;
+		ife_ctx->slave_hw_idx =
+			cid_res_temp->hw_res[1]->hw_intf->hw_idx;
 		CAM_DBG(CAM_ISP, "CID right acquired success is_dual %d",
 			in_port->usage_type);
 	}
@@ -6233,9 +6253,10 @@ static int cam_ife_hw_mgr_handle_hw_rup(
 
 	switch (event_info->res_id) {
 	case CAM_ISP_HW_VFE_IN_CAMIF:
-		if (ife_hw_mgr_ctx->is_dual)
-			if (event_info->hw_idx != 1)
-				break;
+		if ((ife_hw_mgr_ctx->is_dual) &&
+			(event_info->hw_idx !=
+			ife_hw_mgr_ctx->master_hw_idx))
+			break;
 
 		if (atomic_read(&ife_hw_mgr_ctx->overflow_pending))
 			break;
@@ -6276,8 +6297,8 @@ static int cam_ife_hw_mgr_check_irq_for_dual_vfe(
 {
 	int32_t                               rc = -1;
 	uint32_t                             *event_cnt = NULL;
-	uint32_t                              core_idx0 = 0;
-	uint32_t                              core_idx1 = 1;
+	uint32_t                              master_hw_idx;
+	uint32_t                              slave_hw_idx;
 
 	if (!ife_hw_mgr_ctx->is_dual)
 		return 0;
@@ -6296,24 +6317,27 @@ static int cam_ife_hw_mgr_check_irq_for_dual_vfe(
 		return 0;
 	}
 
-	if (event_cnt[core_idx0] == event_cnt[core_idx1]) {
+	master_hw_idx = ife_hw_mgr_ctx->master_hw_idx;
+	slave_hw_idx =  ife_hw_mgr_ctx->slave_hw_idx;
+
+	if (event_cnt[master_hw_idx] == event_cnt[slave_hw_idx]) {
 
-		event_cnt[core_idx0] = 0;
-		event_cnt[core_idx1] = 0;
+		event_cnt[master_hw_idx] = 0;
+		event_cnt[slave_hw_idx] = 0;
 
 		rc = 0;
 		return rc;
 	}
 
-	if ((event_cnt[core_idx0] &&
-		(event_cnt[core_idx0] - event_cnt[core_idx1] > 1)) ||
-		(event_cnt[core_idx1] &&
-		(event_cnt[core_idx1] - event_cnt[core_idx0] > 1))) {
+	if ((event_cnt[master_hw_idx] &&
+		(event_cnt[master_hw_idx] - event_cnt[slave_hw_idx] > 1)) ||
+		(event_cnt[slave_hw_idx] &&
+		(event_cnt[slave_hw_idx] - event_cnt[master_hw_idx] > 1))) {
 
 		CAM_ERR_RATE_LIMIT(CAM_ISP,
-			"One of the VFE could not generate hw event %d core_0_cnt %d core_1_cnt %d",
-			hw_event_type, event_cnt[core_idx0],
-			event_cnt[core_idx1]);
+			"One of the VFE could not generate hw event %d master[%d] core_cnt %d slave[%d] core_cnt %d",
+			hw_event_type, master_hw_idx, event_cnt[master_hw_idx],
+			slave_hw_idx, event_cnt[slave_hw_idx]);
 		rc = -1;
 		return rc;
 	}

+ 4 - 0
drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.h

@@ -101,6 +101,8 @@ struct cam_ife_hw_mgr_debug {
  * @list:                   used by the ctx list.
  * @common:                 common acquired context data
  * @ctx_index:              acquired context id.
+ * @master_hw_idx:          hw index for master core
+ * @slave_hw_idx:           hw index for slave core
  * @hw_mgr:                 IFE hw mgr which owns this context
  * @ctx_in_use:             flag to tell whether context is active
  * @res_list_ife_in:        Starting resource(TPG,PHY0, PHY1...) Can only be
@@ -144,6 +146,8 @@ struct cam_ife_hw_mgr_ctx {
 	struct cam_isp_hw_mgr_ctx       common;
 
 	uint32_t                        ctx_index;
+	uint32_t                        master_hw_idx;
+	uint32_t                        slave_hw_idx;
 	struct cam_ife_hw_mgr          *hw_mgr;
 	uint32_t                        ctx_in_use;