浏览代码

msm: camera: isp: Add TPG mux select logic in CPAS

Add TPG mux select logic in CPAS. To select form which TPG CSID should
get the data, TPG_MUX_SEL register has to be programmed. This change
adds the logic to write this register on CPAS driver.

CRs-Fixed: 3081144
Change-Id: I86560f802a04e88ceca4efa276e853029d8417d3
Signed-off-by: Ayush Kumar <[email protected]>
(cherry picked from commit 323f7225a0e814b2be33cd89109ae6b3ac8c3490)
Ayush Kumar 3 年之前
父节点
当前提交
e01a63cc4f

+ 40 - 0
drivers/cam_cpas/cam_cpas_hw.c

@@ -3674,6 +3674,32 @@ done:
 	return rc;
 }
 
+static int cam_cpas_hw_enable_tpg_mux_sel(struct cam_hw_info *cpas_hw,
+	uint32_t tpg_mux)
+{
+	struct cam_cpas *cpas_core = (struct cam_cpas *) cpas_hw->core_info;
+	int rc = 0;
+
+	mutex_lock(&cpas_hw->hw_mutex);
+
+	if (cpas_core->internal_ops.set_tpg_mux_sel) {
+		rc = cpas_core->internal_ops.set_tpg_mux_sel(
+			cpas_hw, tpg_mux);
+		if (rc) {
+			CAM_ERR(CAM_CPAS,
+				"failed in tpg mux selection rc=%d",
+				rc);
+		}
+	} else {
+		CAM_ERR(CAM_CPAS,
+			"CPAS tpg mux sel not enabled");
+		rc = -EINVAL;
+	}
+
+	mutex_unlock(&cpas_hw->hw_mutex);
+	return rc;
+}
+
 static int cam_cpas_activate_cache(
 	struct cam_hw_info *cpas_hw,
 	struct cam_sys_cache_info *cache_info)
@@ -4343,6 +4369,20 @@ static int cam_cpas_hw_process_cmd(void *hw_priv,
 		rc = cam_cpas_hw_csid_process_resume(hw_priv, *csid_idx);
 		break;
 	}
