Переглянути джерело

Merge "msm: camera: cci: Add CCI Global reset during CCI HW init" into camera-kernel.lnx.4.0

Camera Software Integration 4 роки тому
батько
коміт
1a18173476

+ 1 - 1
drivers/cam_sensor_module/cam_cci/cam_cci_core.c

@@ -1171,7 +1171,7 @@ static int32_t cam_cci_burst_read(struct v4l2_subdev *sd,
 					CCI_I2C_M0_READ_BUF_LEVEL_ADDR +
 					master * 0x100);
 				CAM_ERR(CAM_CCI,
-					"wait timeout for RD_DONE irq for cci: %d, master: %d, rc = %d FIFO buf_lvl:0x%x, rc: %d",
+					"wait timeout for RD_DONE irq for cci: %d, master: %d, FIFO buf_lvl:0x%x, rc: %d",
 					cci_dev->soc_info.index, master,
 					val, rc);
 				cam_cci_dump_registers(cci_dev,

+ 0 - 1
drivers/cam_sensor_module/cam_cci/cam_cci_dev.h

@@ -135,7 +135,6 @@ struct cam_cci_master_info {
 	struct semaphore master_sem;
 	bool is_first_req;
 	uint16_t freq_ref_cnt;
-	bool is_initilized;
 };
 
 struct cam_cci_clk_params_t {

+ 102 - 101
drivers/cam_sensor_module/cam_cci/cam_cci_soc.c

@@ -13,6 +13,7 @@ static int cam_cci_init_master(struct cci_device *cci_dev,
 	void __iomem *base = NULL;
 	struct cam_hw_soc_info *soc_info = NULL;
 	uint32_t max_queue_0_size = 0, max_queue_1_size = 0;
+	struct cam_cci_master_info *cci_master;
 
 	soc_info = &cci_dev->soc_info;
 	base = soc_info->reg_map[0].mem_base;
@@ -25,51 +26,41 @@ static int cam_cci_init_master(struct cci_device *cci_dev,
 		max_queue_1_size = CCI_I2C_QUEUE_1_SIZE;
 	}
 
-	cci_dev->master_active_slave[master]++;
-	if (!cci_dev->cci_master_info[master].is_initilized) {
-		/* Re-initialize the completion */
-		reinit_completion(
-		&cci_dev->cci_master_info[master].reset_complete);
-		reinit_completion(&cci_dev->cci_master_info[master].rd_done);
-
-		/* reinit the reports for the queue */
-		for (i = 0; i < NUM_QUEUES; i++)
-			reinit_completion(
-			&cci_dev->cci_master_info[master].report_q[i]);
-
-		/* Set reset pending flag to true */
-		cci_dev->cci_master_info[master].reset_pending = true;
-		cam_io_w_mb((master == MASTER_0) ?
-			CCI_M0_RESET_RMSK : CCI_M1_RESET_RMSK,
-			base + CCI_RESET_CMD_ADDR);
-		if (!wait_for_completion_timeout(
-			&cci_dev->cci_master_info[master].reset_complete,
-			CCI_TIMEOUT)) {
-			CAM_ERR(CAM_CCI,
-				"Failed: reset complete timeout for master: %d",
-				master);
-			rc = -ETIMEDOUT;
-			cci_dev->master_active_slave[master]--;
-			return rc;
-		}
-
-		flush_workqueue(cci_dev->write_wq[master]);
+	cci_master = &cci_dev->cci_master_info[master];
+	/* Re-initialize the completion */
+	reinit_completion(&cci_master->reset_complete);
+	reinit_completion(&cci_master->rd_done);
+
+	/* reinit the reports for the queue */
+	for (i = 0; i < NUM_QUEUES; i++)
+		reinit_completion(&cci_master->report_q[i]);
+
+	/* Set reset pending flag to true */
+	cci_master->reset_pending = true;
+	cam_io_w_mb((master == MASTER_0) ?
+		CCI_M0_RESET_RMSK : CCI_M1_RESET_RMSK,
+		base + CCI_RESET_CMD_ADDR);
+	if (!wait_for_completion_timeout(
+		&cci_master->reset_complete, CCI_TIMEOUT)) {
+		CAM_ERR(CAM_CCI,
+			"Failed: reset complete timeout for master: %d",
+			master);
+		rc = -ETIMEDOUT;
+		return rc;
+	}
+	flush_workqueue(cci_dev->write_wq[master]);
 
-		/* Setting up the queue size for master */
-		cci_dev->cci_i2c_queue_info[master][QUEUE_0].max_queue_size
-					= max_queue_0_size;
-		cci_dev->cci_i2c_queue_info[master][QUEUE_1].max_queue_size
-					= max_queue_1_size;
+	/* Setting up the queue size for master */
+	cci_dev->cci_i2c_queue_info[master][QUEUE_0].max_queue_size
+				= max_queue_0_size;
+	cci_dev->cci_i2c_queue_info[master][QUEUE_1].max_queue_size
+				= max_queue_1_size;
 
-		CAM_DBG(CAM_CCI, "CCI Master[%d] :: Q0: %d Q1: %d", master,
-			cci_dev->cci_i2c_queue_info[master][QUEUE_0]
-				.max_queue_size,
-			cci_dev->cci_i2c_queue_info[master][QUEUE_1]
-				.max_queue_size);
+	CAM_DBG(CAM_CCI, "CCI Master[%d] :: Q0: %d Q1: %d", master,
+		cci_dev->cci_i2c_queue_info[master][QUEUE_0].max_queue_size,
+		cci_dev->cci_i2c_queue_info[master][QUEUE_1].max_queue_size);
 
-		cci_dev->cci_master_info[master].status = 0;
-		cci_dev->cci_master_info[master].is_initilized = true;
-	}
+	cci_dev->cci_master_info[master].status = 0;
 
 	return 0;
 }
@@ -117,82 +108,94 @@ int cam_cci_init(struct v4l2_subdev *sd,
 		return rc;
 	}
 
-	if (cci_dev->ref_count++) {
-		rc = cam_cci_init_master(cci_dev, master);
+	if (!cci_dev->ref_count) {
+		ahb_vote.type = CAM_VOTE_ABSOLUTE;
+		ahb_vote.vote.level = CAM_LOWSVS_VOTE;
+		axi_vote.num_paths = 1;
+		axi_vote.axi_path[0].path_data_type = CAM_AXI_PATH_DATA_ALL;
+		axi_vote.axi_path[0].transac_type = CAM_AXI_TRANSACTION_WRITE;
+		axi_vote.axi_path[0].camnoc_bw = CAM_CPAS_DEFAULT_AXI_BW;
+		axi_vote.axi_path[0].mnoc_ab_bw = CAM_CPAS_DEFAULT_AXI_BW;
+		axi_vote.axi_path[0].mnoc_ib_bw = CAM_CPAS_DEFAULT_AXI_BW;
+
+		rc = cam_cpas_start(cci_dev->cpas_handle, &ahb_vote, &axi_vote);
 		if (rc) {
-			CAM_ERR(CAM_CCI, "Failed to init: Master: %d: rc: %d",
-				master, rc);
-			cci_dev->ref_count--;
+			CAM_ERR(CAM_CCI, "CPAS start failed rc= %d", rc);
+			return rc;
 		}
-		CAM_DBG(CAM_CCI, "ref_count %d, master: %d",
-			cci_dev->ref_count, master);
-		return rc;
-	}
 
-	ahb_vote.type = CAM_VOTE_ABSOLUTE;
-	ahb_vote.vote.level = CAM_LOWSVS_VOTE;
-	axi_vote.num_paths = 1;
-	axi_vote.axi_path[0].path_data_type = CAM_AXI_PATH_DATA_ALL;
-	axi_vote.axi_path[0].transac_type = CAM_AXI_TRANSACTION_WRITE;
-	axi_vote.axi_path[0].camnoc_bw = CAM_CPAS_DEFAULT_AXI_BW;
-	axi_vote.axi_path[0].mnoc_ab_bw = CAM_CPAS_DEFAULT_AXI_BW;
-	axi_vote.axi_path[0].mnoc_ib_bw = CAM_CPAS_DEFAULT_AXI_BW;
+		cam_cci_get_clk_rates(cci_dev, c_ctrl);
 
-	rc = cam_cpas_start(cci_dev->cpas_handle, &ahb_vote, &axi_vote);
-	if (rc) {
-		CAM_ERR(CAM_CCI, "CPAS start failed rc= %d", rc);
-		return rc;
-	}
+		/* Enable Regulators and IRQ*/
+		rc = cam_soc_util_enable_platform_resource(soc_info, true,
+			CAM_LOWSVS_VOTE, true);
+		if (rc < 0) {
+			CAM_DBG(CAM_CCI,
+				"request platform resources failed,rc:%d", rc);
+			goto platform_enable_failed;
+		}
 
-	cam_cci_get_clk_rates(cci_dev, c_ctrl);
+		cci_dev->hw_version = cam_io_r_mb(base + CCI_HW_VERSION_ADDR);
+		CAM_DBG(CAM_CCI, "hw_version = 0x%x", cci_dev->hw_version);
 
-	/* Enable Regulators and IRQ*/
-	rc = cam_soc_util_enable_platform_resource(soc_info, true,
-		CAM_LOWSVS_VOTE, true);
-	if (rc < 0) {
-		CAM_DBG(CAM_CCI, "request platform resources failed, rc: %d",
-			rc);
-		goto platform_enable_failed;
-	}
+		cci_dev->payload_size = MSM_CCI_WRITE_DATA_PAYLOAD_SIZE_11;
+		cci_dev->support_seq_write = 1;
 
-	cci_dev->hw_version = cam_io_r_mb(base + CCI_HW_VERSION_ADDR);
-	CAM_DBG(CAM_CCI, "hw_version = 0x%x", cci_dev->hw_version);
+		for (i = 0; i < MASTER_MAX; i++)
+			cci_dev->i2c_freq_mode[i] = I2C_MAX_MODES;
 
-	cci_dev->payload_size = MSM_CCI_WRITE_DATA_PAYLOAD_SIZE_11;
-	cci_dev->support_seq_write = 1;
+		reinit_completion(
+			&cci_dev->cci_master_info[master].reset_complete);
+		cci_dev->cci_master_info[master].reset_pending = true;
+		cci_dev->cci_master_info[master].status = 0;
 
-	rc = cam_cci_init_master(cci_dev, master);
-	if (rc) {
-		CAM_ERR(CAM_CCI, "Failed to init: Master: %d, rc: %d",
-			master, rc);
-		goto reset_complete_failed;
-	}
+		cam_io_w_mb(CCI_RESET_CMD_RMSK, base + CCI_RESET_CMD_ADDR);
 
-	for (i = 0; i < MASTER_MAX; i++)
-		cci_dev->i2c_freq_mode[i] = I2C_MAX_MODES;
+		if (!wait_for_completion_timeout(
+			&cci_dev->cci_master_info[master].reset_complete,
+			CCI_TIMEOUT)) {
+			CAM_ERR(CAM_CCI,
+				"Failed: reset complete timeout for master: %d",
+				master);
+			rc = -ETIMEDOUT;
+			goto platform_enable_failed;
+		}
 
-	cam_io_w_mb(CCI_IRQ_MASK_0_RMSK, base + CCI_IRQ_MASK_0_ADDR);
-	cam_io_w_mb(CCI_IRQ_MASK_0_RMSK, base + CCI_IRQ_CLEAR_0_ADDR);
-	cam_io_w_mb(CCI_IRQ_MASK_1_RMSK, base + CCI_IRQ_MASK_1_ADDR);
-	cam_io_w_mb(CCI_IRQ_MASK_1_RMSK, base + CCI_IRQ_CLEAR_1_ADDR);
-	cam_io_w_mb(0x1, base + CCI_IRQ_GLOBAL_CLEAR_CMD_ADDR);
-
-	/* Set RD FIFO threshold for M0 & M1 */
-	if (cci_dev->hw_version != CCI_VERSION_1_2_9) {
-		cam_io_w_mb(CCI_I2C_RD_THRESHOLD_VALUE,
-				base + CCI_I2C_M0_RD_THRESHOLD_ADDR);
-		cam_io_w_mb(CCI_I2C_RD_THRESHOLD_VALUE,
-				base + CCI_I2C_M1_RD_THRESHOLD_ADDR);
+		cam_io_w_mb(CCI_IRQ_MASK_0_RMSK, base + CCI_IRQ_MASK_0_ADDR);
+		cam_io_w_mb(CCI_IRQ_MASK_0_RMSK, base + CCI_IRQ_CLEAR_0_ADDR);
+		cam_io_w_mb(CCI_IRQ_MASK_1_RMSK, base + CCI_IRQ_MASK_1_ADDR);
+		cam_io_w_mb(CCI_IRQ_MASK_1_RMSK, base + CCI_IRQ_CLEAR_1_ADDR);
+		cam_io_w_mb(0x1, base + CCI_IRQ_GLOBAL_CLEAR_CMD_ADDR);
+
+		/* Set RD FIFO threshold for M0 & M1 */
+		if (cci_dev->hw_version != CCI_VERSION_1_2_9) {
+			cam_io_w_mb(CCI_I2C_RD_THRESHOLD_VALUE,
+					base + CCI_I2C_M0_RD_THRESHOLD_ADDR);
+			cam_io_w_mb(CCI_I2C_RD_THRESHOLD_VALUE,
+					base + CCI_I2C_M1_RD_THRESHOLD_ADDR);
+		}
+		cci_dev->cci_state = CCI_STATE_ENABLED;
 	}
+	cci_dev->ref_count++;
 
-	cci_dev->cci_state = CCI_STATE_ENABLED;
+	if (!cci_dev->master_active_slave[master]) {
+		rc = cam_cci_init_master(cci_dev, master);
+		if (rc) {
+			CAM_ERR(CAM_CCI, "Failed to init: Master: %d: rc: %d",
+				master, rc);
+			goto reset_complete_failed;
+		}
+		CAM_DBG(CAM_CCI, "ref_count %d, master: %d",
+			cci_dev->ref_count, master);
+	}
+	cci_dev->master_active_slave[master]++;
 
 	return 0;
 
 reset_complete_failed:
 	cam_soc_util_disable_platform_resource(soc_info, 1, 1);
-platform_enable_failed:
 	cci_dev->ref_count--;
+platform_enable_failed:
 	cam_cpas_stop(cci_dev->cpas_handle);
 
 	return rc;
@@ -213,7 +216,6 @@ static void cam_cci_init_cci_params(struct cci_device *new_cci_dev)
 	for (i = 0; i < MASTER_MAX; i++) {
 		new_cci_dev->cci_master_info[i].status = 0;
 		new_cci_dev->cci_master_info[i].is_first_req = true;
-		new_cci_dev->cci_master_info[i].is_initilized = false;
 		mutex_init(&new_cci_dev->cci_master_info[i].mutex);
 		sema_init(&new_cci_dev->cci_master_info[i].master_sem, 1);
 		spin_lock_init(&new_cci_dev->cci_master_info[i].freq_cnt);
@@ -404,7 +406,6 @@ int cam_cci_soc_release(struct cci_device *cci_dev,
 	}
 
 	if (!(--cci_dev->master_active_slave[master])) {
-		cci_dev->cci_master_info[master].is_initilized = false;
 		CAM_DBG(CAM_CCI,
 			"All submodules are released for master: %d", master);
 	}