Przeglądaj źródła

Merge "msm: camera: csiphy: Add debug enhancement for the pattern test" into camera-kernel.lnx.5.0

Savita Patted 4 lat temu
rodzic
commit
afd6884a53

+ 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_ */