Browse Source

msm: camera: sensor: Move main/aon selection in power operation

Currently main/aon control operation is getting trigger explicitly
from probe control with the reason that Probe IOCTL is exclusive to
sensor core. This operation is required for making sure to get the
control to hlos before reading slave id. Further post probe operation
main/aon control selection is managed by csiphy driver at the time of
acquire and release ioctl call. This will block the main camera
operation after probe ioctl successful and before csiphy acquire ioctl
call. There are some usecase where sensor needs to perform several
operation independently. To add this support moving the main/aon
selection call from probe only ioctl operation to power_up/down call
flow. This call is made upon when it is required to operate on sensor.
This change will help to give AON sensor more flexibility to perform
independently. Further CSIPHY also have the same selection process
in it's acquire ioctl operation which can help to make the hlos end
selection in combo mode scenario.

CRs-Fixed: 3084672
Change-Id: Ic1c6ad41e35605a2291e7e50ff0fe94a0ab30624
Signed-off-by: Jigarkumar Zala <[email protected]>
Signed-off-by: Jigar Agrawal <[email protected]>
Jigar Agrawal 3 years ago
parent
commit
bfbdc29297

+ 30 - 25
drivers/cam_sensor_module/cam_csiphy/cam_csiphy_core.c

@@ -34,6 +34,7 @@
 #define CAM_MAX_PHYS_PER_CP_CTRL_REG 4
 #define CAM_MAX_PHYS_PER_CP_CTRL_REG 4
 
 
 static DEFINE_MUTEX(active_csiphy_cnt_mutex);
 static DEFINE_MUTEX(active_csiphy_cnt_mutex);
+static DEFINE_MUTEX(main_aon_selection);
 
 
 static int csiphy_onthego_reg_count;
 static int csiphy_onthego_reg_count;
 static unsigned int csiphy_onthego_regs[150];
 static unsigned int csiphy_onthego_regs[150];
@@ -44,6 +45,7 @@ struct g_csiphy_data {
 	void __iomem *base_address;
 	void __iomem *base_address;
 	uint8_t is_3phase;
 	uint8_t is_3phase;
 	uint32_t cpas_handle;
 	uint32_t cpas_handle;
+	bool is_configured_for_main;
 	bool enable_aon_support;
 	bool enable_aon_support;
 	struct cam_csiphy_aon_sel_params_t *aon_sel_param;
 	struct cam_csiphy_aon_sel_params_t *aon_sel_param;
 };
 };
