Sfoglia il codice sorgente

Merge changes I1b568b90,I632469bc,I53326589,I8ac4820b,I65e97c6e,I4e149fc8,I450049ab,Ic06531a5,Ic96d1edc,I311c7cd8 into camera-kernel.lnx.6.0

* changes:
  Snap for drop 06/09/2022 mainline 783 LA.VENDOR.13.2.0.AU237
  msm: camera: common: Enable config for rpmh calls
  msm: camera: common: Add debug infrastructure for camera drv
  msm: camera: common: Add support for DRV config
  msm: camera: common: Add support for bw update blob v3
  msm: camera: isp: Read back and update top debug cfg register
  msm: camera: icp: Log all active requests on enomem from FW
  msm: camera: csiphy: Add support for RF channel based csiphy settings
  msm: camera: common: Add I3C Driver support
  msm: camera: isp: Remove IFE HW mgr reference from ISP ctx
Abhijit Trivedi 3 anni fa
parent
commit
9272dea247
73 ha cambiato i file con 2978 aggiunte e 922 eliminazioni
  1. 2 0
      config/kalama.mk
  2. 545 199
      drivers/cam_cpas/cam_cpas_hw.c
  3. 81 16
      drivers/cam_cpas/cam_cpas_hw.h
  4. 18 0
      drivers/cam_cpas/cam_cpas_hw_intf.h
  5. 97 4
      drivers/cam_cpas/cam_cpas_intf.c
  6. 257 188
      drivers/cam_cpas/cam_cpas_soc.c
  7. 9 22
      drivers/cam_cpas/cam_cpas_soc.h
  8. 74 2
      drivers/cam_cpas/include/cam_cpas_api.h
  9. 19 6
      drivers/cam_cre/cam_cre_hw_mgr/cam_cre_hw_mgr.c
  10. 3 3
      drivers/cam_cre/cam_cre_hw_mgr/cam_cre_hw_mgr.h
  11. 1 4
      drivers/cam_icp/icp_hw/bps_hw/bps_core.c
  12. 82 50
      drivers/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c
  13. 3 3
      drivers/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.h
  14. 0 4
      drivers/cam_icp/icp_hw/icp_proc/icp_v1_hw/cam_icp_v1_core.c
  15. 0 2
      drivers/cam_icp/icp_hw/icp_proc/icp_v2_hw/cam_icp_v2_core.c
  16. 1 4
      drivers/cam_icp/icp_hw/ipe_hw/ipe_core.c
  17. 28 50
      drivers/cam_isp/cam_isp_context.c
  18. 324 42
      drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c
  19. 5 0
      drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.h
  20. 19 11
      drivers/cam_isp/isp_hw_mgr/cam_tfe_hw_mgr.c
  21. 10 3
      drivers/cam_isp/isp_hw_mgr/include/cam_isp_hw_mgr_intf.h
  22. 32 3
      drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid780.h
  23. 32 3
      drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid880.h
  24. 5 0
      drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_common.h
  25. 4 0
      drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_hw_ver1.c
  26. 233 11
      drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_hw_ver2.c
  27. 32 0
      drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_hw_ver2.h
  28. 16 0
      drivers/cam_isp/isp_hw_mgr/isp_hw/include/cam_ife_csid_hw_intf.h
  29. 1 0
      drivers/cam_isp/isp_hw_mgr/isp_hw/include/cam_isp_hw.h
  30. 43 4
      drivers/cam_isp/isp_hw_mgr/isp_hw/sfe_hw/sfe_top/cam_sfe_top.c
  31. 1 1
      drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_hw/cam_tfe_core.c
  32. 7 7
      drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_soc.c
  33. 4 0
      drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe17x/cam_vfe480.h
  34. 2 1
      drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_camif_lite_ver2.c
  35. 6 5
      drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_camif_lite_ver3.c
  36. 3 2
      drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_camif_ver2.c
  37. 5 3
      drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_camif_ver3.c
  38. 2 1
      drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_rdi.c
  39. 14 10
      drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top_common.c
  40. 1 1
      drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top_ver4.c
  41. 21 7
      drivers/cam_ope/ope_hw_mgr/cam_ope_hw_mgr.c
  42. 3 3
      drivers/cam_ope/ope_hw_mgr/cam_ope_hw_mgr.h
  43. 8 5
      drivers/cam_sensor_module/cam_actuator/cam_actuator_core.c
  44. 3 0
      drivers/cam_sensor_module/cam_actuator/cam_actuator_core.h
  45. 151 1
      drivers/cam_sensor_module/cam_actuator/cam_actuator_dev.c
  46. 4 2
      drivers/cam_sensor_module/cam_actuator/cam_actuator_dev.h
  47. 21 7
      drivers/cam_sensor_module/cam_csiphy/cam_csiphy_core.c
  48. 7 6
      drivers/cam_sensor_module/cam_csiphy/cam_csiphy_dev.h
  49. 13 13
      drivers/cam_sensor_module/cam_csiphy/include/cam_csiphy_2_1_0_hwreg.h
  50. 13 13
      drivers/cam_sensor_module/cam_csiphy/include/cam_csiphy_2_1_1_hwreg.h
  51. 29 29
      drivers/cam_sensor_module/cam_csiphy/include/cam_csiphy_2_1_2_hwreg.h
  52. 26 26
      drivers/cam_sensor_module/cam_csiphy/include/cam_csiphy_2_1_3_hwreg.h
  53. 31 31
      drivers/cam_sensor_module/cam_csiphy/include/cam_csiphy_2_2_0_hwreg.h
  54. 8 4
      drivers/cam_sensor_module/cam_eeprom/cam_eeprom_core.c
  55. 3 0
      drivers/cam_sensor_module/cam_eeprom/cam_eeprom_core.h
  56. 151 2
      drivers/cam_sensor_module/cam_eeprom/cam_eeprom_dev.c
  57. 3 1
      drivers/cam_sensor_module/cam_eeprom/cam_eeprom_dev.h
  58. 1 1
      drivers/cam_sensor_module/cam_flash/cam_flash_core.c
  59. 11 9
      drivers/cam_sensor_module/cam_ois/cam_ois_core.c
  60. 3 0
      drivers/cam_sensor_module/cam_ois/cam_ois_core.h
  61. 150 13
      drivers/cam_sensor_module/cam_ois/cam_ois_dev.c
  62. 1 11
      drivers/cam_sensor_module/cam_ois/cam_ois_dev.h
  63. 8 20
      drivers/cam_sensor_module/cam_sensor/cam_sensor_core.c
  64. 1 1
      drivers/cam_sensor_module/cam_sensor/cam_sensor_dev.c
  65. 26 2
      drivers/cam_sensor_module/cam_sensor_io/cam_sensor_qup_i3c.c
  66. 2 1
      drivers/cam_sensor_module/cam_sensor_utils/cam_sensor_cmn_header.h
  67. 13 1
      drivers/cam_sensor_module/cam_sensor_utils/cam_sensor_util.c
  68. 1 1
      drivers/cam_sensor_module/cam_sensor_utils/cam_sensor_util.h
  69. 98 2
      drivers/cam_utils/cam_compat.c
  70. 10 2
      drivers/cam_utils/cam_compat.h
  71. 3 1
      drivers/cam_utils/cam_soc_bus.c
  72. 23 4
      drivers/cam_utils/cam_soc_bus.h
  73. 111 38
      drivers/cam_utils/cam_soc_icc.c

+ 2 - 0
config/kalama.mk

@@ -6,6 +6,7 @@ CONFIG_SPECTRA_ICP := y
 CONFIG_SPECTRA_JPEG := y
 CONFIG_SPECTRA_CUSTOM := y
 CONFIG_SPECTRA_SENSOR := y
+CONFIG_USE_RPMH_DRV_API := y
 
 # Flags to pass into C preprocessor
 ccflags-y += -DCONFIG_SPECTRA_ISP=1
@@ -13,6 +14,7 @@ ccflags-y += -DCONFIG_SPECTRA_ICP=1
 ccflags-y += -DCONFIG_SPECTRA_JPEG=1
 ccflags-y += -DCONFIG_SPECTRA_CUSTOM=1
 ccflags-y += -DCONFIG_SPECTRA_SENSOR=1
+ccflags-y += -DCONFIG_USE_RPMH_DRV_API=1
 
 # External Dependencies
 KBUILD_CPPFLAGS += -DCONFIG_MSM_MMRM=1

File diff suppressed because it is too large
+ 545 - 199
drivers/cam_cpas/cam_cpas_hw.c


+ 81 - 16
drivers/cam_cpas/cam_cpas_hw.h

@@ -17,6 +17,7 @@
 #define CAM_CPAS_INFLIGHT_WORKS              5
 #define CAM_CPAS_MAX_CLIENTS                 42
 #define CAM_CPAS_MAX_AXI_PORTS               6
+#define CAM_CPAS_MAX_DRV_PORTS               4
 #define CAM_CPAS_MAX_TREE_LEVELS             4
 #define CAM_CPAS_MAX_RT_WR_NIU_NODES         10
 #define CAM_CPAS_MAX_GRAN_PATHS_PER_CLIENT   32
@@ -65,6 +66,66 @@ enum cam_cpas_access_type {
 	CAM_REG_TYPE_READ_WRITE,
 };
 