+	case CAM_CPAS_HW_CMD_TPG_MUX_SEL: {
+		uint32_t *tpg_mux_sel;
+
+		if (sizeof(uint32_t) != arg_size) {
+			CAM_ERR(CAM_CPAS, "cmd_type %d, size mismatch %d",
+				cmd_type, arg_size);
+			break;
+		}
+
+		tpg_mux_sel = (uint32_t *)cmd_args;
+		rc = cam_cpas_hw_enable_tpg_mux_sel(hw_priv, *tpg_mux_sel);
+		break;
+
+	}
 	case CAM_CPAS_HW_CMD_ENABLE_DISABLE_DOMAIN_ID_CLK: {
 		bool *enable;
 

+ 2 - 0
drivers/cam_cpas/cam_cpas_hw.h

@@ -170,6 +170,7 @@ struct cam_cpas_kobj_map {
  * @print_poweron_settings: Function pointer for hw to print poweron settings
  * @qchannel_handshake: Function pointer for hw core specific qchannel
  *                      handshake settings
+ * @set_tpg_mux_sel: Set tpg mux select on CPAS TOP register
  *
  */
 struct cam_cpas_internal_ops {
@@ -186,6 +187,7 @@ struct cam_cpas_internal_ops {
 		uint32_t selection_mask);
 	int (*print_poweron_settings)(struct cam_hw_info *cpas_hw);
 	int (*qchannel_handshake)(struct cam_hw_info *cpas_hw, bool power_on, bool force_on);
+	int (*set_tpg_mux_sel)(struct cam_hw_info *cpas_hw, uint32_t tpg_num);
 };
 
 /**

+ 7 - 0
drivers/cam_cpas/cam_cpas_hw_intf.h

@@ -72,6 +72,7 @@ enum cam_cpas_hw_cmd_process {
 	CAM_CPAS_HW_CMD_CSID_INPUT_CORE_INFO_UPDATE,
 	CAM_CPAS_HW_CMD_CSID_PROCESS_RESUME,
 	CAM_CPAS_HW_CMD_ENABLE_DISABLE_DOMAIN_ID_CLK,
+	CAM_CPAS_HW_CMD_TPG_MUX_SEL,
 	CAM_CPAS_HW_CMD_DUMP_STATE_MONITOR_INFO,
 	CAM_CPAS_HW_CMD_INVALID,
 };
@@ -201,4 +202,10 @@ int cam_cpas_dev_init_module(void);
  * @brief : API to remove CPAS interface from platform framework.
  */
 void cam_cpas_dev_exit_module(void);
+
+/**
+ * @brief : API to select TPG mux select.
+ */
+int cam_cpas_enable_tpg_mux_sel(uint32_t tpg_mux_sel);
+
 #endif /* _CAM_CPAS_HW_INTF_H_ */

+ 25 - 0
drivers/cam_cpas/cam_cpas_intf.c

@@ -775,6 +775,31 @@ int cam_cpas_select_qos_settings(uint32_t selection_mask)
 }
 EXPORT_SYMBOL(cam_cpas_select_qos_settings);
 
+int cam_cpas_enable_tpg_mux_sel(uint32_t tpg_mux_sel)
+{
+	int rc = 0;
+
+	if (!CAM_CPAS_INTF_INITIALIZED()) {
+		CAM_ERR(CAM_CPAS, "cpas intf not initialized");
+		return -EBADR;
+	}
+
+	if (g_cpas_intf->hw_intf->hw_ops.process_cmd) {
+		rc = g_cpas_intf->hw_intf->hw_ops.process_cmd(
+			g_cpas_intf->hw_intf->hw_priv,
+			CAM_CPAS_HW_CMD_TPG_MUX_SEL, &tpg_mux_sel,
+			sizeof(tpg_mux_sel));
+		if (rc)
+			CAM_ERR(CAM_CPAS, "Failed in process_cmd, rc=%d", rc);
+	} else {
+		CAM_ERR(CAM_CPAS, "Invalid process_cmd ops");
+		rc = -EBADR;
+	}
+
+	return rc;
+}
+EXPORT_SYMBOL(cam_cpas_enable_tpg_mux_sel);
+
 int cam_cpas_notify_event(const char *identifier_string,
 	int32_t identifier_value)
 {

+ 2 - 0
drivers/cam_cpas/camss_top/cam_camsstop_hw.c

@@ -1,6 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
  * Copyright (c) 2017-2018, 2020 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #include "cam_cpas_hw_intf.h"
@@ -80,6 +81,7 @@ int cam_camsstop_get_internal_ops(struct cam_cpas_internal_ops *internal_ops)
 	internal_ops->setup_qos_settings = NULL;
 	internal_ops->print_poweron_settings = NULL;
 	internal_ops->qchannel_handshake = NULL;
+	internal_ops->set_tpg_mux_sel = NULL;
 
 	return 0;
 }

+ 34 - 0
drivers/cam_cpas/cpas_top/cam_cpastop_hw.c

@@ -44,6 +44,8 @@
 
 struct cam_camnoc_info *camnoc_info[CAM_CAMNOC_HW_TYPE_MAX];
 struct cam_cpas_info *cpas_info;
+struct cam_cpas_camnoc_qchannel *qchannel_info;
+struct cam_cpas_top_regs *cpas_top_info;
 
 #if (defined(CONFIG_CAM_TEST_IRQ_LINE) && defined(CONFIG_CAM_TEST_IRQ_LINE_AT_PROBE))
 	struct completion test_irq_hw_complete[CAM_CAMNOC_HW_TYPE_MAX];
@@ -1290,6 +1292,33 @@ static int cam_cpastop_get_hw_capability(struct cam_hw_info *cpas_hw)
 	return 0;
 }
 