@@ -1226,36 +1228,43 @@ static int cam_csiphy_update_lane_selection(struct csiphy_device *csiphy, int in
 }
 }
 
 
 static int __csiphy_cpas_configure_for_main_or_aon(
 static int __csiphy_cpas_configure_for_main_or_aon(
-	bool get_access, uint32_t cpas_handle,
+	bool get_access, uint32_t phy_idx,
 	struct cam_csiphy_aon_sel_params_t *aon_sel_params)
 	struct cam_csiphy_aon_sel_params_t *aon_sel_params)
 {
 {
+	int rc = 0;
 	uint32_t aon_config = 0;
 	uint32_t aon_config = 0;
+	uint32_t cpas_handle = g_phy_data[phy_idx].cpas_handle;
 
 
 	cam_cpas_reg_read(cpas_handle, CAM_CPAS_REG_CPASTOP,
 	cam_cpas_reg_read(cpas_handle, CAM_CPAS_REG_CPASTOP,
 		aon_sel_params->aon_cam_sel_offset,
 		aon_sel_params->aon_cam_sel_offset,
 		true, &aon_config);
 		true, &aon_config);
 
 
-	if (get_access) {
+	if (get_access && !g_phy_data[phy_idx].is_configured_for_main) {
 		aon_config &= ~(aon_sel_params->cam_sel_mask |
 		aon_config &= ~(aon_sel_params->cam_sel_mask |
 			aon_sel_params->mclk_sel_mask);
 			aon_sel_params->mclk_sel_mask);
-		CAM_DBG(CAM_CSIPHY,
+		CAM_INFO(CAM_CSIPHY,
 			"Selecting MainCamera over AON Camera");
 			"Selecting MainCamera over AON Camera");
-	} else if (!get_access) {
+		g_phy_data[phy_idx].is_configured_for_main = true;
+	} else if (!get_access && g_phy_data[phy_idx].is_configured_for_main) {
 		aon_config |= (aon_sel_params->cam_sel_mask |
 		aon_config |= (aon_sel_params->cam_sel_mask |
 			aon_sel_params->mclk_sel_mask);
 			aon_sel_params->mclk_sel_mask);
-		CAM_DBG(CAM_CSIPHY,
+		CAM_INFO(CAM_CSIPHY,
 			"Releasing MainCamera to AON Camera");
 			"Releasing MainCamera to AON Camera");
+		g_phy_data[phy_idx].is_configured_for_main = false;
+	} else {
+		CAM_DBG(CAM_CSIPHY, "Already configured for %s",
+			get_access ? "Main" : "AON");
+		return 0;
 	}
 	}
 
 
 	CAM_DBG(CAM_CSIPHY, "value of aon_config = %u", aon_config);
 	CAM_DBG(CAM_CSIPHY, "value of aon_config = %u", aon_config);
-	if (cam_cpas_reg_write(cpas_handle, CAM_CPAS_REG_CPASTOP,
+	rc = cam_cpas_reg_write(cpas_handle, CAM_CPAS_REG_CPASTOP,
 		aon_sel_params->aon_cam_sel_offset,
 		aon_sel_params->aon_cam_sel_offset,
-		true, aon_config)) {
-		CAM_ERR(CAM_CSIPHY,
-				"CPAS AON sel register write failed");
-	}
+		true, aon_config);
+	if (rc)
+		CAM_ERR(CAM_CSIPHY, "CPAS AON sel register write failed");
 
 
-	return 0;
+	return rc;
 }
 }
 
 
 static int cam_csiphy_cpas_ops(
 static int cam_csiphy_cpas_ops(
@@ -1344,31 +1353,26 @@ int cam_csiphy_util_update_aon_ops(
 	cpas_hdl = g_phy_data[phy_idx].cpas_handle;
 	cpas_hdl = g_phy_data[phy_idx].cpas_handle;
 	aon_sel_params = g_phy_data[phy_idx].aon_sel_param;
 	aon_sel_params = g_phy_data[phy_idx].aon_sel_param;
 
 
+	mutex_lock(&main_aon_selection);
 	rc = cam_csiphy_cpas_ops(cpas_hdl, true);
 	rc = cam_csiphy_cpas_ops(cpas_hdl, true);
 	if (rc) {
 	if (rc) {
-		if (rc == -EPERM) {
-			CAM_WARN(CAM_CSIPHY,
-				"CPHY: %d is already in start state");
-		} else {
-			CAM_ERR(CAM_CSIPHY, "voting CPAS: %d failed", rc);
-			return rc;
-		}
+		CAM_ERR(CAM_CSIPHY, "voting CPAS: %d failed", rc);
+		goto exit;
 	}
 	}
 
 
 	CAM_DBG(CAM_CSIPHY, "PHY idx: %d, AON_support is %s", phy_idx,
 	CAM_DBG(CAM_CSIPHY, "PHY idx: %d, AON_support is %s", phy_idx,
 		(get_access) ? "enable" : "disable");
 		(get_access) ? "enable" : "disable");
+
 	rc = __csiphy_cpas_configure_for_main_or_aon(
 	rc = __csiphy_cpas_configure_for_main_or_aon(
-			get_access, cpas_hdl, aon_sel_params);
-	if (rc) {
+			get_access, phy_idx, aon_sel_params);
+	if (rc)
 		CAM_ERR(CAM_CSIPHY, "Configuration for AON ops failed: rc: %d",
 		CAM_ERR(CAM_CSIPHY, "Configuration for AON ops failed: rc: %d",
 			rc);
 			rc);
-		cam_csiphy_cpas_ops(cpas_hdl, false);
-		return rc;
-	}
 
 
-	if (rc != -EPERM)
-		cam_csiphy_cpas_ops(cpas_hdl, false);
+	cam_csiphy_cpas_ops(cpas_hdl, false);
 
 
+exit:
+	mutex_unlock(&main_aon_selection);
 	return rc;
 	return rc;
 }
 }
 
 
@@ -2321,6 +2325,7 @@ int cam_csiphy_register_baseaddress(struct csiphy_device *csiphy_dev)
 	g_phy_data[phy_idx].aon_sel_param =
 	g_phy_data[phy_idx].aon_sel_param =
 		csiphy_dev->ctrl_reg->csiphy_reg->aon_sel_params;
 		csiphy_dev->ctrl_reg->csiphy_reg->aon_sel_params;
 	g_phy_data[phy_idx].enable_aon_support = false;
 	g_phy_data[phy_idx].enable_aon_support = false;
+	g_phy_data[phy_idx].is_configured_for_main = false;
 
 
 	return 0;
 	return 0;
 }
 }

