Parcourir la source

msm: camera: csiphy: Add debug enhancement for the pattern test

Add support for prbs9 pattern debug and verification support for
3phase and 2phase sensor. This change prints the more information
in case of status error from any of the data lane.

CRs-Fixed: 2943640
Change-Id: I629703d066d119ad8670cbb91f92eba79ea43028
Signed-off-by: Jigarkumar Zala <[email protected]>
Jigarkumar Zala il y a 4 ans
Parent
commit
58819faeca

+ 167 - 0
drivers/cam_sensor_module/cam_csiphy/cam_csiphy_core.c

@@ -1316,6 +1316,170 @@ int cam_csiphy_util_update_aon_ops(
 	return rc;
 }
 
+static int __cam_csiphy_read_2phase_bist_debug_status(
+	struct csiphy_device *csiphy_dev)
+{
+	int i = 0;
+	int bist_status_arr_size =
+		csiphy_dev->ctrl_reg->csiphy_bist_reg->num_status_err_check_reg;
+	struct csiphy_reg_t *csiphy_common_reg = NULL;
+	void __iomem *csiphybase = NULL;
+
+	for (i = 0; i < bist_status_arr_size; i++) {
+		csiphy_common_reg = &csiphy_dev->ctrl_reg->csiphy_bist_reg
+			->bist_status_err_check_arr[i];
+		switch (csiphy_common_reg->csiphy_param_type) {
+		case CSIPHY_2PH_REGS:
+			CAM_INFO(CAM_CSIPHY, "OFFSET: 0x%x value: 0x%x",
+				csiphybase + csiphy_common_reg->reg_addr,
+				cam_io_r(csiphybase + csiphy_common_reg->reg_addr));
+		break;
+		}
+	}
+
+	return 0;
+}
+
+static int __cam_csiphy_poll_2phase_pattern_status(
+	struct csiphy_device *csiphy_dev)
+{
+	int i = 0;
+	int bist_status_arr_size =
+		csiphy_dev->ctrl_reg->csiphy_bist_reg->num_status_reg;
+	struct csiphy_reg_t *csiphy_common_reg = NULL;
+	void __iomem *csiphybase = NULL;
+	uint32_t status = 0x00;
+
+	csiphybase = csiphy_dev->soc_info.reg_map[0].mem_base;
+
+	do {
+		usleep_range(2000, 2010);
+		for (i = 0; i < bist_status_arr_size; i++) {
+			csiphy_common_reg = &csiphy_dev->ctrl_reg->csiphy_bist_reg->bist_arry[i];
+			switch (csiphy_common_reg->csiphy_param_type) {
+			case CSIPHY_2PH_REGS:
+				status |= cam_io_r(csiphybase + csiphy_common_reg->reg_addr);
+			break;
+			}
+
+			if (status != 0) {
+				CAM_INFO(CAM_CSIPHY, "Pattern Test is completed");
+				break;
+			}
+		}
+	} while (!status);
+
+	/* This loop is to read every lane status value
+	 * in case if loop breaks with only last lane.
+	 */
+	for (i = 0; i < bist_status_arr_size; i++) {
+		csiphy_common_reg = &csiphy_dev->ctrl_reg->csiphy_bist_reg->bist_arry[i];
+		switch (csiphy_common_reg->csiphy_param_type) {
+		case CSIPHY_2PH_REGS:
+			status |= cam_io_r(csiphybase + csiphy_common_reg->reg_addr);
+		break;
+		}
+	}
+
+	if (status == csiphy_dev->ctrl_reg->csiphy_bist_reg->expected_status_val) {
+		CAM_INFO(CAM_CSIPHY, "Pattern is received correctly");
+		return 0;
+	} else {
+		__cam_csiphy_read_2phase_bist_debug_status(csiphy_dev);
+	}
+
+	return 0;
+}
+
+static int __cam_csiphy_read_3phase_bist_debug_status(
+	struct csiphy_device *csiphy_dev)
+{
+	int i = 0;
+	int bist_status_arr_size =
+		csiphy_dev->ctrl_reg->csiphy_bist_reg->num_status_err_check_reg;
+	struct csiphy_reg_t *csiphy_common_reg = NULL;
+	void __iomem *csiphybase = NULL;
+
+	for (i = 0; i < bist_status_arr_size; i++) {
+		csiphy_common_reg = &csiphy_dev->ctrl_reg->csiphy_bist_reg
+			->bist_status_err_check_arr[i];
+		switch (csiphy_common_reg->csiphy_param_type) {
+		case CSIPHY_3PH_REGS:
+				CAM_INFO(CAM_CSIPHY, "OFFSET: 0x%x value: 0x%x",
+					csiphybase + csiphy_common_reg->reg_addr,
+					cam_io_r(csiphybase + csiphy_common_reg->reg_addr));
+		break;
+		}
+	}
+
+	return 0;
+}
+
+static int __cam_csiphy_poll_3phase_pattern_status(
+	struct csiphy_device *csiphy_dev)
+{
+	int i = 0;
+	int bist_status_arr_size =
+		csiphy_dev->ctrl_reg->csiphy_bist_reg->num_status_reg;
+	struct csiphy_reg_t *csiphy_common_reg = NULL;
+	void __iomem *csiphybase = NULL;
+	uint32_t status1 = 0x00;
+
+	csiphybase = csiphy_dev->soc_info.reg_map[0].mem_base;
+
+	do {
+		usleep_range(2000, 2010);
+		for (i = 0; i < bist_status_arr_size; i++) {
+			csiphy_common_reg = &csiphy_dev->ctrl_reg->csiphy_bist_reg->bist_status_arr[i];
+			switch (csiphy_common_reg->csiphy_param_type) {
+			case CSIPHY_3PH_REGS:
+				status1 |= cam_io_r(csiphybase + csiphy_common_reg->reg_addr);
+			break;
+			}
+			if (status1 != 0) {
+				CAM_INFO(CAM_CSIPHY, "Pattern Test is completed");
+				break;
+			}
+		}
+	} while (!status1);
+
+	/* This loop is to read every lane status value
+	 * in case if loop breaks with only last lane.
+	 */
+	for (i = 0; i < bist_status_arr_size; i++) {
+		csiphy_common_reg = &csiphy_dev->ctrl_reg->csiphy_bist_reg->bist_status_arr[i];
+		switch (csiphy_common_reg->csiphy_param_type) {
+		case CSIPHY_3PH_REGS:
+			status1 |= cam_io_r(csiphybase + csiphy_common_reg->reg_addr);
+		break;
+		}
+	}
+
+	if (status1 == csiphy_dev->ctrl_reg->csiphy_bist_reg->expected_status_val) {
+		CAM_INFO(CAM_CSIPHY, "Pattern is received correctly");
+		return 0;
+	} else {
+		__cam_csiphy_read_3phase_bist_debug_status(csiphy_dev);
+	}
+
+	return 0;
+}
+
+static int __cam_csiphy_poll_preamble_status(
+	struct csiphy_device *csiphy_dev, int offset)
+{
+	bool is_3phase = false;
+
+	is_3phase = csiphy_dev->csiphy_info[offset].csiphy_3phase;
+
+	if (is_3phase)
+		__cam_csiphy_poll_3phase_pattern_status(csiphy_dev);
+	else
+		__cam_csiphy_poll_2phase_pattern_status(csiphy_dev);
+
+	return 0;
+}
+
 int32_t cam_csiphy_core_cfg(void *phy_dev,
 			void *arg)
 {
@@ -1784,6 +1948,9 @@ int32_t cam_csiphy_core_cfg(void *phy_dev,
 			csiphy_dev->start_dev_count);
 		csiphy_dev->csiphy_state = CAM_CSIPHY_START;
 
+		if (csiphy_dev->preamble_enable) {
+			__cam_csiphy_poll_preamble_status(csiphy_dev, offset);
+		}
 		CAM_INFO(CAM_CSIPHY,
 			"CAM_START_PHYDEV: CSIPHY_IDX: %d, Device_slot: %d, cp_mode: %d, Datarate: %llu, Settletime: %llu",
 			csiphy_dev->soc_info.index, offset,

+ 5 - 0
drivers/cam_sensor_module/cam_csiphy/cam_csiphy_dev.h

@@ -205,8 +205,13 @@ struct data_rate_settings_t {
 };
 
 struct bist_reg_settings_t {
+	uint32_t expected_status_val;
 	ssize_t num_data_settings;
+	ssize_t num_status_reg;
+	ssize_t num_status_err_check_reg;
 	struct csiphy_reg_t *bist_arry;
+	struct csiphy_reg_t *bist_status_arr;
+	struct csiphy_reg_t *bist_status_err_check_arr;
 };
 
 /**

+ 28 - 0
drivers/cam_sensor_module/cam_csiphy/include/cam_csiphy_2_1_0_hwreg.h

@@ -495,9 +495,37 @@ struct csiphy_reg_t bist_arr_2_1_0[] = {
 	{0x0A40, 0x85, 0x00, CSIPHY_3PH_REGS},
 };
 
+struct csiphy_reg_t bist_status_arr_2_1_0[] = {
+	/* STATUS1 for the BIST checker output for 3phase */
+	{0x0344, 0x00, 0x00, CSIPHY_3PH_REGS},
+	{0x0744, 0x00, 0x00, CSIPHY_3PH_REGS},
+	{0x0B44, 0x00, 0x00, CSIPHY_3PH_REGS},
+	/* STATUS0 for BIST checker output for 2phase */
+	{0x00C0, 0x00, 0x00, CSIPHY_2PH_REGS},
+	{0x04C0, 0x00, 0x00, CSIPHY_2PH_REGS},
+	{0x08C0, 0x00, 0x00, CSIPHY_2PH_REGS},
+	{0x0CC0, 0x00, 0x00, CSIPHY_2PH_REGS},
+};
+
+struct csiphy_reg_t bist_status_err_check_arr_2_1_0[] = {
+	/* STATUS2_3 for the BIST word error detection */
+	{0x0348, 0x00, 0x00, CSIPHY_3PH_REGS},
+	{0x0748, 0x00, 0x00, CSIPHY_3PH_REGS},
+	{0x0B48, 0x00, 0x00, CSIPHY_3PH_REGS},
+	{0x034C, 0x00, 0x00, CSIPHY_3PH_REGS},
+	{0x074C, 0x00, 0x00, CSIPHY_3PH_REGS},
+	{0x0B4C, 0x00, 0x00, CSIPHY_3PH_REGS},
+	/* STATUS */
+};
+
 struct bist_reg_settings_t bist_setting_2_1_0 = {
+	.expected_status_val = 0xB,
 	.num_data_settings = ARRAY_SIZE(bist_arr_2_1_0),
 	.bist_arry = bist_arr_2_1_0,
+	.num_status_reg = ARRAY_SIZE(bist_status_arr_2_1_0),
+	.bist_status_arr = bist_status_arr_2_1_0,
+	.num_status_err_check_reg = ARRAY_SIZE(bist_status_err_check_arr_2_1_0),
+	.bist_status_err_check_arr = bist_status_err_check_arr_2_1_0,
 };
 
 #endif /* _CAM_CSIPHY_2_1_0_HWREG_H_ */