+static int cam_cpastop_set_tpg_mux_sel(struct cam_hw_info *cpas_hw,
+	uint32_t tpg_mux)
+{
+	struct cam_cpas *cpas_core = (struct cam_cpas *) cpas_hw->core_info;
+	struct cam_hw_soc_info *soc_info = &cpas_hw->soc_info;
+	int reg_cpas_top;
+	uint32_t curr_tpg_mux = 0;
+
+	reg_cpas_top = cpas_core->regbase_index[CAM_CPAS_REG_CPASTOP];
+
+	if (cpas_top_info == NULL)
+		return 0;
+
+	if (!cpas_top_info->tpg_mux_sel_enabled)
+		return 0;
+
+	curr_tpg_mux = cam_io_r_mb(soc_info->reg_map[reg_cpas_top].mem_base +
+		cpas_top_info->tpg_mux_sel);
+
+	curr_tpg_mux = curr_tpg_mux | ((1 << tpg_mux) << cpas_top_info->tpg_mux_sel_shift);
+	cam_io_w_mb(curr_tpg_mux, soc_info->reg_map[reg_cpas_top].mem_base +
+		cpas_top_info->tpg_mux_sel);
+	CAM_DBG(CAM_CPAS, "SET TPG MUX to 0x%x", curr_tpg_mux);
+
+	return 0;
+}
+
 static int cam_cpastop_init_hw_version(struct cam_hw_info *cpas_hw,
 	struct cam_cpas_hw_caps *hw_caps)
 {
@@ -1299,6 +1328,9 @@ static int cam_cpastop_init_hw_version(struct cam_hw_info *cpas_hw,
 	struct cam_cpas_cesta_info *cesta_info = NULL;
 	struct cam_camnoc_info *alloc_camnoc_info[CAM_CAMNOC_HW_TYPE_MAX] = {0};
 
+	qchannel_info = NULL;
+	cpas_top_info = NULL;
+
 	CAM_DBG(CAM_CPAS,
 		"hw_version=0x%x Camera Version %d.%d.%d, cpas version %d.%d.%d",
 		soc_info->hw_version,
@@ -1389,6 +1421,7 @@ static int cam_cpastop_init_hw_version(struct cam_hw_info *cpas_hw,
 	case CAM_CPAS_TITAN_640_V200:
 		alloc_camnoc_info[CAM_CAMNOC_HW_COMBINED] = &cam640_cpas200_camnoc_info;
 		cpas_info = &cam640_cpas200_cpas_info;
+		cpas_top_info = &cam640_cpas200_cpas_top_info;
 		break;
 	case CAM_CPAS_TITAN_880_V100:
 		alloc_camnoc_info[CAM_CAMNOC_HW_COMBINED] = &cam880_cpas100_camnoc_info;
@@ -1489,6 +1522,7 @@ int cam_cpastop_get_internal_ops(struct cam_cpas_internal_ops *internal_ops)
 	internal_ops->print_poweron_settings =
 		cam_cpastop_print_poweron_settings;
 	internal_ops->qchannel_handshake = cam_cpastop_qchannel_handshake;
+	internal_ops->set_tpg_mux_sel = cam_cpastop_set_tpg_mux_sel;
 
 	return 0;
 }

+ 13 - 0
drivers/cam_cpas/cpas_top/cam_cpastop_hw.h

@@ -534,4 +534,17 @@ struct cam_cpas_info {
 	uint8_t num_qchannel;
 };
 
+/**
+ * struct cam_cpas_top_regs : CPAS Top registers
+ * @tpg_mux_sel_shift:     TPG mux select shift value
+ * @tpg_mux_sel:           For selecting TPG
+ * @tpg_mux_sel_enabled:   TPG mux select enabled or not
+ *
+ */
+struct cam_cpas_top_regs {
+	uint32_t tpg_mux_sel_shift;
+	uint32_t tpg_mux_sel;
+	bool     tpg_mux_sel_enabled;
+};
+
 #endif /* _CAM_CPASTOP_HW_H_ */

+ 6 - 0
drivers/cam_cpas/cpas_top/cpastop_v640_200.h

@@ -573,5 +573,11 @@ static struct cam_cpas_info cam640_cpas200_cpas_info = {
 	.num_qchannel = 1,
 };
 
+static struct cam_cpas_top_regs cam640_cpas200_cpas_top_info = {
+	.tpg_mux_sel_enabled = true,
+	.tpg_mux_sel_shift   = 0x0,
+	.tpg_mux_sel         = 0x1C,
+};
+
 #endif /* _CPASTOP_V640_200_H_ */
 

+ 2 - 0
drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_csid_hw/cam_tfe_csid530.h

@@ -1,6 +1,7 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
 /*
  * Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #ifndef _CAM_TFE_CSID_530_H_
@@ -178,6 +179,7 @@ static struct cam_tfe_csid_csi2_rx_reg_offset
 	.csi2_rx_long_pkt_hdr_rst_stb_shift           = 0x1,
 	.csi2_rx_short_pkt_hdr_rst_stb_shift          = 0x2,
 	.csi2_rx_cphy_pkt_hdr_rst_stb_shift           = 0x3,
+	.need_to_sel_tpg_mux                          = false,
 };
 
 static struct cam_tfe_csid_common_reg_offset

+ 2 - 1
drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_csid_hw/cam_tfe_csid640.h

@@ -200,7 +200,7 @@ static struct cam_tfe_csid_csi2_rx_reg_offset
 	.csid_csi2_rx_stats_ecc_addr                  = 0x164,
 	.csid_csi2_rx_total_crc_err_addr              = 0x168,
 
-	.phy_tpg_base_id                              = 0,
+	.phy_tpg_base_id                              = 1,
 	.csi2_rst_srb_all                             = 0x3FFF,
 	.csi2_rst_done_shift_val                      = 27,
 	.csi2_irq_mask_all                            = 0xFFFFFFF,
@@ -217,6 +217,7 @@ static struct cam_tfe_csid_csi2_rx_reg_offset
 	.csi2_rx_long_pkt_hdr_rst_stb_shift           = 0x1,
 	.csi2_rx_short_pkt_hdr_rst_stb_shift          = 0x2,
 	.csi2_rx_cphy_pkt_hdr_rst_stb_shift           = 0x3,
+	.need_to_sel_tpg_mux                          = true,
 };
 
 static struct cam_tfe_csid_common_reg_offset

+ 8 - 0
drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_csid_hw/cam_tfe_csid_core.c

@@ -23,6 +23,7 @@
 #include "cam_common_util.h"
 #include "cam_tfe_csid_hw_intf.h"
 #include <dt-bindings/msm-camera.h>
+#include "cam_cpas_hw_intf.h"
 
 /* Timeout value in msec */
 #define TFE_CSID_TIMEOUT                               1000
@@ -994,6 +995,13 @@ static int cam_tfe_csid_enable_csi2(
 	cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
 		csid_reg->csi2_reg->csid_csi2_rx_cfg0_addr);
 
+	if (csid_hw->in_res_id >= CAM_ISP_TFE_IN_RES_CPHY_TPG_0 &&
+		csid_hw->in_res_id <= CAM_ISP_TFE_IN_RES_CPHY_TPG_2 &&
+		csid_reg->csi2_reg->need_to_sel_tpg_mux) {
+		cam_cpas_enable_tpg_mux_sel(csid_hw->in_res_id -
+			CAM_ISP_TFE_IN_RES_CPHY_TPG_0);
+	}
+
 	/* rx cfg1 */
 	val = (1 << csid_reg->csi2_reg->csi2_misr_enable_shift_val);
 

+ 1 - 0
drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_csid_hw/cam_tfe_csid_core.h

@@ -236,6 +236,7 @@ struct cam_tfe_csid_csi2_rx_reg_offset {
 	uint32_t csi2_rx_long_pkt_hdr_rst_stb_shift;
 	uint32_t csi2_rx_short_pkt_hdr_rst_stb_shift;
 	uint32_t csi2_rx_cphy_pkt_hdr_rst_stb_shift;
+	bool     need_to_sel_tpg_mux;
 };
 
 struct cam_tfe_csid_common_reg_offset {