+ 29 - 28
drivers/cam_sensor_module/cam_sensor/cam_sensor_core.c

@@ -821,20 +821,6 @@ int32_t cam_sensor_driver_cmd(struct cam_sensor_ctrl_t *s_ctrl,
 			goto free_power_settings;
 			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 */
 		/* Power up and probe sensor */
 		rc = cam_sensor_power_up(s_ctrl);
 		rc = cam_sensor_power_up(s_ctrl);
 		if (rc < 0) {
 		if (rc < 0) {
@@ -868,20 +854,6 @@ int32_t cam_sensor_driver_cmd(struct cam_sensor_ctrl_t *s_ctrl,
 			goto free_power_settings;
 			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
 		 * Set probe succeeded flag to 1 so that no other camera shall
 		 * probed on this slot
 		 * probed on this slot
@@ -1352,6 +1324,20 @@ int cam_sensor_power_up(struct cam_sensor_ctrl_t *s_ctrl)
 		return rc;
 		return rc;
 	}
 	}
 
 
+	if (s_ctrl->is_aon_user) {
+		CAM_INFO(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_ERR(CAM_SENSOR,
+				"Main camera access operation is not successful rc: %d",
+				rc);
+			return rc;
+		}
+	}
+
 	rc = camera_io_init(&(s_ctrl->io_master_info));
 	rc = camera_io_init(&(s_ctrl->io_master_info));
 	if (rc < 0) {
 	if (rc < 0) {
 		CAM_ERR(CAM_SENSOR, "cci_init failed: rc: %d", rc);
 		CAM_ERR(CAM_SENSOR, "cci_init failed: rc: %d", rc);
@@ -1359,6 +1345,7 @@ int cam_sensor_power_up(struct cam_sensor_ctrl_t *s_ctrl)
 	}
 	}
 
 
 	return rc;
 	return rc;
+
 cci_failure:
 cci_failure:
 	if (cam_sensor_util_power_down(power_info, soc_info))
 	if (cam_sensor_util_power_down(power_info, soc_info))
 		CAM_ERR(CAM_SENSOR, "power down failure");
 		CAM_ERR(CAM_SENSOR, "power down failure");
@@ -1394,6 +1381,20 @@ int cam_sensor_power_down(struct cam_sensor_ctrl_t *s_ctrl)
 		return rc;
 		return rc;
 	}
 	}
 
 
+	if (s_ctrl->is_aon_user) {
+		CAM_INFO(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_ERR(CAM_SENSOR,
+				"AON FW access operation is not successful rc: %d",
+				rc);
+			return rc;
+		}
+	}
+
 	if (s_ctrl->bob_pwm_switch) {
 	if (s_ctrl->bob_pwm_switch) {
 		rc = cam_sensor_bob_pwm_mode_switch(soc_info,
 		rc = cam_sensor_bob_pwm_mode_switch(soc_info,
 			s_ctrl->bob_reg_index, false);
 			s_ctrl->bob_reg_index, false);