瀏覽代碼

msm: camera: isp: Prevent false timeout in dual IFE reset

In dual IFE case, HW reset times out because completion struct gets
reinited after reset IRQ is received and before going into wait. During
SW reset, 3 IRQs are observed, 2 during master reset and 1 during slave.
This can cause the done count in the completion struct to be increment
by 1 for the slave CSID during SW reset and result in incorrect
reporting of IRQs during the next reset call.

To solve this problem, there are two reinit_completion calls:
	1. Pre-reset command: Only for SW reset. This is to clear the
	completion struct in the cases of HW reset timeout followed by
	reset IRQ or slave reset IRQ triggerred by master.
	2. Post-reset command: For both HW and SW reset. This is to
	clear the completion struct after successful reset command to
	use it again during next reset.

CRs-Fixed: 2846451
Change-Id: I6d416a63e6d7e3828e55d1deece56b38a349f99f
Signed-off-by: Anand Ravi <[email protected]>
Anand Ravi 4 年之前
父節點
當前提交
6a35b87cdd

+ 8 - 9
drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_hw_ver2.c

@@ -1683,7 +1683,7 @@ static int cam_ife_csid_ver2_wait_for_reset(
 	int rc = 0;
 
 	rem_jiffies = cam_common_wait_for_completion_timeout(
-		&csid_hw->irq_complete[CAM_IFE_CSID_IRQ_REG_TOP],
+		&csid_hw->hw_info->hw_complete,
 		msecs_to_jiffies(CAM_IFE_CSID_RESET_TIMEOUT_MS));
 
 	if (rem_jiffies == 0) {
@@ -1709,9 +1709,9 @@ static int cam_ife_csid_ver2_reset_irq_top_half(uint32_t    evt_id,
 
 	csid_hw = th_payload->handler_priv;
 
-	CAM_DBG(CAM_ISP, "TOP_IRQ_STATUS_0 = 0x%x",
+	CAM_DBG(CAM_ISP, "CSID[%d] TOP_IRQ_STATUS_0 = 0x%x", csid_hw->hw_intf->hw_idx,
 		th_payload->evt_status_arr[0]);
-	complete(&csid_hw->irq_complete[CAM_IFE_CSID_IRQ_REG_TOP]);
+	complete(&csid_hw->hw_info->hw_complete);
 
 	return 0;
 }
@@ -1731,7 +1731,6 @@ static int cam_ife_csid_ver2_internal_reset(
 
 	soc_info = &csid_hw->hw_info->soc_info;
 	mem_base = soc_info->reg_map[CAM_IFE_CSID_CLC_MEM_BASE_ID].mem_base;
-	reinit_completion(&csid_hw->irq_complete[CAM_IFE_CSID_IRQ_REG_TOP]);
 
 	if (csid_hw->hw_info->hw_state != CAM_HW_STATE_POWER_UP) {
 		CAM_ERR(CAM_ISP, "CSID[%d] powered down state",
@@ -1743,6 +1742,9 @@ static int cam_ife_csid_ver2_internal_reset(
 		rst_cmd == CAM_IFE_CSID_RESET_CMD_HW_RST)
 		goto wait_only;
 
+	if (rst_cmd == CAM_IFE_CSID_RESET_CMD_SW_RST)
+		reinit_completion(&csid_hw->hw_info->hw_complete);
+
 	/*Program the reset location */
 	if (rst_location == CAM_IFE_CSID_RESET_LOC_PATH_ONLY)
 		val |= (csid_reg->cmn_reg->rst_loc_path_only_val <<
@@ -1782,6 +1784,7 @@ wait_only:
 			"CSID[%u] Reset failed mode %d cmd %d loc %d",
 			csid_hw->hw_intf->hw_idx,
 			rst_mode, rst_cmd, rst_location);
+	reinit_completion(&csid_hw->hw_info->hw_complete);
 	return rc;
 }
 
@@ -3563,7 +3566,7 @@ static int cam_ife_csid_ver2_enable_core(struct cam_ife_csid_ver2_hw *csid_hw)
 		goto disable_res;
 	}
 
-	reinit_completion(&csid_hw->irq_complete[CAM_IFE_CSID_IRQ_REG_TOP]);
+	reinit_completion(&csid_hw->hw_info->hw_complete);
 	cam_ife_csid_ver2_program_top(csid_hw);
 	csid_hw->hw_info->hw_state = CAM_HW_STATE_POWER_UP;
 
@@ -4788,7 +4791,6 @@ int cam_ife_csid_hw_ver2_init(struct cam_hw_intf *hw_intf,
 	bool is_custom)
 {
 	int rc = -EINVAL;
-	uint32_t i;
 	struct cam_hw_info                   *hw_info;
 	struct cam_ife_csid_ver2_hw          *csid_hw = NULL;
 
@@ -4824,9 +4826,6 @@ int cam_ife_csid_hw_ver2_init(struct cam_hw_intf *hw_intf,
 	init_completion(&csid_hw->hw_info->hw_complete);
 	atomic_set(&csid_hw->discard_frame_per_path, 0);
 
-	for (i = 0; i < CAM_IFE_PIX_PATH_RES_MAX; i++)
-		init_completion(&csid_hw->irq_complete[i]);
-
 	rc = cam_ife_csid_init_soc_resources(&csid_hw->hw_info->soc_info,
 			cam_ife_csid_irq, csid_hw, is_custom);
 	if (rc < 0) {

+ 0 - 2
drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_hw_ver2.h

@@ -625,8 +625,6 @@ struct cam_ife_csid_ver2_hw {
 	struct cam_ife_csid_rx_cfg             rx_cfg;
 	struct cam_ife_csid_hw_counters        counters;
 	struct cam_ife_csid_hw_flags           flags;
-	struct completion                      irq_complete
-						    [CAM_IFE_CSID_IRQ_REG_MAX];
 	struct cam_ife_csid_debug_info         debug_info;
 	struct cam_ife_csid_timestamp          timestamp;
 	struct cam_ife_csid_ver2_evt_payload   rx_evt_payload[