+/**
+ * enum cam_cpas_vote_type - Enum for cpas vote type
+ */
+enum cam_cpas_vote_type {
+	CAM_CPAS_VOTE_TYPE_HLOS,
+	CAM_CPAS_VOTE_TYPE_DRV,
+};
+
+/**
+ * struct cam_cpas_vdd_ahb_mapping : Voltage to ahb level mapping
+ *
+ * @vdd_corner : Voltage corner value
+ * @ahb_level : AHB vote level corresponds to this vdd_corner
+ *
+ */
+struct cam_cpas_vdd_ahb_mapping {
+	unsigned int vdd_corner;
+	enum cam_vote_level ahb_level;
+};
+
+/**
+ * struct cam_cpas_bw_vote : AXI bw vote
+ *
+ * @ab: AB bw value
+ * @ib: IB bw value
+ *
+ */
+struct cam_cpas_bw_vote {
+	uint64_t ab;
+	uint64_t ib;
+};
+
+/**
+ * struct cam_cpas_drv_vote : DRV bw vote
+ *
+ * @high: Active bw values
+ * @low:  Sleep bw values
+ *
+ */
+struct cam_cpas_drv_vote {
+	struct cam_cpas_bw_vote high;
+	struct cam_cpas_bw_vote low;
+};
+
+/**
+ * struct cam_cpas_axi_bw_info : AXI bw info
+ *
+ * @vote_type:  HLOS or DRV vote type
+ * @hlos_vote: HLOS bw values
+ * @drv_vote:  DRV bw values
+ *
+ */
+struct cam_cpas_axi_bw_info {
+	enum cam_cpas_vote_type vote_type;
+	union {
+		struct cam_cpas_bw_vote hlos_vote;
+		struct cam_cpas_drv_vote drv_vote;
+	};
+};
+
 /**
  * struct cam_cpas_internal_ops - CPAS Hardware layer internal ops
  *
@@ -124,6 +185,7 @@ struct cam_cpas_reg {
  * @registered: Whether client has registered with cpas
  * @started: Whether client has streamed on
  * @tree_node_valid: Indicates whether tree node has at least one valid node
+ * @is_drv_dyn: Indicates whether this client is DRV dynamic voting client
  * @ahb_level: Determined/Applied ahb level for the client
  * @axi_vote: Determined/Applied axi vote for the client
  * @axi_port: Client's parent axi port
@@ -135,6 +197,7 @@ struct cam_cpas_client {
 	bool registered;
 	bool started;
 	bool tree_node_valid;
+	bool is_drv_dyn;
 	enum cam_vote_level ahb_level;
 	struct cam_axi_vote axi_vote;
 	struct cam_cpas_axi_port *axi_port;
@@ -168,12 +231,13 @@ struct cam_cpas_bus_client {
  * @ib_bw_voting_needed: if this port can update ib bw dynamically
  * @is_rt: if this port represents a real time axi port
  * @axi_port_node: Node representing AXI Port info in device tree
- * @ab_bw: AB bw value for this port
- * @ib_bw: IB bw value for this port
+ * @drv_idx: DRV index for axi port node
+ * @cam_rsc_dev: Cam RSC device for DRV
+ * @is_drv_started: Indicates if DRV started for RSC device corresponding to port
+ * @curr_bw: Current voted bw after cpas consolidation
  * @camnoc_bw: CAMNOC bw value for this port
  * @additional_bw: Additional bandwidth to cover non-hw cpas clients
- * @applied_ab_bw: applied ab bw for this port
- * @applied_ib_bw: applied ib bw for this port
+ * @applied_bw: Actual applied bw to port
  */
 struct cam_cpas_axi_port {
 	const char *axi_port_name;
@@ -181,31 +245,30 @@ struct cam_cpas_axi_port {
 	bool ib_bw_voting_needed;
 	bool is_rt;
 	struct device_node *axi_port_node;
-	uint64_t ab_bw;
-	uint64_t ib_bw;
+	uint32_t drv_idx;
+	const struct device *cam_rsc_dev;
+	bool is_drv_started;
+	struct cam_cpas_axi_bw_info curr_bw;
 	uint64_t camnoc_bw;
 	uint64_t additional_bw;
-	uint64_t applied_ab_bw;
-	uint64_t applied_ib_bw;
+	struct cam_cpas_axi_bw_info applied_bw;
 };
 
 /**
  * struct cam_cpas_axi_port_debug_info : AXI port information
  *
  * @axi_port_name: Name of this AXI port
- * @ab_bw: AB bw value for this port
- * @ib_bw: IB bw value for this port
+ * @curr_bw: Current voted bw after cpas consolidation
  * @camnoc_bw: CAMNOC bw value for this port
- * @applied_ab_bw: applied ab bw for this port
- * @applied_ib_bw: applied ib bw for this port
+ * @applied_bw: Actual applied bw to port
+ * @is_drv_started: Indicates if DRV started for RSC device corresponding to port
  */
 struct cam_cpas_axi_port_debug_info {
 	const char *axi_port_name;
-	uint64_t ab_bw;
-	uint64_t ib_bw;
+	struct cam_cpas_axi_bw_info curr_bw;
 	uint64_t camnoc_bw;
-	uint64_t applied_ab_bw;
-	uint64_t applied_ib_bw;
+	struct cam_cpas_axi_bw_info applied_bw;
+	bool is_drv_started;
 };
 
 /**
@@ -285,6 +348,7 @@ struct cam_cpas_monitor {
  * @slave_err_irq_en: Whether slave error irq is enabled to detect memory
  *                    config issues
  * @smmu_fault_handled: Handled address decode error, on fault at SMMU
+ * @force_hlos_drv: Whether to force disable DRV voting
  */
 struct cam_cpas {
 	struct cam_cpas_hw_caps hw_caps;
@@ -315,6 +379,7 @@ struct cam_cpas {
 	bool smart_qos_dump;
 	bool slave_err_irq_en;
 	bool smmu_fault_handled;
+	bool force_hlos_drv;
 };
 
 int cam_camsstop_get_internal_ops(struct cam_cpas_internal_ops *internal_ops);

+ 18 - 0
drivers/cam_cpas/cam_cpas_hw_intf.h

@@ -1,6 +1,7 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
 /*
  * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #ifndef _CAM_CPAS_HW_INTF_H_
@@ -47,9 +48,26 @@ enum cam_cpas_hw_cmd_process {
 	CAM_CPAS_HW_CMD_ACTIVATE_LLC,
 	CAM_CPAS_HW_CMD_DEACTIVATE_LLC,
 	CAM_CPAS_HW_CMD_DUMP_BUFF_FILL_INFO,
+	CAM_CPAS_HW_CMD_CSID_INPUT_CORE_INFO_UPDATE,
+	CAM_CPAS_HW_CMD_CSID_PROCESS_RESUME,
 	CAM_CPAS_HW_CMD_INVALID,
 };
 
+/**
+ * struct cam_cpas_hw_cmd_csid_input_core_info_update : CPAS cmd struct for updating acquired
+ *                                                      csid core info to cpas
+ *
+ * @csid_idx: CSID core index
+ * @sfe_idx:  SFE core index corresponding to CSID core
+ * @set_port: Indicates whether to set or reset port for given client
+ *
+ */
+struct cam_cpas_hw_cmd_csid_input_core_info_update {
+	int csid_idx;
+	int sfe_idx;
+	bool set_port;
+};
+
 /**
  * struct cam_cpas_hw_cmd_reg_read_write : CPAS cmd struct for reg read, write
  *

+ 97 - 4
drivers/cam_cpas/cam_cpas_intf.c

@@ -144,6 +144,100 @@ const char *cam_cpas_axi_util_trans_type_to_string(
 }
 EXPORT_SYMBOL(cam_cpas_axi_util_trans_type_to_string);
 
+const char *cam_cpas_axi_util_drv_vote_lvl_to_string(
+	uint32_t vote_lvl)
+{
+	switch (vote_lvl) {
+	case CAM_CPAS_VOTE_LEVEL_LOW:
+		return "VOTE_LVL_LOW";
+	case CAM_CPAS_VOTE_LEVEL_HIGH:
+		return "VOTE_LVL_HIGH";
+	default:
+		return "VOTE_LVL_INVALID";
+	}
+}
+EXPORT_SYMBOL(cam_cpas_axi_util_drv_vote_lvl_to_string);
+
+int cam_cpas_query_drv_enable(bool *is_drv_enabled)
+{
+	struct cam_hw_info *cpas_hw = NULL;
+	struct cam_cpas_private_soc *soc_private = NULL;
+
+	if (!CAM_CPAS_INTF_INITIALIZED()) {
+		CAM_ERR(CAM_CPAS, "cpas intf not initialized");
+		return -ENODEV;
+	}
+
+	if (!is_drv_enabled) {
+		CAM_ERR(CAM_CPAS, "invalid input %pK", is_drv_enabled);
+		return -EINVAL;
+	}
+
+	cpas_hw = (struct cam_hw_info  *) g_cpas_intf->hw_intf->hw_priv;
+	soc_private = (struct cam_cpas_private_soc *) cpas_hw->soc_info.soc_private;
+
+	*is_drv_enabled = soc_private->enable_cam_ddr_drv;
+
+	return 0;
+}
+EXPORT_SYMBOL(cam_cpas_query_drv_enable);
+
+int cam_cpas_csid_process_resume(uint32_t csid_idx)
+{
+	int rc;
+
+	if (!CAM_CPAS_INTF_INITIALIZED()) {
+		CAM_ERR(CAM_CPAS, "cpas intf not initialized");
+		return -ENODEV;
+	}
+
+	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_CSID_PROCESS_RESUME, &csid_idx,
+			sizeof(uint32_t));
+		if (rc)
+			CAM_ERR(CAM_CPAS, "Failed in process_cmd, rc=%d", rc);
+	} else {
+		CAM_ERR(CAM_CPAS, "Invalid process_cmd ops");
+		rc = -EINVAL;
+	}
+
+	return rc;
+}
+EXPORT_SYMBOL(cam_cpas_csid_process_resume);
+
+
+int cam_cpas_csid_input_core_info_update(int csid_idx, int sfe_idx, bool set_port)
+{
+	int rc;
+
+	if (!CAM_CPAS_INTF_INITIALIZED()) {
+		CAM_ERR(CAM_CPAS, "cpas intf not initialized");
+		return -ENODEV;
+	}
+
+	if (g_cpas_intf->hw_intf->hw_ops.process_cmd) {
+		struct cam_cpas_hw_cmd_csid_input_core_info_update core_info_update;
+
+		core_info_update.csid_idx = csid_idx;
+		core_info_update.sfe_idx = sfe_idx;
+		core_info_update.set_port = set_port;
+		rc = g_cpas_intf->hw_intf->hw_ops.process_cmd(
+			g_cpas_intf->hw_intf->hw_priv,
+			CAM_CPAS_HW_CMD_CSID_INPUT_CORE_INFO_UPDATE, &core_info_update,
+			sizeof(core_info_update));
+		if (rc)
+			CAM_ERR(CAM_CPAS, "Failed in process_cmd, rc=%d", rc);
+	} else {
+		CAM_ERR(CAM_CPAS, "Invalid process_cmd ops");
+		rc = -EINVAL;
+	}
+
+	return rc;
+}
+EXPORT_SYMBOL(cam_cpas_csid_input_core_info_update);
+
 int cam_cpas_dump_camnoc_buff_fill_info(uint32_t client_handle)
 {
 	int rc;
@@ -485,9 +579,8 @@ int cam_cpas_start(uint32_t client_handle,
 }
 EXPORT_SYMBOL(cam_cpas_start);
 
-void cam_cpas_log_votes(void)
+void cam_cpas_log_votes(bool ddr_only)
 {
-	uint32_t dummy_args;
 	int rc;
 
 	if (!CAM_CPAS_INTF_INITIALIZED()) {
@@ -498,8 +591,8 @@ void cam_cpas_log_votes(void)
 	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_LOG_VOTE, &dummy_args,
-			sizeof(dummy_args));
+			CAM_CPAS_HW_CMD_LOG_VOTE, &ddr_only,
+			sizeof(ddr_only));
 		if (rc)
 			CAM_ERR(CAM_CPAS, "Failed in process_cmd, rc=%d", rc);
 	} else {

+ 257 - 188
drivers/cam_cpas/cam_cpas_soc.c

@@ -17,8 +17,9 @@
 #include "cam_cpas_hw_intf.h"
 #include "cam_cpas_hw.h"
 #include "cam_cpas_soc.h"
+#include "cam_compat.h"
 
-static uint cpas_dump;
+static uint cpas_dump = 1;
 module_param(cpas_dump, uint, 0644);
 
 #define CAM_ICP_CLK_NAME "cam_icp_clk"
@@ -42,11 +43,12 @@ void cam_cpas_dump_axi_vote_info(
 
 	for (i = 0; i < axi_vote->num_paths; i++) {
 		CAM_INFO(CAM_PERF,
-		"Client [%s][%d] : [%s], Path=[%d] [%d], camnoc[%llu], mnoc_ab[%llu], mnoc_ib[%llu]",
+		"Client [%s][%d] : [%s], Path=[%d] [%d], [%s], camnoc[%llu], mnoc_ab[%llu], mnoc_ib[%llu]",
 		cpas_client->data.identifier, cpas_client->data.cell_index,
 		identifier,
 		axi_vote->axi_path[i].path_data_type,
 		axi_vote->axi_path[i].transac_type,
+		cam_cpas_axi_util_drv_vote_lvl_to_string(axi_vote->axi_path[i].vote_level),
 		axi_vote->axi_path[i].camnoc_bw,
 		axi_vote->axi_path[i].mnoc_ab_bw,
 		axi_vote->axi_path[i].mnoc_ib_bw);
@@ -71,7 +73,7 @@ void cam_cpas_util_debug_parse_data(
 		CAM_INFO(CAM_CPAS,
 			"NODE cell_idx: %d, level: %d, name: %s, axi_port_idx: %d, merge_type: %d, parent_name: %s camnoc_max_needed: %d",
 			curr_node->cell_idx, curr_node->level_idx,
-			curr_node->node_name, curr_node->axi_port_idx,
+			curr_node->node_name, curr_node->axi_port_idx_arr[CAM_CPAS_PORT_HLOS_DRV],
 			curr_node->merge_type, curr_node->parent_node ?
 			curr_node->parent_node->node_name : "no parent",
 			curr_node->camnoc_max_needed);
@@ -79,10 +81,10 @@ void cam_cpas_util_debug_parse_data(
 		if (curr_node->level_idx)
 			continue;
 
-		CAM_INFO(CAM_CPAS, "path_type: %d, transac_type: %s",
+		CAM_INFO(CAM_CPAS, "path_type: %d, transac_type: %s drv_voting_idx:%d",
 			curr_node->path_data_type,
 			cam_cpas_axi_util_trans_type_to_string(
-			curr_node->path_trans_type));
+			curr_node->path_trans_type), curr_node->drv_voting_idx);
 
 		for (j = 0; j < CAM_CPAS_PATH_DATA_MAX; j++) {
 			CAM_INFO(CAM_CPAS, "Constituent path: %d",
@@ -100,6 +102,10 @@ int cam_cpas_node_tree_cleanup(struct cam_cpas *cpas_core,
 
 	for (i = 0; i < CAM_CPAS_MAX_TREE_NODES; i++) {
 		if (soc_private->tree_node[i]) {
+			kfree(soc_private->tree_node[i]->bw_info);
+			kfree(soc_private->tree_node[i]->axi_port_idx_arr);
+			soc_private->tree_node[i]->bw_info = NULL;
+			soc_private->tree_node[i]->axi_port_idx_arr = NULL;
 			of_node_put(soc_private->tree_node[i]->tree_dev_node);
 			kfree(soc_private->tree_node[i]);
 			soc_private->tree_node[i] = NULL;
@@ -182,6 +188,151 @@ static int cam_cpas_update_camnoc_node(struct cam_cpas *cpas_core,
 	return 0;
 }
 
+static int cam_cpas_parse_mnoc_node(struct cam_cpas *cpas_core,
+	struct cam_cpas_private_soc *soc_private, struct cam_cpas_tree_node *curr_node_ptr,
+	struct device_node *mnoc_node, int *mnoc_idx)
+{
+	int rc = 0, count = 0, i;
+	bool ib_voting_needed = false, is_rt_port = false;
+	struct of_phandle_args src_args = {0}, dst_args = {0};
+
+	ib_voting_needed = of_property_read_bool(curr_node_ptr->tree_dev_node,
+		"ib-bw-voting-needed");
+	is_rt_port = of_property_read_bool(curr_node_ptr->tree_dev_node, "rt-axi-port");
+
+	if (soc_private->bus_icc_based) {
+		count = of_property_count_strings(mnoc_node, "interconnect-names");
+		if (count <= 0) {
+			CAM_ERR(CAM_CPAS, "no interconnect-names found");
+			count = 0;
+			return -EINVAL;
+		} else if (count > CAM_CPAS_MAX_DRV_PORTS) {
+			CAM_ERR(CAM_CPAS, "Number of interconnects %d greater than max ports %d",
+				count, CAM_CPAS_MAX_DRV_PORTS);
+			count = 0;
+			return -EINVAL;
+		}
+
+		for (i = 0; i < count; i++) {
+			if ((i > 0) && !soc_private->enable_cam_ddr_drv)
+				break;
+
+			if (*mnoc_idx >= CAM_CPAS_MAX_AXI_PORTS) {
+				CAM_ERR(CAM_CPAS, "Invalid mnoc index: %d", *mnoc_idx);
+				return -EINVAL;
+			}
+
+			cpas_core->axi_port[*mnoc_idx].axi_port_node = mnoc_node;
+			rc = of_property_read_string_index(mnoc_node, "interconnect-names", i,
+				&cpas_core->axi_port[*mnoc_idx].bus_client.common_data.name);
+			if (rc) {
+				CAM_ERR(CAM_CPAS, "failed to read interconnect-names rc=%d", rc);
+				return rc;
+			}
+
+			rc = of_parse_phandle_with_args(mnoc_node, "interconnects",
+				"#interconnect-cells", (2 * i), &src_args);
+			if (rc) {
+				CAM_ERR(CAM_CPAS,
+					"failed to read axi bus src info rc=%d",
+					rc);
+				return -EINVAL;
+			}
+
+			of_node_put(src_args.np);
+			if (src_args.args_count != 1) {
+				CAM_ERR(CAM_CPAS, "Invalid number of axi src args: %d",
+					src_args.args_count);
+				return -EINVAL;
+			}
+
+			cpas_core->axi_port[*mnoc_idx].bus_client.common_data.src_id =
+				src_args.args[0];
+
+			rc = of_parse_phandle_with_args(mnoc_node, "interconnects",
+				"#interconnect-cells", ((2 * i) + 1), &dst_args);
+			if (rc) {
+				CAM_ERR(CAM_CPAS, "failed to read axi bus dst info rc=%d", rc);
+				return -EINVAL;
+			}
+
+			of_node_put(dst_args.np);
+			if (dst_args.args_count != 1) {
+				CAM_ERR(CAM_CPAS, "Invalid number of axi dst args: %d",
+					dst_args.args_count);
+				return -EINVAL;
+			}
+
+			cpas_core->axi_port[*mnoc_idx].bus_client.common_data.dst_id =
+				dst_args.args[0];
+			cpas_core->axi_port[*mnoc_idx].bus_client.common_data.num_usecases = 2;
+			cpas_core->axi_port[*mnoc_idx].axi_port_name =
+				cpas_core->axi_port[*mnoc_idx].bus_client.common_data.name;
+			cpas_core->axi_port[*mnoc_idx].drv_idx = i;
+
+			if (i > CAM_CPAS_PORT_HLOS_DRV) {
+				cpas_core->axi_port[*mnoc_idx].bus_client.common_data.is_drv_port =
+					true;
+				cpas_core->axi_port[*mnoc_idx].curr_bw.vote_type =
+					CAM_CPAS_VOTE_TYPE_DRV;
+				cpas_core->axi_port[*mnoc_idx].applied_bw.vote_type =
+					CAM_CPAS_VOTE_TYPE_DRV;
+				cpas_core->axi_port[*mnoc_idx].cam_rsc_dev =
+					cam_cpas_get_rsc_dev_for_drv(i - CAM_CPAS_PORT_DRV_0);
+				if (!cpas_core->axi_port[*mnoc_idx].cam_rsc_dev) {
+					CAM_ERR(CAM_CPAS,
+						"Port[%s][%d] Failed to get rsc device drv_idx:%d",
+						cpas_core->axi_port[*mnoc_idx].axi_port_name,
+						*mnoc_idx, i);
+					rc = -ENODEV;
+					goto err;
+				}
+			}
+
+			/*
+			 * The indexes of axi_port_idx_arr map to drv_voting_idx,
+			 * with 0 pointing to hlos drv bus ID
+			 */
+			curr_node_ptr->axi_port_idx_arr[i] = *mnoc_idx;
+			cpas_core->axi_port[*mnoc_idx].ib_bw_voting_needed = ib_voting_needed;
+			cpas_core->axi_port[*mnoc_idx].is_rt = is_rt_port;
+			CAM_DBG(CAM_PERF, "Adding Bus Client=[%s] : src=%d, dst=%d mnoc_idx:%d",
+				cpas_core->axi_port[*mnoc_idx].bus_client.common_data.name,
+				cpas_core->axi_port[*mnoc_idx].bus_client.common_data.src_id,
+				cpas_core->axi_port[*mnoc_idx].bus_client.common_data.dst_id,
+				*mnoc_idx);
+			(*mnoc_idx)++;
+			cpas_core->num_axi_ports++;
+		}
+	} else {
+		if (soc_private->enable_cam_ddr_drv) {
+			CAM_ERR(CAM_CPAS, "DRV not supported for old bus scaling clients");
+			return -EPERM;
+		}
+
+		cpas_core->axi_port[*mnoc_idx].axi_port_node = mnoc_node;
+		rc =  of_property_read_string(curr_node_ptr->tree_dev_node, "qcom,axi-port-name",
+			&cpas_core->axi_port[*mnoc_idx].bus_client.common_data.name);
+		if (rc) {
+			CAM_ERR(CAM_CPAS,
+				"failed to read mnoc-port-name rc=%d",
+				rc);
+			return rc;
+		}
+
+		cpas_core->axi_port[*mnoc_idx].axi_port_name =
+			cpas_core->axi_port[*mnoc_idx].bus_client.common_data.name;
+		curr_node_ptr->axi_port_idx_arr[0] = *mnoc_idx;
+		cpas_core->axi_port[*mnoc_idx].ib_bw_voting_needed = ib_voting_needed;
+		cpas_core->axi_port[*mnoc_idx].is_rt = is_rt_port;
+		(*mnoc_idx)++;
+		cpas_core->num_axi_ports++;
+	}
+
+err:
+	return rc;
+}
+
 static int cam_cpas_parse_node_tree(struct cam_cpas *cpas_core,
 	struct device_node *of_node, struct cam_cpas_private_soc *soc_private)
 {
@@ -198,7 +349,7 @@ static int cam_cpas_parse_node_tree(struct cam_cpas *cpas_core,
 	const char *client_name = NULL;
 	uint32_t client_idx = 0, cell_idx = 0;
 	uint8_t niu_idx = 0;
-	int rc = 0, count = 0, i;
+	int rc = 0, count = 0, i, j, num_drv_ports;
 
 	camera_bus_node = of_get_child_by_name(of_node, "camera-bus-nodes");
 	if (!camera_bus_node) {
@@ -209,8 +360,7 @@ static int cam_cpas_parse_node_tree(struct cam_cpas *cpas_core,
 	soc_private->camera_bus_node = camera_bus_node;
 
 	for_each_available_child_of_node(camera_bus_node, level_node) {
-		rc = of_property_read_u32(level_node, "level-index",
-			&level_idx);
+		rc = of_property_read_u32(level_node, "level-index", &level_idx);
 		if (rc) {
 			CAM_ERR(CAM_CPAS, "Error reading level idx rc: %d", rc);
 			return rc;
@@ -226,6 +376,11 @@ static int cam_cpas_parse_node_tree(struct cam_cpas *cpas_core,
 	if (soc_private->enable_smart_qos)
 		soc_private->smart_qos_info->num_rt_wr_nius = 0;
 
+	if (soc_private->enable_cam_ddr_drv)
+		num_drv_ports = CAM_CPAS_MAX_DRV_PORTS;
+	else
+		num_drv_ports = 1;
+
 	for (level_idx = (CAM_CPAS_MAX_TREE_LEVELS - 1); level_idx >= 0;
 		level_idx--) {
 		level_node = soc_private->level_node[level_idx];
@@ -234,12 +389,9 @@ static int cam_cpas_parse_node_tree(struct cam_cpas *cpas_core,
 
 		CAM_DBG(CAM_CPAS, "Parsing level %d nodes", level_idx);
 
-		camnoc_max_needed = of_property_read_bool(level_node,
-			"camnoc-max-needed");
+		camnoc_max_needed = of_property_read_bool(level_node, "camnoc-max-needed");
 		for_each_available_child_of_node(level_node, curr_node) {
-			curr_node_ptr =
-				kzalloc(sizeof(struct cam_cpas_tree_node),
-				GFP_KERNEL);
+			curr_node_ptr = kzalloc(sizeof(struct cam_cpas_tree_node), GFP_KERNEL);
 			if (!curr_node_ptr)
 				return -ENOMEM;
 
@@ -256,50 +408,54 @@ static int cam_cpas_parse_node_tree(struct cam_cpas *cpas_core,
 
 			if (curr_node_ptr->cell_idx >=
 				CAM_CPAS_MAX_TREE_NODES) {
-				CAM_ERR(CAM_CPAS, "Invalid cell idx: %d",
-					curr_node_ptr->cell_idx);
+				CAM_ERR(CAM_CPAS, "Invalid cell idx: %d", curr_node_ptr->cell_idx);
 				return -EINVAL;
 			}
 
-			soc_private->tree_node[curr_node_ptr->cell_idx] =
-				curr_node_ptr;
+			soc_private->tree_node[curr_node_ptr->cell_idx] = curr_node_ptr;
 			curr_node_ptr->level_idx = level_idx;
 
 			rc = of_property_read_string(curr_node, "node-name",
 				&curr_node_ptr->node_name);
 			if (rc) {
-				CAM_ERR(CAM_CPAS,
-					"failed to read node-name rc=%d",
-					rc);
+				CAM_ERR(CAM_CPAS, "failed to read node-name rc=%d", rc);
 				return rc;
 			}
 
-			if (soc_private->enable_smart_qos &&
-				(level_idx == 1) &&
+			curr_node_ptr->bw_info = kzalloc((sizeof(struct cam_cpas_axi_bw_info) *
+				num_drv_ports), GFP_KERNEL);
+			if (!curr_node_ptr->bw_info) {
+				CAM_ERR(CAM_CPAS, "Failed in allocating memory for bw info");
+				return -ENOMEM;
+			}
+
+			curr_node_ptr->axi_port_idx_arr = kzalloc((sizeof(int) * num_drv_ports),
+				GFP_KERNEL);
+			if (!curr_node_ptr->axi_port_idx_arr) {
+				CAM_ERR(CAM_CPAS, "Failed in allocating memory for port indices");
+				return -ENOMEM;
+			}
+
+			if (soc_private->enable_smart_qos && (level_idx == 1) &&
 				of_property_read_bool(curr_node, "rt-wr-niu")) {
 
-				rc = of_property_read_u32(curr_node,
-					"priority-lut-low-offset",
+				rc = of_property_read_u32(curr_node, "priority-lut-low-offset",
 					&curr_node_ptr->pri_lut_low_offset);
 				if (rc) {
-					CAM_ERR(CAM_CPAS,
-						"Invalid priority offset rc %d",
-						rc);
+					CAM_ERR(CAM_CPAS, "Invalid priority offset rc %d", rc);
 					return rc;
 				}
 
 				rc = of_property_read_u32(curr_node, "niu-size",
 					&curr_node_ptr->niu_size);
 				if (rc || !curr_node_ptr->niu_size) {
-					CAM_ERR(CAM_CPAS,
-						"Invalid niu size rc %d", rc);
+					CAM_ERR(CAM_CPAS, "Invalid niu size rc %d", rc);
 					return rc;
 				}
 
 				niu_idx = soc_private->smart_qos_info->num_rt_wr_nius;
 				if (niu_idx >= CAM_CPAS_MAX_RT_WR_NIU_NODES) {
-					CAM_ERR(CAM_CPAS,
-						"Invalid number of level1 nodes %d",
+					CAM_ERR(CAM_CPAS, "Invalid number of level1 nodes %d",
 						soc_private->smart_qos_info->num_rt_wr_nius);
 					return -EINVAL;
 				}
@@ -310,8 +466,7 @@ static int cam_cpas_parse_node_tree(struct cam_cpas *cpas_core,
 
 				CAM_DBG(CAM_CPAS,
 					"level1[%d] : Node %s idx %d priority offset 0x%x, NIU size %dKB",
-					niu_idx,
-					curr_node_ptr->node_name, curr_node_ptr->cell_idx,
+					niu_idx, curr_node_ptr->node_name, curr_node_ptr->cell_idx,
 					curr_node_ptr->pri_lut_low_offset, curr_node_ptr->niu_size);
 			}
 
@@ -321,221 +476,130 @@ static int cam_cpas_parse_node_tree(struct cam_cpas *cpas_core,
 			if (rc)
 				curr_node_ptr->bus_width_factor = 1;
 
-			rc = of_property_read_u32(curr_node,
-				"traffic-merge-type",
+			rc = of_property_read_u32(curr_node, "traffic-merge-type",
 				&curr_node_ptr->merge_type);
 
-			curr_node_ptr->axi_port_idx = -1;
-			mnoc_node = of_get_child_by_name(curr_node,
-				"qcom,axi-port-mnoc");
-			if (mnoc_node) {
-				if (mnoc_idx >= CAM_CPAS_MAX_AXI_PORTS) {
-					CAM_ERR(CAM_CPAS,
-						"Invalid mnoc index: %d",
-						mnoc_idx);
-					return -EINVAL;
-				}
-
-				cpas_core->axi_port[mnoc_idx].axi_port_node
-					= mnoc_node;
-				if (soc_private->bus_icc_based) {
-					struct of_phandle_args src_args = {0},
-						dst_args = {0};
+			for (j = 0; j < num_drv_ports; j++)
+				curr_node_ptr->axi_port_idx_arr[j] = -1;
 
-					rc = of_property_read_string(mnoc_node,
-						"interconnect-names",
-						&cpas_core->axi_port[mnoc_idx]
-						.bus_client.common_data.name);
-					if (rc) {
-						CAM_ERR(CAM_CPAS,
-							"failed to read interconnect-names rc=%d",
-							rc);
-						return rc;
-					}
-
-					rc = of_parse_phandle_with_args(
-						mnoc_node, "interconnects",
-						"#interconnect-cells", 0,
-						&src_args);
-					if (rc) {
-						CAM_ERR(CAM_CPAS,
-							"failed to read axi bus src info rc=%d",
-							rc);
-						return -EINVAL;
-					}
-
-					of_node_put(src_args.np);
-					if (src_args.args_count != 1) {
-						CAM_ERR(CAM_CPAS,
-							"Invalid number of axi src args: %d",
-							src_args.args_count);
-						return -EINVAL;
-					}
-
-					cpas_core->axi_port[mnoc_idx].bus_client
-					.common_data.src_id = src_args.args[0];
-
-					rc = of_parse_phandle_with_args(
-						mnoc_node, "interconnects",
-						"#interconnect-cells", 1,
-						&dst_args);
-					if (rc) {
-						CAM_ERR(CAM_CPAS,
-							"failed to read axi bus dst info rc=%d",
-							rc);
-						return -EINVAL;
-					}
-
-					of_node_put(dst_args.np);
-					if (dst_args.args_count != 1) {
-						CAM_ERR(CAM_CPAS,
-							"Invalid number of axi dst args: %d",
-							dst_args.args_count);
-						return -EINVAL;
-					}
-
-					cpas_core->axi_port[mnoc_idx].bus_client
-					.common_data.dst_id = dst_args.args[0];
-					cpas_core->axi_port[mnoc_idx].bus_client
-						.common_data.num_usecases = 2;
-				} else {
-					rc =  of_property_read_string(
-						curr_node, "qcom,axi-port-name",
-						&cpas_core->axi_port[mnoc_idx]
-						.bus_client.common_data.name);
-					if (rc) {
-						CAM_ERR(CAM_CPAS,
-							"failed to read mnoc-port-name rc=%d",
-							rc);
-						return rc;
-					}
+			mnoc_node = of_get_child_by_name(curr_node, "qcom,axi-port-mnoc");
+			if (mnoc_node) {
+				rc = cam_cpas_parse_mnoc_node(cpas_core, soc_private, curr_node_ptr,
+					mnoc_node, &mnoc_idx);
+				if (rc) {
+					CAM_ERR(CAM_CPAS, "failed to parse mnoc node info rc=%d",
+						rc);
+					return rc;
 				}
-
-				cpas_core->axi_port[mnoc_idx].axi_port_name =
-					cpas_core->axi_port[mnoc_idx]
-						.bus_client.common_data.name;
-				cpas_core->axi_port
-					[mnoc_idx].ib_bw_voting_needed
-					= of_property_read_bool(curr_node,
-					"ib-bw-voting-needed");
-				cpas_core->axi_port
-					[mnoc_idx].is_rt
-					= of_property_read_bool(curr_node,
-					"rt-axi-port");
-				curr_node_ptr->axi_port_idx = mnoc_idx;
-				mnoc_idx++;
-				cpas_core->num_axi_ports++;
 			}
 
 			if (!soc_private->control_camnoc_axi_clk) {
-				rc = cam_cpas_update_camnoc_node(
-					cpas_core, curr_node, curr_node_ptr,
-					&camnoc_idx);
+				rc = cam_cpas_update_camnoc_node(cpas_core, curr_node,
+					curr_node_ptr, &camnoc_idx);
 				if (rc) {
-					CAM_ERR(CAM_CPAS,
-						"Parse Camnoc port fail");
+					CAM_ERR(CAM_CPAS, "failed to parse camnoc node info rc=%d",
+						rc);
 					return rc;
 				}
 			}
 
-			rc = of_property_read_string(curr_node,
-				"client-name", &client_name);
+			rc = of_property_read_string(curr_node, "client-name", &client_name);
 			if (!rc) {
-				rc = of_property_read_u32(curr_node,
-				"traffic-data", &curr_node_ptr->path_data_type);
+				rc = of_property_read_u32(curr_node, "traffic-data",
+					&curr_node_ptr->path_data_type);
 				if (rc) {
 					CAM_ERR(CAM_CPAS,
 						"Path Data type not found");
 					return rc;
 				}
 
-				rc = cam_cpas_util_path_type_to_idx(
-					&curr_node_ptr->path_data_type);
+				rc = cam_cpas_util_path_type_to_idx(&curr_node_ptr->path_data_type);
 				if (rc) {
 					CAM_ERR(CAM_CPAS, "Incorrect path type for client: %s",
 						client_name);
 					return rc;
 				}
 
-				rc = of_property_read_u32(curr_node,
-					"traffic-transaction-type",
+				rc = of_property_read_u32(curr_node, "traffic-transaction-type",
 					&curr_node_ptr->path_trans_type);
 				if (rc) {
-					CAM_ERR(CAM_CPAS,
-						"Path Transac type not found");
+					CAM_ERR(CAM_CPAS, "Path Transac type not found");
 					return rc;
 				}
 
-				if (curr_node_ptr->path_trans_type >=
-					CAM_CPAS_TRANSACTION_MAX) {
-					CAM_ERR(CAM_CPAS,
-						"Invalid transac type: %d",
+				if (curr_node_ptr->path_trans_type >= CAM_CPAS_TRANSACTION_MAX) {
+					CAM_ERR(CAM_CPAS, "Invalid transac type: %d",
 						curr_node_ptr->path_trans_type);
 					return -EINVAL;
 				}
 
-				count = of_property_count_u32_elems(curr_node,
-					"constituent-paths");
+				count = of_property_count_u32_elems(curr_node, "constituent-paths");
 				for (i = 0; i < count; i++) {
-					rc = of_property_read_u32_index(
-						curr_node, "constituent-paths",
-						i, &path_idx);
+					rc = of_property_read_u32_index(curr_node,
+						"constituent-paths", i, &path_idx);
 					if (rc) {
-						CAM_ERR(CAM_CPAS,
-						"No constituent path at %d", i);
+						CAM_ERR(CAM_CPAS, "No constituent path at %d", i);
 						return rc;
 					}
 
-					rc = cam_cpas_util_path_type_to_idx(
-						&path_idx);
+					rc = cam_cpas_util_path_type_to_idx(&path_idx);
 					if (rc)
 						return rc;
 
-					curr_node_ptr->constituent_paths
-						[path_idx] = true;
+					curr_node_ptr->constituent_paths[path_idx] = true;
 				}
 
-				rc = cam_common_util_get_string_index(
-					soc_private->client_name,
-					soc_private->num_clients,
-					client_name, &client_idx);
+				rc = cam_common_util_get_string_index(soc_private->client_name,
+					soc_private->num_clients, client_name, &client_idx);
 				if (rc) {
-					CAM_ERR(CAM_CPAS,
-					"client name not found in list: %s",
-					client_name);
+					CAM_ERR(CAM_CPAS, "client name not found in list: %s",
+						client_name);
 					return rc;
 				}
 
 				if (client_idx >= CAM_CPAS_MAX_CLIENTS)
 					return -EINVAL;
 
-				curr_client =
-					cpas_core->cpas_client[client_idx];
+				curr_client = cpas_core->cpas_client[client_idx];
 				curr_client->tree_node_valid = true;
-				curr_client->tree_node
-					[curr_node_ptr->path_data_type]
-					[curr_node_ptr->path_trans_type] =
-					curr_node_ptr;
-				CAM_DBG(CAM_CPAS,
-					"CLIENT NODE ADDED: %d %d %s",
+				curr_client->tree_node[curr_node_ptr->path_data_type]
+					[curr_node_ptr->path_trans_type] = curr_node_ptr;
+
+				if (soc_private->enable_cam_ddr_drv) {
+					rc = of_property_read_u32(curr_node, "drv-voting-index",
+						&curr_node_ptr->drv_voting_idx);
+					if (curr_node_ptr->drv_voting_idx == CAM_CPAS_PORT_DRV_DYN)
+						curr_client->is_drv_dyn = true;
+
+					if (curr_client->is_drv_dyn &&
+						(curr_node_ptr->drv_voting_idx !=
+						CAM_CPAS_PORT_DRV_DYN))
+						CAM_ERR(CAM_CPAS,
+							"Invalid config for drv dyn client: %s drv_idx: %d",
+							client_name, curr_node_ptr->drv_voting_idx);
+				}
+
+				CAM_DBG(CAM_CPAS, "Client Node Added: %d %d %s %d",
 					curr_node_ptr->path_data_type,
-					curr_node_ptr->path_trans_type,
-					client_name);
+					curr_node_ptr->path_trans_type, client_name,
+					curr_node_ptr->drv_voting_idx);
 			}
 
-			parent_node = of_parse_phandle(curr_node,
-				"parent-node", 0);
+			if (soc_private->enable_cam_ddr_drv)
+				for (j = CAM_CPAS_PORT_DRV_0; j < num_drv_ports; j++)
+					curr_node_ptr->bw_info[j].vote_type =
+						CAM_CPAS_VOTE_TYPE_DRV;
+
+			parent_node = of_parse_phandle(curr_node, "parent-node", 0);
 			if (parent_node) {
-				of_property_read_u32(parent_node, "cell-index",
-					&cell_idx);
-				curr_node_ptr->parent_node =
-					soc_private->tree_node[cell_idx];
+				of_property_read_u32(parent_node, "cell-index", &cell_idx);
+				curr_node_ptr->parent_node = soc_private->tree_node[cell_idx];
 			} else {
-				CAM_DBG(CAM_CPAS,
-					"no parent node at this level");
+				CAM_DBG(CAM_CPAS, "no parent node at this level");
 			}
 		}
 	}
+
 	mutex_init(&cpas_core->tree_lock);
 	cam_cpas_util_debug_parse_data(soc_private);
 
@@ -807,6 +871,7 @@ int cam_cpas_get_custom_dt_info(struct cam_hw_info *cpas_hw,
 	struct device_node *of_node;
 	struct of_phandle_args src_args = {0}, dst_args = {0};
 	int count = 0, i = 0, rc = 0, num_bw_values = 0, num_levels = 0;
+	uint32_t cam_drv_en_mask_val = 0;
 	struct cam_cpas *cpas_core = (struct cam_cpas *) cpas_hw->core_info;
 
 	if (!soc_private || !pdev) {
@@ -1120,6 +1185,10 @@ int cam_cpas_get_custom_dt_info(struct cam_hw_info *cpas_hw,
 		soc_private->smart_qos_info = NULL;
 	}
 
+	rc = of_property_read_u32(of_node, "enable-cam-drv", &cam_drv_en_mask_val);
+	if (cam_drv_en_mask_val & CAM_DDR_DRV)
+		soc_private->enable_cam_ddr_drv = true;
+
 	rc = cam_cpas_parse_node_tree(cpas_core, of_node, soc_private);
 	if (rc) {
 		CAM_ERR(CAM_CPAS, "Node tree parsing failed rc: %d", rc);

+ 9 - 22
drivers/cam_cpas/cam_cpas_soc.h

@@ -15,34 +15,21 @@
 #define CAM_CPAS_MAX_TREE_NODES 61
 #define CAM_CPAS_MAX_FUSE_FEATURE 10
 
-/**
- * struct cam_cpas_vdd_ahb_mapping : Voltage to ahb level mapping
- *
- * @vdd_corner : Voltage corner value
- * @ahb_level : AHB vote level corresponds to this vdd_corner
- *
- */
-struct cam_cpas_vdd_ahb_mapping {
-	unsigned int vdd_corner;
-	enum cam_vote_level ahb_level;
-};
-
 /**
  * struct cpas_tree_node: Generic cpas tree node for BW voting
  *
  * @cell_idx: Index to identify node from device tree and its parent
  * @level_idx: Index to identify at what level the node is present
- * @axi_port_idx: Index to identify which axi port to vote the consolidated bw
+ * @axi_port_idx_arr: Index to identify which axi port to vote the consolidated bw.
+ *                    It can point to multiple indexes in case of camera DRV
+ * @drv_voting_idx: Specifies the index to which the child node would finally vote.
  * @camnoc_axi_port_idx: Index to find which axi port to vote consolidated bw
  * @path_data_type: Traffic type info from device tree (ife-vid, ife-disp etc)
  * @path_trans_type: Transaction type info from device tree (rd, wr)
  * @merge_type: Traffic merge type (calculation info) from device tree
  * @bus_width_factor: Factor for accounting bus width in CAMNOC bw calculation
  * @camnoc_bw: CAMNOC bw value at current node
- * @mnoc_ab_bw: MNOC AB bw value at current node
- * @mnoc_ib_bw: MNOC IB bw value at current node
- * @ddr_ab_bw: DDR AB bw value at current node
- * @ddr_ib_bw: DDR IB bw value at current node
+ * @bw_info: AXI BW info for all drv ports
  * @camnoc_max_needed: If node is needed for CAMNOC BW calculation then true
  * @constituent_paths: Constituent paths presence info from device tree
  *     Ex: For CAM_CPAS_PATH_DATA_IFE_UBWC_STATS, index corresponding to
@@ -61,7 +48,8 @@ struct cam_cpas_vdd_ahb_mapping {
 struct cam_cpas_tree_node {
 	uint32_t cell_idx;
 	int level_idx;
-	int axi_port_idx;
+	int *axi_port_idx_arr;
+	int drv_voting_idx;
 	int camnoc_axi_port_idx;
 	const char *node_name;
 	uint32_t path_data_type;
@@ -69,10 +57,7 @@ struct cam_cpas_tree_node {
 	uint32_t merge_type;
 	uint32_t bus_width_factor;
 	uint64_t camnoc_bw;
-	uint64_t mnoc_ab_bw;
-	uint64_t mnoc_ib_bw;
-	uint64_t ddr_ab_bw;
-	uint64_t ddr_ib_bw;
+	struct cam_cpas_axi_bw_info *bw_info;
 	bool camnoc_max_needed;
 	bool constituent_paths[CAM_CPAS_PATH_DATA_MAX];
 	struct device_node *tree_dev_node;
@@ -163,6 +148,7 @@ struct cam_cpas_smart_qos_info {
  * @num_caches: Number of last level caches
  * @llcc_info: Cache info
  * @enable_smart_qos: Whether to enable Smart QoS mechanism on current chipset
+ * @enable_cam_ddr_drv: Whether to enable Camera DDR DRV on current chipset
  * @smart_qos_info: Pointer to smart qos info
  * @icp_clk_index: Index of optional icp clk
  */
@@ -188,6 +174,7 @@ struct cam_cpas_private_soc {
 	uint32_t num_caches;
 	struct cam_sys_cache_info *llcc_info;
 	bool enable_smart_qos;
+	bool enable_cam_ddr_drv;
 	struct cam_cpas_smart_qos_info *smart_qos_info;
 	int32_t icp_clk_index;
 };

+ 74 - 2
drivers/cam_cpas/include/cam_cpas_api.h

@@ -498,6 +498,27 @@ struct cam_ahb_vote {
 	} vote;
 };
 
+/**
+ * struct cam_cpas_axi_per_path_bw_vote - Internal per path bandwidth vote information
+ *
+ * @usage_data:              client usage data (left/right/rdi)
+ * @transac_type:            Transaction type on the path (read/write)
+ * @path_data_type:          Path for which vote is given (video, display, rdi)
+ * @vote_level:              Vote level for this path
+ * @camnoc_bw:               CAMNOC bw for this path
+ * @mnoc_ab_bw:              MNOC AB bw for this path
+ * @mnoc_ib_bw:              MNOC IB bw for this path
+ */
+struct cam_cpas_axi_per_path_bw_vote {
+	uint32_t                      usage_data;
+	uint32_t                      transac_type;
+	uint32_t                      path_data_type;
+	uint32_t                      vote_level;
+	uint64_t                      camnoc_bw;
+	uint64_t                      mnoc_ab_bw;
+	uint64_t                      mnoc_ib_bw;
+};
+
 /**
  * struct cam_axi_vote : AXI vote
  *
@@ -507,7 +528,7 @@ struct cam_ahb_vote {
  */
 struct cam_axi_vote {
 	uint32_t num_paths;
-	struct cam_axi_per_path_bw_vote axi_path[CAM_CPAS_MAX_PATHS_PER_CLIENT];
+	struct cam_cpas_axi_per_path_bw_vote axi_path[CAM_CPAS_MAX_PATHS_PER_CLIENT];
 };
 
 /**
@@ -729,16 +750,31 @@ const char *cam_cpas_axi_util_path_type_to_string(
 const char *cam_cpas_axi_util_trans_type_to_string(
 	uint32_t path_data_type);
 
+/**
+ * cam_cpas_axi_util_drv_vote_lvl_to_string()
+ *
+ * @brief: API to get string for given DRV vote level
+ *
+ * @vote_lvl  : DRV vote level
+ *
+ * @return string.
+ *
+ */
+const char *cam_cpas_axi_util_drv_vote_lvl_to_string(
+	uint32_t vote_lvl);
+
 /**
  * cam_cpas_log_votes()
  *
  * @brief: API to print the all bw votes of axi client. It also print the
  *     applied camnoc axi clock vote value and ahb vote value
  *
+ * @ddr_only: Print only DDR info
+ *
  * @return 0 on success.
  *
  */
-void cam_cpas_log_votes(void);
+void cam_cpas_log_votes(bool ddr_only);
 
 /**
  * cam_cpas_select_qos_settings()
@@ -817,4 +853,40 @@ int cam_cpas_deactivate_llcc(enum cam_sys_cache_config_types type);
  */
 int cam_cpas_dump_camnoc_buff_fill_info(uint32_t client_handle);
 
+/**
+ * cam_cpas_csid_input_core_info_update()
+ *
+ * @brief: API to communicate csid input core info to cpas
+ *
+ * @csid_idx: csid hw index connected to particular sfe
+ * @sfe_idx:  sfe idx to be connected to particular DRV path
+ * @set_port: Indicates whether to set or reset DRV port info in dynamic client
+ *
+ * @return 0 on success
+ *
+ */
+int cam_cpas_csid_input_core_info_update(int csid_idx, int sfe_idx, bool set_port);
+
+/**
+ * cam_cpas_csid_process_resume()
+ *
+ * @brief: API to process csid resume in cpas
+ * @csid_idx: CSID idx to notify resume for
+ *
+ * @return 0 on success
+ *
+ */
+int cam_cpas_csid_process_resume(uint32_t csid_idx);
+
+/**
+ * cam_cpas_query_drv_enable()
+ *
+ * @brief: API to indicate DRV enabled on hw or not
+ * @is_drv_enabled: Indication to be set by the API
+ *
+ * @return 0 on success
+ *
+ */
+int cam_cpas_query_drv_enable(bool *is_drv_enabled);
+
 #endif /* _CAM_CPAS_API_H_ */

+ 19 - 6
drivers/cam_cre/cam_cre_hw_mgr/cam_cre_hw_mgr.c

@@ -362,7 +362,7 @@ static int cam_cre_update_cpas_vote(struct cam_cre_hw_mgr *hw_mgr,
 	memcpy(&bw_update.axi_vote.axi_path[0],
 		&clk_info->axi_path[0],
 		bw_update.axi_vote.num_paths *
-		sizeof(struct cam_axi_per_path_bw_vote));
+		sizeof(struct cam_cpas_axi_per_path_bw_vote));
 
 	bw_update.axi_vote_valid = true;
 	for (i = 0; i < cre_hw_mgr->num_cre; i++) {
@@ -484,7 +484,7 @@ static bool cam_cre_update_bw_v2(struct cam_cre_hw_mgr *hw_mgr,
 
 	memcpy(&ctx_data->clk_info.axi_path[0],
 		&clk_info->axi_path[0],
-		clk_info->num_paths * sizeof(struct cam_axi_per_path_bw_vote));
+		clk_info->num_paths * sizeof(struct cam_cpas_axi_per_path_bw_vote));
 
 	/*
 	 * Add new vote of this context in hw mgr.
@@ -2045,7 +2045,7 @@ static int cam_cre_packet_generic_blob_handler(void *user_data,
 	struct cam_cre_ctx *ctx_data;
 	uint32_t index;
 	size_t clk_update_size = 0;
-	int rc = 0;
+	int rc = 0, i;
 
 	if (!blob_data || (blob_size == 0)) {
 		CAM_ERR(CAM_CRE, "Invalid blob info %pK %d", blob_data,
@@ -2099,10 +2099,23 @@ static int cam_cre_packet_generic_blob_handler(void *user_data,
 
 		clk_info = &ctx_data->req_list[index]->clk_info;
 		clk_info_v2 = &ctx_data->req_list[index]->clk_info_v2;
+		clk_info_v2.budget_ns = soc_req->budget_ns;
+		clk_info_v2.frame_cycles = soc_req->frame_cycles;
+		clk_info_v2.rt_flag = soc_req->rt_flag;
+		clk_info_v2.num_paths = soc_req->num_paths;
+
+		for (i = 0; i < soc_req->num_paths; i++) {
+			clk_info_v2.axi_path[i].usage_data = soc_req->axi_path[i].usage_data;
+			clk_info_v2.axi_path[i].transac_type = soc_req->axi_path[i].transac_type;
+			clk_info_v2.axi_path[i].path_data_type =
+				soc_req->axi_path[i].path_data_type;
+			clk_info_v2.axi_path[i].vote_level = 0;
+			clk_info_v2.axi_path[i].camnoc_bw = soc_req->axi_path[i].camnoc_bw;
+			clk_info_v2.axi_path[i].mnoc_ab_bw = soc_req->axi_path[i].mnoc_ab_bw;
+			clk_info_v2.axi_path[i].mnoc_ib_bw = soc_req->axi_path[i].mnoc_ib_bw;
+		}
 
-		memcpy(clk_info_v2, soc_req, clk_update_size);
-
-		/* Use v2 structure for clk fields */
+		/* Use v1 structure for clk fields */
 		clk_info->budget_ns = clk_info_v2->budget_ns;
 		clk_info->frame_cycles = clk_info_v2->frame_cycles;
 		clk_info->rt_flag = clk_info_v2->rt_flag;

+ 3 - 3
drivers/cam_cre/cam_cre_hw_mgr/cam_cre_hw_mgr.h

@@ -100,7 +100,7 @@ struct cam_cre_ctx_clk_info {
 	uint32_t reserved;
 	int32_t clk_rate[CAM_MAX_VOTE];
 	uint32_t num_paths;
-	struct cam_axi_per_path_bw_vote axi_path[CAM_CRE_MAX_PER_PATH_VOTES];
+	struct cam_cpas_axi_per_path_bw_vote axi_path[CAM_CRE_MAX_PER_PATH_VOTES];
 };
 
 /**
@@ -135,7 +135,7 @@ struct cam_cre_clk_info {
 	uint32_t threshold;
 	uint32_t over_clked;
 	uint32_t num_paths;
-	struct cam_axi_per_path_bw_vote axi_path[CAM_CRE_MAX_PER_PATH_VOTES];
+	struct cam_cpas_axi_per_path_bw_vote axi_path[CAM_CRE_MAX_PER_PATH_VOTES];
 	uint32_t hw_type;
 	struct cam_req_mgr_timer *watch_dog;
 	uint32_t watch_dog_reset_counter;
@@ -254,7 +254,7 @@ struct cam_cre_clk_bw_req_internal_v2 {
 	uint32_t rt_flag;
 	uint32_t reserved;
 	uint32_t num_paths;
-	struct cam_axi_per_path_bw_vote axi_path[CAM_CRE_MAX_PER_PATH_VOTES];
+	struct cam_cpas_axi_per_path_bw_vote axi_path[CAM_CRE_MAX_PER_PATH_VOTES];
 };
 
 /**

+ 1 - 4
drivers/cam_icp/icp_hw/bps_hw/bps_core.c

@@ -1,6 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
  * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #include <linux/of.h>
@@ -81,10 +82,6 @@ int cam_bps_init_hw(void *device_priv,
 		CAM_CPAS_DEFAULT_AXI_BW;
 	cpas_vote.axi_vote.axi_path[0].mnoc_ib_bw =
 		CAM_CPAS_DEFAULT_AXI_BW;
-	cpas_vote.axi_vote.axi_path[0].ddr_ab_bw =
-		CAM_CPAS_DEFAULT_AXI_BW;
-	cpas_vote.axi_vote.axi_path[0].ddr_ib_bw =
-		CAM_CPAS_DEFAULT_AXI_BW;
 
 	rc = cam_cpas_start(core_info->cpas_handle,
 			&cpas_vote.ahb_vote, &cpas_vote.axi_vote);

+ 82 - 50
drivers/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c

@@ -547,8 +547,6 @@ static int cam_icp_remove_ctx_bw(struct cam_icp_hw_mgr *hw_mgr,
 		do_div(temp, device_share_ratio);
 		clk_update.axi_vote.axi_path[0].mnoc_ab_bw = temp;
 		clk_update.axi_vote.axi_path[0].mnoc_ib_bw = temp;
-		clk_update.axi_vote.axi_path[0].ddr_ab_bw = temp;
-		clk_update.axi_vote.axi_path[0].ddr_ib_bw = temp;
 	} else {
 		int path_index;
 
@@ -584,10 +582,6 @@ static int cam_icp_remove_ctx_bw(struct cam_icp_hw_mgr *hw_mgr,
 				ctx_data->clk_info.axi_path[i].mnoc_ab_bw;
 			clk_info->axi_path[path_index].mnoc_ib_bw -=
 				ctx_data->clk_info.axi_path[i].mnoc_ib_bw;
-			clk_info->axi_path[path_index].ddr_ab_bw -=
-				ctx_data->clk_info.axi_path[i].ddr_ab_bw;
-			clk_info->axi_path[path_index].ddr_ib_bw -=
-				ctx_data->clk_info.axi_path[i].ddr_ib_bw;
 
 			total_ab_bw +=
 				clk_info->axi_path[path_index].mnoc_ab_bw;
@@ -619,7 +613,7 @@ static int cam_icp_remove_ctx_bw(struct cam_icp_hw_mgr *hw_mgr,
 
 		memset(&ctx_data->clk_info.axi_path[0], 0,
 			CAM_ICP_MAX_PER_PATH_VOTES *
-			sizeof(struct cam_axi_per_path_bw_vote));
+			sizeof(struct cam_cpas_axi_per_path_bw_vote));
 		ctx_data->clk_info.curr_fc = 0;
 		ctx_data->clk_info.base_clk = 0;
 
@@ -627,7 +621,7 @@ static int cam_icp_remove_ctx_bw(struct cam_icp_hw_mgr *hw_mgr,
 		memcpy(&clk_update.axi_vote.axi_path[0],
 			&clk_info->axi_path[0],
 			clk_update.axi_vote.num_paths *
-			sizeof(struct cam_axi_per_path_bw_vote));
+			sizeof(struct cam_cpas_axi_per_path_bw_vote));
 
 		if (device_share_ratio > 1) {
 			for (i = 0; i < clk_update.axi_vote.num_paths; i++) {
@@ -640,12 +634,6 @@ static int cam_icp_remove_ctx_bw(struct cam_icp_hw_mgr *hw_mgr,
 				do_div(
 				clk_update.axi_vote.axi_path[i].mnoc_ib_bw,
 					device_share_ratio);
-				do_div(
-				clk_update.axi_vote.axi_path[i].ddr_ab_bw,
-					device_share_ratio);
-				do_div(
-				clk_update.axi_vote.axi_path[i].ddr_ib_bw,
-					device_share_ratio);
 			}
 		}
 	}
@@ -1224,17 +1212,13 @@ static bool cam_icp_update_bw_v2(struct cam_icp_hw_mgr *hw_mgr,
 			ctx_data->clk_info.axi_path[i].mnoc_ab_bw;
 		hw_mgr_clk_info->axi_path[path_index].mnoc_ib_bw -=
 			ctx_data->clk_info.axi_path[i].mnoc_ib_bw;
-		hw_mgr_clk_info->axi_path[path_index].ddr_ab_bw -=
-			ctx_data->clk_info.axi_path[i].ddr_ab_bw;
-		hw_mgr_clk_info->axi_path[path_index].ddr_ib_bw -=
-			ctx_data->clk_info.axi_path[i].ddr_ib_bw;
 	}
 
 	ctx_data->clk_info.num_paths = clk_info->num_paths;
 
 	memcpy(&ctx_data->clk_info.axi_path[0],
 		&clk_info->axi_path[0],
-		clk_info->num_paths * sizeof(struct cam_axi_per_path_bw_vote));
+		clk_info->num_paths * sizeof(struct cam_cpas_axi_per_path_bw_vote));
 
 	/*
 	 * Add new vote of this context in hw mgr.
@@ -1267,11 +1251,6 @@ static bool cam_icp_update_bw_v2(struct cam_icp_hw_mgr *hw_mgr,
 			ctx_data->clk_info.axi_path[i].mnoc_ab_bw;
 		hw_mgr_clk_info->axi_path[path_index].mnoc_ib_bw +=
 			ctx_data->clk_info.axi_path[i].mnoc_ib_bw;
-		hw_mgr_clk_info->axi_path[path_index].ddr_ab_bw +=
-			ctx_data->clk_info.axi_path[i].ddr_ab_bw;
-		hw_mgr_clk_info->axi_path[path_index].ddr_ib_bw +=
-			ctx_data->clk_info.axi_path[i].ddr_ib_bw;
-
 		CAM_DBG(CAM_PERF,
 			"Consolidate Path Vote : Dev[%s] i[%d] path_idx[%d] : [%s %s] [%lld %lld]",
 			cam_icp_dev_type_to_name(
@@ -1617,14 +1596,12 @@ static int cam_icp_update_cpas_vote(struct cam_icp_hw_mgr *hw_mgr,
 		do_div(temp, device_share_ratio);
 		clk_update.axi_vote.axi_path[0].mnoc_ab_bw = temp;
 		clk_update.axi_vote.axi_path[0].mnoc_ib_bw = temp;
-		clk_update.axi_vote.axi_path[0].ddr_ab_bw = temp;
-		clk_update.axi_vote.axi_path[0].ddr_ib_bw = temp;
 	} else {
 		clk_update.axi_vote.num_paths = clk_info->num_paths;
 		memcpy(&clk_update.axi_vote.axi_path[0],
 			&clk_info->axi_path[0],
 			clk_update.axi_vote.num_paths *
-			sizeof(struct cam_axi_per_path_bw_vote));
+			sizeof(struct cam_cpas_axi_per_path_bw_vote));
 
 		if (device_share_ratio > 1) {
 			for (i = 0; i < clk_update.axi_vote.num_paths; i++) {
@@ -1637,12 +1614,6 @@ static int cam_icp_update_cpas_vote(struct cam_icp_hw_mgr *hw_mgr,
 				do_div(
 				clk_update.axi_vote.axi_path[i].mnoc_ib_bw,
 					device_share_ratio);
-				do_div(
-				clk_update.axi_vote.axi_path[i].ddr_ab_bw,
-					device_share_ratio);
-				do_div(
-				clk_update.axi_vote.axi_path[i].ddr_ib_bw,
-					device_share_ratio);
 			}
 		}
 	}
@@ -2285,6 +2256,47 @@ static inline void cam_icp_mgr_validate_inject_err(uint64_t current_req_id, uint
 	memset(&(ctx_data->err_inject_params), 0, sizeof(struct cam_hw_err_param));
 }
 
+static void cam_icp_mgr_dump_active_req_info(void)
+{
+	struct cam_icp_hw_ctx_data *ctx_data = NULL;
+	char log_info[256];
+	size_t buf_size, len;
+	uint32_t total_active_streams = 0, total_active_requests = 0;
+	int i, j;
+
+	buf_size = sizeof(log_info);
+
+	mutex_lock(&icp_hw_mgr.hw_mgr_mutex);
+	for (i = 0; i < CAM_ICP_CTX_MAX; i++) {
+		ctx_data = &icp_hw_mgr.ctx_data[i];
+		mutex_lock(&ctx_data->ctx_mutex);
+		if (ctx_data->state != CAM_ICP_CTX_STATE_ACQUIRED) {
+			mutex_unlock(&ctx_data->ctx_mutex);
+			continue;
+		}
+
+		memset(log_info, 0, buf_size);
+		len = 0;
+		for (j = 0; j < CAM_FRAME_CMD_MAX; j++) {
+			if (!ctx_data->hfi_frame_process.request_id[j])
+				continue;
+
+			len += scnprintf(log_info + len, (buf_size - len), " %llu",
+				ctx_data->hfi_frame_process.request_id[j]);
+			total_active_requests++;
+		}
+		total_active_streams++;
+		CAM_INFO(CAM_ICP, "Requests in ctx: %u type: %s :%s", ctx_data->ctx_id,
+			cam_icp_dev_type_to_name(ctx_data->icp_dev_acquire_info->dev_type),
+			len ? log_info : " None");
+		mutex_unlock(&ctx_data->ctx_mutex);
+	}
+	mutex_unlock(&icp_hw_mgr.hw_mgr_mutex);
+
+	CAM_INFO(CAM_ICP, "Total Active streams: %u, Total active requests: %u",
+		total_active_streams, total_active_requests);
+}
+
 static int cam_icp_mgr_handle_frame_process(uint32_t *msg_ptr, int flag)
 {
 	int i;
@@ -2296,8 +2308,7 @@ static int cam_icp_mgr_handle_frame_process(uint32_t *msg_ptr, int flag)
 	struct cam_hw_done_event_data buf_data = {0};
 	struct cam_icp_hw_buf_done_evt_data icp_done_evt;
 	struct cam_icp_hw_error_evt_data icp_err_evt = {0};
-	uint32_t clk_type;
-	uint32_t event_id;
+	uint32_t clk_type, event_id;
 	struct cam_hangdump_mem_regions *mem_regions = NULL;
 
 	ioconfig_ack = (struct hfi_msg_ipebps_async_ack *)msg_ptr;
@@ -2390,8 +2401,13 @@ static int cam_icp_mgr_handle_frame_process(uint32_t *msg_ptr, int flag)
 	buf_data.request_id = hfi_frame_process->request_id[idx];
 	icp_done_evt.evt_id = event_id;
 	icp_done_evt.buf_done_data = &buf_data;
-	ctx_data->ctxt_event_cb(ctx_data->context_priv, CAM_ICP_EVT_ID_BUF_DONE,
-		&icp_done_evt);
+	if (ctx_data->ctxt_event_cb)
+		ctx_data->ctxt_event_cb(ctx_data->context_priv, CAM_ICP_EVT_ID_BUF_DONE,
+			&icp_done_evt);
+	else
+		CAM_ERR(CAM_ICP,
+			"Event callback invalid for ctx: %u [%s] failed to signal req: %llu",
+			ctx_data->ctx_id, ctx_data->ctx_id_string, buf_data.request_id);
 
 	hfi_frame_process->request_id[idx] = 0;
 	if (ctx_data->hfi_frame_process.in_resource[idx] > 0) {
@@ -2403,14 +2419,21 @@ static int cam_icp_mgr_handle_frame_process(uint32_t *msg_ptr, int flag)
 	clear_bit(idx, ctx_data->hfi_frame_process.bitmap);
 	hfi_frame_process->fw_process_flag[idx] = false;
 
+	mutex_unlock(&ctx_data->ctx_mutex);
+
 	/* report recovery to userspace if FW encounters no memory */
 	if (ioconfig_ack->err_type == CAMERAICP_ENOMEMORY) {
+		cam_icp_mgr_dump_active_req_info();
+
 		icp_err_evt.err_type = CAM_ICP_HW_ERROR_NO_MEM;
 		icp_err_evt.req_id = request_id;
-		ctx_data->ctxt_event_cb(ctx_data->context_priv, CAM_ICP_EVT_ID_ERROR,
-			&icp_err_evt);
+
+		mutex_lock(&ctx_data->ctx_mutex);
+		if (ctx_data->ctxt_event_cb)
+			ctx_data->ctxt_event_cb(ctx_data->context_priv, CAM_ICP_EVT_ID_ERROR,
+				&icp_err_evt);
+		mutex_unlock(&ctx_data->ctx_mutex);
 	}
-	mutex_unlock(&ctx_data->ctx_mutex);
 
 	return 0;
 }
@@ -5277,18 +5300,30 @@ static int cam_icp_packet_generic_blob_handler(void *user_data,
 		}
 
 		clk_update_size = sizeof(struct cam_icp_clk_bw_request_v2) +
-			((soc_req_v2->num_paths - 1) *
-			sizeof(struct cam_axi_per_path_bw_vote));
+			((soc_req_v2->num_paths - 1) * sizeof(struct cam_axi_per_path_bw_vote));
 		if (blob_size < clk_update_size) {
-			CAM_ERR(CAM_ICP, "Invalid blob size: %u",
-				blob_size);
+			CAM_ERR(CAM_ICP, "Invalid blob size: %u", blob_size);
 			return -EINVAL;
 		}
 
 		clk_info = &ctx_data->hfi_frame_process.clk_info[index];
 		clk_info_v2 = &ctx_data->hfi_frame_process.clk_info_v2[index];
-
-		memcpy(clk_info_v2, soc_req_v2, clk_update_size);
+		clk_info_v2->budget_ns = soc_req_v2->budget_ns;
+		clk_info_v2->frame_cycles = soc_req_v2->frame_cycles;
+		clk_info_v2->rt_flag = soc_req_v2->rt_flag;
+		clk_info_v2->num_paths = soc_req_v2->num_paths;
+
+		for (i = 0; i < soc_req_v2->num_paths; i++) {
+			clk_info_v2->axi_path[i].usage_data = soc_req_v2->axi_path[i].usage_data;
+			clk_info_v2->axi_path[i].transac_type =
+				soc_req_v2->axi_path[i].transac_type;
+			clk_info_v2->axi_path[i].path_data_type =
+				soc_req_v2->axi_path[i].path_data_type;
+			clk_info_v2->axi_path[i].vote_level = 0;
+			clk_info_v2->axi_path[i].camnoc_bw = soc_req_v2->axi_path[i].camnoc_bw;
+			clk_info_v2->axi_path[i].mnoc_ab_bw = soc_req_v2->axi_path[i].mnoc_ab_bw;
+			clk_info_v2->axi_path[i].mnoc_ib_bw = soc_req_v2->axi_path[i].mnoc_ib_bw;
+		}
 
 		/* Use v1 structure for clk fields */
 		clk_info->budget_ns = clk_info_v2->budget_ns;
@@ -5296,11 +5331,10 @@ static int cam_icp_packet_generic_blob_handler(void *user_data,
 		clk_info->rt_flag = clk_info_v2->rt_flag;
 
 		CAM_DBG(CAM_PERF,
-			"budget=%llu, frame_cycle=%llu, rt_flag=%d, num_paths=%d, clk_update_size=%d, index=%d, ctx_data=%pK",
+			"budget=%llu, frame_cycle=%llu, rt_flag=%d, num_paths=%d, index=%d, ctx_data=%pK",
 			clk_info_v2->budget_ns, clk_info_v2->frame_cycles,
 			clk_info_v2->rt_flag,
 			clk_info_v2->num_paths,
-			clk_update_size,
 			index,
 			ctx_data);
 
@@ -5944,8 +5978,6 @@ hw_dump:
 		*clk_addr++ = ctx_data->clk_info.axi_path[j].camnoc_bw;
 		*clk_addr++ = ctx_data->clk_info.axi_path[j].mnoc_ab_bw;
 		*clk_addr++ = ctx_data->clk_info.axi_path[j].mnoc_ib_bw;
-		*clk_addr++ = ctx_data->clk_info.axi_path[j].ddr_ab_bw;
-		*clk_addr++ = ctx_data->clk_info.axi_path[j].ddr_ib_bw;
 	}
 	hdr->size = hdr->word_size * (clk_addr - clk_start);
 	dump_args->offset += (hdr->size + sizeof(struct cam_icp_dump_header));

+ 3 - 3
drivers/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.h

@@ -170,7 +170,7 @@ struct cam_icp_clk_bw_req_internal_v2 {
 	uint32_t rt_flag;
 	uint32_t reserved;
 	uint32_t num_paths;
-	struct cam_axi_per_path_bw_vote axi_path[CAM_ICP_MAX_PER_PATH_VOTES];
+	struct cam_cpas_axi_per_path_bw_vote axi_path[CAM_ICP_MAX_PER_PATH_VOTES];
 };
 
 #define HANG_DUMP_REGIONS_MAX 10
@@ -244,7 +244,7 @@ struct cam_ctx_clk_info {
 	uint64_t compressed_bw;
 	int32_t clk_rate[CAM_MAX_VOTE];
 	uint32_t num_paths;
-	struct cam_axi_per_path_bw_vote axi_path[CAM_ICP_MAX_PER_PATH_VOTES];
+	struct cam_cpas_axi_per_path_bw_vote axi_path[CAM_ICP_MAX_PER_PATH_VOTES];
 	bool bw_included;
 };
 
@@ -338,7 +338,7 @@ struct cam_icp_clk_info {
 	uint64_t uncompressed_bw;
 	uint64_t compressed_bw;
 	uint32_t num_paths;
-	struct cam_axi_per_path_bw_vote axi_path[CAM_ICP_MAX_PER_PATH_VOTES];
+	struct cam_cpas_axi_per_path_bw_vote axi_path[CAM_ICP_MAX_PER_PATH_VOTES];
 	uint32_t hw_type;
 	struct cam_req_mgr_timer *watch_dog;
 	uint32_t watch_dog_reset_counter;

+ 0 - 4
drivers/cam_icp/icp_hw/icp_proc/icp_v1_hw/cam_icp_v1_core.c

@@ -230,10 +230,6 @@ int cam_icp_v1_init_hw(void *device_priv,
 		CAM_ICP_BW_BYTES_VOTE;
 	cpas_vote.axi_vote.axi_path[0].mnoc_ib_bw =
 		CAM_ICP_BW_BYTES_VOTE;
-	cpas_vote.axi_vote.axi_path[0].ddr_ab_bw =
-		CAM_ICP_BW_BYTES_VOTE;
-	cpas_vote.axi_vote.axi_path[0].ddr_ib_bw =
-		CAM_ICP_BW_BYTES_VOTE;
 
 	rc = cam_cpas_start(core_info->cpas_handle,
 		&cpas_vote.ahb_vote, &cpas_vote.axi_vote);

+ 0 - 2
drivers/cam_icp/icp_hw/icp_proc/icp_v2_hw/cam_icp_v2_core.c

@@ -160,8 +160,6 @@ static int cam_icp_v2_cpas_start(struct cam_icp_v2_core_info *core_info)
 	vote.axi_vote.axi_path[0].camnoc_bw = CAM_ICP_BW_BYTES_VOTE;
 	vote.axi_vote.axi_path[0].mnoc_ab_bw = CAM_ICP_BW_BYTES_VOTE;
 	vote.axi_vote.axi_path[0].mnoc_ib_bw = CAM_ICP_BW_BYTES_VOTE;
-	vote.axi_vote.axi_path[0].ddr_ab_bw = CAM_ICP_BW_BYTES_VOTE;
-	vote.axi_vote.axi_path[0].ddr_ib_bw = CAM_ICP_BW_BYTES_VOTE;
 
 	return __icp_v2_cpas_start(core_info, &vote);
 }

+ 1 - 4
drivers/cam_icp/icp_hw/ipe_hw/ipe_core.c

@@ -1,6 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
  * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #include <linux/of.h>
@@ -79,10 +80,6 @@ int cam_ipe_init_hw(void *device_priv,
 		CAM_CPAS_DEFAULT_AXI_BW;
 	cpas_vote.axi_vote.axi_path[0].mnoc_ib_bw =
 		CAM_CPAS_DEFAULT_AXI_BW;
-	cpas_vote.axi_vote.axi_path[0].ddr_ab_bw =
-		CAM_CPAS_DEFAULT_AXI_BW;
-	cpas_vote.axi_vote.axi_path[0].ddr_ib_bw =
-		CAM_CPAS_DEFAULT_AXI_BW;
 
 	rc = cam_cpas_start(core_info->cpas_handle,
 		&cpas_vote.ahb_vote, &cpas_vote.axi_vote);

+ 28 - 50
drivers/cam_isp/cam_isp_context.c

@@ -4640,38 +4640,9 @@ static void *cam_isp_ctx_user_dump_stream_info(
 	void *dump_struct, uint8_t *addr_ptr)
 {
 	struct cam_context           *ctx = NULL;
-	struct cam_ife_hw_mgr_ctx    *hw_mgr_ctx = NULL;
-	struct cam_isp_hw_mgr_res    *hw_mgr_res = NULL;
-	struct cam_isp_resource_node *hw_res = NULL;
-	int hw_idx[CAM_ISP_HW_SPLIT_MAX] = { -1, -1 };
-	int sfe_hw_idx[CAM_ISP_HW_SPLIT_MAX] = { -1, -1 };
 	int32_t                      *addr;
-	int                           i;
 
 	ctx = (struct cam_context *)dump_struct;
-	hw_mgr_ctx = (struct cam_ife_hw_mgr_ctx *)ctx->ctxt_to_hw_map;
-
-	if (!list_empty(&hw_mgr_ctx->res_list_ife_src)) {
-		hw_mgr_res = list_first_entry(&hw_mgr_ctx->res_list_ife_src,
-			struct cam_isp_hw_mgr_res, list);
-
-		for (i = 0; i < CAM_ISP_HW_SPLIT_MAX; i++) {
-			hw_res = hw_mgr_res->hw_res[i];
-			if (hw_res && hw_res->hw_intf)
-				hw_idx[i] = hw_res->hw_intf->hw_idx;
-		}
-	}
-
-	if (!list_empty(&hw_mgr_ctx->res_list_sfe_src)) {
-		hw_mgr_res = list_first_entry(&hw_mgr_ctx->res_list_sfe_src,
-			struct cam_isp_hw_mgr_res, list);
-
-		for (i = 0; i < CAM_ISP_HW_SPLIT_MAX; i++) {
-			hw_res = hw_mgr_res->hw_res[i];
-			if (hw_res && hw_res->hw_intf)
-				sfe_hw_idx[i] = hw_res->hw_intf->hw_idx;
-		}
-	}
 
 	addr = (int32_t *)addr_ptr;
 
@@ -4679,20 +4650,6 @@ static void *cam_isp_ctx_user_dump_stream_info(
 	*addr++ = ctx->dev_hdl;
 	*addr++ = ctx->link_hdl;
 
-	*addr++ = hw_mgr_ctx->flags.is_dual;
-	*addr++ = hw_mgr_ctx->ctx_type;
-
-	*addr++ = hw_idx[CAM_ISP_HW_SPLIT_LEFT];
-	*addr++ = hw_idx[CAM_ISP_HW_SPLIT_RIGHT];
-	*addr++ = sfe_hw_idx[CAM_ISP_HW_SPLIT_LEFT];
-	*addr++ = sfe_hw_idx[CAM_ISP_HW_SPLIT_RIGHT];
-
-	*addr++ = hw_mgr_ctx->flags.is_sfe_shdr;
-	*addr++ = hw_mgr_ctx->flags.is_sfe_fs;
-	*addr++ = hw_mgr_ctx->flags.dsp_enabled;
-	*addr++ = hw_mgr_ctx->flags.is_offline;
-
-
 	return addr;
 }
 
@@ -4714,6 +4671,8 @@ static int __cam_isp_ctx_dump_in_top_state(
 	struct cam_ctx_request             *req_temp;
 	struct cam_hw_dump_args             ife_dump_args;
 	struct cam_common_hw_dump_args      dump_args;
+	struct cam_hw_cmd_args              hw_cmd_args;
+	struct cam_isp_hw_cmd_args          isp_hw_cmd_args;
 
 	spin_lock_bh(&ctx->lock);
 	list_for_each_entry_safe(req, req_temp,
@@ -4789,14 +4748,33 @@ hw_dump:
 
 	/* Dump stream info */
 	ctx->ctxt_to_hw_map = ctx_isp->hw_ctx;
-	rc = cam_common_user_dump_helper(&dump_args, cam_isp_ctx_user_dump_stream_info,
-		ctx, sizeof(int32_t), "ISP_STREAM_INFO:");
-	if (rc) {
-		CAM_ERR(CAM_ISP, "Stream info dump fail %lld, rc: %d",
-			req->request_id, rc);
-		goto end;
+	if (ctx->hw_mgr_intf->hw_dump) {
+		/* Dump first part of stream info from isp context */
+		rc = cam_common_user_dump_helper(&dump_args,
+			cam_isp_ctx_user_dump_stream_info, ctx,
+			sizeof(int32_t), "ISP_STREAM_INFO_FROM_CTX:");
+		if (rc) {
+			CAM_ERR(CAM_ISP, "ISP CTX stream info dump fail %lld, rc: %d",
+				req->request_id, rc);
+			goto end;
+		}
+
+		/* Dump second part of stream info from ife hw manager */
+		hw_cmd_args.ctxt_to_hw_map = ctx->ctxt_to_hw_map;
+		hw_cmd_args.cmd_type = CAM_HW_MGR_CMD_INTERNAL;
+		isp_hw_cmd_args.cmd_type = CAM_ISP_HW_MGR_DUMP_STREAM_INFO;
+		isp_hw_cmd_args.cmd_data = &dump_args;
+		hw_cmd_args.u.internal_args = (void *)&isp_hw_cmd_args;
+
+		rc = ctx->hw_mgr_intf->hw_cmd(ctx->hw_mgr_intf->hw_mgr_priv, &hw_cmd_args);
+		if (rc) {
+			CAM_ERR(CAM_ISP, "IFE HW MGR stream info dump fail %lld, rc: %d",
+				req->request_id, rc);
+			goto end;
+		}
+
+		dump_info->offset = dump_args.offset;
 	}
-	dump_info->offset = dump_args.offset;
 
 	/* Dump event record */
 	rc = __cam_isp_ctx_dump_event_record(ctx_isp, &dump_args);

+ 324 - 42
drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c

@@ -24,7 +24,6 @@
 #include "cam_cdm_intf_api.h"
 #include "cam_packet_util.h"
 #include "cam_debug_util.h"
-#include "cam_cpas_api.h"
 #include "cam_mem_mgr.h"
 #include "cam_mem_mgr_api.h"
 #include "cam_common_util.h"
@@ -66,6 +65,9 @@ static struct cam_ife_hw_mgr g_ife_hw_mgr;
 static uint32_t g_num_ife, g_num_ife_lite, g_num_sfe;
 static uint32_t max_ife_out_res, max_sfe_out_res;
 
+static int cam_ife_mgr_find_core_idx(int split_id, struct cam_ife_hw_mgr_ctx *ctx,
+	enum cam_isp_hw_type hw_type, uint32_t *core_idx);
+
 static int cam_isp_blob_ife_clock_update(
 	struct cam_isp_clock_config           *clock_config,
 	struct cam_ife_hw_mgr_ctx             *ctx);
@@ -86,6 +88,88 @@ static int cam_ife_mgr_prog_default_settings(
 static int cam_ife_mgr_cmd_get_sof_timestamp(struct cam_ife_hw_mgr_ctx *ife_ctx,
 	uint64_t *time_stamp, uint64_t *boot_time_stamp, uint64_t *prev_time_stamp);
 
+static int cam_ife_mgr_update_core_info_to_cpas(struct cam_ife_hw_mgr_ctx           *ctx,
+	bool set_port)
+{
+	struct cam_isp_hw_mgr_res *hw_mgr_res;
+	int i, sfe_core_idx, csid_core_idx, rc = 0;
+
+	list_for_each_entry(hw_mgr_res, &ctx->res_list_ife_csid, list) {
+		for (i = 0; i < CAM_ISP_HW_SPLIT_MAX; i++) {
+			if (!hw_mgr_res->hw_res[i])
+				continue;
+
+			rc = cam_ife_mgr_find_core_idx(i, ctx, CAM_ISP_HW_TYPE_CSID,
+				&csid_core_idx);
+			if (rc)
+				return rc;
+
+			rc = cam_ife_mgr_find_core_idx(i, ctx, CAM_ISP_HW_TYPE_SFE, &sfe_core_idx);
+			if (rc)
+				return rc;
+
+			rc = cam_cpas_csid_input_core_info_update(csid_core_idx, sfe_core_idx,
+				set_port);
+			if (rc) {
+				CAM_ERR(CAM_PERF, "Failed in updating core info to cpas rc: %d",
+					rc);
+				return rc;
+			}
+		}
+	}
+
+	return rc;
+}
+
+static int cam_isp_blob_drv_config(struct cam_ife_hw_mgr_ctx         *ctx,
+	uint64_t request_id, struct cam_isp_prepare_hw_update_data *prepare_hw_data)
+{
+	struct cam_ife_hw_mgr                  *ife_hw_mgr;
+	struct cam_hw_intf                     *hw_intf;
+	struct cam_isp_drv_config              *drv_config;
+	struct cam_ife_csid_drv_config_args     drv_config_args = {0};
+	int i, rc = 0;
+
+	ife_hw_mgr = ctx->hw_mgr;
+	drv_config = &prepare_hw_data->isp_drv_config;
+
+	CAM_DBG(CAM_PERF,
+		"DRV config blob opcode:%u req_id:%llu disable_drv_override:%s ctx_idx:%u drv_en:%u path_idle_en:0x%x timeout_val:%u",
+		prepare_hw_data->packet_opcode_type, request_id,
+		CAM_BOOL_TO_YESNO(g_ife_hw_mgr.debug_cfg.disable_isp_drv),
+		ctx->ctx_index, drv_config->drv_en, drv_config->path_idle_en,
+		drv_config->timeout_val);
+
+	if (!g_ife_hw_mgr.cam_ddr_drv_support || g_ife_hw_mgr.debug_cfg.disable_isp_drv)
+		return rc;
+
+	if (prepare_hw_data->packet_opcode_type == CAM_ISP_PACKET_INIT_DEV)
+		drv_config_args.is_init_config = true;
+
+	drv_config_args.drv_en = drv_config->drv_en;
+	drv_config_args.path_idle_en = drv_config->path_idle_en;
+	drv_config_args.timeout_val = drv_config->timeout_val;
+	for (i = 0; i < ctx->num_base; i++) {
+		if (ctx->base[i].hw_type != CAM_ISP_HW_TYPE_CSID)
+			continue;
+
+		hw_intf = ife_hw_mgr->csid_devices[ctx->base[i].idx];
+		if (hw_intf && hw_intf->hw_ops.process_cmd) {
+			rc = hw_intf->hw_ops.process_cmd(hw_intf->hw_priv,
+				CAM_ISP_HW_CMD_DRV_CONFIG, &drv_config_args,
+				sizeof(struct cam_ife_csid_drv_config_args));
+			if (rc) {
+				CAM_ERR(CAM_PERF,
+					"DRV config failed req_id:%d i:%d hw_idx=%d rc:%d",
+					request_id, i, ctx->base[i].idx, rc);
+				break;
+			}
+		}
+	}
+
+	return rc;
+}
+
 static bool cam_isp_is_ctx_primary_rdi(struct cam_ife_hw_mgr_ctx  *ctx)
 {
 	/* check for RDI only and RDI PD context*/
@@ -1808,6 +1892,7 @@ static int cam_ife_mgr_process_base_info(
 				res->hw_intf->hw_idx);
 		}
 	}
+
 	CAM_DBG(CAM_ISP, "ctx base num = %d", ctx->num_base);
 
 	return 0;
@@ -5191,6 +5276,12 @@ static int cam_ife_mgr_acquire_hw(void *hw_mgr_priv, void *acquire_hw_args)
 		goto free_res;
 	}
 
+	if (ife_ctx->ctx_type == CAM_IFE_CTX_TYPE_SFE) {
+		rc = cam_ife_mgr_update_core_info_to_cpas(ife_ctx, true);
+		if (rc)
+			goto free_res;
+	}
+
 	rc = cam_ife_mgr_allocate_cdm_cmd(
 		(ife_ctx->ctx_type == CAM_IFE_CTX_TYPE_SFE ? true : false),
 		&ife_ctx->cdm_cmd);
@@ -5527,6 +5618,12 @@ static int cam_ife_mgr_acquire_dev(void *hw_mgr_priv, void *acquire_hw_args)
 		goto free_res;
 	}
 
+	if (ife_ctx->ctx_type == CAM_IFE_CTX_TYPE_SFE) {
+		rc = cam_ife_mgr_update_core_info_to_cpas(ife_ctx, true);
+		if (rc)
+			goto free_res;
+	}
+
 	rc = cam_ife_mgr_allocate_cdm_cmd(false,
 		&ife_ctx->cdm_cmd);
 	if (rc)
@@ -5647,8 +5744,9 @@ static void cam_ife_mgr_print_blob_info(struct cam_ife_hw_mgr_ctx *ctx, uint64_t
 	struct cam_isp_prepare_hw_update_data *hw_update_data)
 {
 	int i;
-	struct cam_isp_bw_config_v2 *bw_config =
-		(struct cam_isp_bw_config_v2 *) &hw_update_data->bw_clk_config.bw_config_v2;
+	struct cam_isp_bw_config_internal_v2 *bw_config =
+		(struct cam_isp_bw_config_internal_v2 *)
+		&hw_update_data->bw_clk_config.bw_config_v2;
 	struct cam_isp_clock_config *ife_clock_config =
 		(struct cam_isp_clock_config *) &hw_update_data->bw_clk_config.ife_clock_config;
 	struct cam_isp_clock_config *sfe_clock_config =
@@ -5698,13 +5796,13 @@ end:
 }
 
 static int cam_isp_classify_vote_info(
-	struct cam_isp_hw_mgr_res            *hw_mgr_res,
-	struct cam_isp_bw_config_v2          *bw_config,
-	struct cam_axi_vote                  *isp_vote,
-	uint32_t                              hw_type,
-	uint32_t                              split_idx,
-	bool                                 *nrdi_l_bw_updated,
-	bool                                 *nrdi_r_bw_updated)
+	struct cam_isp_hw_mgr_res              *hw_mgr_res,
+	struct cam_isp_bw_config_internal_v2   *bw_config,
+	struct cam_axi_vote                    *isp_vote,
+	uint32_t                                hw_type,
+	uint32_t                                split_idx,
+	bool                                   *nrdi_l_bw_updated,
+	bool                                   *nrdi_r_bw_updated)
 {
 	int                                   rc = 0, i, j = 0;
 
@@ -5723,7 +5821,7 @@ static int cam_isp_classify_vote_info(
 						memcpy(&isp_vote->axi_path[j],
 							&bw_config->axi_path[i],
 							sizeof(struct
-							cam_axi_per_path_bw_vote));
+							cam_cpas_axi_per_path_bw_vote));
 						j++;
 					}
 				}
@@ -5740,7 +5838,7 @@ static int cam_isp_classify_vote_info(
 						memcpy(&isp_vote->axi_path[j],
 							&bw_config->axi_path[i],
 							sizeof(struct
-							cam_axi_per_path_bw_vote));
+							cam_cpas_axi_per_path_bw_vote));
 						j++;
 					}
 				}
@@ -5761,7 +5859,7 @@ static int cam_isp_classify_vote_info(
 					memcpy(&isp_vote->axi_path[j],
 						&bw_config->axi_path[i],
 						sizeof(struct
-						cam_axi_per_path_bw_vote));
+						cam_cpas_axi_per_path_bw_vote));
 					j++;
 				}
 			}
@@ -5787,7 +5885,7 @@ static int cam_isp_classify_vote_info(
 						memcpy(&isp_vote->axi_path[j],
 							&bw_config->axi_path[i],
 							sizeof(struct
-							cam_axi_per_path_bw_vote));
+							cam_cpas_axi_per_path_bw_vote));
 						j++;
 					}
 				}
@@ -5804,7 +5902,7 @@ static int cam_isp_classify_vote_info(
 						memcpy(&isp_vote->axi_path[j],
 							&bw_config->axi_path[i],
 							sizeof(struct
-							cam_axi_per_path_bw_vote));
+							cam_cpas_axi_per_path_bw_vote));
 						j++;
 					}
 				}
@@ -5825,7 +5923,7 @@ static int cam_isp_classify_vote_info(
 					memcpy(&isp_vote->axi_path[j],
 						&bw_config->axi_path[i],
 						sizeof(struct
-						cam_axi_per_path_bw_vote));
+						cam_cpas_axi_per_path_bw_vote));
 					j++;
 				}
 			}
@@ -5843,13 +5941,15 @@ static int cam_isp_classify_vote_info(
 
 	for (i = 0; i < isp_vote->num_paths; i++) {
 		CAM_DBG(CAM_PERF,
-			"CLASSIFY_VOTE [%s] [%s] [%s] [%llu] [%llu] [%llu]",
+			"CLASSIFY_VOTE [%s] [%s] [%s] [%s] [%llu] [%llu] [%llu]",
 			cam_isp_util_usage_data_to_string(
 			isp_vote->axi_path[i].usage_data),
 			cam_cpas_axi_util_path_type_to_string(
 			isp_vote->axi_path[i].path_data_type),
 			cam_cpas_axi_util_trans_type_to_string(
 			isp_vote->axi_path[i].transac_type),
+			cam_cpas_axi_util_drv_vote_lvl_to_string(
+			isp_vote->axi_path[i].vote_level),
 			isp_vote->axi_path[i].camnoc_bw,
 			isp_vote->axi_path[i].mnoc_ab_bw,
 			isp_vote->axi_path[i].mnoc_ib_bw);
@@ -5859,8 +5959,8 @@ static int cam_isp_classify_vote_info(
 }
 
 static int cam_isp_blob_bw_update_v2(
-	struct cam_isp_bw_config_v2           *bw_config,
-	struct cam_ife_hw_mgr_ctx             *ctx)
+	struct cam_isp_bw_config_internal_v2   *bw_config,
+	struct cam_ife_hw_mgr_ctx              *ctx)
 {
 	struct cam_isp_hw_mgr_res             *hw_mgr_res;
 	struct cam_hw_intf                    *hw_intf;
@@ -5873,7 +5973,7 @@ static int cam_isp_blob_bw_update_v2(
 
 	for (i = 0; i < bw_config->num_paths; i++) {
 		CAM_DBG(CAM_PERF,
-			"ISP_BLOB usage_type=%u [%s] [%s] [%s] [%llu] [%llu] [%llu]",
+			"ISP_BLOB usage_type=%u [%s] [%s] [%s] [%s] [%llu] [%llu] [%llu]",
 			bw_config->usage_type,
 			cam_isp_util_usage_data_to_string(
 			bw_config->axi_path[i].usage_data),
@@ -5881,6 +5981,8 @@ static int cam_isp_blob_bw_update_v2(
 			bw_config->axi_path[i].path_data_type),
 			cam_cpas_axi_util_trans_type_to_string(
 			bw_config->axi_path[i].transac_type),
+			cam_cpas_axi_util_drv_vote_lvl_to_string(
+			bw_config->axi_path[i].vote_level),
 			bw_config->axi_path[i].camnoc_bw,
 			bw_config->axi_path[i].mnoc_ab_bw,
 			bw_config->axi_path[i].mnoc_ib_bw);
@@ -6167,6 +6269,14 @@ static int cam_ife_mgr_config_hw(void *hw_mgr_priv,
 		hw_update_data->bw_clk_config.ife_clock_config_valid,
 		hw_update_data->bw_clk_config.sfe_clock_config_valid);
 
+	if (hw_update_data->drv_config_valid) {
+		rc = cam_isp_blob_drv_config(ctx, cfg->request_id, hw_update_data);
+		if (rc) {
+			CAM_ERR(CAM_ISP, "DRV config failed for req: %llu rc:%d", cfg->request_id,
+				rc);
+		}
+	}
+
 	/*
 	 * Update clock and bw values to top layer, the actual application of these
 	 * votes to hw will happen for all relevant hw indices at once, in a separate
@@ -6199,9 +6309,10 @@ static int cam_ife_mgr_config_hw(void *hw_mgr_priv,
 				CAM_ERR(CAM_PERF, "Bandwidth Update Failed rc: %d", rc);
 				return rc;
 			}
-		} else if (ctx->bw_config_version == CAM_ISP_BW_CONFIG_V2) {
-			rc = cam_isp_blob_bw_update_v2((struct cam_isp_bw_config_v2 *)
-				&hw_update_data->bw_clk_config.bw_config_v2, ctx);
+		} else if ((ctx->bw_config_version == CAM_ISP_BW_CONFIG_V2) ||
+			(ctx->bw_config_version == CAM_ISP_BW_CONFIG_V3)) {
+			rc = cam_isp_blob_bw_update_v2(&hw_update_data->bw_clk_config.bw_config_v2,
+				ctx);
 			if (rc) {
 				CAM_ERR(CAM_PERF, "Bandwidth Update Failed rc: %d", rc);
 				return rc;
@@ -6779,29 +6890,27 @@ err:
 	return rc;
 }
 
-/* To find SFE core idx for CSID wrapper config */
-static int cam_ife_mgr_find_sfe_core_idx(
+static int cam_ife_mgr_find_core_idx(
 	int split_id,
 	struct cam_ife_hw_mgr_ctx *ctx,
+	enum cam_isp_hw_type hw_type,
 	uint32_t *core_idx)
 {
 	int i;
 
 	for (i = 0; i < ctx->num_base; i++) {
-		if (ctx->base[i].hw_type != CAM_ISP_HW_TYPE_SFE)
+		if (ctx->base[i].hw_type != hw_type)
 			continue;
 
 		if (ctx->base[i].split_id == split_id) {
-			CAM_DBG(CAM_ISP, "Found SFE core: %u for split_id: %d",
-				ctx->base[i].idx, split_id);
+			CAM_DBG(CAM_ISP, "Found core: %u for split_id: %d hw_type: %d",
+				ctx->base[i].idx, split_id, hw_type);
 			*core_idx = ctx->base[i].idx;
 			goto end;
 		}
 	}
 
-	CAM_ERR(CAM_ISP,
-		"Failed to find SFE core idx for split_id %d",
-		split_id);
+	CAM_ERR(CAM_ISP, "Failed to find core idx for hw_type: %d split_id %d", hw_type, split_id);
 	return -EINVAL;
 
 end:
@@ -6961,8 +7070,8 @@ static int cam_ife_mgr_start_hw(void *hw_mgr_priv, void *start_hw_args)
 				if (ctx->ctx_type == CAM_IFE_CTX_TYPE_SFE) {
 					csid_top_args.input_core_type =
 						CAM_IFE_CSID_INPUT_CORE_SFE_IFE;
-					rc = cam_ife_mgr_find_sfe_core_idx(
-						i, ctx, &csid_top_args.core_idx);
+					rc = cam_ife_mgr_find_core_idx(i, ctx, CAM_ISP_HW_TYPE_SFE,
+						&csid_top_args.core_idx);
 					if (rc)
 						goto tasklet_stop;
 				} else {
@@ -7034,6 +7143,12 @@ static int cam_ife_mgr_start_hw(void *hw_mgr_priv, void *start_hw_args)
 		goto safe_disable;
 	}
 
+	rc = cam_cpas_query_drv_enable(&g_ife_hw_mgr.cam_ddr_drv_support);
+	if (rc) {
+		CAM_ERR(CAM_ISP, "Failed to query DRV enable rc: %d", rc);
+		goto cdm_streamoff;
+	}
+
 start_only:
 
 	atomic_set(&ctx->overflow_pending, 0);
@@ -7269,6 +7384,12 @@ static int cam_ife_mgr_release_hw(void *hw_mgr_priv,
 	/* we should called the stop hw before this already */
 	cam_ife_hw_mgr_release_hw_for_ctx(ctx);
 
+	if (ctx->ctx_type == CAM_IFE_CTX_TYPE_SFE) {
+		rc = cam_ife_mgr_update_core_info_to_cpas(ctx, false);
+		if (rc)
+			CAM_ERR(CAM_ISP, "Failed to update core info to cpas rc:%d", rc);
+	}
+
 	/* reset base info */
 	ctx->num_base = 0;
 	memset(ctx->base, 0, sizeof(ctx->base));
@@ -9494,7 +9615,7 @@ static int cam_isp_validate_scratch_buffer_blob(
 static int cam_isp_packet_generic_blob_handler(void *user_data,
 	uint32_t blob_type, uint32_t blob_size, uint8_t *blob_data)
 {
-	int rc = 0;
+	int rc = 0, i;
 	struct cam_isp_generic_blob_info *blob_info = user_data;
 	struct cam_ife_hw_mgr_ctx *ife_mgr_ctx = NULL;
 	struct cam_hw_prepare_update_args *prepare = NULL;
@@ -9677,9 +9798,9 @@ static int cam_isp_packet_generic_blob_handler(void *user_data,
 	}
 		break;
 	case CAM_ISP_GENERIC_BLOB_TYPE_BW_CONFIG_V2: {
-		size_t bw_config_size = 0;
 		struct cam_isp_bw_config_v2    *bw_config;
 		struct cam_isp_prepare_hw_update_data   *prepare_hw_data;
+		struct cam_cpas_axi_per_path_bw_vote *path_vote;
 
 		if (blob_size < sizeof(struct cam_isp_bw_config_v2)) {
 			CAM_ERR(CAM_ISP, "Invalid blob size %u", blob_size);
@@ -9729,21 +9850,99 @@ static int cam_isp_packet_generic_blob_handler(void *user_data,
 			return -EINVAL;
 		}
 
-		prepare_hw_data = (struct cam_isp_prepare_hw_update_data  *)
-			prepare->priv;
+		prepare_hw_data = (struct cam_isp_prepare_hw_update_data  *) prepare->priv;
 
 		memset(&prepare_hw_data->bw_clk_config.bw_config_v2, 0,
 			sizeof(prepare_hw_data->bw_clk_config.bw_config_v2));
-		bw_config_size = sizeof(struct cam_isp_bw_config_v2) +
-			((bw_config->num_paths - 1) *
-			sizeof(struct cam_axi_per_path_bw_vote));
-		memcpy(&prepare_hw_data->bw_clk_config.bw_config_v2, bw_config,
-			bw_config_size);
+		prepare_hw_data->bw_clk_config.bw_config_v2.usage_type = bw_config->usage_type;
+		prepare_hw_data->bw_clk_config.bw_config_v2.num_paths = bw_config->num_paths;
+
+		for (i = 0; i < bw_config->num_paths; i++) {
+			path_vote = &prepare_hw_data->bw_clk_config.bw_config_v2.axi_path[i];
+			path_vote->usage_data = bw_config->axi_path[i].usage_data;
+			path_vote->transac_type = bw_config->axi_path[i].transac_type;
+			path_vote->path_data_type = bw_config->axi_path[i].path_data_type;
+			path_vote->vote_level = 0;
+			path_vote->camnoc_bw = bw_config->axi_path[i].camnoc_bw;
+			path_vote->mnoc_ab_bw = bw_config->axi_path[i].mnoc_ab_bw;
+			path_vote->mnoc_ib_bw = bw_config->axi_path[i].mnoc_ib_bw;
+		}
 
 		ife_mgr_ctx->bw_config_version = CAM_ISP_BW_CONFIG_V2;
 		prepare_hw_data->bw_clk_config.bw_config_valid = true;
 	}
 		break;
+	case CAM_ISP_GENERIC_BLOB_TYPE_BW_CONFIG_V3: {
+		struct cam_isp_bw_config_v3    *bw_config;
+		struct cam_isp_prepare_hw_update_data   *prepare_hw_data;
+		struct cam_cpas_axi_per_path_bw_vote *path_vote;
+
+		if (blob_size < sizeof(struct cam_isp_bw_config_v3)) {
+			CAM_ERR(CAM_ISP, "Invalid blob size %u", blob_size);
+			return -EINVAL;
+		}
+
+		bw_config = (struct cam_isp_bw_config_v3 *)blob_data;
+
+		if (bw_config->num_paths > CAM_ISP_MAX_PER_PATH_VOTES || !bw_config->num_paths) {
+			CAM_ERR(CAM_ISP, "Invalid num paths %d", bw_config->num_paths);
+			return -EINVAL;
+		}
+
+		/* Check for integer overflow */
+		if (bw_config->num_paths > 1) {
+			if (sizeof(struct cam_axi_per_path_bw_vote_v2) > ((UINT_MAX -
+				sizeof(struct cam_isp_bw_config_v3)) /
+				(bw_config->num_paths - 1))) {
+				CAM_ERR(CAM_ISP,
+					"Size exceeds limit paths:%u size per path:%lu",
+					bw_config->num_paths - 1,
+					sizeof(struct cam_axi_per_path_bw_vote_v2));
+				return -EINVAL;
+			}
+		}
+
+		if ((bw_config->num_paths != 0) && (blob_size <
+			(sizeof(struct cam_isp_bw_config_v3) +
+			(bw_config->num_paths - 1) *
+			sizeof(struct cam_axi_per_path_bw_vote_v2)))) {
+			CAM_ERR(CAM_ISP,
+				"Invalid blob size: %u, num_paths: %u, bw_config size: %lu, per_path_vote size: %lu",
+				blob_size, bw_config->num_paths,
+				sizeof(struct cam_isp_bw_config_v3),
+				sizeof(struct cam_axi_per_path_bw_vote_v2));
+			return -EINVAL;
+		}
+
+		if (!prepare || !prepare->priv ||
+			(bw_config->usage_type >= CAM_ISP_HW_USAGE_TYPE_MAX)) {
+			CAM_ERR(CAM_ISP, "Invalid inputs usage type %d",
+				bw_config->usage_type);
+			return -EINVAL;
+		}
+
+		prepare_hw_data = (struct cam_isp_prepare_hw_update_data  *) prepare->priv;
+		memset(&prepare_hw_data->bw_clk_config.bw_config_v2, 0,
+			sizeof(prepare_hw_data->bw_clk_config.bw_config_v2));
+		prepare_hw_data->bw_clk_config.bw_config_v2.usage_type = bw_config->usage_type;
+		prepare_hw_data->bw_clk_config.bw_config_v2.num_paths = bw_config->num_paths;
+
+		for (i = 0; i < bw_config->num_paths; i++) {
+			path_vote = &prepare_hw_data->bw_clk_config.bw_config_v2.axi_path[i];
+			path_vote->usage_data = bw_config->axi_path[i].usage_data;
+			path_vote->transac_type = bw_config->axi_path[i].transac_type;
+			path_vote->path_data_type = bw_config->axi_path[i].path_data_type;
+			path_vote->vote_level = bw_config->axi_path[i].vote_level;
+			path_vote->camnoc_bw = bw_config->axi_path[i].camnoc_bw;
+			path_vote->mnoc_ab_bw = bw_config->axi_path[i].mnoc_ab_bw;
+			path_vote->mnoc_ib_bw = bw_config->axi_path[i].mnoc_ib_bw;
+		}
+
+		ife_mgr_ctx->bw_config_version = CAM_ISP_BW_CONFIG_V3;
+		prepare_hw_data->bw_clk_config.bw_config_valid = true;
+	}
+		break;
+
 	case CAM_ISP_GENERIC_BLOB_TYPE_UBWC_CONFIG: {
 		struct cam_ubwc_config *ubwc_config;
 
@@ -10130,6 +10329,28 @@ static int cam_isp_packet_generic_blob_handler(void *user_data,
 
 	}
 		break;
+	case CAM_ISP_GENERIC_BLOB_TYPE_DRV_CONFIG: {
+		struct cam_isp_drv_config *drv_config;
+		struct cam_isp_prepare_hw_update_data   *prepare_hw_data;
+
+		if (blob_size < sizeof(struct cam_isp_drv_config)) {
+			CAM_ERR(CAM_ISP, "Invalid DRV blob size %u expected %u",
+				blob_size, sizeof(struct cam_isp_drv_config));
+			return -EINVAL;
+		}
+
+		prepare_hw_data = (struct cam_isp_prepare_hw_update_data  *)
+			prepare->priv;
+		drv_config = (struct cam_isp_drv_config *)blob_data;
+		memcpy(&prepare_hw_data->isp_drv_config, drv_config,
+			sizeof(prepare_hw_data->isp_drv_config));
+
+		CAM_DBG(CAM_ISP, "DRV config blob en:%d timeout_val:%u path_idle_en: 0x%x",
+			drv_config->drv_en, drv_config->timeout_val, drv_config->path_idle_en);
+		prepare_hw_data->drv_config_valid = true;
+	}
+		break;
+
 	default:
 		CAM_WARN(CAM_ISP, "Invalid blob type %d", blob_type);
 		break;
@@ -11977,6 +12198,59 @@ end:
 	return rc;
 }
 
+static void *cam_ife_mgr_user_dump_stream_info(
+	void *dump_struct, uint8_t *addr_ptr)
+{
+	struct cam_ife_hw_mgr_ctx    *hw_mgr_ctx = NULL;
+	struct cam_isp_hw_mgr_res    *hw_mgr_res = NULL;
+	struct cam_isp_resource_node *hw_res = NULL;
+	int32_t                      *addr;
+	int                           i;
+	int hw_idx[CAM_ISP_HW_SPLIT_MAX] = { -1, -1 };
+	int sfe_hw_idx[CAM_ISP_HW_SPLIT_MAX] = { -1, -1 };
+
+	hw_mgr_ctx = (struct cam_ife_hw_mgr_ctx *)dump_struct;
+
+	if (!list_empty(&hw_mgr_ctx->res_list_ife_src)) {
+		hw_mgr_res = list_first_entry(&hw_mgr_ctx->res_list_ife_src,
+			struct cam_isp_hw_mgr_res, list);
+
+		for (i = 0; i < CAM_ISP_HW_SPLIT_MAX; i++) {
+			hw_res = hw_mgr_res->hw_res[i];
+			if (hw_res && hw_res->hw_intf)
+				hw_idx[i] = hw_res->hw_intf->hw_idx;
+		}
+	}
+
+	if (!list_empty(&hw_mgr_ctx->res_list_sfe_src)) {
+		hw_mgr_res = list_first_entry(&hw_mgr_ctx->res_list_sfe_src,
+			struct cam_isp_hw_mgr_res, list);
+
+		for (i = 0; i < CAM_ISP_HW_SPLIT_MAX; i++) {
+			hw_res = hw_mgr_res->hw_res[i];
+			if (hw_res && hw_res->hw_intf)
+				sfe_hw_idx[i] = hw_res->hw_intf->hw_idx;
+		}
+	}
+
+	addr = (int32_t *)addr_ptr;
+
+	*addr++ = hw_mgr_ctx->flags.is_dual;
+	*addr++ = hw_mgr_ctx->ctx_type;
+
+	*addr++ = hw_idx[CAM_ISP_HW_SPLIT_LEFT];
+	*addr++ = hw_idx[CAM_ISP_HW_SPLIT_RIGHT];
+	*addr++ = sfe_hw_idx[CAM_ISP_HW_SPLIT_LEFT];
+	*addr++ = sfe_hw_idx[CAM_ISP_HW_SPLIT_RIGHT];
+
+	*addr++ = hw_mgr_ctx->flags.is_sfe_shdr;
+	*addr++ = hw_mgr_ctx->flags.is_sfe_fs;
+	*addr++ = hw_mgr_ctx->flags.dsp_enabled;
+	*addr++ = hw_mgr_ctx->flags.is_offline;
+
+	return addr;
+}
+
 static int cam_ife_mgr_cmd(void *hw_mgr_priv, void *cmd_args)
 {
 	int rc = 0;
@@ -12056,6 +12330,12 @@ static int cam_ife_mgr_cmd(void *hw_mgr_priv, void *cmd_args)
 				&isp_hw_cmd_args->u.sof_ts.boot,
 				&isp_hw_cmd_args->u.sof_ts.prev);
 			break;
+		case CAM_ISP_HW_MGR_DUMP_STREAM_INFO:
+			rc = cam_common_user_dump_helper(
+				(void *)(isp_hw_cmd_args->cmd_data),
+				cam_ife_mgr_user_dump_stream_info, ctx,
+				sizeof(int32_t), "ISP_STREAM_INFO_FROM_IFE_HW_MGR:");
+			break;
 		default:
 			CAM_ERR(CAM_ISP, "Invalid HW mgr command:0x%x",
 				hw_cmd_args->cmd_type);
@@ -14050,6 +14330,8 @@ static int cam_ife_hw_mgr_debug_register(void)
 		g_ife_hw_mgr.debug_cfg.dentry, NULL, &cam_ife_hw_mgr_perfcnter_debug);
 	debugfs_create_file("ife_csid_testbus", 0644,
 		g_ife_hw_mgr.debug_cfg.dentry, NULL, &cam_ife_csid_testbus_debug);
+	debugfs_create_bool("disable_isp_drv", 0644, g_ife_hw_mgr.debug_cfg.dentry,
+		&g_ife_hw_mgr.debug_cfg.disable_isp_drv);
 end:
 	g_ife_hw_mgr.debug_cfg.enable_csid_recovery = 1;
 	return rc;

+ 5 - 0
drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.h

@@ -14,6 +14,7 @@
 #include "cam_ife_csid_hw_intf.h"
 #include "cam_tasklet_util.h"
 #include "cam_cdm_intf_api.h"
+#include "cam_cpas_api.h"
 
 /*
  * enum cam_ife_ctx_master_type - HW master type
@@ -57,6 +58,7 @@ enum cam_ife_ctx_master_type {
  * @disable_ubwc_comp:         Disable UBWC compression
  * @disable_ife_mmu_prefetch:  Disable MMU prefetch for IFE bus WR
  * @rx_capture_debug_set:      If rx capture debug is set by user
+ * @disable_isp_drv:           Disable ISP DRV config
  *
  */
 struct cam_ife_hw_mgr_debug {
@@ -77,6 +79,7 @@ struct cam_ife_hw_mgr_debug {
 	bool           disable_ubwc_comp;
 	bool           disable_ife_mmu_prefetch;
 	bool           rx_capture_debug_set;
+	bool           disable_isp_drv;
 };
 
 /**
@@ -419,6 +422,7 @@ struct cam_isp_sfe_cache_info {
  * @csid_rup_en            Reg update at CSID side
  * @csid_global_reset_en   CSID global reset enable
  * @csid_camif_irq_support CSID camif IRQ support
+ * @cam_ddr_drv_support    DDR DRV support
  * @isp_caps               Capability of underlying SFE/IFE HW
  * @path_port_map          Mapping of outport to IFE mux
  * @num_caches_found       Number of caches supported
@@ -448,6 +452,7 @@ struct cam_ife_hw_mgr {
 	bool                             csid_rup_en;
 	bool                             csid_global_reset_en;
 	bool                             csid_camif_irq_support;
+	bool                             cam_ddr_drv_support;
 	struct cam_isp_ife_sfe_hw_caps   isp_caps;
 	struct cam_isp_hw_path_port_map  path_port_map;
 

+ 19 - 11
drivers/cam_isp/isp_hw_mgr/cam_tfe_hw_mgr.c

@@ -2462,7 +2462,7 @@ static int cam_tfe_classify_vote_info(
 					memcpy(&isp_vote->axi_path[j],
 						&bw_config->axi_path[i],
 						sizeof(struct
-						cam_axi_per_path_bw_vote));
+						cam_cpas_axi_per_path_bw_vote));
 					j++;
 				}
 			}
@@ -2479,7 +2479,7 @@ static int cam_tfe_classify_vote_info(
 					memcpy(&isp_vote->axi_path[j],
 						&bw_config->axi_path[i],
 						sizeof(struct
-						cam_axi_per_path_bw_vote));
+						cam_cpas_axi_per_path_bw_vote));
 					j++;
 				}
 			}
@@ -2500,7 +2500,7 @@ static int cam_tfe_classify_vote_info(
 				memcpy(&isp_vote->axi_path[j],
 					&bw_config->axi_path[i],
 					sizeof(struct
-					cam_axi_per_path_bw_vote));
+					cam_cpas_axi_per_path_bw_vote));
 				j++;
 			}
 		}
@@ -3866,7 +3866,7 @@ static int cam_isp_tfe_blob_clock_update(
 static int cam_isp_tfe_packet_generic_blob_handler(void *user_data,
 	uint32_t blob_type, uint32_t blob_size, uint8_t *blob_data)
 {
-	int rc = 0;
+	int rc = 0, i;
 	struct cam_isp_generic_blob_info  *blob_info = user_data;
 	struct cam_hw_prepare_update_args *prepare = NULL;
 	struct cam_tfe_hw_mgr_ctx *tfe_mgr_ctx = NULL;
@@ -3984,6 +3984,7 @@ static int cam_isp_tfe_packet_generic_blob_handler(void *user_data,
 		struct cam_isp_tfe_bw_config_v2    *bw_config =
 			(struct cam_isp_tfe_bw_config_v2 *)blob_data;
 		struct cam_isp_prepare_hw_update_data   *prepare_hw_data;
+		struct cam_cpas_axi_per_path_bw_vote *path_vote;
 
 		if (blob_size < sizeof(struct cam_isp_tfe_bw_config_v2)) {
 			CAM_ERR(CAM_ISP, "Invalid blob size %u", blob_size);
@@ -4030,15 +4031,22 @@ static int cam_isp_tfe_packet_generic_blob_handler(void *user_data,
 			return -EINVAL;
 		}
 
-		prepare_hw_data = (struct cam_isp_prepare_hw_update_data  *)
-			prepare->priv;
-
+		prepare_hw_data = (struct cam_isp_prepare_hw_update_data  *) prepare->priv;
 		memset(&prepare_hw_data->bw_clk_config.bw_config_v2,
 			0, sizeof(prepare_hw_data->bw_clk_config.bw_config_v2));
-		bw_config_size = sizeof(struct cam_isp_tfe_bw_config_v2) +
-			((bw_config->num_paths - 1) *
-			sizeof(struct cam_axi_per_path_bw_vote));
-		memcpy(&prepare_hw_data->bw_clk_config.bw_config_v2, bw_config, bw_config_size);
+		prepare_hw_data->bw_clk_config.bw_config_v2.usage_type = bw_config->usage_type;
+		prepare_hw_data->bw_clk_config.bw_config_v2.num_paths = bw_config->num_paths;
+
+		for (i = 0; i < bw_config->num_paths; i++) {
+			path_vote = &prepare_hw_data->bw_clk_config.bw_config_v2.axi_path[i];
+			path_vote.usage_data = bw_config->axi_path[i].usage_data;
+			path_vote.transac_type = bw_config->axi_path[i].transac_type;
+			path_vote.path_data_type = bw_config->axi_path[i].path_data_type;
+			path_vote.vote_level = 0;
+			path_vote.camnoc_bw = bw_config->axi_path[i].camnoc_bw;
+			path_vote.mnoc_ab_bw = bw_config->axi_path[i].mnoc_ab_bw;
+			path_vote.mnoc_ib_bw = bw_config->axi_path[i].mnoc_ib_bw;
+		}
 
 		tfe_mgr_ctx->bw_config_version = CAM_ISP_BW_CONFIG_V2;
 		prepare_hw_data->bw_clk_config.bw_config_valid = true;

+ 10 - 3
drivers/cam_isp/isp_hw_mgr/include/cam_isp_hw_mgr_intf.h

@@ -13,6 +13,7 @@
 #include <media/cam_isp.h>
 #include "cam_hw_mgr_intf.h"
 #include "cam_packet_util.h"
+#include "cam_cpas_api.h"
 
 /* MAX IFE instance */
 #define CAM_IFE_HW_NUM_MAX       8
@@ -22,6 +23,7 @@
 #define CAM_SFE_FE_RDI_NUM_MAX   3
 #define CAM_ISP_BW_CONFIG_V1     1
 #define CAM_ISP_BW_CONFIG_V2     2
+#define CAM_ISP_BW_CONFIG_V3     2
 #define CAM_TFE_HW_NUM_MAX       3
 #define CAM_TFE_RDI_NUM_MAX      3
 #define CAM_IFE_SCRATCH_NUM_MAX  2
@@ -181,9 +183,9 @@ struct cam_isp_clock_config_internal {
  * @axi_path                    per path vote info
  */
 struct cam_isp_bw_config_internal_v2 {
-	uint32_t                          usage_type;
-	uint32_t                          num_paths;
-	struct cam_axi_per_path_bw_vote   axi_path[CAM_ISP_MAX_PER_PATH_VOTES];
+	uint32_t                               usage_type;
+	uint32_t                               num_paths;
+	struct cam_cpas_axi_per_path_bw_vote   axi_path[CAM_ISP_MAX_PER_PATH_VOTES];
 };
 
 /**
@@ -238,6 +240,8 @@ struct cam_isp_bw_clk_config_info {
  * @frame_header_iova:      Frame header iova
  * @frame_header_res_id:    Out port res_id corresponding to frame header
  * @bw_clk_config:          BW and clock config info
+ * @isp_drv_config:         DRV config info
+ * @bw_config_valid:        Flag indicating if DRV config is valid for current request
  * @reg_dump_buf_desc:     cmd buffer descriptors for reg dump
  * @num_reg_dump_buf:      Count of descriptors in reg_dump_buf_desc
  * @packet:                CSL packet from user mode driver
@@ -253,6 +257,8 @@ struct cam_isp_prepare_hw_update_data {
 	uint64_t                              frame_header_iova;
 	uint32_t                              frame_header_res_id;
 	struct cam_isp_bw_clk_config_info     bw_clk_config;
+	struct cam_isp_drv_config             isp_drv_config;
+	bool                                  drv_config_valid;
 	struct cam_cmd_buf_desc               reg_dump_buf_desc[
 						CAM_REG_DUMP_MAX_BUF_ENTRIES];
 	uint32_t                              num_reg_dump_buf;
@@ -365,6 +371,7 @@ enum cam_isp_hw_mgr_command {
 	CAM_ISP_HW_MGR_GET_LAST_CDM_DONE,
 	CAM_ISP_HW_MGR_CMD_PROG_DEFAULT_CFG,
 	CAM_ISP_HW_MGR_GET_SOF_TS,
+	CAM_ISP_HW_MGR_DUMP_STREAM_INFO,
 	CAM_ISP_HW_MGR_CMD_MAX,
 };
 

+ 32 - 3
drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid780.h

@@ -256,11 +256,10 @@ static const struct cam_ife_csid_top_irq_desc cam_ife_csid_780_top_irq_desc[] =
 		.bitmask  = BIT(1),
 		.err_type = CAM_ISP_HW_ERROR_CSID_SENSOR_SWITCH_ERROR,
 		.err_name = "FATAL_SENSOR_SWITCHING_IRQ",
-		.desc = "Fatal Error duirng dynamically switching between 2 sensors",
+		.desc = "Fatal Error during dynamically switching between 2 sensors",
 	},
 	{
 		.bitmask  = BIT(18),
-		.err_type = CAM_ISP_HW_ERROR_RECOVERY_OVERFLOW,
 		.err_name = "ERROR_NO_VOTE_DN",
 		.desc = "vote_up is asserted before IDLE is encountered in a frame",
 	},
@@ -269,6 +268,7 @@ static const struct cam_ife_csid_top_irq_desc cam_ife_csid_780_top_irq_desc[] =
 		.err_type = CAM_ISP_HW_ERROR_RECOVERY_OVERFLOW,
 		.err_name = "ERROR_VOTE_UP_LATE",
 		.desc = "vote_up is asserted at the same time as an SOF",
+		.err_handler = cam_ife_csid_hw_ver2_drv_err_handler,
 	},
 	{
 		.bitmask  = BIT(20),
@@ -1241,6 +1241,11 @@ static struct cam_ife_csid_ver2_common_reg_info
 	.buf_done_irq_set_addr                   = 0x98,
 	.test_bus_ctrl                           = 0x1E8,
 	.test_bus_debug                          = 0x1EC,
+	.drv_cfg0_addr                           = 0x13c,
+	.drv_cfg1_addr                           = 0x140,
+	.drv_cfg2_addr                           = 0x144,
+	.debug_drv_0_addr                        = 0x148,
+	.debug_drv_1_addr                        = 0x14C,
 
 	/*configurations */
 	.major_version                           = 6,
@@ -1273,6 +1278,8 @@ static struct cam_ife_csid_ver2_common_reg_info
 	.shdr_slave_rdi1_shift                   = 21,
 	.shdr_master_rdi0_shift                  = 5,
 	.shdr_master_slave_en_shift              = 0,
+	.drv_en_shift                            = 0,
+	.drv_rup_en_shift                        = 0,
 	.early_eof_supported                     = 1,
 	.vfr_supported                           = 1,
 	.multi_vcdt_supported                    = 1,
@@ -1287,7 +1294,7 @@ static struct cam_ife_csid_ver2_common_reg_info
 	.ipp_irq_mask_all                        = 0x7FFF,
 	.rdi_irq_mask_all                        = 0x7FFF,
 	.ppp_irq_mask_all                        = 0xFFFF,
-	.top_err_irq_mask                        = 0x1C0002,
+	.top_err_irq_mask                        = 0x180002,
 	.rst_loc_path_only_val                   = 0x0,
 	.rst_loc_complete_csid_val               = 0x1,
 	.rst_mode_frame_boundary_val             = 0x0,
@@ -1312,6 +1319,28 @@ static struct cam_ife_csid_ver2_common_reg_info
 	.timestamp_enabled_in_cfg0               = true,
 	.camif_irq_support                       = true,
 	.sfe_ipp_input_rdi_res                   = BIT(CAM_IFE_PIX_PATH_RES_RDI_0),
+	.drv_rup_en_val_map = {
+		2, //RDI0
+		3, //RDI1
+		4, //RDI2
+		5, //RDI3
+		6, //RDI4
+		0, //IPP
+		1, //PPP
+		0, //UDI0
+		0, //UDI1
+		0, //UDI2
+	},
+	.drv_path_idle_en_val_map = {
+		BIT(4), //CAM_ISP_PXL_PATH
+		BIT(5), //CAM_ISP_PPP_PATH
+		0,      // LCR not applicable
+		BIT(6), //CAM_ISP_RDI0_PATH
+		BIT(7), //CAM_ISP_RDI1_PATH
+		BIT(8), //CAM_ISP_RDI2_PATH
+		BIT(9), //CAM_ISP_RDI3_PATH
+		BIT(10), //CAM_ISP_RDI4_PATH
+	},
 };
 
 static struct cam_ife_csid_ver2_top_reg_info

+ 32 - 3
drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid880.h

@@ -264,11 +264,10 @@ static const struct cam_ife_csid_top_irq_desc cam_ife_csid_880_top_irq_desc[] =
 		.bitmask  = BIT(1),
 		.err_type = CAM_ISP_HW_ERROR_CSID_SENSOR_SWITCH_ERROR,
 		.err_name = "FATAL_SENSOR_SWITCHING_IRQ",
-		.desc = "Fatal Error duirng dynamically switching between 2 sensors",
+		.desc = "Fatal Error during dynamically switching between 2 sensors",
 	},
 	{
 		.bitmask  = BIT(18),
-		.err_type = CAM_ISP_HW_ERROR_RECOVERY_OVERFLOW,
 		.err_name = "ERROR_NO_VOTE_DN",
 		.desc = "vote_up is asserted before IDLE is encountered in a frame",
 	},
@@ -277,6 +276,7 @@ static const struct cam_ife_csid_top_irq_desc cam_ife_csid_880_top_irq_desc[] =
 		.err_type = CAM_ISP_HW_ERROR_RECOVERY_OVERFLOW,
 		.err_name = "ERROR_VOTE_UP_LATE",
 		.desc = "vote_up is asserted at the same time as an SOF",
+		.err_handler = cam_ife_csid_hw_ver2_drv_err_handler,
 	},
 	{
 		.bitmask  = BIT(20),
@@ -1280,6 +1280,11 @@ static struct cam_ife_csid_ver2_common_reg_info
 	.test_bus_debug                          = 0x11EC,
 	.path_domain_id_cfg0                     = 0x0,
 	.path_domain_id_cfg1                     = 0x4,
+	.drv_cfg0_addr                           = 0x13c,
+	.drv_cfg1_addr                           = 0x140,
+	.drv_cfg2_addr                           = 0x144,
+	.debug_drv_0_addr                        = 0x148,
+	.debug_drv_1_addr                        = 0x14C,
 
 	/*configurations */
 	.major_version                           = 6,
@@ -1312,6 +1317,8 @@ static struct cam_ife_csid_ver2_common_reg_info
 	.shdr_slave_rdi1_shift                   = 21,
 	.shdr_master_rdi0_shift                  = 5,
 	.shdr_master_slave_en_shift              = 0,
+	.drv_en_shift                            = 0,
+	.drv_rup_en_shift                        = 0,
 	.early_eof_supported                     = 1,
 	.vfr_supported                           = 1,
 	.multi_vcdt_supported                    = 1,
@@ -1326,7 +1333,7 @@ static struct cam_ife_csid_ver2_common_reg_info
 	.ipp_irq_mask_all                        = 0x7FFF,
 	.rdi_irq_mask_all                        = 0x7FFF,
 	.ppp_irq_mask_all                        = 0xFFFF,
-	.top_err_irq_mask                        = 0x1C0002,
+	.top_err_irq_mask                        = 0x180002,
 	.rst_loc_path_only_val                   = 0x0,
 	.rst_loc_complete_csid_val               = 0x1,
 	.rst_mode_frame_boundary_val             = 0x0,
@@ -1351,6 +1358,28 @@ static struct cam_ife_csid_ver2_common_reg_info
 	.timestamp_enabled_in_cfg0               = true,
 	.sfe_ipp_input_rdi_res                   = BIT(CAM_IFE_PIX_PATH_RES_RDI_0),
 	.camif_irq_support                       = true,
+	.drv_rup_en_val_map = {
+		2, //RDI0
+		3, //RDI1
+		4, //RDI2
+		5, //RDI3
+		6, //RDI4
+		0, //IPP
+		1, //PPP
+		0, //UDI0
+		0, //UDI1
+		0, //UDI2
+	},
+	.drv_path_idle_en_val_map = {
+		BIT(4), //CAM_ISP_PXL_PATH
+		BIT(5), //CAM_ISP_PPP_PATH
+		0,      // LCR not applicable
+		BIT(6), //CAM_ISP_RDI0_PATH
+		BIT(7), //CAM_ISP_RDI1_PATH
+		BIT(8), //CAM_ISP_RDI2_PATH
+		BIT(9), //CAM_ISP_RDI3_PATH
+		BIT(10), //CAM_ISP_RDI4_PATH
+	},
 };
 
 static struct cam_ife_csid_ver2_top_reg_info

+ 5 - 0
drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_common.h

@@ -61,6 +61,9 @@
 #define CAM_IFE_CSID_DEBUG_ENABLE_HBI_VBI_INFO            BIT(7)
 #define CAM_IFE_CSID_DEBUG_DISABLE_EARLY_EOF              BIT(8)
 #define CAM_IFE_DEBUG_ENABLE_UNMAPPED_VC_DT_IRQ           BIT(9)
+#define CAM_IFE_CSID_DEBUG_ENABLE_VOTE_UP_IRQ             BIT(10)
+#define CAM_IFE_CSID_DEBUG_ENABLE_VOTE_DN_IRQ             BIT(11)
+#define CAM_IFE_CSID_DEBUG_ENABLE_ERR_NO_VOTE_DN_IRQ      BIT(12)
 
 /* Binning supported masks. Binning support changes for specific paths
  * and also for targets. With the mask, we handle the supported features
@@ -300,6 +303,7 @@ struct cam_ife_csid_hw_counters {
  * @rx_capture_vc:         rx packet vc capture
  * @rx_capture_dt:         rx packet dt capture
  * @rst_capture_strobes:   rx packet capture rst strobes
+ * @top_mask:              Debug mask for top irq
  * @rx_mask:               Debug mask for rx irq
  * @path_mask:             Debug mask for path irq
  * @test_bus_val:          CSID test bus value
@@ -311,6 +315,7 @@ struct cam_ife_csid_debug_info {
 	uint32_t                          rx_capture_vc;
 	uint32_t                          rx_capture_dt;
 	uint32_t                          rst_capture_strobes;
+	uint32_t                          top_mask;
 	uint32_t                          rx_mask;
 	uint32_t                          path_mask;
 	uint32_t                          test_bus_val;

+ 4 - 0
drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_hw_ver1.c

@@ -3756,6 +3756,10 @@ static int cam_ife_csid_ver1_process_cmd(void *hw_priv,
 		/* Not supported for V1 */
 		rc = 0;
 		break;
+	case CAM_ISP_HW_CMD_DRV_CONFIG:
+		/* Not supported for V1 */
+		rc = 0;
+		break;
 	default:
 		CAM_ERR(CAM_ISP, "CSID:%d unsupported cmd:%d",
 			csid_hw->hw_intf->hw_idx, cmd_type);

+ 233 - 11
drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_hw_ver2.c

@@ -179,6 +179,18 @@ static int cam_ife_csid_ver2_set_debug(
 			csid_hw->debug_info.rx_mask |=
 				IFE_CSID_VER2_RX_UNMAPPED_VC_DT;
 			break;
+		case CAM_IFE_CSID_DEBUG_ENABLE_VOTE_UP_IRQ:
+			csid_hw->debug_info.top_mask |=
+				IFE_CSID_VER2_TOP_INFO_VOTE_UP;
+			break;
+		case CAM_IFE_CSID_DEBUG_ENABLE_VOTE_DN_IRQ:
+			csid_hw->debug_info.top_mask |=
+				IFE_CSID_VER2_TOP_INFO_VOTE_DN;
+			break;
+		case CAM_IFE_CSID_DEBUG_ENABLE_ERR_NO_VOTE_DN_IRQ:
+			csid_hw->debug_info.top_mask |=
+				IFE_CSID_VER2_TOP_ERR_NO_VOTE_DN;
+			break;
 		default:
 			break;
 		}
@@ -305,6 +317,36 @@ static int cam_ife_csid_ver2_put_evt_payload(
 	return 0;
 }
 
+static int cam_ife_csid_ver2_top_info_irq_top_half(
+	uint32_t                                   evt_id,
+	struct cam_irq_th_payload                 *th_payload)
+{
+	int rc = 0;
+	struct cam_ife_csid_ver2_hw               *csid_hw = NULL;
+	struct cam_ife_csid_ver2_evt_payload      *evt_payload;
+
+	csid_hw = th_payload->handler_priv;
+
+	rc  = cam_ife_csid_ver2_get_evt_payload(csid_hw, &evt_payload,
+			&csid_hw->path_free_payload_list,
+			&csid_hw->path_payload_lock);
+	if (rc) {
+		CAM_WARN_RATE_LIMIT(CAM_ISP, "CSID:%d get payload failed, TOP info status: 0x%x",
+			csid_hw->hw_intf->hw_idx,
+			th_payload->evt_status_arr[0]);
+		return rc;
+	}
+
+	CAM_DBG(CAM_ISP, "CSID:%d TOP info status: 0x%x", csid_hw->hw_intf->hw_idx,
+		th_payload->evt_status_arr[0]);
+
+	evt_payload->irq_reg_val = th_payload->evt_status_arr[0];
+	ktime_get_boottime_ts64(&evt_payload->timestamp);
+	th_payload->evt_payload_priv = evt_payload;
+
+	return 0;
+}
+
 static int cam_ife_csid_ver2_top_err_irq_top_half(
 	uint32_t                                   evt_id,
 	struct cam_irq_th_payload                 *th_payload)
@@ -312,11 +354,8 @@ static int cam_ife_csid_ver2_top_err_irq_top_half(
 	int rc = 0;
 	struct cam_ife_csid_ver2_hw               *csid_hw = NULL;
 	struct cam_ife_csid_ver2_evt_payload      *evt_payload;
-	struct cam_ife_csid_ver2_reg_info         *csid_reg = NULL;
 
 	csid_hw = th_payload->handler_priv;
-	csid_reg = (struct cam_ife_csid_ver2_reg_info *)
-			csid_hw->core_info->csid_reg;
 
 	rc  = cam_ife_csid_ver2_get_evt_payload(csid_hw, &evt_payload,
 			&csid_hw->path_free_payload_list,
@@ -332,6 +371,7 @@ static int cam_ife_csid_ver2_top_err_irq_top_half(
 	}
 
 	evt_payload->irq_reg_val = th_payload->evt_status_arr[0];
+	ktime_get_boottime_ts64(&evt_payload->timestamp);
 	th_payload->evt_payload_priv = evt_payload;
 
 	return 0;
@@ -484,7 +524,7 @@ static int cam_ife_csid_ver2_path_top_half(
 	}
 
 	evt_payload->irq_reg_val = th_payload->evt_status_arr[0];
-
+	ktime_get_boottime_ts64(&evt_payload->timestamp);
 	th_payload->evt_payload_priv = evt_payload;
 
 	return 0;
@@ -1292,6 +1332,27 @@ void cam_ife_csid_hw_ver2_rdi_line_buffer_conflict_handler(
 
 }
 
+void cam_ife_csid_hw_ver2_drv_err_handler(void *csid)
+{
+	struct cam_ife_csid_ver2_hw       *csid_hw  = csid;
+	struct cam_ife_csid_ver2_reg_info *csid_reg = csid_hw->core_info->csid_reg;
+	struct cam_hw_soc_info            *soc_info = &csid_hw->hw_info->soc_info;
+	void __iomem                      *base =
+		soc_info->reg_map[CAM_IFE_CSID_CLC_MEM_BASE_ID].mem_base;
+	uint32_t cfg0_val = 0, cfg1_val = 0, cfg2_val = 0, debug_drv_0_val = 0, debug_drv_1_val = 0;
+
+	cfg0_val = cam_io_r_mb(base + csid_reg->cmn_reg->drv_cfg0_addr);
+	cfg1_val = cam_io_r_mb(base + csid_reg->cmn_reg->drv_cfg1_addr);
+	cfg2_val = cam_io_r_mb(base + csid_reg->cmn_reg->drv_cfg2_addr);
+	debug_drv_0_val = cam_io_r_mb(base + csid_reg->cmn_reg->debug_drv_0_addr);
+	debug_drv_1_val = cam_io_r_mb(base + csid_reg->cmn_reg->debug_drv_1_addr);
+
+	CAM_INFO(CAM_ISP,
+		"CSID[%d] DRV cfg0:0x%x cfg1:0x%x cfg2:0x%x qtimer_val [start:end] [0x%x : 0x%x]",
+		csid_hw->hw_intf->hw_idx, cfg0_val, cfg1_val, cfg2_val, debug_drv_0_val,
+		debug_drv_1_val);
+}
+
 void cam_ife_csid_hw_ver2_mup_mismatch_handler(
 	void *csid, void *resource)
 {
@@ -1456,7 +1517,8 @@ static int cam_ife_csid_ver2_parse_path_irq_status(
 	struct cam_isp_resource_node *res,
 	uint32_t                     index,
 	uint32_t                     err_mask,
-	uint32_t                     irq_status)
+	uint32_t                     irq_status,
+	struct cam_ife_csid_ver2_evt_payload *evt_payload)
 {
 	const uint8_t                          **irq_reg_tag;
 	const struct cam_ife_csid_ver2_reg_info *csid_reg;
@@ -1497,9 +1559,11 @@ static int cam_ife_csid_ver2_parse_path_irq_status(
 	bit_pos = 0;
 	while (status) {
 		if (status & 0x1)
-			CAM_INFO(CAM_ISP, "CSID[%d] IRQ %s %s ",
+			CAM_INFO(CAM_ISP, "CSID[%d] IRQ %s %s timestamp:[%lld:%lld]",
 				csid_hw->hw_intf->hw_idx, irq_reg_tag[index],
-				csid_reg->path_irq_desc[bit_pos].desc);
+				csid_reg->path_irq_desc[bit_pos].desc,
+				evt_payload->timestamp.tv_sec,
+				evt_payload->timestamp.tv_nsec);
 
 		bit_pos++;
 		status >>= 1;
@@ -1520,6 +1584,57 @@ static int cam_ife_csid_ver2_parse_path_irq_status(
 	return err_type;
 }
 
+static int cam_ife_csid_ver2_top_info_irq_bottom_half(
+	void                                      *handler_priv,
+	void                                      *evt_payload_priv)
+{
+	struct cam_ife_csid_ver2_evt_payload       *payload;
+	struct cam_ife_csid_ver2_hw                *csid_hw = NULL;
+	uint32_t                                    irq_status;
+
+	if (!handler_priv || !evt_payload_priv) {
+		CAM_ERR(CAM_ISP, "Invalid params");
+		return -EINVAL;
+	}
+
+	payload = evt_payload_priv;
+	csid_hw = handler_priv;
+
+	irq_status = payload->irq_reg_val & csid_hw->debug_info.top_mask;
+	if (!irq_status) {
+		CAM_ERR(CAM_ISP, "Unexpected Scenario");
+		return 0;
+	}
+
+	if (irq_status & IFE_CSID_VER2_TOP_INFO_VOTE_UP) {
+		cam_cpas_log_votes(true);
+		CAM_INFO(CAM_ISP, "CSID:%d INFO_VOTE_UP timestamp:[%lld:%lld]",
+			csid_hw->hw_intf->hw_idx, payload->timestamp.tv_sec,
+			payload->timestamp.tv_nsec);
+	}
+
+	if (irq_status & IFE_CSID_VER2_TOP_INFO_VOTE_DN) {
+		cam_cpas_log_votes(true);
+		CAM_INFO(CAM_ISP, "CSID:%d INFO_VOTE_DN timestamp:[%lld:%lld]",
+			csid_hw->hw_intf->hw_idx, payload->timestamp.tv_sec,
+			payload->timestamp.tv_nsec);
+	}
+
+	if (irq_status & IFE_CSID_VER2_TOP_ERR_NO_VOTE_DN) {
+		CAM_INFO(CAM_ISP, "CSID:%d ERR_NO_VOTE_DN timestamp:[%lld:%lld]",
+			csid_hw->hw_intf->hw_idx, payload->timestamp.tv_sec,
+			payload->timestamp.tv_nsec);
+
+		cam_ife_csid_hw_ver2_drv_err_handler(csid_hw);
+	}
+
+	cam_ife_csid_ver2_put_evt_payload(csid_hw, &payload,
+		&csid_hw->path_free_payload_list,
+		&csid_hw->path_payload_lock);
+
+	return 0;
+}
+
 static int cam_ife_csid_ver2_top_err_irq_bottom_half(
 	void                                      *handler_priv,
 	void                                      *evt_payload_priv)
@@ -1555,8 +1670,10 @@ static int cam_ife_csid_ver2_top_err_irq_bottom_half(
 			CAM_ERR(CAM_ISP, "%s %s",
 				csid_reg->top_irq_desc[i].err_name,
 				csid_reg->top_irq_desc[i].desc);
+
 			if (csid_reg->top_irq_desc[i].err_handler)
 				csid_reg->top_irq_desc[i].err_handler(csid_hw);
+
 			event_type |= csid_reg->top_irq_desc[i].err_type;
 		}
 	}
@@ -1697,7 +1814,7 @@ static int cam_ife_csid_ver2_ipp_bottom_half(
 	err_type = cam_ife_csid_ver2_parse_path_irq_status(
 		csid_hw, res,
 		CAM_IFE_CSID_IRQ_REG_IPP,
-		err_mask, irq_status_ipp);
+		err_mask, irq_status_ipp, payload);
 
 	if (err_type)
 		cam_ife_csid_ver2_handle_event_err(csid_hw,
@@ -1778,9 +1895,10 @@ static int cam_ife_csid_ver2_ppp_bottom_half(
 			csid_hw->hw_intf->hw_idx);
 		goto unlock;
 	}
+
 	err_type = cam_ife_csid_ver2_parse_path_irq_status(
 		csid_hw, res, CAM_IFE_CSID_IRQ_REG_PPP,
-		err_mask, irq_status_ppp);
+		err_mask, irq_status_ppp, payload);
 
 	if (err_type)
 		cam_ife_csid_ver2_handle_event_err(csid_hw,
@@ -1873,7 +1991,7 @@ static int cam_ife_csid_ver2_rdi_bottom_half(
 
 	err_type = cam_ife_csid_ver2_parse_path_irq_status(csid_hw, res,
 		path_cfg->irq_reg_idx,
-		err_mask, irq_status_rdi);
+		err_mask, irq_status_rdi, payload);
 
 	spin_unlock(&csid_hw->lock_state);
 	if (err_type) {
@@ -4086,6 +4204,7 @@ static int cam_ife_csid_ver2_enable_hw(
 	const struct cam_ife_csid_ver2_path_reg_info *path_reg = NULL;
 	uint32_t top_err_irq_mask = 0;
 	uint32_t buf_done_irq_mask = 0;
+	uint32_t top_info_irq_mask = 0;
 
 	if (csid_hw->flags.device_enabled) {
 		CAM_DBG(CAM_ISP, "CSID[%d] hw has already been enabled",
@@ -4172,6 +4291,27 @@ static int cam_ife_csid_ver2_enable_hw(
 		goto unsubscribe_top_err;
 	}
 
+	if (csid_hw->debug_info.top_mask) {
+		top_info_irq_mask = csid_hw->debug_info.top_mask;
+		csid_hw->top_info_irq_handle = cam_irq_controller_subscribe_irq(
+						csid_hw->top_irq_controller,
+						CAM_IRQ_PRIORITY_1,
+						&top_info_irq_mask,
+						csid_hw,
+						cam_ife_csid_ver2_top_info_irq_top_half,
+						cam_ife_csid_ver2_top_info_irq_bottom_half,
+						csid_hw->tasklet,
+						&tasklet_bh_api,
+						CAM_IRQ_EVT_GROUP_0);
+
+		if (csid_hw->top_info_irq_handle < 1) {
+			CAM_ERR(CAM_ISP, "CSID[%d] Subscribe Top Info Irq fail",
+				csid_hw->hw_intf->hw_idx);
+			return -EINVAL;
+			goto unsubscribe_top_err;
+		}
+	}
+
 	csid_hw->flags.device_enabled = true;
 	csid_hw->flags.fatal_err_detected = false;
 	CAM_DBG(CAM_ISP, "CSID:%d CSID HW version: 0x%x",
@@ -4415,6 +4555,15 @@ int cam_ife_csid_ver2_start(void *hw_priv, void *args,
 	csid_hw->flags.sof_irq_triggered = false;
 	csid_hw->counters.irq_debug_cnt = 0;
 
+	if (start_args->is_internal_start) {
+		rc = cam_cpas_csid_process_resume(csid_hw->hw_intf->hw_idx);
+		if (rc) {
+			CAM_ERR(CAM_ISP, "CSID:%u Failed to process resume rc: %d",
+				csid_hw->hw_intf->hw_idx, rc);
+			goto end;
+		}
+	}
+
 	rc = cam_ife_csid_ver2_enable_hw(csid_hw);
 
 	for (i = 0; i < start_args->num_res; i++) {
@@ -4572,6 +4721,12 @@ int cam_ife_csid_ver2_stop(void *hw_priv,
 		csid_hw->top_err_irq_handle = 0;
 	}
 
+	if (csid_hw->debug_info.top_mask) {
+		cam_irq_controller_unsubscribe_irq(csid_hw->top_irq_controller,
+			csid_hw->top_info_irq_handle);
+		csid_hw->top_info_irq_handle = 0;
+	}
+
 	cam_ife_csid_ver2_disable_csi2(csid_hw);
 	if (csid_hw->debug_info.test_bus_enabled)
 		cam_ife_csid_ver2_testbus_config(csid_hw, 0x0);
@@ -4690,7 +4845,6 @@ static int cam_ife_csid_ver2_top_cfg(
 		hw_idx, top_args->input_core_type, top_args->core_idx);
 
 	/*config dual sync params */
-
 	if (csid_hw->sync_mode == CAM_ISP_HW_SYNC_NONE)
 		return rc;
 	else if (csid_hw->sync_mode == CAM_ISP_HW_SYNC_MASTER)
@@ -5378,6 +5532,71 @@ static int cam_ife_csid_init_config_update(
 	return 0;
 }
 
+static int cam_ife_csid_ver2_drv_config(
+	struct cam_ife_csid_ver2_hw  *csid_hw, void *cmd_args)
+{
+	struct cam_hw_soc_info *soc_info;
+	struct cam_ife_csid_ver2_reg_info *csid_reg;
+	struct cam_ife_csid_drv_config_args *drv_config;
+	uint32_t cfg0_val = 0, cfg1_val = 0;
+	void __iomem *mem_base;
+	int i;
+
+	if (!csid_hw || !cmd_args) {
+		CAM_ERR(CAM_ISP, "Invalid params");
+		return -EINVAL;
+	}
+
+	drv_config = (struct cam_ife_csid_drv_config_args *) cmd_args;
+	soc_info = &csid_hw->hw_info->soc_info;
+	csid_reg = (struct cam_ife_csid_ver2_reg_info *) csid_hw->core_info->csid_reg;
+	mem_base = soc_info->reg_map[CAM_IFE_CSID_CLC_MEM_BASE_ID].mem_base;
+
+	cfg0_val = drv_config->drv_en << csid_reg->cmn_reg->drv_en_shift;
+
+	/* Configure DRV RUP EN for init request, one time */
+	if (drv_config->is_init_config) {
+		if (csid_hw->path_res[CAM_IFE_PIX_PATH_RES_IPP].res_state >=
+			CAM_ISP_RESOURCE_STATE_RESERVED) {
+			cfg1_val = csid_reg->cmn_reg->drv_rup_en_val_map[CAM_IFE_PIX_PATH_RES_IPP];
+		} else if (csid_hw->path_res[CAM_IFE_PIX_PATH_RES_RDI_0].res_state >=
+			CAM_ISP_RESOURCE_STATE_RESERVED) {
+			cfg1_val =
+				csid_reg->cmn_reg->drv_rup_en_val_map[CAM_IFE_PIX_PATH_RES_RDI_0];
+		} else if (csid_hw->path_res[CAM_IFE_PIX_PATH_RES_PPP].res_state >=
+			CAM_ISP_RESOURCE_STATE_RESERVED) {
+			cfg1_val = csid_reg->cmn_reg->drv_rup_en_val_map[CAM_IFE_PIX_PATH_RES_PPP];
+		} else {
+			CAM_ERR(CAM_ISP, "Failed to configure rup_en for drv");
+			return -EINVAL;
+		}
+
+		cam_io_w_mb(cfg1_val, mem_base + csid_reg->cmn_reg->drv_cfg1_addr);
+		csid_hw->drv_init_done = true;
+	}
+
+	if (!csid_hw->drv_init_done) {
+		CAM_ERR(CAM_ISP, "Failed to update drv config, init config not done");
+		return -EINVAL;
+	}
+
+	for (i = 0; i < CAM_ISP_MAX_PATHS; i++)
+		cfg0_val |= ((drv_config->path_idle_en & BIT(i)) ?
+			csid_reg->cmn_reg->drv_path_idle_en_val_map[i] : 0);
+
+	cam_io_w_mb(cfg0_val, mem_base + csid_reg->cmn_reg->drv_cfg0_addr);
+
+	cam_io_w_mb(drv_config->timeout_val, mem_base + csid_reg->cmn_reg->drv_cfg2_addr);
+
+	CAM_DBG(CAM_ISP,
+		"CSID[%u] sfe_en:%s DRV config init_req:%s cfg0_val:0x%x cfg1_val:0x%x cfg2_val:0x%x",
+		csid_hw->hw_intf->hw_idx, CAM_BOOL_TO_YESNO(csid_hw->flags.sfe_en),
+		CAM_BOOL_TO_YESNO(drv_config->is_init_config), cfg0_val, cfg1_val,
+		drv_config->timeout_val);
+
+	return 0;
+}
+
 static int cam_ife_csid_ver2_process_cmd(void *hw_priv,
 	uint32_t cmd_type, void *cmd_args, uint32_t arg_size)
 {
@@ -5468,6 +5687,9 @@ static int cam_ife_csid_ver2_process_cmd(void *hw_priv,
 	case CAM_ISP_HW_CMD_INIT_CONFIG_UPDATE:
 		rc = cam_ife_csid_init_config_update(cmd_args, arg_size);
 		break;
+	case CAM_ISP_HW_CMD_DRV_CONFIG:
+		rc = cam_ife_csid_ver2_drv_config(csid_hw, cmd_args);
+		break;
 	default:
 		CAM_ERR(CAM_ISP, "CSID:%d unsupported cmd:%d",
 			csid_hw->hw_intf->hw_idx, cmd_type);

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

@@ -12,6 +12,10 @@
 #include "cam_ife_csid_soc.h"
 #include "cam_ife_csid_common.h"
 
+#define IFE_CSID_VER2_TOP_INFO_VOTE_UP                BIT(16)
+#define IFE_CSID_VER2_TOP_INFO_VOTE_DN                BIT(17)
+#define IFE_CSID_VER2_TOP_ERR_NO_VOTE_DN              BIT(18)
+
 #define IFE_CSID_VER2_RX_DL0_EOT_CAPTURED             BIT(0)
 #define IFE_CSID_VER2_RX_DL1_EOT_CAPTURED             BIT(1)
 #define IFE_CSID_VER2_RX_DL2_EOT_CAPTURED             BIT(2)
@@ -114,6 +118,18 @@ struct cam_ife_csid_ver2_top_cfg {
 struct cam_ife_csid_ver2_evt_payload {
 	struct list_head            list;
 	uint32_t                    irq_reg_val;
+	struct timespec64           timestamp;
+};
+
+/*
+ * struct cam_ife_csid_ver2_camif_data: place holder for camif parameters
+ *
+ * @epoch0_cfg:   Epoch 0 configuration value
+ * @epoch1_cfg:   Epoch 1 configuration value
+ */
+struct cam_ife_csid_ver2_camif_data {
+	uint32_t epoch0;
+	uint32_t epoch1;
 };
 
 /*
@@ -379,6 +395,11 @@ struct cam_ife_csid_ver2_common_reg_info {
 	uint32_t test_bus_debug;
 	uint32_t path_domain_id_cfg0;
 	uint32_t path_domain_id_cfg1;
+	uint32_t drv_cfg0_addr;
+	uint32_t drv_cfg1_addr;
+	uint32_t drv_cfg2_addr;
+	uint32_t debug_drv_0_addr;
+	uint32_t debug_drv_1_addr;
 
 	/*Shift Bit Configurations*/
 	uint32_t rst_done_shift_val;
@@ -437,6 +458,8 @@ struct cam_ife_csid_ver2_common_reg_info {
 	uint32_t shdr_slave_rdi1_shift;
 	uint32_t shdr_master_rdi0_shift;
 	uint32_t shdr_master_slave_en_shift;
+	uint32_t drv_en_shift;
+	uint32_t drv_rup_en_shift;
 	/* config Values */
 	uint32_t major_version;
 	uint32_t minor_version;
@@ -466,6 +489,8 @@ struct cam_ife_csid_ver2_common_reg_info {
 	uint32_t sfe_ipp_input_rdi_res;
 	bool     timestamp_enabled_in_cfg0;
 	bool     camif_irq_support;
+	uint32_t drv_rup_en_val_map[CAM_IFE_PIX_PATH_RES_MAX];
+	uint32_t drv_path_idle_en_val_map[CAM_ISP_MAX_PATHS];
 
 	/* Masks */
 	uint32_t pxl_cnt_mask;
@@ -551,9 +576,12 @@ struct cam_ife_csid_ver2_reg_info {
  * @tasklet:                  Tasklet for irq events
  * @reset_irq_handle:         Reset irq handle
  * @buf_done_irq_handle:      Buf done irq handle
+ * @top_err_irq_handle:       Top Err IRQ handle
+ * @top_info_irq_handle:      Top Info IRQ handle
  * @sync_mode:                Master/Slave modes
  * @mup:                      MUP for incoming VC of next frame
  * @discard_frame_per_path:   Count of paths dropping initial frames
+ * @drv_init_done:            Indicates if drv init config is done
  *
  */
 struct cam_ife_csid_ver2_hw {
@@ -593,9 +621,11 @@ struct cam_ife_csid_ver2_hw {
 	int                                    reset_irq_handle;
 	int                                    buf_done_irq_handle;
 	int                                    top_err_irq_handle;
+	int                                    top_info_irq_handle;
 	enum cam_isp_hw_sync_mode              sync_mode;
 	uint32_t                               mup;
 	atomic_t                               discard_frame_per_path;
+	bool                                   drv_init_done;
 };
 
 /*
@@ -638,5 +668,7 @@ void cam_ife_csid_ver2_print_illegal_programming_irq_status(void *csid_hw, void
 void cam_ife_csid_ver2_print_format_measure_info(void *csid_hw, void *res);
 void cam_ife_csid_hw_ver2_mup_mismatch_handler(void *csid_hw, void *res);
 void cam_ife_csid_hw_ver2_rdi_line_buffer_conflict_handler(void *csid_hw);
+void cam_ife_csid_hw_ver2_drv_err_handler(void *csid);
+
 
 #endif

+ 16 - 0
drivers/cam_isp/isp_hw_mgr/isp_hw/include/cam_ife_csid_hw_intf.h

@@ -14,6 +14,7 @@
 #define CAM_IFE_CSID_HW_NUM_MAX                        8
 #define CAM_IFE_CSID_UDI_MAX                           3
 #define RT_BASE_IDX                                    2
+#define CAM_ISP_MAX_PATHS                              8
 
 /**
  * enum cam_ife_csid_input_core_type - Specify the csid input core
@@ -480,4 +481,19 @@ struct cam_ife_csid_debug_cfg_args {
 	bool                              rx_capture_debug_set;
 };
 
+/*
+ * struct cam_ife_csid_drv_config_args:
+ *
+ * @is_init_config: Indicator for init config
+ * @drv_en:         Indicator for camera DRV enable
+ * @timeout_val:    Timeout value from SOF to trigger up vote, given in number of GC cycles
+ * @path_idle_en:   Mask for paths to be considered for consolidated IDLE
+ */
+struct cam_ife_csid_drv_config_args {
+	bool                               is_init_config;
+	bool                               drv_en;
+	uint32_t                           timeout_val;
+	uint32_t                           path_idle_en;
+};
+
 #endif /* _CAM_CSID_HW_INTF_H_ */

+ 1 - 0
drivers/cam_isp/isp_hw_mgr/isp_hw/include/cam_isp_hw.h

@@ -216,6 +216,7 @@ enum cam_isp_hw_cmd_type {
 	CAM_ISP_HW_BUS_MINI_DUMP,
 	CAM_ISP_HW_USER_DUMP,
 	CAM_ISP_HW_CMD_RDI_LCR_CFG,
+	CAM_ISP_HW_CMD_DRV_CONFIG,
 	CAM_ISP_HW_CMD_MAX,
 };
 

+ 43 - 4
drivers/cam_isp/isp_hw_mgr/isp_hw/sfe_hw/sfe_top/cam_sfe_top.c

@@ -114,6 +114,7 @@ static int cam_sfe_top_set_axi_bw_vote(
 	int rc = 0;
 	struct cam_hw_soc_info        *soc_info = NULL;
 	struct cam_sfe_soc_private    *soc_private = NULL;
+	int i, j;
 
 	soc_info = top_priv->common_data.soc_info;
 	soc_private = (struct cam_sfe_soc_private *)soc_info->soc_private;
@@ -131,6 +132,38 @@ static int cam_sfe_top_set_axi_bw_vote(
 		top_priv->total_bw_applied = total_bw_new_vote;
 	} else {
 		CAM_ERR(CAM_PERF, "BW request failed, rc=%d", rc);
+		for (i = 0; i < final_bw_vote->num_paths; i++) {
+			CAM_INFO(CAM_PERF,
+				"sfe[%d] : Applied BW Vote : [%s][%s][%s] [%llu %llu %llu]",
+				top_priv->common_data.hw_intf->hw_idx,
+				cam_cpas_axi_util_path_type_to_string(
+				final_bw_vote->axi_path[i].path_data_type),
+				cam_cpas_axi_util_trans_type_to_string(
+				final_bw_vote->axi_path[i].transac_type),
+				cam_cpas_axi_util_drv_vote_lvl_to_string(
+				final_bw_vote->axi_path[i].vote_level),
+				final_bw_vote->axi_path[i].camnoc_bw,
+				final_bw_vote->axi_path[i].mnoc_ab_bw,
+				final_bw_vote->axi_path[i].mnoc_ib_bw);
+		}
+
+		for (i = 0; i < CAM_DELAY_CLK_BW_REDUCTION_NUM_REQ; i++) {
+			for (j = 0; j < top_priv->last_bw_vote[i].num_paths; j++) {
+				CAM_INFO(CAM_PERF,
+					"sfe[%d] : History[%d] BW Vote : [%s][%s] [%s] [%llu %llu %llu]",
+					top_priv->common_data.hw_intf->hw_idx, i,
+					cam_cpas_axi_util_path_type_to_string(
+					top_priv->last_bw_vote[i].axi_path[j].path_data_type),
+					cam_cpas_axi_util_trans_type_to_string(
+					top_priv->last_bw_vote[i].axi_path[j].transac_type),
+					cam_cpas_axi_util_drv_vote_lvl_to_string(
+					top_priv->last_bw_vote[i].axi_path[j].vote_level),
+					top_priv->last_bw_vote[i].axi_path[j].camnoc_bw,
+					top_priv->last_bw_vote[i].axi_path[j].mnoc_ab_bw,
+					top_priv->last_bw_vote[i].axi_path[j].mnoc_ib_bw);
+			}
+		}
+
 	}
 
 	return rc;
@@ -390,7 +423,7 @@ int cam_sfe_top_calc_axi_bw_vote(struct cam_sfe_top_priv *top_priv,
 				&top_priv->req_axi_vote[i].axi_path[0],
 				top_priv->req_axi_vote[i].num_paths *
 				sizeof(
-				struct cam_axi_per_path_bw_vote));
+				struct cam_cpas_axi_per_path_bw_vote));
 			num_paths += top_priv->req_axi_vote[i].num_paths;
 		}
 	}
@@ -399,13 +432,15 @@ int cam_sfe_top_calc_axi_bw_vote(struct cam_sfe_top_priv *top_priv,
 
 	for (i = 0; i < top_priv->agg_incoming_vote.num_paths; i++) {
 		CAM_DBG(CAM_PERF,
-			"sfe[%d] : New BW Vote : counter[%d] [%s][%s] [%llu %llu %llu]",
+			"sfe[%d] : New BW Vote : counter[%d] [%s][%s][%s] [%llu %llu %llu]",
 			top_priv->common_data.hw_intf->hw_idx,
 			top_priv->last_bw_counter,
 			cam_cpas_axi_util_path_type_to_string(
 			top_priv->agg_incoming_vote.axi_path[i].path_data_type),
 			cam_cpas_axi_util_trans_type_to_string(
 			top_priv->agg_incoming_vote.axi_path[i].transac_type),
+			cam_cpas_axi_util_drv_vote_lvl_to_string(
+			top_priv->agg_incoming_vote.axi_path[i].vote_level),
 			top_priv->agg_incoming_vote.axi_path[i].camnoc_bw,
 			top_priv->agg_incoming_vote.axi_path[i].mnoc_ab_bw,
 			top_priv->agg_incoming_vote.axi_path[i].mnoc_ib_bw);
@@ -463,12 +498,14 @@ int cam_sfe_top_calc_axi_bw_vote(struct cam_sfe_top_priv *top_priv,
 
 	for (i = 0; i < final_bw_vote->num_paths; i++) {
 		CAM_DBG(CAM_PERF,
-			"sfe[%d] : Apply BW Vote : [%s][%s] [%llu %llu %llu]",
+			"sfe[%d] : Apply BW Vote : [%s][%s][%s] [%llu %llu %llu]",
 			top_priv->common_data.hw_intf->hw_idx,
 			cam_cpas_axi_util_path_type_to_string(
 			final_bw_vote->axi_path[i].path_data_type),
 			cam_cpas_axi_util_trans_type_to_string(
 			final_bw_vote->axi_path[i].transac_type),
+			cam_cpas_axi_util_drv_vote_lvl_to_string(
+			final_bw_vote->axi_path[i].vote_level),
 			final_bw_vote->axi_path[i].camnoc_bw,
 			final_bw_vote->axi_path[i].mnoc_ab_bw,
 			final_bw_vote->axi_path[i].mnoc_ib_bw);
@@ -846,7 +883,7 @@ static int cam_sfe_top_handle_overflow(
 	cam_sfe_top_print_debug_reg_info(top_priv);
 
 	if (bus_overflow_status) {
-		cam_cpas_log_votes();
+		cam_cpas_log_votes(false);
 		overflow_info->is_bus_overflow = true;
 	}
 
@@ -912,6 +949,8 @@ static int cam_sfe_top_apply_clk_bw_update(struct cam_sfe_top_priv *top_priv,
 	if ((!to_be_applied_axi_vote) && (top_priv->bw_state != CAM_CLK_BW_STATE_UNCHANGED)) {
 		CAM_ERR(CAM_PERF, "SFE:%d Invalid BW vote for state:%s", hw_intf->hw_idx,
 			cam_sfe_top_clk_bw_state_to_string(top_priv->bw_state));
+		rc = -EINVAL;
+		goto end;
 	}
 
 	CAM_DBG(CAM_PERF, "SFE:%d APPLY CLK/BW req_id:%ld clk_state:%s bw_state:%s ",

+ 1 - 1
drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_hw/cam_tfe_core.c

@@ -1057,7 +1057,7 @@ static int cam_tfe_top_set_axi_bw_vote(
 				&top_priv->req_axi_vote[i].axi_path[0],
 				top_priv->req_axi_vote[i].num_paths *
 				sizeof(
-				struct cam_axi_per_path_bw_vote));
+				struct cam_cpas_axi_per_path_bw_vote));
 			num_paths += top_priv->req_axi_vote[i].num_paths;
 		}
 	}

+ 7 - 7
drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/cam_vfe_soc.c

@@ -1,6 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
  * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #include <linux/slab.h>
@@ -186,6 +187,7 @@ int cam_vfe_init_soc_resources(struct cam_hw_soc_info *soc_info,
 	cpas_register_param.dev = soc_info->dev;
 	cpas_register_param.cam_cpas_client_cb = cam_vfe_cpas_cb;
 	cpas_register_param.userdata = soc_info;
+
 	rc = cam_cpas_register_client(&cpas_register_param);
 	if (rc) {
 		CAM_ERR(CAM_ISP, "CPAS registration failed rc=%d", rc);
@@ -252,18 +254,16 @@ int cam_vfe_enable_soc_resources(struct cam_hw_soc_info *soc_info)
 		rc = -EINVAL;
 		goto end;
 	}
-	soc_private = soc_info->soc_private;
 
+	soc_private = soc_info->soc_private;
 	ahb_vote.type       = CAM_VOTE_ABSOLUTE;
 	ahb_vote.vote.level = CAM_LOWSVS_VOTE;
 	axi_vote.num_paths = 1;
-	if (strnstr(soc_info->compatible, "lite",
-		strlen(soc_info->compatible))) {
-		axi_vote.axi_path[0].path_data_type =
-			CAM_AXI_PATH_DATA_IFE_RDI1;
+	if (soc_private->is_ife_lite) {
+		axi_vote.axi_path[0].path_data_type = CAM_AXI_PATH_DATA_IFE_RDI1;
 	} else {
-		axi_vote.axi_path[0].path_data_type =
-			CAM_AXI_PATH_DATA_IFE_VID;
+		axi_vote.axi_path[0].path_data_type = CAM_AXI_PATH_DATA_IFE_VID;
+		axi_vote.axi_path[0].vote_level = CAM_CPAS_VOTE_LEVEL_LOW;
 	}
 
 	axi_vote.axi_path[0].transac_type = CAM_AXI_TRANSACTION_WRITE;

+ 4 - 0
drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe17x/cam_vfe480.h

@@ -1,6 +1,7 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
 /*
  * Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 
@@ -183,6 +184,7 @@ static struct cam_vfe_camif_lite_ver3_reg_data vfe480_camif_rdi_reg_data[3] = {
 		.error_irq_mask2                 = 0x20000,
 		.subscribe_irq_mask1             = 0x30,
 		.enable_diagnostic_hw            = 0x1,
+		.top_debug_cfg_en                = 1,
 	},
 	{
 		.extern_reg_update_shift         = 0,
@@ -196,6 +198,7 @@ static struct cam_vfe_camif_lite_ver3_reg_data vfe480_camif_rdi_reg_data[3] = {
 		.error_irq_mask2                 = 0x40000,
 		.subscribe_irq_mask1             = 0x300,
 		.enable_diagnostic_hw            = 0x1,
+		.top_debug_cfg_en                = 1,
 	},
 	{
 		.extern_reg_update_shift         = 0,
@@ -209,6 +212,7 @@ static struct cam_vfe_camif_lite_ver3_reg_data vfe480_camif_rdi_reg_data[3] = {
 		.error_irq_mask2                 = 0x80000,
 		.subscribe_irq_mask1             = 0x3000,
 		.enable_diagnostic_hw            = 0x1,
+		.top_debug_cfg_en                = 1,
 	},
 };
 

+ 2 - 1
drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_camif_lite_ver2.c

@@ -1,6 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
  * Copyright (c) 2018-2021, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #include <linux/slab.h>
@@ -571,7 +572,7 @@ static int cam_vfe_camif_lite_handle_irq_bottom_half(
 
 		ret = CAM_VFE_IRQ_STATUS_OVERFLOW;
 
-		cam_cpas_log_votes();
+		cam_cpas_log_votes(false);
 
 	}
 

+ 6 - 5
drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_camif_lite_ver3.c

@@ -1,6 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
  * Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #include <linux/slab.h>
@@ -325,9 +326,9 @@ skip_core_cfg:
 	memset(err_irq_mask, 0, sizeof(err_irq_mask));
 	memset(irq_mask, 0, sizeof(irq_mask));
 
-	/* config debug status registers */
-	cam_io_w_mb(rsrc_data->reg_data->top_debug_cfg_en, rsrc_data->mem_base +
-		rsrc_data->common_reg->top_debug_cfg);
+	val = cam_io_r(rsrc_data->mem_base + rsrc_data->common_reg->top_debug_cfg);
+	val |= rsrc_data->reg_data->top_debug_cfg_en;
+	cam_io_w_mb(val, rsrc_data->mem_base + rsrc_data->common_reg->top_debug_cfg);
 
 	if (!camif_lite_res->is_rdi_primary_res)
 		goto subscribe_err;
@@ -887,7 +888,7 @@ static void cam_vfe_camif_lite_print_status(uint32_t *status,
 
 		if (status_0 & 0x40000000) {
 			CAM_INFO(CAM_ISP, "PD PIPE OVERFLOW");
-			cam_cpas_log_votes();
+			cam_cpas_log_votes(false);
 		}
 	}
 
@@ -1019,7 +1020,7 @@ print_state:
 
 	if ((err_type == CAM_VFE_IRQ_STATUS_OVERFLOW) &&
 		bus_overflow_status)
-		cam_cpas_log_votes();
+		cam_cpas_log_votes(false);
 
 }
 

+ 3 - 2
drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_camif_ver2.c

@@ -1,6 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
  * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #include <linux/slab.h>
@@ -903,7 +904,7 @@ static int cam_vfe_camif_handle_irq_bottom_half(void *handler_priv,
 		CAM_INFO(CAM_ISP, "ife_clk_src:%lld",
 			soc_private->ife_clk_src);
 
-		cam_cpas_log_votes();
+		cam_cpas_log_votes(false);
 
 		if (camif_priv->camif_debug & CAMIF_DEBUG_ENABLE_REG_DUMP)
 			cam_vfe_camif_reg_dump(camif_node->res_priv);
@@ -931,7 +932,7 @@ static int cam_vfe_camif_handle_irq_bottom_half(void *handler_priv,
 		CAM_INFO(CAM_ISP, "ife_clk_src:%lld",
 			soc_private->ife_clk_src);
 
-		cam_cpas_log_votes();
+		cam_cpas_log_votes(false);
 
 		if (camif_priv->camif_debug & CAMIF_DEBUG_ENABLE_REG_DUMP)
 			cam_vfe_camif_reg_dump(camif_node->res_priv);

+ 5 - 3
drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_camif_ver3.c

@@ -1,6 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
  * Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #include <linux/slab.h>
@@ -400,8 +401,9 @@ static int cam_vfe_camif_ver3_resource_start(
 	}
 
 	/* config debug status registers */
-	cam_io_w_mb(rsrc_data->reg_data->top_debug_cfg_en, rsrc_data->mem_base +
-		rsrc_data->common_reg->top_debug_cfg);
+	val = cam_io_r(rsrc_data->mem_base + rsrc_data->common_reg->top_debug_cfg);
+	val |= rsrc_data->reg_data->top_debug_cfg_en;
+	cam_io_w_mb(val, rsrc_data->mem_base + rsrc_data->common_reg->top_debug_cfg);
 
 	val = cam_io_r_mb(rsrc_data->mem_base +
 		rsrc_data->common_reg->core_cfg_0);
@@ -1281,7 +1283,7 @@ print_state:
 	if ((err_type == CAM_VFE_IRQ_STATUS_OVERFLOW) &&
 		((camif_priv->cam_common_cfg.input_mux_sel_pp & 0x3) ||
 		(bus_overflow_status)))
-		cam_cpas_log_votes();
+		cam_cpas_log_votes(false);
 }
 
 static int cam_vfe_camif_ver3_handle_irq_top_half(uint32_t evt_id,

+ 2 - 1
drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_rdi.c

@@ -1,6 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
  * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #include <linux/slab.h>
@@ -572,7 +573,7 @@ static int cam_vfe_rdi_handle_irq_bottom_half(void *handler_priv,
 			rdi_priv->event_cb(rdi_priv->priv,
 			CAM_ISP_HW_EVENT_ERROR,
 			(void *)&evt_info);
-		cam_cpas_log_votes();
+		cam_cpas_log_votes(false);
 	}
 end:
 	cam_vfe_rdi_put_evt_payload(rdi_priv, &payload);

+ 14 - 10
drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top_common.c

@@ -1,6 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
  * Copyright (c) 2019, 2021, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #include "cam_vfe_top_common.h"
@@ -48,12 +49,14 @@ static int cam_vfe_top_set_axi_bw_vote(struct cam_vfe_top_priv_common *top_commo
 			final_bw_vote->num_paths, rc);
 		for (i = 0; i < final_bw_vote->num_paths; i++) {
 			CAM_INFO(CAM_PERF,
-				"ife[%d] : Applied BW Vote : [%s][%s] [%llu %llu %llu]",
+				"ife[%d] : Applied BW Vote : [%s][%s][%s] [%llu %llu %llu]",
 				top_common->hw_idx,
 				cam_cpas_axi_util_path_type_to_string(
 				final_bw_vote->axi_path[i].path_data_type),
 				cam_cpas_axi_util_trans_type_to_string(
 				final_bw_vote->axi_path[i].transac_type),
+				cam_cpas_axi_util_drv_vote_lvl_to_string(
+				final_bw_vote->axi_path[i].vote_level),
 				final_bw_vote->axi_path[i].camnoc_bw,
 				final_bw_vote->axi_path[i].mnoc_ab_bw,
 				final_bw_vote->axi_path[i].mnoc_ib_bw);
@@ -62,12 +65,14 @@ static int cam_vfe_top_set_axi_bw_vote(struct cam_vfe_top_priv_common *top_commo
 		for (i = 0; i < CAM_DELAY_CLK_BW_REDUCTION_NUM_REQ; i++) {
 			for (j = 0; j < top_common->last_bw_vote[i].num_paths; j++) {
 				CAM_INFO(CAM_PERF,
-					"ife[%d] : History[%d] BW Vote : [%s][%s] [%llu %llu %llu]",
+					"ife[%d] : History[%d] BW Vote : [%s][%s] [%s] [%llu %llu %llu]",
 					top_common->hw_idx, i,
 					cam_cpas_axi_util_path_type_to_string(
 					top_common->last_bw_vote[i].axi_path[j].path_data_type),
 					cam_cpas_axi_util_trans_type_to_string(
 					top_common->last_bw_vote[i].axi_path[j].transac_type),
+					cam_cpas_axi_util_drv_vote_lvl_to_string(
+					top_common->last_bw_vote[i].axi_path[j].vote_level),
 					top_common->last_bw_vote[i].axi_path[j].camnoc_bw,
 					top_common->last_bw_vote[i].axi_path[j].mnoc_ab_bw,
 					top_common->last_bw_vote[i].axi_path[j].mnoc_ib_bw);
@@ -284,7 +289,7 @@ static int cam_vfe_top_calc_axi_bw_vote(
 				&top_common->req_axi_vote[i].axi_path[0],
 				top_common->req_axi_vote[i].num_paths *
 				sizeof(
-				struct cam_axi_per_path_bw_vote));
+				struct cam_cpas_axi_per_path_bw_vote));
 			num_paths += top_common->req_axi_vote[i].num_paths;
 		}
 	}
@@ -293,13 +298,15 @@ static int cam_vfe_top_calc_axi_bw_vote(
 
 	for (i = 0; i < top_common->agg_incoming_vote.num_paths; i++) {
 		CAM_DBG(CAM_PERF,
-			"ife[%d] : New BW Vote : counter[%d] [%s][%s] [%llu %llu %llu]",
+			"ife[%d] : New BW Vote : counter[%d] [%s][%s][%s] [%llu %llu %llu]",
 			top_common->hw_idx,
 			top_common->last_bw_counter,
 			cam_cpas_axi_util_path_type_to_string(
 			top_common->agg_incoming_vote.axi_path[i].path_data_type),
 			cam_cpas_axi_util_trans_type_to_string(
 			top_common->agg_incoming_vote.axi_path[i].transac_type),
+			cam_cpas_axi_util_drv_vote_lvl_to_string(
+			top_common->agg_incoming_vote.axi_path[i].vote_level),
 			top_common->agg_incoming_vote.axi_path[i].camnoc_bw,
 			top_common->agg_incoming_vote.axi_path[i].mnoc_ab_bw,
 			top_common->agg_incoming_vote.axi_path[i].mnoc_ib_bw);
@@ -359,12 +366,14 @@ static int cam_vfe_top_calc_axi_bw_vote(
 
 	for (i = 0; i < final_bw_vote->num_paths; i++) {
 		CAM_DBG(CAM_PERF,
-			"ife[%d] : Apply BW Vote : [%s][%s] [%llu %llu %llu]",
+			"ife[%d] : Apply BW Vote : [%s][%s][%s] [%llu %llu %llu]",
 			top_common->hw_idx,
 			cam_cpas_axi_util_path_type_to_string(
 			final_bw_vote->axi_path[i].path_data_type),
 			cam_cpas_axi_util_trans_type_to_string(
 			final_bw_vote->axi_path[i].transac_type),
+			cam_cpas_axi_util_drv_vote_lvl_to_string(
+			final_bw_vote->axi_path[i].vote_level),
 			final_bw_vote->axi_path[i].camnoc_bw,
 			final_bw_vote->axi_path[i].mnoc_ab_bw,
 			final_bw_vote->axi_path[i].mnoc_ib_bw);
@@ -493,11 +502,6 @@ int cam_vfe_top_bw_update(struct cam_vfe_soc_private *soc_private,
 				bw_update->external_bw_bytes;
 			mux_axi_vote->axi_path[0].mnoc_ib_bw =
 				bw_update->external_bw_bytes;
-			/* Make ddr bw same as mnoc bw */
-			mux_axi_vote->axi_path[0].ddr_ab_bw =
-				bw_update->external_bw_bytes;
-			mux_axi_vote->axi_path[0].ddr_ib_bw =
-				bw_update->external_bw_bytes;
 
 			top_common->axi_vote_control[i] =
 				CAM_ISP_BW_CONTROL_INCLUDE;

+ 1 - 1
drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top_ver4.c

@@ -560,7 +560,7 @@ static int cam_vfe_top_ver4_print_overflow_debug_info(
 	cam_vfe_top_ver4_dump_timestamps(top_priv, res_id);
 	cam_cpas_dump_camnoc_buff_fill_info(soc_private->cpas_handle);
 	if (bus_overflow_status)
-		cam_cpas_log_votes();
+		cam_cpas_log_votes(false);
 
 	if (violation_status)
 		CAM_INFO(CAM_ISP, "VFE[%d] Bus violation status: 0x%x",

+ 21 - 7
drivers/cam_ope/ope_hw_mgr/cam_ope_hw_mgr.c

@@ -778,7 +778,7 @@ static int32_t cam_ope_process_request_timer(void *priv, void *data)
 
 	memset(&ctx_data->clk_info.axi_path[0], 0,
 		CAM_OPE_MAX_PER_PATH_VOTES *
-		sizeof(struct cam_axi_per_path_bw_vote));
+		sizeof(struct cam_cpas_axi_per_path_bw_vote));
 	ctx_data->clk_info.curr_fc = 0;
 	ctx_data->clk_info.base_clk = 0;
 
@@ -786,7 +786,7 @@ static int32_t cam_ope_process_request_timer(void *priv, void *data)
 	memcpy(&clk_update.axi_vote.axi_path[0],
 		&clk_info->axi_path[0],
 		clk_update.axi_vote.num_paths *
-		sizeof(struct cam_axi_per_path_bw_vote));
+		sizeof(struct cam_cpas_axi_per_path_bw_vote));
 
 	if (device_share_ratio > 1) {
 		for (i = 0; i < clk_update.axi_vote.num_paths; i++) {
@@ -1463,7 +1463,7 @@ static bool cam_ope_update_bw_v2(struct cam_ope_hw_mgr *hw_mgr,
 
 	memcpy(&ctx_data->clk_info.axi_path[0],
 		&clk_info->axi_path[0],
-		clk_info->num_paths * sizeof(struct cam_axi_per_path_bw_vote));
+		clk_info->num_paths * sizeof(struct cam_cpas_axi_per_path_bw_vote));
 
 	/*
 	 * Add new vote of this context in hw mgr.
@@ -1568,7 +1568,7 @@ static int cam_ope_update_cpas_vote(struct cam_ope_hw_mgr *hw_mgr,
 	memcpy(&bw_update.axi_vote.axi_path[0],
 		&clk_info->axi_path[0],
 		bw_update.axi_vote.num_paths *
-		sizeof(struct cam_axi_per_path_bw_vote));
+		sizeof(struct cam_cpas_axi_per_path_bw_vote));
 
 	bw_update.axi_vote_valid = true;
 	for (i = 0; i < ope_hw_mgr->num_ope; i++) {
@@ -3068,7 +3068,7 @@ static int cam_ope_packet_generic_blob_handler(void *user_data,
 	struct cam_ope_ctx *ctx_data;
 	uint32_t index;
 	size_t clk_update_size;
-	int rc = 0;
+	int rc = 0, i;
 
 	if (!blob_data || (blob_size == 0)) {
 		CAM_ERR(CAM_OPE, "Invalid blob info %pK %d", blob_data,
@@ -3122,8 +3122,22 @@ static int cam_ope_packet_generic_blob_handler(void *user_data,
 
 		clk_info = &ctx_data->req_list[index]->clk_info;
 		clk_info_v2 = &ctx_data->req_list[index]->clk_info_v2;
-
-		memcpy(clk_info_v2, soc_req_v2, clk_update_size);
+		clk_info_v2->budget_ns = soc_req_v2->budget_ns;
+		clk_info_v2->frame_cycles = soc_req_v2->frame_cycles;
+		clk_info_v2->rt_flag = soc_req_v2->rt_flag;
+		clk_info_v2->num_paths = soc_req_v2->num_paths;
+
+		for (i = 0; i < soc_req_v2->num_paths; i++) {
+			clk_info_v2->axi_path[i].usage_data = soc_req_v2->axi_path[i].usage_data;
+			clk_info_v2->axi_path[i].transac_type =
+				soc_req_v2->axi_path[i].transac_type;
+			clk_info_v2->axi_path[i].path_data_type =
+				soc_req_v2->axi_path[i].path_data_type;
+			clk_info_v2->axi_path[i].vote_level = 0;
+			clk_info_v2->axi_path[i].camnoc_bw = soc_req_v2->axi_path[i].camnoc_bw;
+			clk_info_v2->axi_path[i].mnoc_ab_bw = soc_req_v2->axi_path[i].mnoc_ab_bw;
+			clk_info_v2->axi_path[i].mnoc_ib_bw = soc_req_v2->axi_path[i].mnoc_ib_bw;
+		}
 
 		/* Use v1 structure for clk fields */
 		clk_info->budget_ns = clk_info_v2->budget_ns;

+ 3 - 3
drivers/cam_ope/ope_hw_mgr/cam_ope_hw_mgr.h

@@ -79,7 +79,7 @@ struct cam_ope_clk_bw_req_internal_v2 {
 	uint32_t rt_flag;
 	uint32_t reserved;
 	uint32_t num_paths;
-	struct cam_axi_per_path_bw_vote axi_path[CAM_OPE_MAX_PER_PATH_VOTES];
+	struct cam_cpas_axi_per_path_bw_vote axi_path[CAM_OPE_MAX_PER_PATH_VOTES];
 };
 
 /**
@@ -119,7 +119,7 @@ struct cam_ctx_clk_info {
 	uint64_t compressed_bw;
 	int32_t clk_rate[CAM_MAX_VOTE];
 	uint32_t num_paths;
-	struct cam_axi_per_path_bw_vote axi_path[CAM_OPE_MAX_PER_PATH_VOTES];
+	struct cam_cpas_axi_per_path_bw_vote axi_path[CAM_OPE_MAX_PER_PATH_VOTES];
 };
 
 /**
@@ -156,7 +156,7 @@ struct cam_ope_clk_info {
 	uint64_t uncompressed_bw;
 	uint64_t compressed_bw;
 	uint32_t num_paths;
-	struct cam_axi_per_path_bw_vote axi_path[CAM_OPE_MAX_PER_PATH_VOTES];
+	struct cam_cpas_axi_per_path_bw_vote axi_path[CAM_OPE_MAX_PER_PATH_VOTES];
 	uint32_t hw_type;
 	struct cam_req_mgr_timer *watch_dog;
 	uint32_t watch_dog_reset_counter;

+ 8 - 5
drivers/cam_sensor_module/cam_actuator/cam_actuator_core.c

@@ -54,10 +54,10 @@ free_power_settings:
 static int32_t cam_actuator_power_up(struct cam_actuator_ctrl_t *a_ctrl)
 {
 	int rc = 0;
-	struct cam_hw_soc_info  *soc_info =
-		&a_ctrl->soc_info;
-	struct cam_actuator_soc_private  *soc_private;
-	struct cam_sensor_power_ctrl_t *power_info;
+	struct cam_hw_soc_info                 *soc_info = &a_ctrl->soc_info;
+	struct cam_actuator_soc_private        *soc_private;
+	struct cam_sensor_power_ctrl_t         *power_info;
+	struct completion                      *i3c_probe_completion = NULL;
 
 	soc_private =
 		(struct cam_actuator_soc_private *)a_ctrl->soc_info.soc_private;
@@ -99,7 +99,10 @@ static int32_t cam_actuator_power_up(struct cam_actuator_ctrl_t *a_ctrl)
 
 	power_info->dev = soc_info->dev;
 
-	rc = cam_sensor_core_power_up(power_info, soc_info);
+	if (a_ctrl->io_master_info.master_type == I3C_MASTER)
+		i3c_probe_completion = cam_actuator_get_i3c_completion(a_ctrl->soc_info.index);
+
+	rc = cam_sensor_core_power_up(power_info, soc_info, i3c_probe_completion);
 	if (rc) {
 		CAM_ERR(CAM_ACTUATOR,
 			"failed in actuator power up rc %d", rc);

+ 3 - 0
drivers/cam_sensor_module/cam_actuator/cam_actuator_core.h

@@ -1,6 +1,7 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
 /*
  * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #ifndef _CAM_ACTUATOR_CORE_H_
@@ -63,4 +64,6 @@ int32_t cam_actuator_driver_cmd(struct cam_actuator_ctrl_t *a_ctrl, void *arg);
  */
 void cam_actuator_shutdown(struct cam_actuator_ctrl_t *a_ctrl);
 
+struct completion *cam_actuator_get_i3c_completion(uint32_t index);
+
 #endif /* _CAM_ACTUATOR_CORE_H_ */

+ 151 - 1
drivers/cam_sensor_module/cam_actuator/cam_actuator_dev.c

@@ -10,6 +10,17 @@
 #include "cam_actuator_core.h"
 #include "cam_trace.h"
 #include "camera_main.h"
+#include "cam_compat.h"
+
+static struct cam_i3c_actuator_data {
+	struct cam_actuator_ctrl_t                  *a_ctrl;
+	struct completion                            probe_complete;
+} g_i3c_actuator_data[MAX_CAMERAS];
+
+struct completion *cam_actuator_get_i3c_completion(uint32_t index)
+{
+	return &g_i3c_actuator_data[index].probe_complete;
+}
 
 static int cam_actuator_subdev_close_internal(struct v4l2_subdev *sd,
 	struct v4l2_subdev_fh *fh)
@@ -411,6 +422,9 @@ static int cam_actuator_platform_component_bind(struct device *dev,
 	CAM_DBG(CAM_ACTUATOR, "Component bound successfully %d",
 		a_ctrl->soc_info.index);
 
+	g_i3c_actuator_data[a_ctrl->soc_info.index].a_ctrl = a_ctrl;
+	init_completion(&g_i3c_actuator_data[a_ctrl->soc_info.index].probe_complete);
+
 	return rc;
 
 free_mem:
@@ -525,6 +539,120 @@ struct i2c_driver cam_actuator_i2c_driver = {
 	},
 };
 
+static struct i3c_device_id actuator_i3c_id[MAX_I3C_DEVICE_ID_ENTRIES + 1];
+
+static int cam_actuator_i3c_driver_probe(struct i3c_device *client)
+{
+	int32_t rc = 0;
+	struct cam_actuator_ctrl_t       *a_ctrl = NULL;
+	uint32_t                          index;
+	struct device                    *dev;
+
+	if (!client) {
+		CAM_INFO(CAM_ACTUATOR, "Null Client pointer");
+		return -EINVAL;
+	}
+
+	dev = &client->dev;
+
+	CAM_DBG(CAM_ACTUATOR, "Probe for I3C Slave %s", dev_name(dev));
+
+	rc = of_property_read_u32(dev->of_node, "cell-index", &index);
+	if (rc) {
+		CAM_ERR(CAM_ACTUATOR, "device %s failed to read cell-index", dev_name(dev));
+		return rc;
+	}
+
+	if (index >= MAX_CAMERAS) {
+		CAM_ERR(CAM_ACTUATOR, "Invalid Cell-Index: %u for %s", index, dev_name(dev));
+		return -EINVAL;
+	}
+
+	a_ctrl = g_i3c_actuator_data[index].a_ctrl;
+	if (!a_ctrl) {
+		CAM_ERR(CAM_ACTUATOR,
+			"a_ctrl is null. I3C Probe before platfom driver probe for %s",
+			dev_name(dev));
+		return -EINVAL;
+	}
+
+	a_ctrl->io_master_info.i3c_client = client;
+
+	complete_all(&g_i3c_actuator_data[index].probe_complete);
+
+	CAM_DBG(CAM_ACTUATOR, "I3C Probe Finished for %s", dev_name(dev));
+	return rc;
+}
+
+static struct i3c_driver cam_actuator_i3c_driver = {
+	.id_table = actuator_i3c_id,
+	.probe = cam_actuator_i3c_driver_probe,
+	.remove = cam_i3c_driver_remove,
+	.driver = {
+		.owner = THIS_MODULE,
+		.name = ACTUATOR_DRIVER_I3C,
+		.of_match_table = cam_actuator_driver_dt_match,
+		.suppress_bind_attrs = true,
+	},
+};
+
+static int cam_actuator_fill_i3c_device_id(void)
+{
+	struct device_node                      *dev;
+	int                                      num_entries;
+	int                                      i = 0;
+	uint8_t                                  ent_num = 0;
+	uint32_t                                 mid;
+	uint32_t                                 pid;
+	int                                      rc;
+
+	dev = of_find_node_by_path(I3C_SENSOR_DEV_ID_DT_PATH);
+	if (!dev) {
+		CAM_WARN(CAM_ACTUATOR, "Couldnt Find the i3c-id-table dev node");
+		return 0;
+	}
+
+	num_entries = of_property_count_u32_elems(dev, "i3c-actuator-id-table");
+	if (num_entries <= 0) {
+		CAM_WARN(CAM_ACTUATOR, "Failed while reading the property. num_entries:%d",
+			num_entries);
+		return 0;
+	}
+
+	while (i < num_entries) {
+		if (ent_num >= MAX_I3C_DEVICE_ID_ENTRIES) {
+			CAM_WARN(CAM_ACTUATOR,
+				"Num_entries are more than MAX_I3C_DEVICE_ID_ENTRIES");
+			return -ENOMEM;
+		}
+
+		rc = of_property_read_u32_index(dev, "i3c-actuator-id-table", i, &mid);
+		if (rc) {
+			CAM_ERR(CAM_ACTUATOR, "Failed in reading the MID. rc: %d", rc);
+			return rc;
+		}
+		i++;
+
+		rc = of_property_read_u32_index(dev, "i3c-actuator-id-table", i, &pid);
+		if (rc) {
+			CAM_ERR(CAM_ACTUATOR, "Failed in reading the PID. rc: %d", rc);
+			return rc;
+		}
+		i++;
+
+		CAM_DBG(CAM_ACTUATOR, "PID: 0x%x, MID: 0x%x", pid, mid);
+
+		actuator_i3c_id[ent_num].manuf_id = mid;
+		actuator_i3c_id[ent_num].match_flags = I3C_MATCH_MANUF_AND_PART;
+		actuator_i3c_id[ent_num].part_id  = pid;
+		actuator_i3c_id[ent_num].data     = 0;
+
+		ent_num++;
+	}
+
+	return 0;
+}
+
 int cam_actuator_driver_init(void)
 {
 	int32_t rc = 0;
@@ -535,9 +663,30 @@ int cam_actuator_driver_init(void)
 			"platform_driver_register failed rc = %d", rc);
 		return rc;
 	}
+
 	rc = i2c_add_driver(&cam_actuator_i2c_driver);
-	if (rc)
+	if (rc) {
 		CAM_ERR(CAM_ACTUATOR, "i2c_add_driver failed rc = %d", rc);
+		goto i2c_register_err;
+	}
+
+	memset(actuator_i3c_id, 0, sizeof(struct i3c_device_id) * (MAX_I3C_DEVICE_ID_ENTRIES + 1));
+	rc = cam_actuator_fill_i3c_device_id();
+	if (rc)
+		goto i3c_register_err;
+
+	rc = i3c_driver_register_with_owner(&cam_actuator_i3c_driver, THIS_MODULE);
+	if (rc) {
+		CAM_ERR(CAM_ACTUATOR, "i3c_driver registration failed, rc: %d", rc);
+		goto i3c_register_err;
+	}
+
+	return 0;
+
+i3c_register_err:
+	i2c_del_driver(&cam_actuator_i2c_driver);
+i2c_register_err:
+	platform_driver_unregister(&cam_actuator_platform_driver);
 
 	return rc;
 }
@@ -546,6 +695,7 @@ void cam_actuator_driver_exit(void)
 {
 	platform_driver_unregister(&cam_actuator_platform_driver);
 	i2c_del_driver(&cam_actuator_i2c_driver);
+	i3c_driver_unregister(&cam_actuator_i3c_driver);
 }
 
 MODULE_DESCRIPTION("cam_actuator_driver");

+ 4 - 2
drivers/cam_sensor_module/cam_actuator/cam_actuator_dev.h

@@ -31,8 +31,10 @@
 #define NUM_MASTERS 2
 #define NUM_QUEUES 2
 
-#define ACTUATOR_DRIVER_I2C "cam-i2c-actuator"
-#define CAMX_ACTUATOR_DEV_NAME "cam-actuator-driver"
+#define ACTUATOR_DRIVER_I2C                    "cam-i2c-actuator"
+#define CAMX_ACTUATOR_DEV_NAME                 "cam-actuator-driver"
+#define ACTUATOR_DRIVER_I3C                    "i3c_camera_actuator"
+
 
 #define MSM_ACTUATOR_MAX_VREGS (10)
 #define ACTUATOR_MAX_POLL_COUNT 10

+ 21 - 7
drivers/cam_sensor_module/cam_csiphy/cam_csiphy_core.c

@@ -1027,8 +1027,8 @@ static inline void __cam_csiphy_compute_cdr_value(
 		*cdr_val -= csiphy_device->cdr_params.cdr_tolerance;
 }
 
-static int cam_csiphy_cphy_data_rate_config(
-	struct csiphy_device *csiphy_device, int32_t idx)
+static int cam_csiphy_cphy_data_rate_config(struct csiphy_device *csiphy_device, int32_t idx,
+	uint8_t datarate_variant_idx)
 {
 	int i;
 	unsigned int data_rate_idx;
@@ -1080,7 +1080,20 @@ static int cam_csiphy_cphy_data_rate_config(
 
 		CAM_DBG(CAM_CSIPHY, "table[%d] BW : %llu Selected",
 			data_rate_idx, supported_phy_bw);
-		config_params = drate_settings[data_rate_idx].data_rate_reg_array;
+
+		if (datarate_variant_idx >= CAM_CSIPHY_MAX_DATARATE_VARIANTS) {
+			CAM_ERR(CAM_CSIPHY, "Datarate variant Idx: %u can not exceed %u",
+				datarate_variant_idx, CAM_CSIPHY_MAX_DATARATE_VARIANTS-1);
+			return -EINVAL;
+		}
+
+		config_params =
+			drate_settings[data_rate_idx].data_rate_reg_array[datarate_variant_idx];
+		if (!config_params) {
+			CAM_ERR(CAM_CSIPHY, "Datarate settings are null. datarate variant idx: %u",
+				datarate_variant_idx);
+			return -EINVAL;
+		}
 
 		for (i = 0; i < num_reg_entries; i++) {
 			reg_addr = config_params[i].reg_addr;
@@ -1200,7 +1213,7 @@ static int __cam_csiphy_prgm_bist_reg(struct csiphy_device *csiphy_dev, bool is_
 }
 
 int32_t cam_csiphy_config_dev(struct csiphy_device *csiphy_dev,
-	int32_t dev_handle)
+	int32_t dev_handle, uint8_t datarate_variant_idx)
 {
 	int32_t      rc = 0;
 	uint32_t     lane_enable = 0;
@@ -1302,7 +1315,7 @@ int32_t cam_csiphy_config_dev(struct csiphy_device *csiphy_dev,
 
 
 	if (csiphy_dev->csiphy_info[index].csiphy_3phase) {
-		rc = cam_csiphy_cphy_data_rate_config(csiphy_dev, index);
+		rc = cam_csiphy_cphy_data_rate_config(csiphy_dev, index, datarate_variant_idx);
 		if (rc) {
 			CAM_ERR(CAM_CSIPHY,
 				"Date rate specific configuration failed rc: %d",
@@ -2298,6 +2311,7 @@ int32_t cam_csiphy_core_cfg(void *phy_dev,
 		struct cam_start_stop_dev_cmd config;
 		int32_t offset;
 		int clk_vote_level = -1;
+		uint8_t data_rate_variant_idx = 0;
 
 		CAM_DBG(CAM_CSIPHY, "START_DEV Called");
 		rc = copy_from_user(&config, (void __user *)cmd->handle,
@@ -2363,7 +2377,7 @@ int32_t cam_csiphy_core_cfg(void *phy_dev,
 
 			if (csiphy_dev->csiphy_info[offset].csiphy_3phase) {
 				rc = cam_csiphy_cphy_data_rate_config(
-					csiphy_dev, offset);
+					csiphy_dev, offset, data_rate_variant_idx);
 				if (rc) {
 					CAM_ERR(CAM_CSIPHY,
 						"Data rate specific configuration failed rc: %d",
@@ -2446,7 +2460,7 @@ int32_t cam_csiphy_core_cfg(void *phy_dev,
 				CAM_CSIPHY_PRGM_INDVDL);
 		}
 
-		rc = cam_csiphy_config_dev(csiphy_dev, config.dev_handle);
+		rc = cam_csiphy_config_dev(csiphy_dev, config.dev_handle, data_rate_variant_idx);
 		if (rc < 0) {
 			CAM_ERR(CAM_CSIPHY, "cam_csiphy_config_dev failed");
 			cam_csiphy_disable_hw(csiphy_dev);

+ 7 - 6
drivers/cam_sensor_module/cam_csiphy/cam_csiphy_dev.h

@@ -56,9 +56,10 @@
 
 #define CSIPHY_MAX_INSTANCES_PER_PHY     3
 
-#define CAM_CSIPHY_MAX_DPHY_LANES    4
-#define CAM_CSIPHY_MAX_CPHY_LANES    3
+#define CAM_CSIPHY_MAX_DPHY_LANES            4
+#define CAM_CSIPHY_MAX_CPHY_LANES            3
 #define CAM_CSIPHY_MAX_CPHY_DPHY_COMBO_LN    3
+#define CAM_CSIPHY_MAX_DATARATE_VARIANTS     3
 
 #define DPHY_LANE_0    BIT(0)
 #define CPHY_LANE_0    BIT(1)
@@ -187,14 +188,14 @@ struct csiphy_device;
 
 /*
  * struct data_rate_reg_info_t
- * @bandwidth               : max bandwidth supported by this reg settings
- * @data_rate_reg_array_size: number of reg value pairs in the array
- * @csiphy_data_rate_regs   : array of data rate specific reg value pairs
+ * @bandwidth                 : max bandwidth supported by this reg settings
+ * @data_rate_reg_array_size  : data rate settings size
+ * @data_rate_reg_array       : array of data rate specific reg value pairs
  */
 struct data_rate_reg_info_t {
 	uint64_t bandwidth;
 	ssize_t  data_rate_reg_array_size;
-	struct csiphy_reg_t *data_rate_reg_array;
+	struct csiphy_reg_t *data_rate_reg_array[CAM_CSIPHY_MAX_DATARATE_VARIANTS];
 };
 
 /**

+ 13 - 13
drivers/cam_sensor_module/cam_csiphy/include/cam_csiphy_2_1_0_hwreg.h

@@ -735,78 +735,78 @@ struct csiphy_reg_t datarate_210_5Gsps[] = {
 	{0x108C, 0x03, 0x00, CSIPHY_DEFAULT_PARAMS},
 };
 
-struct data_rate_reg_info_t data_rate_settings_2_1_0[] = {
+static struct data_rate_reg_info_t data_rate_settings_2_1_0[] = {
 	{
 		/* ((1.2 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value*/
 		.bandwidth = 2736000000,
 		.data_rate_reg_array_size = ARRAY_SIZE(datarate_210_1p2Gsps),
-		.data_rate_reg_array = datarate_210_1p2Gsps
+		.data_rate_reg_array[0] = datarate_210_1p2Gsps
 	},
 	{
 		/* ((1.5 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value*/
 		.bandwidth = 3420000000,
 		.data_rate_reg_array_size = ARRAY_SIZE(datarate_210_1p5Gsps),
-		.data_rate_reg_array = datarate_210_1p5Gsps,
+		.data_rate_reg_array[0] = datarate_210_1p5Gsps,
 	},
 	{
 		/* ((1.7 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value*/
 		.bandwidth = 3876000000,
 		.data_rate_reg_array_size = ARRAY_SIZE(datarate_210_1p7Gsps),
-		.data_rate_reg_array = datarate_210_1p7Gsps,
+		.data_rate_reg_array[0] = datarate_210_1p7Gsps,
 	},
 	{
 		/* ((2.1 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value*/
 		.bandwidth = 4788000000,
 		.data_rate_reg_array_size = ARRAY_SIZE(datarate_210_2p1Gsps),
-		.data_rate_reg_array = datarate_210_2p1Gsps,
+		.data_rate_reg_array[0] = datarate_210_2p1Gsps,
 	},
 	{
 		/* ((2.35 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value*/
 		.bandwidth = 5358000000,
 		.data_rate_reg_array_size = ARRAY_SIZE(datarate_210_2p35Gsps),
-		.data_rate_reg_array = datarate_210_2p35Gsps,
+		.data_rate_reg_array[0] = datarate_210_2p35Gsps,
 	},
 	{
 		/* ((2.6 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value*/
 		.bandwidth = 5928000000,
 		.data_rate_reg_array_size = ARRAY_SIZE(datarate_210_2p6Gsps),
-		.data_rate_reg_array = datarate_210_2p6Gsps,
+		.data_rate_reg_array[0] = datarate_210_2p6Gsps,
 	},
 	{
 		/* ((2.8 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value */
 		.bandwidth = 6384000000,
 		.data_rate_reg_array_size = ARRAY_SIZE(datarate_210_2p8Gsps),
-		.data_rate_reg_array = datarate_210_2p8Gsps,
+		.data_rate_reg_array[0] = datarate_210_2p8Gsps,
 	},
 	{
 		/* ((3.3 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value */
 		.bandwidth = 7524000000,
 		.data_rate_reg_array_size = ARRAY_SIZE(datarate_210_3p3Gsps),
-		.data_rate_reg_array = datarate_210_3p3Gsps,
+		.data_rate_reg_array[0] = datarate_210_3p3Gsps,
 	},
 	{
 		/* ((3.5 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value */
 		.bandwidth = 7980000000,
 		.data_rate_reg_array_size = ARRAY_SIZE(datarate_210_3p5Gsps),
-		.data_rate_reg_array = datarate_210_3p5Gsps,
+		.data_rate_reg_array[0] = datarate_210_3p5Gsps,
 	},
 	{
 		/* ((4 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value */
 		.bandwidth = 9120000000,
 		.data_rate_reg_array_size = ARRAY_SIZE(datarate_210_4Gsps),
-		.data_rate_reg_array = datarate_210_4Gsps,
+		.data_rate_reg_array[0] = datarate_210_4Gsps,
 	},
 	{
 		/* ((4.5 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value */
 		.bandwidth = 10260000000,
 		.data_rate_reg_array_size = ARRAY_SIZE(datarate_210_4p5Gsps),
-		.data_rate_reg_array = datarate_210_4p5Gsps,
+		.data_rate_reg_array[0] = datarate_210_4p5Gsps,
 	},
 	{
 		/* ((5.0 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value */
 		.bandwidth = 11400000000,
 		.data_rate_reg_array_size = ARRAY_SIZE(datarate_210_5Gsps),
-		.data_rate_reg_array = datarate_210_5Gsps,
+		.data_rate_reg_array[0] = datarate_210_5Gsps,
 	},
 };
 

+ 13 - 13
drivers/cam_sensor_module/cam_csiphy/include/cam_csiphy_2_1_1_hwreg.h

@@ -724,78 +724,78 @@ struct csiphy_reg_t datarate_211_5Gsps[] = {
 	{0x108C, 0x03, 0x00, CSIPHY_DEFAULT_PARAMS},
 };
 
-struct data_rate_reg_info_t data_rate_settings_2_1_1[] = {
+static struct data_rate_reg_info_t data_rate_settings_2_1_1[] = {
 	{
 		/* ((1.2 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value*/
 		.bandwidth = 2736000000,
 		.data_rate_reg_array_size = ARRAY_SIZE(datarate_211_1p2Gsps),
-		.data_rate_reg_array = datarate_211_1p2Gsps,
+		.data_rate_reg_array[0] = datarate_211_1p2Gsps,
 	},
 	{
 		/* ((1.5 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value*/
 		.bandwidth = 3420000000,
 		.data_rate_reg_array_size = ARRAY_SIZE(datarate_211_1p5Gsps),
-		.data_rate_reg_array = datarate_211_1p5Gsps,
+		.data_rate_reg_array[0] = datarate_211_1p5Gsps,
 	},
 	{
 		/* ((1.7 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value*/
 		.bandwidth = 3876000000,
 		.data_rate_reg_array_size = ARRAY_SIZE(datarate_211_1p7Gsps),
-		.data_rate_reg_array = datarate_211_1p7Gsps,
+		.data_rate_reg_array[0] = datarate_211_1p7Gsps,
 	},
 	{
 		/* ((2.1 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value*/
 		.bandwidth = 4788000000,
 		.data_rate_reg_array_size = ARRAY_SIZE(datarate_211_2p1Gsps),
-		.data_rate_reg_array = datarate_211_2p1Gsps,
+		.data_rate_reg_array[0] = datarate_211_2p1Gsps,
 	},
 	{
 		/* ((2.35 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value*/
 		.bandwidth = 5358000000,
 		.data_rate_reg_array_size = ARRAY_SIZE(datarate_211_2p35Gsps),
-		.data_rate_reg_array = datarate_211_2p35Gsps,
+		.data_rate_reg_array[0] = datarate_211_2p35Gsps,
 	},
 	{
 		/* ((2.6 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value*/
 		.bandwidth = 5928000000,
 		.data_rate_reg_array_size = ARRAY_SIZE(datarate_211_2p6Gsps),
-		.data_rate_reg_array = datarate_211_2p6Gsps,
+		.data_rate_reg_array[0] = datarate_211_2p6Gsps,
 	},
 	{
 		/* ((2.8 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value */
 		.bandwidth = 6384000000,
 		.data_rate_reg_array_size = ARRAY_SIZE(datarate_211_2p8Gsps),
-		.data_rate_reg_array = datarate_211_2p8Gsps,
+		.data_rate_reg_array[0] = datarate_211_2p8Gsps,
 	},
 	{
 		/* ((3.3 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value */
 		.bandwidth = 7524000000,
 		.data_rate_reg_array_size = ARRAY_SIZE(datarate_211_3p3Gsps),
-		.data_rate_reg_array = datarate_211_3p3Gsps,
+		.data_rate_reg_array[0] = datarate_211_3p3Gsps,
 	},
 	{
 		/* ((3.5 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value */
 		.bandwidth = 7980000000,
 		.data_rate_reg_array_size = ARRAY_SIZE(datarate_211_3p5Gsps),
-		.data_rate_reg_array = datarate_211_3p5Gsps,
+		.data_rate_reg_array[0] = datarate_211_3p5Gsps,
 	},
 	{
 		/* ((4 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value */
 		.bandwidth = 9120000000,
 		.data_rate_reg_array_size = ARRAY_SIZE(datarate_211_4Gsps),
-		.data_rate_reg_array = datarate_211_4Gsps,
+		.data_rate_reg_array[0] = datarate_211_4Gsps,
 	},
 	{
 		/* ((4.5 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value */
 		.bandwidth = 10260000000,
 		.data_rate_reg_array_size = ARRAY_SIZE(datarate_211_4p5Gsps),
-		.data_rate_reg_array = datarate_211_4p5Gsps,
+		.data_rate_reg_array[0] = datarate_211_4p5Gsps,
 	},
 	{
 		/* ((5.0 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value */
 		.bandwidth = 11400000000,
 		.data_rate_reg_array_size = ARRAY_SIZE(datarate_211_5Gsps),
-		.data_rate_reg_array = datarate_211_5Gsps,
+		.data_rate_reg_array[0] = datarate_211_5Gsps,
 	},
 };
 

+ 29 - 29
drivers/cam_sensor_module/cam_csiphy/include/cam_csiphy_2_1_2_hwreg.h

@@ -1330,174 +1330,174 @@ struct csiphy_reg_t datarate_212_6p0Gsps[] = {
 	{0x0A14, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
 };
 
-struct data_rate_reg_info_t data_rate_settings_2_1_2[] = {
+static struct data_rate_reg_info_t data_rate_settings_2_1_2[] = {
 	{
 		/* ((100 MSpS) * (10^6) * (2.28 bits/symbol)) rounded value*/
 		.bandwidth = 228000000,
+		.data_rate_reg_array[0] = datarate_212_100Msps,
 		.data_rate_reg_array_size = ARRAY_SIZE(datarate_212_100Msps),
-		.data_rate_reg_array = datarate_212_100Msps
 	},
 	{
 		/* ((200 MSpS) * (10^6) * (2.28 bits/symbol)) rounded value*/
 		.bandwidth = 456000000,
+		.data_rate_reg_array[0] = datarate_212_200Msps,
 		.data_rate_reg_array_size = ARRAY_SIZE(datarate_212_200Msps),
-		.data_rate_reg_array = datarate_212_200Msps
 	},
 	{
 		/* ((300 MSpS) * (10^6) * (2.28 bits/symbol)) rounded value*/
 		.bandwidth = 684000000,
+		.data_rate_reg_array[0] = datarate_212_300Msps,
 		.data_rate_reg_array_size = ARRAY_SIZE(datarate_212_300Msps),
-		.data_rate_reg_array = datarate_212_300Msps
 	},
 	{
 		/* ((350 MSpS) * (10^6) * (2.28 bits/symbol)) rounded value*/
 		.bandwidth = 798000000,
+		.data_rate_reg_array[0] = datarate_212_350Msps,
 		.data_rate_reg_array_size = ARRAY_SIZE(datarate_212_350Msps),
-		.data_rate_reg_array = datarate_212_350Msps
 	},
 	{
 		/* ((400 MSpS) * (10^6) * (2.28 bits/symbol)) rounded value*/
 		.bandwidth = 912000000,
+		.data_rate_reg_array[0] = datarate_212_400Msps,
 		.data_rate_reg_array_size = ARRAY_SIZE(datarate_212_400Msps),
-		.data_rate_reg_array = datarate_212_400Msps
 	},
 	{
 		/* ((500 MSpS) * (10^6) * (2.28 bits/symbol)) rounded value*/
 		.bandwidth = 1140000000,
+		.data_rate_reg_array[0] = datarate_212_500Msps,
 		.data_rate_reg_array_size = ARRAY_SIZE(datarate_212_500Msps),
-		.data_rate_reg_array = datarate_212_500Msps
 	},
 	{
 		/* ((600 MSpS) * (10^6) * (2.28 bits/symbol)) rounded value*/
 		.bandwidth = 1368000000,
+		.data_rate_reg_array[0] = datarate_212_600Msps,
 		.data_rate_reg_array_size = ARRAY_SIZE(datarate_212_600Msps),
-		.data_rate_reg_array = datarate_212_600Msps
 	},
 	{
 		/* ((700 MSpS) * (10^6) * (2.28 bits/symbol)) rounded value*/
 		.bandwidth = 1596000000,
+		.data_rate_reg_array[0] = datarate_212_700Msps,
 		.data_rate_reg_array_size = ARRAY_SIZE(datarate_212_700Msps),
-		.data_rate_reg_array = datarate_212_700Msps
 	},
 	{
 		/* ((800 MSpS) * (10^6) * (2.28 bits/symbol)) rounded value*/
 		.bandwidth = 1824000000,
+		.data_rate_reg_array[0] = datarate_212_800Msps,
 		.data_rate_reg_array_size = ARRAY_SIZE(datarate_212_800Msps),
-		.data_rate_reg_array = datarate_212_800Msps
 	},
 	{
 		/* ((900 MSpS) * (10^6) * (2.28 bits/symbol)) rounded value*/
 		.bandwidth = 2052000000,
+		.data_rate_reg_array[0] = datarate_212_900Msps,
 		.data_rate_reg_array_size = ARRAY_SIZE(datarate_212_900Msps),
-		.data_rate_reg_array = datarate_212_900Msps
 	},
 	{
 		/* ((1000 MSpS) * (10^6) * (2.28 bits/symbol)) rounded value*/
 		.bandwidth = 2280000000,
+		.data_rate_reg_array[0] = datarate_212_1p0Gsps,
 		.data_rate_reg_array_size = ARRAY_SIZE(datarate_212_1p0Gsps),
-		.data_rate_reg_array = datarate_212_1p0Gsps
 	},
 	{
 		/* ((1.2 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value*/
 		.bandwidth = 2736000000,
+		.data_rate_reg_array[0] = datarate_212_1p2Gsps,
 		.data_rate_reg_array_size = ARRAY_SIZE(datarate_212_1p2Gsps),
-		.data_rate_reg_array = datarate_212_1p2Gsps
 	},
 	{
 		/* ((1.5 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value*/
 		.bandwidth = 3420000000,
+		.data_rate_reg_array[0] = datarate_212_1p5Gsps,
 		.data_rate_reg_array_size = ARRAY_SIZE(datarate_212_1p5Gsps),
-		.data_rate_reg_array = datarate_212_1p5Gsps,
 	},
 	{
 		/* ((1.7 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value*/
 		.bandwidth = 3876000000,
+		.data_rate_reg_array[0] = datarate_212_1p7Gsps,
 		.data_rate_reg_array_size = ARRAY_SIZE(datarate_212_1p7Gsps),
-		.data_rate_reg_array = datarate_212_1p7Gsps,
 	},
 	{
 		/* ((2.0 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value*/
 		.bandwidth = 4560000000,
+		.data_rate_reg_array[0] = datarate_212_2p0Gsps,
 		.data_rate_reg_array_size = ARRAY_SIZE(datarate_212_2p0Gsps),
-		.data_rate_reg_array = datarate_212_2p0Gsps
 	},
 	{
 		/* ((2.1 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value*/
 		.bandwidth = 4788000000,
+		.data_rate_reg_array[0] = datarate_212_2p1Gsps,
 		.data_rate_reg_array_size = ARRAY_SIZE(datarate_212_2p1Gsps),
-		.data_rate_reg_array = datarate_212_2p1Gsps,
 	},
 	{
 		/* ((2.35 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value*/
 		.bandwidth = 5358000000,
+		.data_rate_reg_array[0] = datarate_212_2p35Gsps,
 		.data_rate_reg_array_size = ARRAY_SIZE(datarate_212_2p35Gsps),
-		.data_rate_reg_array = datarate_212_2p35Gsps,
 	},
 	{
 		/* ((2.5 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value*/
 		.bandwidth = 5700000000,
+		.data_rate_reg_array[0] = datarate_212_2p5Gsps,
 		.data_rate_reg_array_size = ARRAY_SIZE(datarate_212_2p5Gsps),
-		.data_rate_reg_array = datarate_212_2p5Gsps
 	},
 	{
 		/* ((2.6 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value*/
 		.bandwidth = 5928000000,
+		.data_rate_reg_array[0] = datarate_212_2p6Gsps,
 		.data_rate_reg_array_size = ARRAY_SIZE(datarate_212_2p6Gsps),
-		.data_rate_reg_array = datarate_212_2p6Gsps,
 	},
 	{
 		/* ((2.8 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value */
 		.bandwidth = 6384000000,
+		.data_rate_reg_array[0] = datarate_212_2p8Gsps,
 		.data_rate_reg_array_size = ARRAY_SIZE(datarate_212_2p8Gsps),
-		.data_rate_reg_array = datarate_212_2p8Gsps,
 	},
 	{
 		/* ((3.0 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value */
 		.bandwidth = 6840000000,
+		.data_rate_reg_array[0] = datarate_212_3p0Gsps,
 		.data_rate_reg_array_size = ARRAY_SIZE(datarate_212_3p0Gsps),
-		.data_rate_reg_array = datarate_212_3p0Gsps
 	},
 	{
 		/* ((3.3 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value */
 		.bandwidth = 7524000000,
+		.data_rate_reg_array[0] = datarate_212_3p3Gsps,
 		.data_rate_reg_array_size = ARRAY_SIZE(datarate_212_3p3Gsps),
-		.data_rate_reg_array = datarate_212_3p3Gsps,
 	},
 	{
 		/* ((3.5 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value */
 		.bandwidth = 7980000000,
+		.data_rate_reg_array[0] = datarate_212_3p5Gsps,
 		.data_rate_reg_array_size = ARRAY_SIZE(datarate_212_3p5Gsps),
-		.data_rate_reg_array = datarate_212_3p5Gsps,
 	},
 	{
 		/* ((4 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value */
 		.bandwidth = 9120000000,
+		.data_rate_reg_array[0] = datarate_212_4p0Gsps,
 		.data_rate_reg_array_size = ARRAY_SIZE(datarate_212_4p0Gsps),
-		.data_rate_reg_array = datarate_212_4p0Gsps,
 	},
 	{
 		/* ((4.5 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value */
 		.bandwidth = 10260000000,
+		.data_rate_reg_array[0] = datarate_212_4p5Gsps,
 		.data_rate_reg_array_size = ARRAY_SIZE(datarate_212_4p5Gsps),
-		.data_rate_reg_array = datarate_212_4p5Gsps,
 	},
 	{
 		/* ((5.0 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value */
 		.bandwidth = 11400000000,
+		.data_rate_reg_array[0] = datarate_212_5p0Gsps,
 		.data_rate_reg_array_size = ARRAY_SIZE(datarate_212_5p0Gsps),
-		.data_rate_reg_array = datarate_212_5p0Gsps,
 	},
 	{
 		/* ((5.5 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value */
 		.bandwidth = 12540000000,
+		.data_rate_reg_array[0] = datarate_212_5p5Gsps,
 		.data_rate_reg_array_size = ARRAY_SIZE(datarate_212_5p5Gsps),
-		.data_rate_reg_array = datarate_212_5p5Gsps,
 	},
 	{
 		/* ((6.0 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value */
 		.bandwidth = 13680000000,
+		.data_rate_reg_array[0] = datarate_212_6p0Gsps,
 		.data_rate_reg_array_size = ARRAY_SIZE(datarate_212_6p0Gsps),
-		.data_rate_reg_array = datarate_212_6p0Gsps,
 	},
 };
 

+ 26 - 26
drivers/cam_sensor_module/cam_csiphy/include/cam_csiphy_2_1_3_hwreg.h

@@ -1106,156 +1106,156 @@ struct csiphy_reg_t datarate_213_5Gsps[] = {
 	{0x108C, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
 };
 
-struct data_rate_reg_info_t data_rate_settings_2_1_3[] = {
+static struct data_rate_reg_info_t data_rate_settings_2_1_3[] = {
 	{
 		/* ((100 MSpS) * (10^6) * (2.28 bits/symbol)) rounded value*/
 		.bandwidth = 228000000,
 		.data_rate_reg_array_size = ARRAY_SIZE(datarate_213_100Msps),
-		.data_rate_reg_array = datarate_213_100Msps
+		.data_rate_reg_array[0] = datarate_213_100Msps
 	},
 	{
 		/* ((200 MSpS) * (10^6) * (2.28 bits/symbol)) rounded value*/
 		.bandwidth = 456000000,
 		.data_rate_reg_array_size = ARRAY_SIZE(datarate_213_200Msps),
-		.data_rate_reg_array = datarate_213_200Msps
+		.data_rate_reg_array[0] = datarate_213_200Msps
 	},
 	{
 		/* ((300 MSpS) * (10^6) * (2.28 bits/symbol)) rounded value*/
 		.bandwidth = 684000000,
 		.data_rate_reg_array_size = ARRAY_SIZE(datarate_213_300Msps),
-		.data_rate_reg_array = datarate_213_300Msps
+		.data_rate_reg_array[0] = datarate_213_300Msps
 	},
 	{
 		/* ((400 MSpS) * (10^6) * (2.28 bits/symbol)) rounded value*/
 		.bandwidth = 912000000,
 		.data_rate_reg_array_size = ARRAY_SIZE(datarate_213_400Msps),
-		.data_rate_reg_array = datarate_213_400Msps
+		.data_rate_reg_array[0] = datarate_213_400Msps
 	},
 	{
 		/* ((500 MSpS) * (10^6) * (2.28 bits/symbol)) rounded value*/
 		.bandwidth = 1140000000,
 		.data_rate_reg_array_size = ARRAY_SIZE(datarate_213_500Msps),
-		.data_rate_reg_array = datarate_213_500Msps
+		.data_rate_reg_array[0] = datarate_213_500Msps
 	},
 	{
 		/* ((600 MSpS) * (10^6) * (2.28 bits/symbol)) rounded value*/
 		.bandwidth = 1368000000,
 		.data_rate_reg_array_size = ARRAY_SIZE(datarate_213_600Msps),
-		.data_rate_reg_array = datarate_213_600Msps
+		.data_rate_reg_array[0] = datarate_213_600Msps
 	},
 	{
 		/* ((700 MSpS) * (10^6) * (2.28 bits/symbol)) rounded value*/
 		.bandwidth = 1596000000,
 		.data_rate_reg_array_size = ARRAY_SIZE(datarate_213_700Msps),
-		.data_rate_reg_array = datarate_213_700Msps
+		.data_rate_reg_array[0] = datarate_213_700Msps
 	},
 	{
 		/* ((800 MSpS) * (10^6) * (2.28 bits/symbol)) rounded value*/
 		.bandwidth = 1824000000,
 		.data_rate_reg_array_size = ARRAY_SIZE(datarate_213_800Msps),
-		.data_rate_reg_array = datarate_213_800Msps
+		.data_rate_reg_array[0] = datarate_213_800Msps
 	},
 	{
 		/* ((900 MSpS) * (10^6) * (2.28 bits/symbol)) rounded value*/
 		.bandwidth = 2052000000,
 		.data_rate_reg_array_size = ARRAY_SIZE(datarate_213_900Msps),
-		.data_rate_reg_array = datarate_213_900Msps
+		.data_rate_reg_array[0] = datarate_213_900Msps
 	},
 	{
 		/* ((1000 MSpS) * (10^6) * (2.28 bits/symbol)) rounded value*/
 		.bandwidth = 2280000000,
 		.data_rate_reg_array_size = ARRAY_SIZE(datarate_213_1p0Gsps),
-		.data_rate_reg_array = datarate_213_1p0Gsps
+		.data_rate_reg_array[0] = datarate_213_1p0Gsps
 	},
 	{
 		/* ((1.2 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value*/
 		.bandwidth = 2736000000,
 		.data_rate_reg_array_size = ARRAY_SIZE(datarate_213_1p2Gsps),
-		.data_rate_reg_array = datarate_213_1p2Gsps
+		.data_rate_reg_array[0] = datarate_213_1p2Gsps
 	},
 	{
 		/* ((1.5 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value*/
 		.bandwidth = 3420000000,
 		.data_rate_reg_array_size = ARRAY_SIZE(datarate_213_1p5Gsps),
-		.data_rate_reg_array = datarate_213_1p5Gsps,
+		.data_rate_reg_array[0] = datarate_213_1p5Gsps,
 	},
 	{
 		/* ((1.7 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value*/
 		.bandwidth = 3876000000,
 		.data_rate_reg_array_size = ARRAY_SIZE(datarate_213_1p7Gsps),
-		.data_rate_reg_array = datarate_213_1p7Gsps,
+		.data_rate_reg_array[0] = datarate_213_1p7Gsps,
 	},
 	{
 		/* ((2.0 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value*/
 		.bandwidth = 4560000000,
 		.data_rate_reg_array_size = ARRAY_SIZE(datarate_213_2p0Gsps),
-		.data_rate_reg_array = datarate_213_2p0Gsps
+		.data_rate_reg_array[0] = datarate_213_2p0Gsps
 	},
 	{
 		/* ((2.1 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value*/
 		.bandwidth = 4788000000,
 		.data_rate_reg_array_size = ARRAY_SIZE(datarate_213_2p1Gsps),
-		.data_rate_reg_array = datarate_213_2p1Gsps,
+		.data_rate_reg_array[0] = datarate_213_2p1Gsps,
 	},
 	{
 		/* ((2.35 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value*/
 		.bandwidth = 5358000000,
 		.data_rate_reg_array_size = ARRAY_SIZE(datarate_213_2p35Gsps),
-		.data_rate_reg_array = datarate_213_2p35Gsps,
+		.data_rate_reg_array[0] = datarate_213_2p35Gsps,
 	},
 	{
 		/* ((2.5 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value*/
 		.bandwidth = 5700000000,
 		.data_rate_reg_array_size = ARRAY_SIZE(datarate_213_2p5Gsps),
-		.data_rate_reg_array = datarate_213_2p5Gsps
+		.data_rate_reg_array[0] = datarate_213_2p5Gsps
 	},
 	{
 		/* ((2.6 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value*/
 		.bandwidth = 5928000000,
 		.data_rate_reg_array_size = ARRAY_SIZE(datarate_213_2p6Gsps),
-		.data_rate_reg_array = datarate_213_2p6Gsps,
+		.data_rate_reg_array[0] = datarate_213_2p6Gsps,
 	},
 	{
 		/* ((2.8 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value */
 		.bandwidth = 6384000000,
 		.data_rate_reg_array_size = ARRAY_SIZE(datarate_213_2p8Gsps),
-		.data_rate_reg_array = datarate_213_2p8Gsps,
+		.data_rate_reg_array[0] = datarate_213_2p8Gsps,
 	},
 	{
 		/* ((3.0 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value */
 		.bandwidth = 6840000000,
 		.data_rate_reg_array_size = ARRAY_SIZE(datarate_213_3p0Gsps),
-		.data_rate_reg_array = datarate_213_3p0Gsps
+		.data_rate_reg_array[0] = datarate_213_3p0Gsps
 	},
 	{
 		/* ((3.3 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value */
 		.bandwidth = 7524000000,
 		.data_rate_reg_array_size = ARRAY_SIZE(datarate_213_3p3Gsps),
-		.data_rate_reg_array = datarate_213_3p3Gsps,
+		.data_rate_reg_array[0] = datarate_213_3p3Gsps,
 	},
 	{
 		/* ((3.5 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value */
 		.bandwidth = 7980000000,
 		.data_rate_reg_array_size = ARRAY_SIZE(datarate_213_3p5Gsps),
-		.data_rate_reg_array = datarate_213_3p5Gsps,
+		.data_rate_reg_array[0] = datarate_213_3p5Gsps,
 	},
 	{
 		/* ((4 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value */
 		.bandwidth = 9120000000,
 		.data_rate_reg_array_size = ARRAY_SIZE(datarate_213_4Gsps),
-		.data_rate_reg_array = datarate_213_4Gsps,
+		.data_rate_reg_array[0] = datarate_213_4Gsps,
 	},
 	{
 		/* ((4.5 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value */
 		.bandwidth = 10260000000,
 		.data_rate_reg_array_size = ARRAY_SIZE(datarate_213_4p5Gsps),
-		.data_rate_reg_array = datarate_213_4p5Gsps,
+		.data_rate_reg_array[0] = datarate_213_4p5Gsps,
 	},
 	{
 		/* ((5.0 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value */
 		.bandwidth = 11400000000,
 		.data_rate_reg_array_size = ARRAY_SIZE(datarate_213_5Gsps),
-		.data_rate_reg_array = datarate_213_5Gsps,
+		.data_rate_reg_array[0] = datarate_213_5Gsps,
 	},
 };
 

+ 31 - 31
drivers/cam_sensor_module/cam_csiphy/include/cam_csiphy_2_2_0_hwreg.h

@@ -1574,186 +1574,186 @@ struct csiphy_reg_t datarate_220_8p0Gsps[] = {
 	{0x0A14, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
 };
 
-struct data_rate_reg_info_t data_rate_settings_2_2_0[] = {
+static struct data_rate_reg_info_t data_rate_settings_2_2_0[] = {
 	{
 		/* ((100 MSpS) * (10^6) * (2.28 bits/symbol)) rounded value*/
 		.bandwidth = 228000000,
 		.data_rate_reg_array_size = ARRAY_SIZE(datarate_220_100Msps),
-		.data_rate_reg_array = datarate_220_100Msps
+		.data_rate_reg_array[0] = datarate_220_100Msps
 	},
 	{
 		/* ((200 MSpS) * (10^6) * (2.28 bits/symbol)) rounded value*/
 		.bandwidth = 456000000,
 		.data_rate_reg_array_size = ARRAY_SIZE(datarate_220_200Msps),
-		.data_rate_reg_array = datarate_220_200Msps
+		.data_rate_reg_array[0] = datarate_220_200Msps
 	},
 	{
 		/* ((300 MSpS) * (10^6) * (2.28 bits/symbol)) rounded value*/
 		.bandwidth = 684000000,
 		.data_rate_reg_array_size = ARRAY_SIZE(datarate_220_300Msps),
-		.data_rate_reg_array = datarate_220_300Msps
+		.data_rate_reg_array[0] = datarate_220_300Msps
 	},
 	{
 		/* ((350 MSpS) * (10^6) * (2.28 bits/symbol)) rounded value*/
 		.bandwidth = 798000000,
 		.data_rate_reg_array_size = ARRAY_SIZE(datarate_220_350Msps),
-		.data_rate_reg_array = datarate_220_350Msps
+		.data_rate_reg_array[0] = datarate_220_350Msps
 	},
 	{
 		/* ((400 MSpS) * (10^6) * (2.28 bits/symbol)) rounded value*/
 		.bandwidth = 912000000,
 		.data_rate_reg_array_size = ARRAY_SIZE(datarate_220_400Msps),
-		.data_rate_reg_array = datarate_220_400Msps
+		.data_rate_reg_array[0] = datarate_220_400Msps
 	},
 	{
 		/* ((500 MSpS) * (10^6) * (2.28 bits/symbol)) rounded value*/
 		.bandwidth = 1140000000,
 		.data_rate_reg_array_size = ARRAY_SIZE(datarate_220_500Msps),
-		.data_rate_reg_array = datarate_220_500Msps
+		.data_rate_reg_array[0] = datarate_220_500Msps
 	},
 	{
 		/* ((600 MSpS) * (10^6) * (2.28 bits/symbol)) rounded value*/
 		.bandwidth = 1368000000,
 		.data_rate_reg_array_size = ARRAY_SIZE(datarate_220_600Msps),
-		.data_rate_reg_array = datarate_220_600Msps
+		.data_rate_reg_array[0] = datarate_220_600Msps
 	},
 	{
 		/* ((700 MSpS) * (10^6) * (2.28 bits/symbol)) rounded value*/
 		.bandwidth = 1596000000,
 		.data_rate_reg_array_size = ARRAY_SIZE(datarate_220_700Msps),
-		.data_rate_reg_array = datarate_220_700Msps
+		.data_rate_reg_array[0] = datarate_220_700Msps
 	},
 	{
 		/* ((800 MSpS) * (10^6) * (2.28 bits/symbol)) rounded value*/
 		.bandwidth = 1824000000,
 		.data_rate_reg_array_size = ARRAY_SIZE(datarate_220_800Msps),
-		.data_rate_reg_array = datarate_220_800Msps
+		.data_rate_reg_array[0] = datarate_220_800Msps
 	},
 	{
 		/* ((900 MSpS) * (10^6) * (2.28 bits/symbol)) rounded value*/
 		.bandwidth = 2052000000,
 		.data_rate_reg_array_size = ARRAY_SIZE(datarate_220_900Msps),
-		.data_rate_reg_array = datarate_220_900Msps
+		.data_rate_reg_array[0] = datarate_220_900Msps
 	},
 	{
 		/* ((1000 MSpS) * (10^6) * (2.28 bits/symbol)) rounded value*/
 		.bandwidth = 2280000000,
 		.data_rate_reg_array_size = ARRAY_SIZE(datarate_220_1p0Gsps),
-		.data_rate_reg_array = datarate_220_1p0Gsps
+		.data_rate_reg_array[0] = datarate_220_1p0Gsps
 	},
 	{
 		/* ((1.2 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value*/
 		.bandwidth = 2736000000,
 		.data_rate_reg_array_size = ARRAY_SIZE(datarate_220_1p2Gsps),
-		.data_rate_reg_array = datarate_220_1p2Gsps
+		.data_rate_reg_array[0] = datarate_220_1p2Gsps
 	},
 	{
 		/* ((1.5 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value*/
 		.bandwidth = 3420000000,
 		.data_rate_reg_array_size = ARRAY_SIZE(datarate_220_1p5Gsps),
-		.data_rate_reg_array = datarate_220_1p5Gsps,
+		.data_rate_reg_array[0] = datarate_220_1p5Gsps,
 	},
 	{
 		/* ((1.7 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value*/
 		.bandwidth = 3876000000,
 		.data_rate_reg_array_size = ARRAY_SIZE(datarate_220_1p7Gsps),
-		.data_rate_reg_array = datarate_220_1p7Gsps,
+		.data_rate_reg_array[0] = datarate_220_1p7Gsps,
 	},
 	{
 		/* ((2.0 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value*/
 		.bandwidth = 4560000000,
 		.data_rate_reg_array_size = ARRAY_SIZE(datarate_220_2p0Gsps),
-		.data_rate_reg_array = datarate_220_2p0Gsps
+		.data_rate_reg_array[0] = datarate_220_2p0Gsps
 	},
 	{
 		/* ((2.1 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value*/
 		.bandwidth = 4788000000,
 		.data_rate_reg_array_size = ARRAY_SIZE(datarate_220_2p1Gsps),
-		.data_rate_reg_array = datarate_220_2p1Gsps,
+		.data_rate_reg_array[0] = datarate_220_2p1Gsps,
 	},
 	{
 		/* ((2.35 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value*/
 		.bandwidth = 5358000000,
 		.data_rate_reg_array_size = ARRAY_SIZE(datarate_220_2p35Gsps),
-		.data_rate_reg_array = datarate_220_2p35Gsps,
+		.data_rate_reg_array[0] = datarate_220_2p35Gsps,
 	},
 	{
 		/* ((2.5 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value*/
 		.bandwidth = 5700000000,
 		.data_rate_reg_array_size = ARRAY_SIZE(datarate_220_2p5Gsps),
-		.data_rate_reg_array = datarate_220_2p5Gsps
+		.data_rate_reg_array[0] = datarate_220_2p5Gsps
 	},
 	{
 		/* ((2.6 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value*/
 		.bandwidth = 5928000000,
 		.data_rate_reg_array_size = ARRAY_SIZE(datarate_220_2p6Gsps),
-		.data_rate_reg_array = datarate_220_2p6Gsps,
+		.data_rate_reg_array[0] = datarate_220_2p6Gsps,
 	},
 	{
 		/* ((2.8 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value */
 		.bandwidth = 6384000000,
 		.data_rate_reg_array_size = ARRAY_SIZE(datarate_220_2p8Gsps),
-		.data_rate_reg_array = datarate_220_2p8Gsps,
+		.data_rate_reg_array[0] = datarate_220_2p8Gsps,
 	},
 	{
 		/* ((3.0 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value */
 		.bandwidth = 6840000000,
 		.data_rate_reg_array_size = ARRAY_SIZE(datarate_220_3p0Gsps),
-		.data_rate_reg_array = datarate_220_3p0Gsps
+		.data_rate_reg_array[0] = datarate_220_3p0Gsps
 	},
 	{
 		/* ((3.3 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value */
 		.bandwidth = 7524000000,
 		.data_rate_reg_array_size = ARRAY_SIZE(datarate_220_3p3Gsps),
-		.data_rate_reg_array = datarate_220_3p3Gsps,
+		.data_rate_reg_array[0] = datarate_220_3p3Gsps,
 	},
 	{
 		/* ((3.5 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value */
 		.bandwidth = 7980000000,
 		.data_rate_reg_array_size = ARRAY_SIZE(datarate_220_3p5Gsps),
-		.data_rate_reg_array = datarate_220_3p5Gsps,
+		.data_rate_reg_array[0] = datarate_220_3p5Gsps,
 	},
 	{
 		/* ((4 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value */
 		.bandwidth = 9120000000,
 		.data_rate_reg_array_size = ARRAY_SIZE(datarate_220_4p0Gsps),
-		.data_rate_reg_array = datarate_220_4p0Gsps,
+		.data_rate_reg_array[0] = datarate_220_4p0Gsps,
 	},
 	{
 		/* ((4.5 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value */
 		.bandwidth = 10260000000,
 		.data_rate_reg_array_size = ARRAY_SIZE(datarate_220_4p5Gsps),
-		.data_rate_reg_array = datarate_220_4p5Gsps,
+		.data_rate_reg_array[0] = datarate_220_4p5Gsps,
 	},
 	{
 		/* ((5.0 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value */
 		.bandwidth = 11400000000,
 		.data_rate_reg_array_size = ARRAY_SIZE(datarate_220_5p0Gsps),
-		.data_rate_reg_array = datarate_220_5p0Gsps,
+		.data_rate_reg_array[0] = datarate_220_5p0Gsps,
 	},
 	{
 		/* ((5.5 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value */
 		.bandwidth = 12540000000,
 		.data_rate_reg_array_size = ARRAY_SIZE(datarate_220_5p5Gsps),
-		.data_rate_reg_array = datarate_220_5p5Gsps,
+		.data_rate_reg_array[0] = datarate_220_5p5Gsps,
 	},
 	{
 		/* ((6.0 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value */
 		.bandwidth = 13680000000,
 		.data_rate_reg_array_size = ARRAY_SIZE(datarate_220_6p0Gsps),
-		.data_rate_reg_array = datarate_220_6p0Gsps,
+		.data_rate_reg_array[0] = datarate_220_6p0Gsps,
 	},
 	{
 		/* ((7.0 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value */
 		.bandwidth = 15960000000,
 		.data_rate_reg_array_size = ARRAY_SIZE(datarate_220_7p0Gsps),
-		.data_rate_reg_array = datarate_220_7p0Gsps,
+		.data_rate_reg_array[0] = datarate_220_7p0Gsps,
 	},
 	{
 		/* ((8.0 GSpS) * (10^9) * (2.28 bits/symbol)) rounded value */
 		.bandwidth = 18240000000,
 		.data_rate_reg_array_size = ARRAY_SIZE(datarate_220_8p0Gsps),
-		.data_rate_reg_array = datarate_220_8p0Gsps,
+		.data_rate_reg_array[0] = datarate_220_8p0Gsps,
 	},
 
 };

+ 8 - 4
drivers/cam_sensor_module/cam_eeprom/cam_eeprom_core.c

@@ -148,9 +148,9 @@ static int cam_eeprom_read_memory(struct cam_eeprom_ctrl_t *e_ctrl,
 static int cam_eeprom_power_up(struct cam_eeprom_ctrl_t *e_ctrl,
 	struct cam_sensor_power_ctrl_t *power_info)
 {
-	int32_t                 rc = 0;
-	struct cam_hw_soc_info *soc_info =
-		&e_ctrl->soc_info;
+	int32_t                                 rc = 0;
+	struct cam_hw_soc_info                 *soc_info = &e_ctrl->soc_info;
+	struct completion                      *i3c_probe_completion = NULL;
 
 	/* Parse and fill vreg params for power up settings */
 	rc = msm_camera_fill_vreg_params(
@@ -176,7 +176,10 @@ static int cam_eeprom_power_up(struct cam_eeprom_ctrl_t *e_ctrl,
 
 	power_info->dev = soc_info->dev;
 
-	rc = cam_sensor_core_power_up(power_info, soc_info);
+	if (e_ctrl->io_master_info.master_type == I3C_MASTER)
+		i3c_probe_completion = cam_eeprom_get_i3c_completion(e_ctrl->soc_info.index);
+
+	rc = cam_sensor_core_power_up(power_info, soc_info, i3c_probe_completion);
 	if (rc) {
 		CAM_ERR(CAM_EEPROM, "failed in eeprom power up rc %d", rc);
 		return rc;
@@ -189,6 +192,7 @@ static int cam_eeprom_power_up(struct cam_eeprom_ctrl_t *e_ctrl,
 			goto cci_failure;
 		}
 	}
+
 	return rc;
 cci_failure:
 	if (cam_sensor_util_power_down(power_info, soc_info))

+ 3 - 0
drivers/cam_sensor_module/cam_eeprom/cam_eeprom_core.h

@@ -1,6 +1,7 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
 /*
  * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
  */
 #ifndef _CAM_EEPROM_CORE_H_
 #define _CAM_EEPROM_CORE_H_
@@ -17,5 +18,7 @@ int32_t cam_eeprom_parse_read_memory_map(struct device_node *of_node,
  */
 void cam_eeprom_shutdown(struct cam_eeprom_ctrl_t *e_ctrl);
 
+struct completion *cam_eeprom_get_i3c_completion(uint32_t index);
+
 #endif
 /* _CAM_EEPROM_CORE_H_ */

+ 151 - 2
drivers/cam_sensor_module/cam_eeprom/cam_eeprom_dev.c

@@ -1,6 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
  * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #include "cam_eeprom_dev.h"
@@ -9,6 +10,17 @@
 #include "cam_eeprom_core.h"
 #include "cam_debug_util.h"
 #include "camera_main.h"
+#include "cam_compat.h"
+
+static struct cam_i3c_eeprom_data {
+	struct cam_eeprom_ctrl_t                  *e_ctrl;
+	struct completion                          probe_complete;
+} g_i3c_eeprom_data[MAX_CAMERAS];
+
+struct completion *cam_eeprom_get_i3c_completion(uint32_t index)
+{
+	return &g_i3c_eeprom_data[index].probe_complete;
+}
 
 static int cam_eeprom_subdev_close_internal(struct v4l2_subdev *sd,
 	struct v4l2_subdev_fh *fh)
@@ -546,6 +558,9 @@ static int cam_eeprom_component_bind(struct device *dev,
 	e_ctrl->cam_eeprom_state = CAM_EEPROM_INIT;
 	CAM_DBG(CAM_EEPROM, "Component bound successfully");
 
+	g_i3c_eeprom_data[e_ctrl->soc_info.index].e_ctrl = e_ctrl;
+	init_completion(&g_i3c_eeprom_data[e_ctrl->soc_info.index].probe_complete);
+
 	return rc;
 free_soc:
 	kfree(soc_private);
@@ -665,6 +680,119 @@ static struct spi_driver cam_eeprom_spi_driver = {
 	.probe = cam_eeprom_spi_driver_probe,
 	.remove = cam_eeprom_spi_driver_remove,
 };
+
+static struct i3c_device_id eeprom_i3c_id[MAX_I3C_DEVICE_ID_ENTRIES + 1];
+
+static int cam_eeprom_i3c_driver_probe(struct i3c_device *client)
+{
+	int32_t rc = 0;
+	struct cam_eeprom_ctrl_t       *e_ctrl = NULL;
+	uint32_t                        index;
+	struct device                  *dev;
+
+	if (!client) {
+		CAM_INFO(CAM_EEPROM, "Null Client pointer");
+		return -EINVAL;
+	}
+
+	dev = &client->dev;
+
+	CAM_DBG(CAM_EEPROM, "Probe for I3C Slave %s", dev_name(dev));
+
+	rc = of_property_read_u32(dev->of_node, "cell-index", &index);
+	if (rc) {
+		CAM_ERR(CAM_EEPROM, "device %s failed to read cell-index", dev_name(dev));
+		return rc;
+	}
+
+	if (index >= MAX_CAMERAS) {
+		CAM_ERR(CAM_EEPROM, "Invalid Cell-Index: %u for %s", index, dev_name(dev));
+		return -EINVAL;
+	}
+
+	e_ctrl = g_i3c_eeprom_data[index].e_ctrl;
+	if (!e_ctrl) {
+		CAM_ERR(CAM_EEPROM, "e_ctrl is null. I3C Probe before platfom driver probe for %s",
+			dev_name(dev));
+		return -EINVAL;
+	}
+
+	e_ctrl->io_master_info.i3c_client = client;
+
+	complete_all(&g_i3c_eeprom_data[index].probe_complete);
+
+	CAM_DBG(CAM_EEPROM, "I3C Probe Finished for %s", dev_name(dev));
+	return rc;
+}
+
+static struct i3c_driver cam_eeprom_i3c_driver = {
+	.id_table = eeprom_i3c_id,
+	.probe = cam_eeprom_i3c_driver_probe,
+	.remove = cam_i3c_driver_remove,
+	.driver = {
+		.owner = THIS_MODULE,
+		.name = EEPROM_DRIVER_I3C,
+		.of_match_table = cam_eeprom_dt_match,
+		.suppress_bind_attrs = true,
+	},
+};
+
+static int cam_eeprom_fill_i3c_device_id(void)
+{
+	struct device_node                      *dev;
+	int                                      num_entries;
+	int                                      i = 0;
+	uint8_t                                  ent_num = 0;
+	uint32_t                                 mid;
+	uint32_t                                 pid;
+	int                                      rc;
+
+	dev = of_find_node_by_path(I3C_SENSOR_DEV_ID_DT_PATH);
+	if (!dev) {
+		CAM_WARN(CAM_EEPROM, "Couldnt Find the i3c-id-table dev node");
+		return 0;
+	}
+
+	num_entries = of_property_count_u32_elems(dev, "i3c-eeprom-id-table");
+	if (num_entries <= 0) {
+		CAM_WARN(CAM_EEPROM, "Failed while reading the property. num_entries:%d",
+			num_entries);
+		return 0;
+	}
+
+	while (i < num_entries) {
+		if (ent_num >= MAX_I3C_DEVICE_ID_ENTRIES) {
+			CAM_WARN(CAM_EEPROM, "Num_entries are more than MAX_I3C_DEVICE_ID_ENTRIES");
+			return -ENOMEM;
+		}
+
+		rc = of_property_read_u32_index(dev, "i3c-eeprom-id-table", i, &mid);
+		if (rc) {
+			CAM_ERR(CAM_EEPROM, "Failed in reading the MID. rc: %d", rc);
+			return rc;
+		}
+		i++;
+
+		rc = of_property_read_u32_index(dev, "i3c-eeprom-id-table", i, &pid);
+		if (rc) {
+			CAM_ERR(CAM_EEPROM, "Failed in reading the PID. rc: %d", rc);
+			return rc;
+		}
+		i++;
+
+		CAM_DBG(CAM_EEPROM, "PID: 0x%x, MID: 0x%x", pid, mid);
+
+		eeprom_i3c_id[ent_num].manuf_id = mid;
+		eeprom_i3c_id[ent_num].match_flags = I3C_MATCH_MANUF_AND_PART;
+		eeprom_i3c_id[ent_num].part_id  = pid;
+		eeprom_i3c_id[ent_num].data     = 0;
+
+		ent_num++;
+	}
+
+	return 0;
+}
+
 int cam_eeprom_driver_init(void)
 {
 	int rc = 0;
@@ -679,15 +807,35 @@ int cam_eeprom_driver_init(void)
 	rc = spi_register_driver(&cam_eeprom_spi_driver);
 	if (rc < 0) {
 		CAM_ERR(CAM_EEPROM, "spi_register_driver failed rc = %d", rc);
-		return rc;
+		goto spi_register_err;
 	}
 
 	rc = i2c_add_driver(&cam_eeprom_i2c_driver);
 	if (rc < 0) {
 		CAM_ERR(CAM_EEPROM, "i2c_add_driver failed rc = %d", rc);
-		return rc;
+		goto i2c_register_err;
 	}
 
+	memset(eeprom_i3c_id, 0, sizeof(struct i3c_device_id) * (MAX_I3C_DEVICE_ID_ENTRIES + 1));
+
+	rc = cam_eeprom_fill_i3c_device_id();
+	if (rc)
+		goto i3c_register_err;
+
+	rc = i3c_driver_register_with_owner(&cam_eeprom_i3c_driver, THIS_MODULE);
+	if (rc) {
+		CAM_ERR(CAM_EEPROM, "i3c_driver registration failed, rc: %d", rc);
+		goto i3c_register_err;
+	}
+
+	return 0;
+i3c_register_err:
+	i2c_del_driver(&cam_sensor_i2c_driver);
+i2c_register_err:
+	spi_unregister_driver(&cam_eeprom_spi_driver);
+spi_register_err:
+	platform_driver_unregister(&cam_sensor_platform_driver);
+
 	return rc;
 }
 
@@ -696,6 +844,7 @@ void cam_eeprom_driver_exit(void)
 	platform_driver_unregister(&cam_eeprom_platform_driver);
 	spi_unregister_driver(&cam_eeprom_spi_driver);
 	i2c_del_driver(&cam_eeprom_i2c_driver);
+	i3c_driver_unregister(&cam_eeprom_i3c_driver);
 }
 
 MODULE_DESCRIPTION("CAM EEPROM driver");

+ 3 - 1
drivers/cam_sensor_module/cam_eeprom/cam_eeprom_dev.h

@@ -34,7 +34,9 @@
 #define MSM_EEPROM_MAX_MEM_MAP_CNT             100
 #define MSM_EEPROM_MEM_MAP_PROPERTIES_CNT      8
 
-#define EEPROM_DRIVER_I2C "cam-i2c-eeprom"
+#define EEPROM_DRIVER_I2C                      "cam-i2c-eeprom"
+#define EEPROM_DRIVER_I3C                      "i3c_camera_eeprom"
+
 
 enum cam_eeprom_state {
 	CAM_EEPROM_INIT,

+ 1 - 1
drivers/cam_sensor_module/cam_flash/cam_flash_core.c

@@ -169,7 +169,7 @@ int cam_flash_i2c_power_ops(struct cam_flash_ctrl *fctrl,
 			}
 		}
 
-		rc = cam_sensor_core_power_up(power_info, soc_info);
+		rc = cam_sensor_core_power_up(power_info, soc_info, NULL);
 		if (rc) {
 			CAM_ERR(CAM_FLASH, "power up the core is failed:%d",
 				rc);

+ 11 - 9
drivers/cam_sensor_module/cam_ois/cam_ois_core.c

@@ -7,7 +7,7 @@
 #include <linux/module.h>
 #include <linux/firmware.h>
 
-#include <cam_sensor_cmn_header.h>
+#include "cam_sensor_cmn_header.h"
 #include "cam_ois_core.h"
 #include "cam_ois_soc.h"
 #include "cam_sensor_util.h"
@@ -105,14 +105,13 @@ static int cam_ois_get_dev_handle(struct cam_ois_ctrl_t *o_ctrl,
 
 static int cam_ois_power_up(struct cam_ois_ctrl_t *o_ctrl)
 {
-	int                             rc = 0;
-	struct cam_hw_soc_info          *soc_info =
-		&o_ctrl->soc_info;
-	struct cam_ois_soc_private *soc_private;
-	struct cam_sensor_power_ctrl_t  *power_info;
+	int                                     rc = 0;
+	struct cam_hw_soc_info                 *soc_info = &o_ctrl->soc_info;
+	struct cam_ois_soc_private             *soc_private;
+	struct cam_sensor_power_ctrl_t         *power_info;
+	struct completion                      *i3c_probe_completion = NULL;
 
-	soc_private =
-		(struct cam_ois_soc_private *)o_ctrl->soc_info.soc_private;
+	soc_private = (struct cam_ois_soc_private *)o_ctrl->soc_info.soc_private;
 	power_info = &soc_private->power_info;
 
 	if ((power_info->power_setting == NULL) &&
@@ -151,7 +150,10 @@ static int cam_ois_power_up(struct cam_ois_ctrl_t *o_ctrl)
 
 	power_info->dev = soc_info->dev;
 
-	rc = cam_sensor_core_power_up(power_info, soc_info);
+	if (o_ctrl->io_master_info.master_type == I3C_MASTER)
+		i3c_probe_completion = cam_ois_get_i3c_completion(o_ctrl->soc_info.index);
+
+	rc = cam_sensor_core_power_up(power_info, soc_info, i3c_probe_completion);
 	if (rc) {
 		CAM_ERR(CAM_OIS, "failed in ois power up rc %d", rc);
 		return rc;

+ 3 - 0
drivers/cam_sensor_module/cam_ois/cam_ois_core.h

@@ -1,6 +1,7 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
 /*
  * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
  */
 #ifndef _CAM_OIS_CORE_H_
 #define _CAM_OIS_CORE_H_
@@ -30,5 +31,7 @@ int cam_ois_driver_cmd(struct cam_ois_ctrl_t *e_ctrl, void *arg);
  */
 void cam_ois_shutdown(struct cam_ois_ctrl_t *o_ctrl);
 
+struct completion *cam_ois_get_i3c_completion(uint32_t index);
+
 #endif
 /* _CAM_OIS_CORE_H_ */

+ 150 - 13
drivers/cam_sensor_module/cam_ois/cam_ois_dev.c

@@ -1,6 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
  * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #include "cam_ois_dev.h"
@@ -9,6 +10,17 @@
 #include "cam_ois_core.h"
 #include "cam_debug_util.h"
 #include "camera_main.h"
+#include "cam_compat.h"
+
+static struct cam_i3c_ois_data {
+	struct cam_ois_ctrl_t                       *o_ctrl;
+	struct completion                            probe_complete;
+} g_i3c_ois_data[MAX_CAMERAS];
+
+struct completion *cam_ois_get_i3c_completion(uint32_t index)
+{
+	return &g_i3c_ois_data[index].probe_complete;
+}
 
 static int cam_ois_subdev_close_internal(struct v4l2_subdev *sd,
 	struct v4l2_subdev_fh *fh)
@@ -372,6 +384,10 @@ static int cam_ois_component_bind(struct device *dev,
 
 	platform_set_drvdata(pdev, o_ctrl);
 	o_ctrl->cam_ois_state = CAM_OIS_INIT;
+
+	g_i3c_ois_data[o_ctrl->soc_info.index].o_ctrl = o_ctrl;
+	init_completion(&g_i3c_ois_data[o_ctrl->soc_info.index].probe_complete);
+
 	CAM_DBG(CAM_OIS, "Component bound successfully");
 	return rc;
 unreg_subdev:
@@ -485,8 +501,117 @@ struct i2c_driver cam_ois_i2c_driver = {
 	},
 };
 
-static struct cam_ois_registered_driver_t registered_driver = {
-	0, 0};
+static struct i3c_device_id ois_i3c_id[MAX_I3C_DEVICE_ID_ENTRIES + 1];
+
+static int cam_ois_i3c_driver_probe(struct i3c_device *client)
+{
+	int32_t rc = 0;
+	struct cam_ois_ctrl_t            *o_ctrl = NULL;
+	uint32_t                          index;
+	struct device                    *dev;
+
+	if (!client) {
+		CAM_INFO(CAM_OIS, "Null Client pointer");
+		return -EINVAL;
+	}
+
+	dev = &client->dev;
+
+	CAM_DBG(CAM_OIS, "Probe for I3C Slave %s", dev_name(dev));
+
+	rc = of_property_read_u32(dev->of_node, "cell-index", &index);
+	if (rc) {
+		CAM_ERR(CAM_OIS, "device %s failed to read cell-index", dev_name(dev));
+		return rc;
+	}
+
+	if (index >= MAX_CAMERAS) {
+		CAM_ERR(CAM_OIS, "Invalid Cell-Index: %u for %s", index, dev_name(dev));
+		return -EINVAL;
+	}
+
+	o_ctrl = g_i3c_ois_data[index].o_ctrl;
+	if (!o_ctrl) {
+		CAM_ERR(CAM_OIS, "o_ctrl is null. I3C Probe before platfom driver probe for %s",
+			dev_name(dev));
+		return -EINVAL;
+	}
+
+	o_ctrl->io_master_info.i3c_client = client;
+
+	complete_all(&g_i3c_ois_data[index].probe_complete);
+
+	CAM_DBG(CAM_OIS, "I3C Probe Finished for %s", dev_name(dev));
+	return rc;
+}
+
+static struct i3c_driver cam_ois_i3c_driver = {
+	.id_table = ois_i3c_id,
+	.probe = cam_ois_i3c_driver_probe,
+	.remove = cam_i3c_driver_remove,
+	.driver = {
+		.owner = THIS_MODULE,
+		.name = OIS_DRIVER_I3C,
+		.of_match_table = cam_ois_dt_match,
+		.suppress_bind_attrs = true,
+	},
+};
+
+static int cam_ois_fill_i3c_device_id(void)
+{
+	struct device_node                      *dev;
+	int                                      num_entries;
+	int                                      i = 0;
+	uint8_t                                  ent_num = 0;
+	uint32_t                                 mid;
+	uint32_t                                 pid;
+	int                                      rc;
+
+	dev = of_find_node_by_path(I3C_SENSOR_DEV_ID_DT_PATH);
+	if (!dev) {
+		CAM_WARN(CAM_OIS, "Couldnt Find the i3c-id-table dev node");
+		return 0;
+	}
+
+	num_entries = of_property_count_u32_elems(dev, "i3c-ois-id-table");
+	if (num_entries <= 0) {
+		CAM_WARN(CAM_OIS, "Failed while reading the property. num_entries:%d",
+			num_entries);
+		return 0;
+	}
+
+	while (i < num_entries) {
+		if (ent_num >= MAX_I3C_DEVICE_ID_ENTRIES) {
+			CAM_WARN(CAM_OIS, "Num_entries are more than MAX_I3C_DEVICE_ID_ENTRIES");
+			return -ENOMEM;
+		}
+
+		rc = of_property_read_u32_index(dev, "i3c-ois-id-table", i, &mid);
+		if (rc) {
+			CAM_ERR(CAM_OIS, "Failed in reading the MID. rc: %d", rc);
+			return rc;
+		}
+		i++;
+
+		rc = of_property_read_u32_index(dev, "i3c-ois-id-table", i, &pid);
+		if (rc) {
+			CAM_ERR(CAM_OIS, "Failed in reading the PID. rc: %d", rc);
+			return rc;
+		}
+		i++;
+
+		CAM_DBG(CAM_OIS, "PID: 0x%x, MID: 0x%x", pid, mid);
+
+		ois_i3c_id[ent_num].manuf_id = mid;
+		ois_i3c_id[ent_num].match_flags = I3C_MATCH_MANUF_AND_PART;
+		ois_i3c_id[ent_num].part_id  = pid;
+		ois_i3c_id[ent_num].data     = 0;
+
+		ent_num++;
+	}
+
+	return 0;
+}
 
 int cam_ois_driver_init(void)
 {
@@ -494,30 +619,42 @@ int cam_ois_driver_init(void)
 
 	rc = platform_driver_register(&cam_ois_platform_driver);
 	if (rc) {
-		CAM_ERR(CAM_OIS, "platform_driver_register failed rc = %d",
-			rc);
+		CAM_ERR(CAM_OIS, "platform_driver_register failed rc = %d", rc);
 		return rc;
 	}
 
-	registered_driver.platform_driver = 1;
-
 	rc = i2c_add_driver(&cam_ois_i2c_driver);
 	if (rc) {
 		CAM_ERR(CAM_OIS, "i2c_add_driver failed rc = %d", rc);
-		return rc;
+		goto i2c_register_err;
 	}
 
-	registered_driver.i2c_driver = 1;
+	memset(ois_i3c_id, 0, sizeof(struct i3c_device_id) * (MAX_I3C_DEVICE_ID_ENTRIES + 1));
+	rc = cam_ois_fill_i3c_device_id();
+	if (rc)
+		goto i3c_register_err;
+
+	rc = i3c_driver_register_with_owner(&cam_ois_i3c_driver, THIS_MODULE);
+	if (rc) {
+		CAM_ERR(CAM_OIS, "i3c_driver registration failed, rc: %d", rc);
+		goto i3c_register_err;
+	}
+
+	return 0;
+
+i3c_register_err:
+	i2c_del_driver(&cam_ois_i2c_driver);
+i2c_register_err:
+	platform_driver_unregister(&cam_ois_platform_driver);
+
 	return rc;
 }
 
 void cam_ois_driver_exit(void)
 {
-	if (registered_driver.platform_driver)
-		platform_driver_unregister(&cam_ois_platform_driver);
-
-	if (registered_driver.i2c_driver)
-		i2c_del_driver(&cam_ois_i2c_driver);
+	platform_driver_unregister(&cam_ois_platform_driver);
+	i2c_del_driver(&cam_ois_i2c_driver);
+	i3c_driver_unregister(&cam_ois_i3c_driver);
 }
 
 MODULE_DESCRIPTION("CAM OIS driver");

+ 1 - 11
drivers/cam_sensor_module/cam_ois/cam_ois_dev.h

@@ -27,6 +27,7 @@
 	static struct mutex mutexname = __MUTEX_INITIALIZER(mutexname)
 
 #define OIS_DRIVER_I2C "cam-i2c-ois"
+#define OIS_DRIVER_I3C "i3c_camera_ois"
 
 enum cam_ois_state {
 	CAM_OIS_INIT,
@@ -35,17 +36,6 @@ enum cam_ois_state {
 	CAM_OIS_START,
 };
 
-/**
- * struct cam_ois_registered_driver_t - registered driver info
- * @platform_driver      :   flag indicates if platform driver is registered
- * @i2c_driver           :   flag indicates if i2c driver is registered
- *
- */
-struct cam_ois_registered_driver_t {
-	bool platform_driver;
-	bool i2c_driver;
-};
-
 /**
  * struct cam_ois_i2c_info_t - I2C info
  * @slave_addr      :   slave address

+ 8 - 20
drivers/cam_sensor_module/cam_sensor/cam_sensor_core.c

@@ -866,9 +866,7 @@ int32_t cam_sensor_driver_cmd(struct cam_sensor_ctrl_t *s_ctrl,
 	struct cam_sensor_power_ctrl_t *power_info =
 		&s_ctrl->sensordata->power_info;
 	struct timespec64 ts;
-	struct completion *i3c_probe_completion;
 	uint64_t ms, sec, min, hrs;
-	long time_left;
 
 	if (!s_ctrl || !arg) {
 		CAM_ERR(CAM_SENSOR, "s_ctrl is NULL");
@@ -943,6 +941,7 @@ int32_t cam_sensor_driver_cmd(struct cam_sensor_ctrl_t *s_ctrl,
 				);
 			goto free_power_settings;
 		}
+
 		if (s_ctrl->i2c_data.reg_bank_unlock_settings.is_settings_valid) {
 			rc = cam_sensor_apply_settings(s_ctrl, 0,
 				CAM_SENSOR_PACKET_OPCODE_SENSOR_REG_BANK_UNLOCK);
@@ -958,20 +957,6 @@ int32_t cam_sensor_driver_cmd(struct cam_sensor_ctrl_t *s_ctrl,
 			}
 		}
 
-		if (s_ctrl->io_master_info.master_type == I3C_MASTER) {
-			i3c_probe_completion =
-				cam_sensor_get_i3c_completion(s_ctrl->soc_info.index);
-
-			time_left = cam_common_wait_for_completion_timeout(
-					i3c_probe_completion,
-					msecs_to_jiffies(CAM_SENSOR_I3C_PROBE_TIMEOUT_MS));
-			if (!time_left) {
-				CAM_ERR(CAM_SENSOR, "Wait for I3C probe timedout for %s",
-					s_ctrl->sensor_name);
-				return -ETIMEDOUT;
-			}
-		}
-
 		/* Match sensor ID */
 		rc = cam_sensor_match_id(s_ctrl);
 		if (rc < 0) {
@@ -1428,9 +1413,9 @@ int cam_sensor_power_up(struct cam_sensor_ctrl_t *s_ctrl)
 {
 	int rc;
 	struct cam_sensor_power_ctrl_t *power_info;
-	struct cam_camera_slave_info *slave_info;
-	struct cam_hw_soc_info *soc_info =
-		&s_ctrl->soc_info;
+	struct cam_camera_slave_info   *slave_info;
+	struct cam_hw_soc_info         *soc_info = &s_ctrl->soc_info;
+	struct completion              *i3c_probe_completion = NULL;
 
 	if (!s_ctrl) {
 		CAM_ERR(CAM_SENSOR, "failed: %pK", s_ctrl);
@@ -1469,7 +1454,10 @@ int cam_sensor_power_up(struct cam_sensor_ctrl_t *s_ctrl)
 		}
 	}
 
-	rc = cam_sensor_core_power_up(power_info, soc_info);
+	if (s_ctrl->io_master_info.master_type == I3C_MASTER)
+		i3c_probe_completion = cam_sensor_get_i3c_completion(s_ctrl->soc_info.index);
+
+	rc = cam_sensor_core_power_up(power_info, soc_info, i3c_probe_completion);
 	if (rc < 0) {
 		CAM_ERR(CAM_SENSOR, "core power up failed:%d", rc);
 		return rc;

+ 1 - 1
drivers/cam_sensor_module/cam_sensor/cam_sensor_dev.c

@@ -572,7 +572,7 @@ static struct i3c_device_id sensor_i3c_id[MAX_I3C_DEVICE_ID_ENTRIES + 1];
 static struct i3c_driver cam_sensor_i3c_driver = {
 	.id_table = sensor_i3c_id,
 	.probe = cam_sensor_i3c_driver_probe,
-	.remove = cam_sensor_i3c_driver_remove,
+	.remove = cam_i3c_driver_remove,
 	.driver = {
 		.owner = THIS_MODULE,
 		.name = SENSOR_DRIVER_I3C,

+ 26 - 2
drivers/cam_sensor_module/cam_sensor_io/cam_sensor_qup_i3c.c

@@ -12,6 +12,7 @@ static int cam_qup_i3c_rxdata(struct i3c_device *dev_client, unsigned char *rxda
 	enum camera_sensor_i2c_type addr_type, int data_length)
 {
 	int rc;
+	uint32_t us = 0;
 	struct i3c_priv_xfer read_buf[2] = {
 		{
 			.rnw = 0,
@@ -26,7 +27,18 @@ static int cam_qup_i3c_rxdata(struct i3c_device *dev_client, unsigned char *rxda
 	};
 
 	rc = i3c_device_do_priv_xfers(dev_client, read_buf, ARRAY_SIZE(read_buf));
-	if (rc)
+	if (rc == -ENOTCONN) {
+		while (us < CAM_I3C_DEV_PROBE_TIMEOUT_US) {
+			usleep_range(1000, 1005);
+			rc = i3c_device_do_priv_xfers(dev_client, read_buf, ARRAY_SIZE(read_buf));
+			if (rc != -ENOTCONN)
+				break;
+			us += 1000;
+		}
+
+		if (rc)
+			CAM_ERR(CAM_SENSOR, "Retry Failed i3c_read: rc = %d, us = %d", rc, us);
+	} else if (rc)
 		CAM_ERR(CAM_SENSOR, "Failed with i3c_read: rc = %d", rc);
 
 	return rc;
@@ -37,6 +49,7 @@ static int cam_qup_i3c_txdata(struct camera_io_master *dev_client, unsigned char
 	int length)
 {
 	int rc;
+	uint32_t us = 0;
 	struct i3c_priv_xfer write_buf = {
 		.rnw = 0,
 		.len = length,
@@ -44,7 +57,18 @@ static int cam_qup_i3c_txdata(struct camera_io_master *dev_client, unsigned char
 	};
 
 	rc = i3c_device_do_priv_xfers(dev_client->i3c_client, &write_buf, 1);
-	if (rc)
+	if (rc == -ENOTCONN) {
+		while (us < CAM_I3C_DEV_PROBE_TIMEOUT_US) {
+			usleep_range(1000, 1005);
+			rc = i3c_device_do_priv_xfers(dev_client->i3c_client, &write_buf, 1);
+			if (rc != -ENOTCONN)
+				break;
+			us += 1000;
+		}
+
+		if (rc)
+			CAM_ERR(CAM_SENSOR, "Retry Failed i3c_write: rc = %d, us = %d", rc, us);
+	} else if (rc)
 		CAM_ERR(CAM_SENSOR, "Failed with i3c_write: rc = %d", rc);
 
 	return rc;

+ 2 - 1
drivers/cam_sensor_module/cam_sensor_utils/cam_sensor_cmn_header.h

@@ -23,7 +23,8 @@
 #define MAX_POWER_CONFIG                       12
 #define MAX_PER_FRAME_ARRAY                    32
 #define BATCH_SIZE_MAX                         16
-#define CAM_SENSOR_I3C_PROBE_TIMEOUT_MS        10
+#define CAM_I3C_DEV_PROBE_TIMEOUT_MS           10
+#define CAM_I3C_DEV_PROBE_TIMEOUT_US          (CAM_I3C_DEV_PROBE_TIMEOUT_MS * 1000)
 #define I3C_SENSOR_DEV_ID_DT_PATH              "/soc/qcom,cam-i3c-id-table"
 #define MAX_I3C_DEVICE_ID_ENTRIES              MAX_CAMERAS
 

+ 13 - 1
drivers/cam_sensor_module/cam_sensor_utils/cam_sensor_util.c

@@ -1977,12 +1977,13 @@ static int cam_config_mclk_reg(struct cam_sensor_power_ctrl_t *ctrl,
 }
 
 int cam_sensor_core_power_up(struct cam_sensor_power_ctrl_t *ctrl,
-		struct cam_hw_soc_info *soc_info)
+		struct cam_hw_soc_info *soc_info, struct completion *i3c_probe_status)
 {
 	int rc = 0, index = 0, no_gpio = 0, ret = 0, num_vreg, j = 0, i = 0;
 	int32_t vreg_idx = -1;
 	struct cam_sensor_power_setting *power_setting = NULL;
 	struct msm_camera_gpio_num_info *gpio_num_info = NULL;
+	long                                    time_left;
 
 	CAM_DBG(CAM_SENSOR, "Enter");
 	if (!ctrl) {
@@ -2195,6 +2196,17 @@ int cam_sensor_core_power_up(struct cam_sensor_power_ctrl_t *ctrl,
 				(power_setting->delay * 1000) + 1000);
 	}
 
+	if (i3c_probe_status) {
+		time_left = cam_common_wait_for_completion_timeout(
+			i3c_probe_status,
+			msecs_to_jiffies(CAM_I3C_DEV_PROBE_TIMEOUT_MS));
+		if (!time_left) {
+			CAM_ERR(CAM_SENSOR, "Wait for I3C probe timedout");
+			rc = -ETIMEDOUT;
+			goto power_up_failed;
+		}
+	}
+
 	return 0;
 power_up_failed:
 	CAM_ERR(CAM_SENSOR, "failed. rc:%d", rc);

+ 1 - 1
drivers/cam_sensor_module/cam_sensor_utils/cam_sensor_util.h

@@ -66,7 +66,7 @@ int cam_sensor_util_init_gpio_pin_tbl(
 	struct cam_hw_soc_info *soc_info,
 	struct msm_camera_gpio_num_info **pgpio_num_info);
 int cam_sensor_core_power_up(struct cam_sensor_power_ctrl_t *ctrl,
-		struct cam_hw_soc_info *soc_info);
+		struct cam_hw_soc_info *soc_info, struct completion *i3c_probe_status);
 
 int cam_sensor_util_power_down(struct cam_sensor_power_ctrl_t *ctrl,
 		struct cam_hw_soc_info *soc_info);

+ 98 - 2
drivers/cam_utils/cam_compat.c

@@ -9,11 +9,107 @@
 #include <linux/of_address.h>
 #include <linux/slab.h>
 
+#include <soc/qcom/rpmh.h>
+
 #include "cam_compat.h"
 #include "cam_debug_util.h"
 #include "cam_cpas_api.h"
 #include "camera_main.h"
 
+#if IS_ENABLED(CONFIG_USE_RPMH_DRV_API)
+#define CAM_RSC_DRV_IDENTIFIER "cam_rsc"
+
+const struct device *cam_cpas_get_rsc_dev_for_drv(uint32_t index)
+{
+	const struct device *rsc_dev;
+
+	rsc_dev = rpmh_get_device(CAM_RSC_DRV_IDENTIFIER, index);
+	if (!rsc_dev) {
+		CAM_ERR(CAM_CPAS, "Invalid dev for index: %u", index);
+		return NULL;
+	}
+
+	return rsc_dev;
+}
+
+int cam_cpas_start_drv_for_dev(const struct device *dev)
+{
+	int rc = 0;
+
+	if (!dev) {
+		CAM_ERR(CAM_CPAS, "Invalid dev for DRV enable");
+		return -EINVAL;
+	}
+
+	rc = rpmh_drv_start(dev);
+	if (rc) {
+		CAM_ERR(CAM_CPAS, "[%s] Failed in DRV start", dev_name(dev));
+		return rc;
+	}
+
+	return rc;
+}
+
+int cam_cpas_stop_drv_for_dev(const struct device *dev)
+{
+	int rc = 0;
+
+	if (!dev) {
+		CAM_ERR(CAM_CPAS, "Invalid dev for DRV disable");
+		return -EINVAL;
+	}
+
+	rc = rpmh_drv_stop(dev);
+	if (rc) {
+		CAM_ERR(CAM_CPAS, "[%s] Failed in DRV stop", dev_name(dev));
+		return rc;
+	}
+
+	return rc;
+}
+
+int cam_cpas_drv_channel_switch_for_dev(const struct device *dev)
+{
+	int rc = 0;
+
+	if (!dev) {
+		CAM_ERR(CAM_CPAS, "Invalid dev for DRV channel switch");
+		return -EINVAL;
+	}
+
+	rc = rpmh_write_sleep_and_wake_no_child(dev);
+	if (rc) {
+		CAM_ERR(CAM_CPAS, "[%s] Failed in DRV channel switch", dev_name(dev));
+		return rc;
+	}
+
+	return rc;
+}
+
+#else
+const struct device *cam_cpas_get_rsc_dev_for_drv(uint32_t index)
+{
+	return NULL;
+}
+
+int cam_cpas_start_drv_for_dev(const struct device *dev)
+
+{
+	return 0;
+}
+
+int cam_cpas_stop_drv_for_dev(const struct device *dev)
+{
+	return 0;
+}
+
+int cam_cpas_drv_channel_switch_for_dev(const struct device *dev)
+{
+	return 0;
+}
+#endif
+
+
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0)
 int cam_reserve_icp_fw(struct cam_fw_alloc_info *icp_fw, size_t fw_length)
 {
@@ -366,7 +462,7 @@ void cam_compat_util_put_dmabuf_va(struct dma_buf *dmabuf, void *vaddr)
 	dma_buf_vunmap(dmabuf, &mapping);
 }
 
-void cam_sensor_i3c_driver_remove(struct i3c_device *client)
+void cam_i3c_driver_remove(struct i3c_device *client)
 {
 	CAM_DBG(CAM_SENSOR, "I3C remove invoked for %s",
 		(client ? dev_name(&client->dev) : "none"));
@@ -411,7 +507,7 @@ void cam_compat_util_put_dmabuf_va(struct dma_buf *dmabuf, void *vaddr)
 	dma_buf_vunmap(dmabuf, vaddr);
 }
 
-int cam_sensor_i3c_driver_remove(struct i3c_device *client)
+int cam_i3c_driver_remove(struct i3c_device *client)
 {
 	CAM_DBG(CAM_SENSOR, "I3C remove invoked for %s",
 		(client ? dev_name(&client->dev) : "none"));

+ 10 - 2
drivers/cam_utils/cam_compat.h

@@ -55,14 +55,22 @@ void cam_compat_util_put_dmabuf_va(struct dma_buf *dmabuf, void *vaddr);
 void cam_smmu_util_iommu_custom(struct device *dev,
 	dma_addr_t discard_start, size_t discard_length);
 
+const struct device *cam_cpas_get_rsc_dev_for_drv(uint32_t index);
+
+int cam_cpas_start_drv_for_dev(const struct device *dev);
+
+int cam_cpas_stop_drv_for_dev(const struct device *dev);
+
+int cam_cpas_drv_channel_switch_for_dev(const struct device *dev);
+
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 15, 0)
 int cam_req_mgr_ordered_list_cmp(void *priv,
 	const struct list_head *head_1, const struct list_head *head_2);
-void cam_sensor_i3c_driver_remove(struct i3c_device *client);
+void cam_i3c_driver_remove(struct i3c_device *client);
 #else
 int cam_req_mgr_ordered_list_cmp(void *priv,
 	struct list_head *head_1, struct list_head *head_2);
-int cam_sensor_i3c_driver_remove(struct i3c_device *client);
+int cam_i3c_driver_remove(struct i3c_device *client);
 #endif
 
 long cam_dma_buf_set_name(struct dma_buf *dmabuf, const char *name);

+ 3 - 1
drivers/cam_utils/cam_soc_bus.c

@@ -1,6 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
  * Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #include <linux/msm-bus.h>
@@ -65,7 +66,8 @@ end:
 	return rc;
 }
 
-int cam_soc_bus_client_update_bw(void *client, uint64_t ab, uint64_t ib)
+int cam_soc_bus_client_update_bw(void *client, uint64_t ab, uint64_t ib,
+	enum cam_soc_bus_path_data bus_path_data)
 {
 	int idx = 0;
 	struct msm_bus_paths *path;

+ 23 - 4
drivers/cam_utils/cam_soc_bus.h

@@ -1,6 +1,7 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
 /*
  * Copyright (c) 2019, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #ifndef _CAM_SOC_BUS_H_
@@ -10,9 +11,17 @@
 #include <linux/slab.h>
 #include <linux/platform_device.h>
 #include "cam_debug_util.h"
+#include "cam_cpas.h"
 
 #define CAM_SOC_BUS_MAX_NUM_USECASES 8
 
+enum cam_soc_bus_path_data {
+	CAM_SOC_BUS_PATH_DATA_HLOS,
+	CAM_SOC_BUS_PATH_DATA_DRV_HIGH,
+	CAM_SOC_BUS_PATH_DATA_DRV_LOW,
+	CAM_SOC_BUS_PATH_DATA_MAX,
+};
+
 /**
  * struct cam_soc_bus_client_ab_ib : Bandwidth values for selected usecase
  *
@@ -30,6 +39,7 @@ struct cam_soc_bus_client_ab_ib {
  * @name: Name of bus client
  * @src_id: Bus master/src id
  * @dst_id: Bus slave/dst id
+ * @is_drv_port: If DRV bus client
  * @num_usecases: Number of use cases for this client
  * @bw_pair: Bandwidth values for applicable usecases
  */
@@ -37,6 +47,7 @@ struct cam_soc_bus_client_common_data {
 	const char *name;
 	uint32_t src_id;
 	uint32_t dst_id;
+	bool is_drv_port;
 	int num_usecases;
 	struct cam_soc_bus_client_ab_ib bw_pair[CAM_SOC_BUS_MAX_NUM_USECASES];
 };
@@ -56,10 +67,12 @@ struct cam_soc_bus_client {
 #if IS_REACHABLE(CONFIG_QCOM_BUS_SCALING) || \
 	IS_REACHABLE(CONFIG_INTERCONNECT_QCOM)
 
+const char *cam_soc_bus_path_data_to_str(enum cam_soc_bus_path_data bus_path_data);
+
 int cam_soc_bus_client_update_request(void *client, unsigned int idx);
 
-int cam_soc_bus_client_update_bw(void *client, uint64_t ab,
-	uint64_t ib);
+int cam_soc_bus_client_update_bw(void *client, uint64_t ab, uint64_t ib,
+	enum cam_soc_bus_path_data bus_path_data);
 
 int cam_soc_bus_client_register(struct platform_device *pdev,
 	struct device_node *dev_node, void **client,
@@ -68,14 +81,20 @@ int cam_soc_bus_client_register(struct platform_device *pdev,
 void cam_soc_bus_client_unregister(void **client);
 
 #else
+
+static const char *cam_soc_bus_path_data_to_str(enum cam_soc_bus_path_data bus_path_data)
+{
+	return NULL;
+}
+
 static inline int cam_soc_bus_client_update_request(void *client,
 	unsigned int idx)
 {
 	return 0;
 }
 
-static inline int cam_soc_bus_client_update_bw(void *client,
-	uint64_t ab, uint64_t ib)
+int cam_soc_bus_client_update_bw(void *client, uint64_t ab, uint64_t ib,
+	enum cam_soc_bus_path_data bus_path_data)
 {
 	return 0;
 }

+ 111 - 38
drivers/cam_utils/cam_soc_icc.c

@@ -1,9 +1,11 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
  * Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #include <linux/interconnect.h>
+#include <dt-bindings/interconnect/qcom,icc.h>
 #include "cam_soc_bus.h"
 
 /**
@@ -12,9 +14,22 @@
  * @icc_data: Bus icc path information
  */
 struct cam_soc_bus_client_data {
-	struct icc_path *icc_data;
+	struct icc_path *icc_data[CAM_SOC_BUS_PATH_DATA_MAX];
 };
 
+const char *cam_soc_bus_path_data_to_str(enum cam_soc_bus_path_data bus_path_data)
+{
+	switch (bus_path_data) {
+	case CAM_SOC_BUS_PATH_DATA_HLOS:
+		return "BUS_PATH_HLOS";
+	case CAM_SOC_BUS_PATH_DATA_DRV_HIGH:
+		return "BUS_PATH_DRV_HIGH";
+	case CAM_SOC_BUS_PATH_DATA_DRV_LOW:
+		return "BUS_PATH_DRV_LOW";
+	default:
+		return "BUS_PATH_INVALID";
+	}
+}
 int cam_soc_bus_client_update_request(void *client, unsigned int idx)
 {
 	int rc = 0;
@@ -37,7 +52,7 @@ int cam_soc_bus_client_update_request(void *client, unsigned int idx)
 	CAM_DBG(CAM_PERF, "Bus client=[%s] index[%d] ab[%llu] ib[%llu]",
 		bus_client->common_data->name, idx, ab, ib);
 
-	rc = icc_set_bw(bus_client_data->icc_data, Bps_to_icc(ab),
+	rc = icc_set_bw(bus_client_data->icc_data[CAM_SOC_BUS_PATH_DATA_HLOS], Bps_to_icc(ab),
 		Bps_to_icc(ib));
 	if (rc) {
 		CAM_ERR(CAM_UTIL,
@@ -50,26 +65,29 @@ end:
 	return rc;
 }
 
-int cam_soc_bus_client_update_bw(void *client, uint64_t ab, uint64_t ib)
+int cam_soc_bus_client_update_bw(void *client, uint64_t ab, uint64_t ib,
+	enum cam_soc_bus_path_data bus_path_data)
 {
-	struct cam_soc_bus_client *bus_client =
-		(struct cam_soc_bus_client *) client;
-	struct cam_soc_bus_client_data *bus_client_data =
-		(struct cam_soc_bus_client_data *) bus_client->client_data;
-	int rc = 0;
-
-	CAM_DBG(CAM_PERF, "Bus client=[%s] :ab[%llu] ib[%llu]",
-		bus_client->common_data->name, ab, ib);
-	rc = icc_set_bw(bus_client_data->icc_data, Bps_to_icc(ab),
-		Bps_to_icc(ib));
-	if (rc) {
-		CAM_ERR(CAM_UTIL, "Update request failed, client[%s]",
-			bus_client->common_data->name);
-		goto end;
-	}
+		struct cam_soc_bus_client *bus_client =
+			(struct cam_soc_bus_client *) client;
+		struct cam_soc_bus_client_data *bus_client_data =
+			(struct cam_soc_bus_client_data *) bus_client->client_data;
+		int rc = 0;
+
+		CAM_DBG(CAM_PERF, "Bus client=[%s] [%s] :ab[%llu] ib[%llu]",
+			bus_client->common_data->name, cam_soc_bus_path_data_to_str(bus_path_data),
+			ab, ib);
+		rc = icc_set_bw(bus_client_data->icc_data[bus_path_data], Bps_to_icc(ab),
+			Bps_to_icc(ib));
+		if (rc) {
+			CAM_ERR(CAM_UTIL, "Update request failed, client[%s]",
+				bus_client->common_data->name);
+			goto end;
+		}
 
 end:
 	return rc;
+
 }
 
 int cam_soc_bus_client_register(struct platform_device *pdev,
@@ -89,8 +107,7 @@ int cam_soc_bus_client_register(struct platform_device *pdev,
 
 	*client = bus_client;
 
-	bus_client_data = kzalloc(sizeof(struct cam_soc_bus_client_data),
-		GFP_KERNEL);
+	bus_client_data = kzalloc(sizeof(struct cam_soc_bus_client_data), GFP_KERNEL);
 	if (!bus_client_data) {
 		kfree(bus_client);
 		*client = NULL;
@@ -100,30 +117,80 @@ int cam_soc_bus_client_register(struct platform_device *pdev,
 
 	bus_client->client_data = bus_client_data;
 	bus_client->common_data = common_data;
-	bus_client_data->icc_data = icc_get(&pdev->dev,
-		bus_client->common_data->src_id,
-		bus_client->common_data->dst_id);
-	if (IS_ERR_OR_NULL(bus_client_data->icc_data)) {
-		CAM_ERR(CAM_UTIL, "failed in register bus client");
-		rc = -EINVAL;
-		goto error;
+	if (bus_client->common_data->is_drv_port) {
+		bus_client_data->icc_data[CAM_SOC_BUS_PATH_DATA_DRV_HIGH] = icc_get(&pdev->dev,
+			bus_client->common_data->src_id, bus_client->common_data->dst_id);
+		if (IS_ERR_OR_NULL(bus_client_data->icc_data[CAM_SOC_BUS_PATH_DATA_DRV_HIGH])) {
+			CAM_ERR(CAM_UTIL,
+				"Failed to register DRV bus client Bus Client=[%s] : src=%d, dst=%d bus_path:%d",
+				bus_client->common_data->src_id, bus_client->common_data->dst_id,
+				CAM_SOC_BUS_PATH_DATA_DRV_HIGH);
+			rc = -EINVAL;
+			goto error;
+		}
+
+		bus_client_data->icc_data[CAM_SOC_BUS_PATH_DATA_DRV_LOW] = icc_get(&pdev->dev,
+			bus_client->common_data->src_id, bus_client->common_data->dst_id);
+		if (IS_ERR_OR_NULL(bus_client_data->icc_data[CAM_SOC_BUS_PATH_DATA_DRV_LOW])) {
+			CAM_ERR(CAM_UTIL,
+				"Failed to register DRV bus client Bus Client=[%s] : src=%d, dst=%d bus_path:%d",
+				bus_client->common_data->src_id, bus_client->common_data->dst_id,
+				CAM_SOC_BUS_PATH_DATA_DRV_LOW);
+			rc = -EINVAL;
+			goto error;
+		}
+
+		/* Set appropriate tags for HIGH and LOW vote paths */
+		icc_set_tag(bus_client_data->icc_data[CAM_SOC_BUS_PATH_DATA_DRV_HIGH],
+			QCOM_ICC_TAG_ACTIVE_ONLY);
+		icc_set_tag(bus_client_data->icc_data[CAM_SOC_BUS_PATH_DATA_DRV_LOW],
+			QCOM_ICC_TAG_SLEEP);
+
+		rc = icc_set_bw(bus_client_data->icc_data[CAM_SOC_BUS_PATH_DATA_DRV_HIGH], 0, 0);
+		if (rc) {
+			CAM_ERR(CAM_UTIL, "Bus client[%s] update request failed, rc = %d",
+				bus_client->common_data->name, rc);
+			goto fail_unregister_client;
+		}
+
+		rc = icc_set_bw(bus_client_data->icc_data[CAM_SOC_BUS_PATH_DATA_DRV_LOW], 0, 0);
+		if (rc) {
+			CAM_ERR(CAM_UTIL, "Bus client[%s] update request failed, rc = %d",
+				bus_client->common_data->name, rc);
+			goto fail_unregister_client;
+		}
+	} else {
+		bus_client_data->icc_data[CAM_SOC_BUS_PATH_DATA_HLOS] = icc_get(&pdev->dev,
+			bus_client->common_data->src_id, bus_client->common_data->dst_id);
+		if (IS_ERR_OR_NULL(bus_client_data->icc_data[CAM_SOC_BUS_PATH_DATA_HLOS])) {
+			CAM_ERR(CAM_UTIL, "failed to register HLOS bus client");
+			rc = -EINVAL;
+			goto error;
+		}
+
+		rc = icc_set_bw(bus_client_data->icc_data[CAM_SOC_BUS_PATH_DATA_HLOS], 0, 0);
+		if (rc) {
+			CAM_ERR(CAM_UTIL, "Bus client[%s] update request failed, rc = %d",
+				bus_client->common_data->name, rc);
+			goto fail_unregister_client;
+		}
 	}
 
-	rc = icc_set_bw(bus_client_data->icc_data, 0, 0);
-	if (rc) {
-		CAM_ERR(CAM_UTIL, "Bus client update request failed, rc = %d",
-			rc);
-		goto fail_unregister_client;
-	}
-
-	CAM_DBG(CAM_PERF, "Register Bus Client=[%s] : src=%d, dst=%d",
+	CAM_DBG(CAM_PERF, "Register Bus Client=[%s] : src=%d, dst=%d is_drv_port:%s",
 		bus_client->common_data->name, bus_client->common_data->src_id,
-		bus_client->common_data->dst_id);
+		bus_client->common_data->dst_id,
+		CAM_BOOL_TO_YESNO(bus_client->common_data->is_drv_port));
 
 	return 0;
 
 fail_unregister_client:
-	icc_put(bus_client_data->icc_data);
+	if (bus_client->common_data->is_drv_port) {
+		icc_put(bus_client_data->icc_data[CAM_SOC_BUS_PATH_DATA_DRV_HIGH]);
+		icc_put(bus_client_data->icc_data[CAM_SOC_BUS_PATH_DATA_DRV_LOW]);
+	} else {
+		icc_put(bus_client_data->icc_data[CAM_SOC_BUS_PATH_DATA_HLOS]);
+	}
+
 error:
 	kfree(bus_client_data);
 	bus_client->client_data = NULL;
@@ -141,7 +208,13 @@ void cam_soc_bus_client_unregister(void **client)
 	struct cam_soc_bus_client_data *bus_client_data =
 		(struct cam_soc_bus_client_data *) bus_client->client_data;
 
-	icc_put(bus_client_data->icc_data);
+	if (bus_client->common_data->is_drv_port) {
+		icc_put(bus_client_data->icc_data[CAM_SOC_BUS_PATH_DATA_DRV_HIGH]);
+		icc_put(bus_client_data->icc_data[CAM_SOC_BUS_PATH_DATA_DRV_LOW]);
+	} else {
+		icc_put(bus_client_data->icc_data[CAM_SOC_BUS_PATH_DATA_HLOS]);
+	}
+
 	kfree(bus_client_data);
 	bus_client->client_data = NULL;
 	kfree(bus_client);

Some files were not shown because too many files changed in this diff