소스 검색

msm: camera: cci: Move load report cmd in lock context

This change moves load report cmd in lock context,
then all sequence in one queue will be defined as
atomic queue commands without interruption from
the other queue commands.

CRs-Fixed: 3415571
Change-Id: Icda2271b580bd3f462c306ad0f229969a94079f6
Signed-off-by: Depeng Shao <[email protected]>
Depeng Shao 2 년 전
부모
커밋
a039cf068a
1개의 변경된 파일32개의 추가작업 그리고 4개의 파일을 삭제
  1. 32 4
      drivers/cam_sensor_module/cam_cci/cam_cci_core.c

+ 32 - 4
drivers/cam_sensor_module/cam_cci/cam_cci_core.c

@@ -197,13 +197,39 @@ static int32_t cam_cci_lock_queue(struct cci_device *cci_dev,
 	enum cci_i2c_master_t master,
 	enum cci_i2c_queue_t queue, uint32_t en)
 {
-	uint32_t val;
+	int32_t                 rc = 0;
+	uint32_t                val = 0;
+	uint32_t                read_val = 0;
+	struct cam_hw_soc_info *soc_info =
+		&cci_dev->soc_info;
+	void __iomem           *base =
+		soc_info->reg_map[0].mem_base;
+	uint32_t                reg_offset =
+		master * 0x200 + queue * 0x100;
 
 	if (queue != PRIORITY_QUEUE)
-		return 0;
+		goto end;
+
+	read_val = cam_io_r_mb(base +
+		CCI_I2C_M0_Q0_CUR_WORD_CNT_ADDR + reg_offset);
 
 	val = en ? CCI_I2C_LOCK_CMD : CCI_I2C_UNLOCK_CMD;
-	return cam_cci_write_i2c_queue(cci_dev, val, master, queue);
+	rc = cam_cci_write_i2c_queue(cci_dev, val, master, queue);
+
+	if (rc) {
+		CAM_ERR(CAM_CCI,
+			"CCI%d_I2C_M%d_Q%d Failed to write i2c data:0x%x rc:%d",
+			cci_dev->soc_info.index, master, queue, val, rc);
+		goto end;
+	}
+
+	read_val++;
+
+	cam_io_w_mb(read_val, base +
+		CCI_I2C_M0_Q0_EXEC_WORD_CNT_ADDR + reg_offset);
+
+end:
+	return rc;
 }
 
 
@@ -356,7 +382,6 @@ static int32_t cam_cci_wait_report_cmd(struct cci_device *cci_dev,
 
 	uint32_t reg_val = 1 << ((master * 2) + queue);
 
-	cam_cci_load_report_cmd(cci_dev, master, queue);
 	spin_lock_irqsave(
 		&cci_dev->cci_master_info[master].lock_q[queue], flags);
 	atomic_set(&cci_dev->cci_master_info[master].q_free[queue], 1);
@@ -380,6 +405,7 @@ static int32_t cam_cci_transfer_end(struct cci_device *cci_dev,
 	if (atomic_read(&cci_dev->cci_master_info[master].q_free[queue]) == 0) {
 		spin_unlock_irqrestore(
 			&cci_dev->cci_master_info[master].lock_q[queue], flags);
+		cam_cci_load_report_cmd(cci_dev, master, queue);
 		rc = cam_cci_lock_queue(cci_dev, master, queue, 0);
 		if (rc < 0) {
 			CAM_ERR(CAM_CCI,
@@ -407,6 +433,7 @@ static int32_t cam_cci_transfer_end(struct cci_device *cci_dev,
 				cci_dev->soc_info.index, master, queue, rc);
 			return rc;
 		}
+		cam_cci_load_report_cmd(cci_dev, master, queue);
 		rc = cam_cci_lock_queue(cci_dev, master, queue, 0);
 		if (rc < 0) {
 			CAM_ERR(CAM_CCI,
@@ -498,6 +525,7 @@ static int32_t cam_cci_process_full_q(struct cci_device *cci_dev,
 		spin_unlock_irqrestore(
 			&cci_dev->cci_master_info[master].lock_q[queue], flags);
 		CAM_DBG(CAM_CCI, "CCI%d_I2C_M%d_Q%d is set to 0", cci_dev->soc_info.index, master, queue);
+		cam_cci_load_report_cmd(cci_dev, master, queue);
 		rc = cam_cci_wait_report_cmd(cci_dev, master, queue);
 		if (rc < 0) {
 			CAM_ERR(CAM_CCI,