Explorar o código

msm: camera: csiphy: Handle the aon/non_aon configuration

Combo mode with AON/Main camera operation is corrupted if AON
image sensor probe later than non AON operation sensor mode. This
sequence will put csiphy access to AON FW, and at the time of
Non AON image sensor can not able to stream. To address this issue
add csiphy hw an knowledge of AON capability to acquire the resources
in such usecase. This can assure any of the combo mode sensor will
have access of csiphy hw before start streaming.

CRs-Fixed: 2926885
Change-Id: Id9e0fad6b7f305ca9b3688629bf7692340f73d8e
Signed-off-by: Jigarkumar Zala <[email protected]>
Jigarkumar Zala %!s(int64=4) %!d(string=hai) anos
pai
achega
f9512d306a

+ 84 - 27
drivers/cam_sensor_module/cam_csiphy/cam_csiphy_core.c

@@ -41,6 +41,7 @@ struct g_csiphy_data {
 	void __iomem *base_address;
 	uint8_t is_3phase;
 	uint32_t cpas_handle;
+	bool enable_aon_support;
 	struct cam_csiphy_aon_sel_params_t *aon_sel_param;
 };
 
@@ -1214,6 +1215,39 @@ static int cam_csiphy_update_lane(
 	return 0;
 }
 
+static int __csiphy_cpas_configure_for_main_or_aon(
+	bool get_access, uint32_t cpas_handle,
+	struct cam_csiphy_aon_sel_params_t *aon_sel_params)
+{
+	uint32_t aon_config = 0;
+
+	cam_cpas_reg_read(cpas_handle, CAM_CPAS_REG_CPASTOP,
+		aon_sel_params->aon_cam_sel_offset,
+		true, &aon_config);
+
+	if (get_access) {
+		aon_config &= ~(aon_sel_params->cam_sel_mask |
+			aon_sel_params->mclk_sel_mask);
+		CAM_DBG(CAM_CSIPHY,
+			"Selecting MainCamera over AON Camera");
+	} else if (!get_access) {
+		aon_config |= (aon_sel_params->cam_sel_mask |
+			aon_sel_params->mclk_sel_mask);
+		CAM_DBG(CAM_CSIPHY,
+			"Releasing MainCamera to AON Camera");
+	}
+
+	CAM_DBG(CAM_CSIPHY, "value of aon_config = %u", aon_config);
+	if (cam_cpas_reg_write(cpas_handle, CAM_CPAS_REG_CPASTOP,
+		aon_sel_params->aon_cam_sel_offset,
+		true, aon_config)) {
+		CAM_ERR(CAM_CSIPHY,
+				"CPAS AON sel register write failed");
+	}
+
+	return 0;
+}
+
 static int cam_csiphy_cpas_ops(
 	uint32_t cpas_handle, bool start)
 {
@@ -1255,10 +1289,24 @@ static int cam_csiphy_cpas_ops(
 	return rc;
 }
 
+int cam_csiphy_util_update_aon_registration
+	(uint32_t phy_idx, bool is_aon_user)
+{
+	/* aon support enable for the sensor associated with phy idx*/
+	if (phy_idx >= MAX_CSIPHY) {
+		CAM_ERR(CAM_CSIPHY,
+			"Invalid PHY index: %u", phy_idx);
+		return -EINVAL;
+	}
+
+	g_phy_data[phy_idx].enable_aon_support = is_aon_user;
+
+	return 0;
+}
+
 int cam_csiphy_util_update_aon_ops(
 	bool get_access, uint32_t phy_idx)
 {
-	uint32_t aon_config = 0;
 	uint32_t cpas_hdl = 0;
 	struct cam_csiphy_aon_sel_params_t *aon_sel_params;
 	int rc = 0;
@@ -1276,7 +1324,6 @@ int cam_csiphy_util_update_aon_ops(
 	cpas_hdl = g_phy_data[phy_idx].cpas_handle;
 	aon_sel_params = g_phy_data[phy_idx].aon_sel_param;
 
-	CAM_DBG(CAM_CSIPHY, "PHY idx: %d", phy_idx);
 	rc = cam_csiphy_cpas_ops(cpas_hdl, true);
 	if (rc) {
 		if (rc == -EPERM) {
@@ -1288,28 +1335,15 @@ int cam_csiphy_util_update_aon_ops(
 		}
 	}
 
-	cam_cpas_reg_read(cpas_hdl, CAM_CPAS_REG_CPASTOP,
-		aon_sel_params->aon_cam_sel_offset,
-		true, &aon_config);
-
-	if (get_access) {
-		aon_config &= ~(aon_sel_params->cam_sel_mask |
-			aon_sel_params->mclk_sel_mask);
-		CAM_DBG(CAM_CSIPHY,
-			"Selecting MainCamera over AON Camera");
-	} else if (!get_access) {
-		aon_config |= (aon_sel_params->cam_sel_mask |
-			aon_sel_params->mclk_sel_mask);
-		CAM_DBG(CAM_CSIPHY,
-			"Releasing MainCamera to AON Camera");
-	}
-
-	CAM_DBG(CAM_CSIPHY, "value of aon_config = %u", aon_config);
-	if (cam_cpas_reg_write(cpas_hdl, CAM_CPAS_REG_CPASTOP,
-		aon_sel_params->aon_cam_sel_offset,
-		true, aon_config)) {
-		CAM_ERR(CAM_CSIPHY,
-				"CPAS AON sel register write failed");
+	CAM_DBG(CAM_CSIPHY, "PHY idx: %d, AON_support is %s", phy_idx,
+		(get_access) ? "enable" : "disable");
+	rc = __csiphy_cpas_configure_for_main_or_aon(
+			get_access, cpas_hdl, aon_sel_params);
+	if (rc) {
+		CAM_ERR(CAM_CSIPHY, "Configuration for AON ops failed: rc: %d",
+			rc);
+		cam_csiphy_cpas_ops(cpas_hdl, false);
+		return rc;
 	}
 
 	if (rc != -EPERM)
@@ -1636,6 +1670,16 @@ int32_t cam_csiphy_core_cfg(void *phy_dev,
 					g_phy_data[csiphy_dev->soc_info.index].is_3phase);
 		}
 
+		if (g_phy_data[csiphy_dev->soc_info.index].enable_aon_support) {
+			rc = cam_csiphy_util_update_aon_ops(true, csiphy_dev->soc_info.index);
+			if (rc) {
+				CAM_ERR(CAM_CSIPHY,
+					"Error in setting up AON operation for phy_idx: %d, rc: %d",
+					csiphy_dev->soc_info.index, rc);
+				goto release_mutex;
+			}
+		}
+
 		csiphy_dev->acquire_count++;
 		CAM_DBG(CAM_CSIPHY, "ACQUIRE_CNT: %d",
 			csiphy_dev->acquire_count);
@@ -1789,6 +1833,15 @@ int32_t cam_csiphy_core_cfg(void *phy_dev,
 
 		if (csiphy_dev->acquire_count == 0) {
 			CAM_DBG(CAM_CSIPHY, "All PHY devices released");
+			if (g_phy_data[csiphy_dev->soc_info.index].enable_aon_support) {
+				rc = cam_csiphy_util_update_aon_ops(false, csiphy_dev->soc_info.index);
+				if (rc) {
+					CAM_WARN(CAM_CSIPHY,
+						"Error in releasing AON operation for phy_idx: %d, rc: %d",
+						csiphy_dev->soc_info.index, rc);
+					rc = 0;
+				}
+			}
 			csiphy_dev->combo_mode = 0;
 			csiphy_dev->csiphy_state = CAM_CSIPHY_INIT;
 		}
@@ -2025,6 +2078,8 @@ release_mutex:
 
 void cam_csiphy_register_baseaddress(struct csiphy_device *csiphy_dev)
 {
+	int phy_idx;
+
 	if (!csiphy_dev) {
 		CAM_WARN(CAM_CSIPHY, "Data is NULL");
 		return;
@@ -2036,10 +2091,12 @@ void cam_csiphy_register_baseaddress(struct csiphy_device *csiphy_dev)
 		return;
 	}
 
-	g_phy_data[csiphy_dev->soc_info.index].base_address =
+	phy_idx = csiphy_dev->soc_info.index;
+	g_phy_data[phy_idx].base_address =
 		csiphy_dev->soc_info.reg_map[0].mem_base;
-	g_phy_data[csiphy_dev->soc_info.index].cpas_handle =
+	g_phy_data[phy_idx].cpas_handle =
 		csiphy_dev->cpas_handle;
-	g_phy_data[csiphy_dev->soc_info.index].aon_sel_param =
+	g_phy_data[phy_idx].aon_sel_param =
 		csiphy_dev->ctrl_reg->csiphy_reg.aon_sel_params;
+	g_phy_data[phy_idx].enable_aon_support = false;
 }

+ 10 - 0
drivers/cam_sensor_module/cam_csiphy/cam_csiphy_core.h

@@ -72,4 +72,14 @@ int cam_csiphy_util_update_aon_ops(bool get_access, uint32_t phy_idx);
  * This API allows to print all the cphy/dphy specific status registers
  */
 int cam_csiphy_print_status_reg(struct csiphy_device *csiphy_dev);
+
+/**
+ * @phy_idx    : To acquire the correct PHY hw to do the operation with
+ *
+ * This API provides Utility/helper function to register AON Hw supprot for
+ * correct PHY hw.
+ *
+ */
+int cam_csiphy_util_update_aon_registration(uint32_t phy_idx, bool is_aon_user);
+
 #endif /* _CAM_CSIPHY_CORE_H_ */

+ 37 - 35
drivers/cam_sensor_module/cam_sensor/cam_sensor_core.c

@@ -812,6 +812,20 @@ int32_t cam_sensor_driver_cmd(struct cam_sensor_ctrl_t *s_ctrl,
 			goto free_power_settings;
 		}
 
+		if (s_ctrl->is_aon_user) {
+			CAM_DBG(CAM_SENSOR,
+				"Setup for Main Camera with csiphy index: %d",
+				s_ctrl->sensordata->subdev_id[SUB_MODULE_CSIPHY]);
+			rc = cam_sensor_util_aon_ops(true,
+				s_ctrl->sensordata->subdev_id[SUB_MODULE_CSIPHY]);
+			if (rc) {
+				CAM_WARN(CAM_SENSOR,
+					"Main camera access operation is not successful rc: %d",
+					rc);
+				goto free_power_settings;
+			}
+		}
+
 		/* Power up and probe sensor */
 		rc = cam_sensor_power_up(s_ctrl);
 		if (rc < 0) {
@@ -838,25 +852,41 @@ int32_t cam_sensor_driver_cmd(struct cam_sensor_ctrl_t *s_ctrl,
 			goto free_power_settings;
 		}
 
-		CAM_INFO(CAM_SENSOR,
-			"Probe success for %s slot:%d,slave_addr:0x%x,sensor_id:0x%x",
-			s_ctrl->sensor_name,
-			s_ctrl->soc_info.index,
-			s_ctrl->sensordata->slave_info.sensor_slave_addr,
-			s_ctrl->sensordata->slave_info.sensor_id);
-
 		rc = cam_sensor_power_down(s_ctrl);
 		if (rc < 0) {
 			CAM_ERR(CAM_SENSOR, "Fail in %s sensor Power Down",
 				s_ctrl->sensor_name);
 			goto free_power_settings;
 		}
+
+		if (s_ctrl->is_aon_user) {
+			CAM_DBG(CAM_SENSOR,
+				"Setup for AON FW with csiphy index: %d",
+				s_ctrl->sensordata->subdev_id[SUB_MODULE_CSIPHY]);
+			rc = cam_sensor_util_aon_ops(false,
+				s_ctrl->sensordata->subdev_id[SUB_MODULE_CSIPHY]);
+			if (rc) {
+				CAM_WARN(CAM_SENSOR,
+					"AON FW access operation is not successful rc: %d",
+					rc);
+				goto free_power_settings;
+			}
+		}
+
 		/*
 		 * Set probe succeeded flag to 1 so that no other camera shall
 		 * probed on this slot
 		 */
 		s_ctrl->is_probe_succeed = 1;
 		s_ctrl->sensor_state = CAM_SENSOR_INIT;
+
+		CAM_INFO(CAM_SENSOR,
+				"Probe success for %s slot:%d,slave_addr:0x%x,sensor_id:0x%x",
+				s_ctrl->sensor_name,
+				s_ctrl->soc_info.index,
+				s_ctrl->sensordata->slave_info.sensor_slave_addr,
+				s_ctrl->sensordata->slave_info.sensor_id);
+
 	}
 		break;
 	case CAM_ACQUIRE_DEV: {
@@ -1293,20 +1323,6 @@ int cam_sensor_power_up(struct cam_sensor_ctrl_t *s_ctrl)
 		}
 	}
 
-	if (s_ctrl->is_aon_user) {
-		CAM_DBG(CAM_SENSOR,
-			"Setup for Main Camera with csiphy index: %d",
-			s_ctrl->sensordata->subdev_id[SUB_MODULE_CSIPHY]);
-		rc = cam_sensor_util_aon_ops(true,
-			s_ctrl->sensordata->subdev_id[SUB_MODULE_CSIPHY]);
-		if (rc) {
-			CAM_WARN(CAM_SENSOR,
-				"Main camera access opertion is not successful rc: %d",
-				rc);
-			return rc;
-		}
-	}
-
 	rc = cam_sensor_core_power_up(power_info, soc_info);
 	if (rc < 0) {
 		CAM_ERR(CAM_SENSOR, "core power up failed:%d", rc);
@@ -1366,20 +1382,6 @@ int cam_sensor_power_down(struct cam_sensor_ctrl_t *s_ctrl)
 		}
 	}
 
-	if (s_ctrl->is_aon_user) {
-		CAM_DBG(CAM_SENSOR,
-			"Setup for AON FW with csiphy index: %d",
-			s_ctrl->sensordata->subdev_id[SUB_MODULE_CSIPHY]);
-		rc = cam_sensor_util_aon_ops(false,
-			s_ctrl->sensordata->subdev_id[SUB_MODULE_CSIPHY]);
-		if (rc) {
-			CAM_WARN(CAM_SENSOR,
-				"AON FW access opertion is not successful rc: %d",
-				rc);
-			return rc;
-		}
-	}
-
 	camera_io_release(&(s_ctrl->io_master_info));
 
 	return rc;

+ 8 - 0
drivers/cam_sensor_module/cam_sensor/cam_sensor_soc.c

@@ -215,6 +215,14 @@ static int32_t cam_sensor_driver_get_dt_data(struct cam_sensor_ctrl_t *s_ctrl)
 		s_ctrl->is_aon_user = true;
 	}
 
+	rc = cam_sensor_util_aon_registration(
+		s_ctrl->sensordata->subdev_id[SUB_MODULE_CSIPHY],
+		s_ctrl->is_aon_user);
+	if (rc) {
+		CAM_ERR(CAM_SENSOR, "Aon registration failed, rc: %d", rc);
+		goto FREE_SENSOR_DATA;
+	}
+
 	return rc;
 
 FREE_SENSOR_DATA:

+ 6 - 0
drivers/cam_sensor_module/cam_sensor_utils/cam_sensor_util.h

@@ -89,4 +89,10 @@ static inline int cam_sensor_util_aon_ops(bool get_access, uint32_t phy_idx)
 	return cam_csiphy_util_update_aon_ops(get_access, phy_idx);
 }
 
+static inline int cam_sensor_util_aon_registration(uint32_t phy_idx, bool aon_user)
+{
+	CAM_DBG(CAM_SENSOR, "Regsiter phy_idx: %u for AON operatoin: %d", phy_idx, aon_user);
+	return cam_csiphy_util_update_aon_registration(phy_idx, aon_user);
+}
+
 #endif /* _CAM_SENSOR_UTIL_H_ */