Răsfoiți Sursa

Merge "msm: camera: csiphy: Add logic to program common register" into camera-kernel.lnx.5.0

Savita Patted 4 ani în urmă
părinte
comite
4984d6a339

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

@@ -35,9 +35,19 @@
 /* Mask to enable skew calibration registers */
 #define SKEW_CAL_MASK 0x2
 
+static DEFINE_MUTEX(active_csiphy_cnt_mutex);
+
 static int csiphy_dump;
 module_param(csiphy_dump, int, 0644);
 
+struct g_csiphy_data {
+	void __iomem *base_address;
+	uint8_t is_3phase;
+};
+
+static struct g_csiphy_data g_phy_data[MAX_CSIPHY] = {{0, 0}};
+static int active_csiphy_hw_cnt;
+
 int32_t cam_csiphy_get_instance_offset(
 	struct csiphy_device *csiphy_dev,
 	int32_t dev_handle)
@@ -109,6 +119,59 @@ void cam_csiphy_reset(struct csiphy_device *csiphy_dev)
 	}
 }
 
+static void cam_csiphy_prgm_cmn_data(
+	struct csiphy_device *csiphy_dev,
+	bool reset)
+{
+	int csiphy_idx = 0;
+	uint32_t size = 0;
+	int i = 0;
+	void __iomem *csiphybase;
+	bool is_3phase = false;
+	struct csiphy_reg_t *csiphy_common_reg = NULL;
+
+	size = csiphy_dev->ctrl_reg->csiphy_reg.csiphy_common_array_size;
+
+	if (active_csiphy_hw_cnt < 0 || active_csiphy_hw_cnt >= MAX_CSIPHY) {
+		CAM_WARN(CAM_CSIPHY,
+			"MisMatched in active phy hw: %d and Max supported: %d",
+			active_csiphy_hw_cnt, MAX_CSIPHY);
+		return;
+	}
+
+	if (active_csiphy_hw_cnt == 0) {
+		CAM_DBG(CAM_CSIPHY, "CSIPHYs HW state needs to be %s",
+			reset ? "reset" : "set");
+	} else {
+		CAM_DBG(CAM_CSIPHY, "Active CSIPHY hws are %d",
+			active_csiphy_hw_cnt);
+		return;
+	}
+
+	for (csiphy_idx = 0; csiphy_idx < MAX_CSIPHY; csiphy_idx++) {
+		csiphybase = g_phy_data[csiphy_idx].base_address;
+		is_3phase = g_phy_data[csiphy_idx].is_3phase;
+
+		for (i = 0; i < size; i++) {
+			csiphy_common_reg =
+				&csiphy_dev->ctrl_reg->csiphy_common_reg[i];
+			switch (csiphy_common_reg->csiphy_param_type) {
+			case CSIPHY_DEFAULT_PARAMS:
+				cam_io_w_mb(reset ? 0x00 :
+					csiphy_common_reg->reg_data,
+					csiphybase +
+					csiphy_common_reg->reg_addr);
+				break;
+			default:
+				break;
+			}
+			if (csiphy_common_reg->delay > 0)
+				usleep_range(csiphy_common_reg->delay,
+					csiphy_common_reg->delay + 5);
+		}
+	}
+}
+
 static int32_t cam_csiphy_update_secure_info(
 	struct csiphy_device *csiphy_dev, int32_t index)
 {
@@ -1132,6 +1195,15 @@ int32_t cam_csiphy_core_cfg(void *phy_dev,
 			goto release_mutex;
 		}
 
+		if (!csiphy_dev->acquire_count) {
+			g_phy_data[csiphy_dev->soc_info.index].is_3phase =
+					csiphy_acq_params.csiphy_3phase;
+			CAM_DBG(CAM_CSIPHY,
+					"g_csiphy data is updated for index: %d is_3phase: %u",
+					csiphy_dev->soc_info.index,
+					g_phy_data[csiphy_dev->soc_info.index].is_3phase);
+		}
+
 		csiphy_dev->acquire_count++;
 		CAM_DBG(CAM_CSIPHY, "ACQUIRE_CNT: %d",
 			csiphy_dev->acquire_count);
@@ -1209,6 +1281,15 @@ int32_t cam_csiphy_core_cfg(void *phy_dev,
 
 		csiphy_dev->csiphy_info[offset].csiphy_cpas_cp_reg_mask = 0x0;
 
+		if (csiphy_dev->ctrl_reg->csiphy_reg
+			.prgm_cmn_reg_across_csiphy) {
+			mutex_lock(&active_csiphy_cnt_mutex);
+			active_csiphy_hw_cnt--;
+			mutex_unlock(&active_csiphy_cnt_mutex);
+
+			cam_csiphy_prgm_cmn_data(csiphy_dev, true);
+		}
+
 		rc = cam_csiphy_disable_hw(csiphy_dev);
 		if (rc < 0)
 			CAM_ERR(CAM_CSIPHY, "Failed in csiphy release");
@@ -1451,6 +1532,16 @@ int32_t cam_csiphy_core_cfg(void *phy_dev,
 			goto release_mutex;
 		}
 		csiphy_dev->start_dev_count++;
+
+		if (csiphy_dev->ctrl_reg->csiphy_reg
+			.prgm_cmn_reg_across_csiphy) {
+			cam_csiphy_prgm_cmn_data(csiphy_dev, false);
+
+			mutex_lock(&active_csiphy_cnt_mutex);
+			active_csiphy_hw_cnt++;
+			mutex_unlock(&active_csiphy_cnt_mutex);
+		}
+
 		CAM_DBG(CAM_CSIPHY, "START DEV CNT: %d",
 			csiphy_dev->start_dev_count);
 		csiphy_dev->csiphy_state = CAM_CSIPHY_START;
@@ -1480,3 +1571,20 @@ release_mutex:
 
 	return rc;
 }
+
+void cam_csiphy_register_baseaddress(struct csiphy_device *csiphy_dev)
+{
+	if (!csiphy_dev) {
+		CAM_WARN(CAM_CSIPHY, "Data is NULL");
+		return;
+	}
+
+	if (csiphy_dev->soc_info.index >= MAX_CSIPHY) {
+		CAM_ERR(CAM_CSIPHY, "Invalid soc index: %u Max soc index: %u",
+			csiphy_dev->soc_info.index, MAX_CSIPHY);
+		return;
+	}
+
+	g_phy_data[csiphy_dev->soc_info.index].base_address =
+		csiphy_dev->soc_info.reg_map[0].mem_base;
+}

+ 8 - 1
drivers/cam_sensor_module/cam_csiphy/cam_csiphy_core.h

@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
 /*
- * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-2018, 2020 The Linux Foundation. All rights reserved.
  */
 
 #ifndef _CAM_CSIPHY_CORE_H_
@@ -49,4 +49,11 @@ irqreturn_t cam_csiphy_irq(int irq_num, void *data);
  */
 void cam_csiphy_shutdown(struct csiphy_device *csiphy_dev);
 
+/**
+ * @soc_idx : CSIPHY cell index
+ *
+ * This API registers base address per soc_idx
+ */
+void cam_csiphy_register_baseaddress(struct csiphy_device *csiphy_dev);
+
 #endif /* _CAM_CSIPHY_CORE_H_ */

+ 4 - 0
drivers/cam_sensor_module/cam_csiphy/cam_csiphy_dev.c

@@ -221,6 +221,10 @@ static int cam_csiphy_component_bind(struct device *dev,
 	CAM_DBG(CAM_CSIPHY, "CPAS registration successful handle=%d",
 		cpas_parms.client_handle);
 	new_csiphy_dev->cpas_handle = cpas_parms.client_handle;
+
+	cam_csiphy_register_baseaddress(new_csiphy_dev);
+
+
 	CAM_DBG(CAM_CSIPHY, "%s component bound successfully",
 		pdev->name);
 	return rc;

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

@@ -117,6 +117,7 @@ struct csiphy_reg_parms_t {
 	uint32_t csiphy_cpas_cp_3ph_offset;
 	uint32_t csiphy_2ph_clock_lane;
 	uint32_t csiphy_2ph_combo_ck_ln;
+	uint32_t prgm_cmn_reg_across_csiphy;
 };
 
 /**

+ 3 - 8
drivers/cam_sensor_module/cam_csiphy/include/cam_csiphy_1_2_3_hwreg.h

@@ -13,13 +13,14 @@ struct csiphy_reg_parms_t csiphy_v1_2_3 = {
 	.mipi_csiphy_interrupt_clear0_addr = 0x858,
 	.mipi_csiphy_glbl_irq_cmd_addr = 0x828,
 	.csiphy_interrupt_status_size = 11,
-	.csiphy_common_array_size = 8,
-	.csiphy_reset_array_size = 5,
+	.csiphy_common_array_size = 5,
+	.csiphy_reset_array_size = 2,
 	.csiphy_2ph_config_array_size = 16,
 	.csiphy_3ph_config_array_size = 26,
 	.csiphy_2ph_3ph_config_array_size = 0,
 	.csiphy_2ph_clock_lane = 0x1,
 	.csiphy_2ph_combo_ck_ln = 0x10,
+	.prgm_cmn_reg_across_csiphy = 1,
 };
 
 struct csiphy_reg_t csiphy_common_reg_1_2_3[] = {
@@ -28,15 +29,9 @@ struct csiphy_reg_t csiphy_common_reg_1_2_3[] = {
 	{0x0818, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS},
 	{0x081C, 0x5A, 0x00, CSIPHY_DEFAULT_PARAMS},
 	{0x0824, 0x72, 0x00, CSIPHY_2PH_REGS},
-	{0x0800, 0x01, 0x02, CSIPHY_DEFAULT_PARAMS},
-	{0x0800, 0x02, 0x00, CSIPHY_2PH_REGS},
-	{0x0800, 0x0E, 0x00, CSIPHY_3PH_REGS},
 };
 
 struct csiphy_reg_t csiphy_reset_reg_1_2_3[] = {
-	{0x0814, 0x00, 0x00, CSIPHY_LANE_ENABLE},
-	{0x0818, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
-	{0x081C, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
 	{0x0800, 0x01, 0x02, CSIPHY_DEFAULT_PARAMS},
 	{0x0800, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
 };