Преглед изворни кода

msm: camera: icp: Support multiple HFIs

During probe, each hw mgr register as a client to HFI layer and share
the handle to icp core layer to book keep. HFI register routine searches
for a free hfi slot to dynamically allocated hfi info struct and returns
a client handle to the caller. During open sequence, HW mgr is required to
initialize the hfi using the handle obtained from the registering in boot
up. Upon unregistering, the hfi slot and the hfi info memory is freed.
Hw mgr layer can invoke the existing hfi interfaces by passing hfi handle
to fetch the right hfi info. With this change, each hw mgr can
independently run on one HFI to interact with FW.

Add support in enabling OFE PC and config OFE UBWC in hfi layer, and parse
OFE UBWC config values from DT.

CRs-Fixed: 3338951
Change-Id: Iec2358fef124e9c169d06df79ce31b65a9b80d40
Signed-off-by: Sokchetra Eung <[email protected]>
Sokchetra Eung пре 2 година
родитељ
комит
96ff2ea80b

+ 61 - 26
drivers/cam_icp/fw_inc/hfi_intf.h

@@ -12,6 +12,9 @@
 #define HFI_CMD_Q_MINI_DUMP_SIZE_IN_BYTES      4096
 #define HFI_MSG_Q_MINI_DUMP_SIZE_IN_BYTES      4096
 
+#define HFI_NUM_MAX                            2
+#define HFI_HANDLE_INIT_VALUE                  HFI_NUM_MAX
+
 /**
  * struct hfi_mem
  * @len: length of memory
@@ -84,14 +87,16 @@ struct hfi_mini_dump_info {
 };
 /**
  * hfi_write_cmd() - function for hfi write
+ * @client_handle: client handle
  * @cmd_ptr: pointer to command data for hfi write
  *
  * Returns success(zero)/failure(non zero)
  */
-int hfi_write_cmd(void *cmd_ptr);
+int hfi_write_cmd(int client_handle, void *cmd_ptr);
 
 /**
  * hfi_read_message() - function for hfi read
+ * @client_handle: client handle
  * @pmsg: buffer to place read message for hfi queue
  * @q_id: queue id
  * @words_read: total number of words read from the queue
@@ -99,10 +104,11 @@ int hfi_write_cmd(void *cmd_ptr);
  *
  * Returns success(zero)/failure(non zero)
  */
-int hfi_read_message(uint32_t *pmsg, uint8_t q_id, uint32_t *words_read);
+int hfi_read_message(int client_handle, uint32_t *pmsg, uint8_t q_id, uint32_t *words_read);
 
 /**
  * hfi_init() - function initialize hfi after firmware download
+ * @client_handle: client handle
  * @hfi_mem: hfi memory info
  * @hfi_ops: processor-specific hfi ops
  * @priv: device private data
@@ -110,8 +116,24 @@ int hfi_read_message(uint32_t *pmsg, uint8_t q_id, uint32_t *words_read);
  *
  * Returns success(zero)/failure(non zero)
  */
-int cam_hfi_init(struct hfi_mem_info *hfi_mem, const struct hfi_ops *hfi_ops,
-		void *priv, uint8_t event_driven_mode);
+int cam_hfi_init(int client_handle, struct hfi_mem_info *hfi_mem,
+	const struct hfi_ops *hfi_ops, void *priv, uint8_t event_driven_modem);
+
+/**
+ * cam_hfi_register() - function to register user as hfi client and retrieve handle
+ * @client_handle: client handle to be retrieved
+ *
+ * Returns success(zero)/failure(non zero)
+ */
+int cam_hfi_register(int *client_handle);
+
+/**
+ * cam_hfi_unregister() - function to unregister hfi client
+ * @client_handle: client handle
+ *
+ * Returns success(zero)/failure(non zero)
+ */
+int cam_hfi_unregister(int *client_handle);
 
 /**
  * hfi_get_hw_caps() - hardware capabilities from firmware
@@ -123,79 +145,92 @@ int hfi_get_hw_caps(void *query_caps);
 
 /**
  * hfi_send_system_cmd() - send hfi system command to firmware
+ * @client_handle: client handle
  * @type: type of system command
  * @data: command data
  * @size: size of command data
+ *
+ * Returns success(zero)/failure(non zero)
  */
-void hfi_send_system_cmd(uint32_t type, uint64_t data, uint32_t size);
+int hfi_send_system_cmd(int client_handle, uint32_t type, uint64_t data, uint32_t size);
 
 /**
  * cam_hfi_deinit() - cleanup HFI
+ * @client_handle: client handle to be retrieved
  */
-void cam_hfi_deinit(void);
+void cam_hfi_deinit(int client_handle);
 /**
  * hfi_set_debug_level() - set debug level
+ * @client_handle: client handle to be retrieved
  * @icp_dbg_type: 1 for debug_q & 2 for qdss
  * @lvl: FW debug message level
+ *
+ * Returns success(zero)/failure(non zero)
  */
-int hfi_set_debug_level(u64 icp_dbg_type, uint32_t lvl);
+int hfi_set_debug_level(int client_handle, u64 icp_dbg_type, uint32_t lvl);
 
 /**
  * hfi_set_fw_dump_levels() - set firmware hang dump/ramdump levels
+ * @client_handle: client handle to be retrieved
  * @hang_dump_lvl : level of firmware hang dump
  * @ram_dump_lvl  : level of firmware ram dump
+ *
+ * Returns success(zero)/failure(non zero)
  */
-int hfi_set_fw_dump_levels(uint32_t hang_dump_lvl, uint32_t ram_dump_lvl);
+int hfi_set_fw_dump_levels(int client_handle,
+	uint32_t hang_dump_lvl, uint32_t ram_dump_lvl);
 
 /**
  * hfi_send_freq_info() - set firmware dump level
+ * @client_handle: client handle to be retrieved
  * @freq: icp freq
- */
-int hfi_send_freq_info(int32_t freq);
-
-/**
- * hfi_enable_dev_pc() - Enable interframe pc
- * Host sends a command to firmware to enable interframe
- * power collapse for ICP's controlled hardware.
  *
- * @enable: flag to enable/disable
- * @core_info: Core information to firmware
+ * Returns success(zero)/failure(non zero)
  */
-int hfi_enable_dev_pc(bool enable, uint32_t core_info);
+int hfi_send_freq_info(int client_handle, int32_t freq);
 
 /**
  * hfi_cmd_ubwc_config_ext() - UBWC configuration to firmware
+ * @client_handle: client handle to be retrieved
  * @ubwc_ipe_cfg: UBWC ipe fetch/write configuration params
  * @ubwc_bps_cfg: UBWC bps fetch/write configuration params
+ * @ubwc_ofe_cfg: UBWC ofe fetch/write configuration params
+ *
+ * Returns success(zero)/failure(non zero)
  */
-int hfi_cmd_ubwc_config_ext(uint32_t *ubwc_ipe_cfg,
-	uint32_t *ubwc_bps_cfg);
+int hfi_cmd_ubwc_config_ext(int client_handle, uint32_t *ubwc_ipe_cfg,
+	uint32_t *ubwc_bps_cfg, uint32_t *ubwc_ofe_cfg);
 
 /**
  * hfi_cmd_ubwc_config() - UBWC configuration to firmware
  *                         for older targets
+ * @client_handle: client handle to be retrieved
  * @ubwc_cfg: UBWC configuration parameters
+ *
+ * Returns success(zero)/failure(non zero)
  */
-int hfi_cmd_ubwc_config(uint32_t *ubwc_cfg);
+int hfi_cmd_ubwc_config(int client_handle, uint32_t *ubwc_cfg);
 
 /**
  * cam_hfi_resume() - function to resume
- * @hfi_mem: hfi memory info
+ * @client_handle: client handle to be retrieved
  *
  * Returns success(zero)/failure(non zero)
  */
-int cam_hfi_resume(struct hfi_mem_info *hfi_mem);
+int cam_hfi_resume(int client_handle);
 
 /**
  * cam_hfi_queue_dump() - utility function to dump hfi queues
+ * @client_handle: client handle to be retrieved
  * @dump_queue_data: if set dumps queue contents
- *
  */
-void cam_hfi_queue_dump(bool dump_queue_data);
+void cam_hfi_queue_dump(int client_handle, bool dump_queue_data);
 
 /**
  * cam_hfi_mini_dump() - utility function for mini dump
+ * @client_handle: client handle to be retrieved
+ * @dst: memory destination
  */
-void cam_hfi_mini_dump(struct hfi_mini_dump_info *dst);
+void cam_hfi_mini_dump(int client_handle, struct hfi_mini_dump_info *dst);
 
 #endif /* _HFI_INTF_H_ */

+ 4 - 0
drivers/cam_icp/fw_inc/hfi_reg.h

@@ -72,6 +72,10 @@
 #define U32_OFFSET                              0x1
 #define BYTE_WORD_SHIFT                         2
 
+#define HFI_GET_CLIENT_HANDLE(idx) (idx)
+#define HFI_GET_INDEX(client_handle) (client_handle)
+#define IS_VALID_HFI_INDEX(idx) (((idx) >= 0) && ((idx) < HFI_NUM_MAX))
+
 /**
  * @INVALID: Invalid state
  * @HFI_DEINIT: HFI is not initialized yet

+ 5 - 0
drivers/cam_icp/fw_inc/hfi_sys_defs.h

@@ -270,6 +270,11 @@
 
 #define HFI_DEV_VERSION_MAX      0x6
 
+#define ICP_PWR_CLP_BPS          0x00000001
+#define ICP_PWR_CLP_IPE0         0x00010000
+#define ICP_PWR_CLP_IPE1         0x00020000
+#define ICP_PWR_CLP_OFE          0x00000001
+
 /**
  * start of sys command packet types
  * These commands are used to get system level information

Разлика између датотеке није приказан због своје велике величине
+ 400 - 199
drivers/cam_icp/hfi.c


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

@@ -422,7 +422,7 @@ int cam_bps_process_cmd(void *device_priv, uint32_t cmd_type,
 		rc = cam_bps_handle_resume(bps_dev);
 		break;
 	case CAM_ICP_DEV_CMD_UPDATE_CLK: {
-		struct cam_icp_clk_update_cmd *clk_upd_cmd = cmd_args;
+		struct cam_icp_dev_clk_update_cmd *clk_upd_cmd = cmd_args;
 		struct cam_ahb_vote ahb_vote;
 		uint32_t clk_rate = clk_upd_cmd->curr_clk_rate;
 		int32_t clk_level  = 0, err = 0;

+ 168 - 41
drivers/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c

@@ -155,7 +155,7 @@ static inline void cam_icp_dump_debug_info(struct cam_icp_hw_mgr *hw_mgr,
 
 	dump_type = CAM_ICP_DUMP_STATUS_REGISTERS;
 	cam_icp_mgr_process_dbg_buf(hw_mgr);
-	cam_hfi_queue_dump(false);
+	cam_hfi_queue_dump(hw_mgr->hfi_handle, false);
 
 	rc = icp_dev_intf->hw_ops.process_cmd(icp_dev_intf->hw_priv,
 		CAM_ICP_CMD_HW_REG_DUMP, &dump_type, sizeof(dump_type));
@@ -166,18 +166,19 @@ static inline void cam_icp_dump_debug_info(struct cam_icp_hw_mgr *hw_mgr,
 static int cam_icp_send_ubwc_cfg(struct cam_icp_hw_mgr *hw_mgr)
 {
 	struct cam_hw_intf *icp_dev_intf = hw_mgr->icp_dev_intf;
+	struct cam_icp_ubwc_cfg_cmd ubwc_cmd;
 	int rc;
-	uint32_t disable_ubwc_comp = 0;
 
 	if (!icp_dev_intf) {
 		CAM_ERR(CAM_ICP, "ICP device interface is NULL");
 		return -EINVAL;
 	}
 
-	disable_ubwc_comp = hw_mgr->disable_ubwc_comp;
+	ubwc_cmd.ubwc_cfg_dev_mask = hw_mgr->hw_cap_mask;
+	ubwc_cmd.disable_ubwc_comp = hw_mgr->disable_ubwc_comp;
 
 	rc = icp_dev_intf->hw_ops.process_cmd(icp_dev_intf->hw_priv, CAM_ICP_CMD_UBWC_CFG,
-		&disable_ubwc_comp, sizeof(disable_ubwc_comp));
+		&ubwc_cmd, sizeof(ubwc_cmd));
 	if (rc)
 		CAM_ERR(CAM_ICP, "Fail to submit UBWC config");
 
@@ -397,7 +398,7 @@ static int32_t cam_icp_deinit_idle_clk(void *priv, void *data)
 		(struct cam_icp_clk_info *)task_data->data;
 	struct cam_icp_hw_ctx_data *ctx_data;
 	struct cam_hw_intf *dev_intf = NULL;
-	struct cam_icp_clk_update_cmd clk_upd_cmd;
+	struct cam_icp_dev_clk_update_cmd clk_upd_cmd;
 	int rc = 0;
 	uint32_t i, hw_dev_type;
 	bool busy = false;
@@ -1486,7 +1487,7 @@ static int cam_icp_update_clk_rate(struct cam_icp_hw_mgr *hw_mgr,
 	uint32_t i, curr_clk_rate;
 	struct cam_hw_intf *dev_intf = NULL;
 	struct cam_icp_clk_info *hw_mgr_clk_info = NULL;
-	struct cam_icp_clk_update_cmd clk_upd_cmd;
+	struct cam_icp_dev_clk_update_cmd clk_upd_cmd;
 	char tmp_buff[64];
 
 	hw_mgr_clk_info = &hw_mgr->clk_info[ctx_data->hw_clk_type];
@@ -1681,7 +1682,8 @@ static int cam_icp_mgr_device_resume(struct cam_icp_hw_mgr *hw_mgr,
 	struct cam_icp_hw_ctx_data *ctx_data)
 {
 	struct cam_hw_intf *dev_intf = NULL;
-	uint32_t core_info_mask = 0, num_dev, hw_dev_type, dev_info_idx;
+	struct hfi_cmd_prop *dbg_prop = NULL;
+	uint32_t core_info_mask = 0, num_dev, hw_dev_type, dev_info_idx, size;
 	int rc = 0, i;
 
 	hw_dev_type = ctx_data->hw_dev_type;
@@ -1717,11 +1719,40 @@ static int cam_icp_mgr_device_resume(struct cam_icp_hw_mgr *hw_mgr,
 			cam_icp_hw_dev_type_to_name(ctx_data->hw_dev_type), ctx_data->ctx_id, rc);
 	}
 
-	CAM_DBG(CAM_PERF, "core_info %X", core_info_mask);
-	if (hw_mgr->dev_pc_flag)
-		rc = hfi_enable_dev_pc(true, core_info_mask);
-	else
-		rc = hfi_enable_dev_pc(false, core_info_mask);
+	CAM_DBG(CAM_PERF, "core_info 0x%x", core_info_mask);
+
+	size = sizeof(struct hfi_cmd_prop) + sizeof(struct hfi_dev_pc);
+	dbg_prop = kzalloc(size, GFP_KERNEL);
+	if (!dbg_prop) {
+		CAM_ERR(CAM_ICP, "Allocate command prop failed");
+		return -ENOMEM;
+	}
+
+	dbg_prop->size = size;
+	dbg_prop->pkt_type = HFI_CMD_SYS_SET_PROPERTY;
+	dbg_prop->num_prop = 1;
+
+	switch (ctx_data->hw_dev_type) {
+	case CAM_ICP_DEV_IPE:
+		fallthrough;
+	case CAM_ICP_DEV_BPS:
+		dbg_prop->prop_data[0] = HFI_PROP_SYS_IPEBPS_PC;
+		break;
+	case CAM_ICP_DEV_OFE:
+		dbg_prop->prop_data[0] = HFI_PROP_SYS_OFE_PC;
+		break;
+	default:
+		CAM_ERR(CAM_ICP, "Invalid hw dev type: %u",
+			ctx_data->hw_dev_type);
+		return -EINVAL;
+	}
+
+	dbg_prop->prop_data[1] = hw_mgr->dev_pc_flag;
+	dbg_prop->prop_data[2] = core_info_mask;
+
+	hfi_write_cmd(hw_mgr->hfi_handle, dbg_prop);
+
+	kfree(dbg_prop);
 
 end:
 	return rc;
@@ -2067,7 +2098,7 @@ static int cam_icp_mgr_process_cmd(void *priv, void *data)
 	hw_mgr = priv;
 	task_data = (struct hfi_cmd_work_data *)data;
 
-	rc = hfi_write_cmd(task_data->data);
+	rc = hfi_write_cmd(hw_mgr->hfi_handle, task_data->data);
 
 	return rc;
 }
@@ -2917,7 +2948,7 @@ static void cam_icp_mgr_process_dbg_buf(struct cam_icp_hw_mgr *hw_mgr)
 	char *dbg_buf;
 	int rc = 0;
 
-	rc = hfi_read_message(hw_mgr->dbg_buf, Q_DBG, &read_len);
+	rc = hfi_read_message(hw_mgr->hfi_handle, hw_mgr->dbg_buf, Q_DBG, &read_len);
 	if (rc)
 		return;
 
@@ -3040,7 +3071,7 @@ static int32_t cam_icp_mgr_process_msg(void *priv, void *data)
 	task_data = data;
 	hw_mgr = priv;
 
-	rc = hfi_read_message(hw_mgr->msg_buf, Q_MSG, &read_len);
+	rc = hfi_read_message(hw_mgr->hfi_handle, hw_mgr->msg_buf, Q_MSG, &read_len);
 	if (rc) {
 		CAM_DBG(CAM_ICP, "Unable to read msg q rc %d", rc);
 	} else {
@@ -3807,7 +3838,7 @@ static int cam_icp_mgr_icp_power_collapse(struct cam_icp_hw_mgr *hw_mgr)
 	if (rc)
 		CAM_ERR(CAM_ICP, "Fail to power collapse ICP rc: %d", rc);
 
-	rc = icp_dev_intf->hw_ops.deinit(icp_dev_intf->hw_priv, (void *)&send_freq_info,
+	rc = icp_dev_intf->hw_ops.deinit(icp_dev_intf->hw_priv, &send_freq_info,
 		sizeof(send_freq_info));
 	if (rc)
 		CAM_ERR(CAM_ICP, "Fail to deinit ICP");
@@ -3857,18 +3888,21 @@ static int cam_icp_mgr_proc_boot(struct cam_icp_hw_mgr *hw_mgr)
 static void cam_icp_mgr_proc_shutdown(struct cam_icp_hw_mgr *hw_mgr)
 {
 	struct cam_hw_intf *icp_dev_intf = hw_mgr->icp_dev_intf;
+	bool send_freq_info = false;
 
 	if (!icp_dev_intf) {
 		CAM_ERR(CAM_ICP, "ICP device interface is NULL");
 		return;
 	}
 
-	icp_dev_intf->hw_ops.init(icp_dev_intf->hw_priv, NULL, 0);
+	icp_dev_intf->hw_ops.init(icp_dev_intf->hw_priv,
+		&send_freq_info, sizeof(send_freq_info));
 
 	icp_dev_intf->hw_ops.process_cmd(icp_dev_intf->hw_priv,
 		CAM_ICP_CMD_PROC_SHUTDOWN, NULL, 0);
 
-	icp_dev_intf->hw_ops.deinit(icp_dev_intf->hw_priv, NULL, 0);
+	icp_dev_intf->hw_ops.deinit(icp_dev_intf->hw_priv,
+		&send_freq_info, sizeof(send_freq_info));
 
 	hw_mgr->icp_resumed = false;
 }
@@ -3968,11 +4002,7 @@ static void cam_icp_mgr_populate_hfi_mem_info(struct cam_icp_hw_mgr *hw_mgr,
 
 static int cam_icp_mgr_hfi_resume(struct cam_icp_hw_mgr *hw_mgr)
 {
-	struct hfi_mem_info hfi_mem;
-
-	cam_icp_mgr_populate_hfi_mem_info(hw_mgr, &hfi_mem);
-
-	return cam_hfi_resume(&hfi_mem);
+	return cam_hfi_resume(hw_mgr->hfi_handle);
 }
 
 static int cam_icp_mgr_populate_abort_cmd(struct cam_icp_hw_ctx_data *ctx_data,
@@ -4022,6 +4052,7 @@ static int cam_icp_mgr_populate_abort_cmd(struct cam_icp_hw_ctx_data *ctx_data,
 	abort_cmd->user_data2 = (uint64_t)0x0;
 
 	*abort_cmd_ptr = abort_cmd;
+
 	return 0;
 }
 
@@ -4029,6 +4060,7 @@ static int cam_icp_mgr_abort_handle_wq(
 	void *priv, void *data)
 {
 	int rc = 0;
+	struct cam_icp_hw_mgr      *hw_mgr;
 	struct hfi_cmd_work_data   *task_data = NULL;
 	struct cam_icp_hw_ctx_data *ctx_data;
 	struct hfi_cmd_dev_async   *abort_cmd;
@@ -4041,12 +4073,13 @@ static int cam_icp_mgr_abort_handle_wq(
 	task_data = (struct hfi_cmd_work_data *)data;
 	ctx_data =
 		(struct cam_icp_hw_ctx_data *)task_data->data;
+	hw_mgr = ctx_data->hw_mgr_priv;
 
 	rc = cam_icp_mgr_populate_abort_cmd(ctx_data, &abort_cmd);
 	if (rc)
 		return rc;
 
-	rc = hfi_write_cmd(abort_cmd);
+	rc = hfi_write_cmd(hw_mgr->hfi_handle, abort_cmd);
 	if (rc) {
 		kfree(abort_cmd);
 		return rc;
@@ -4064,6 +4097,7 @@ static int cam_icp_mgr_abort_handle(struct cam_icp_hw_ctx_data *ctx_data)
 	unsigned long rem_jiffies = 0;
 	int timeout = 2000;
 	struct hfi_cmd_dev_async *abort_cmd;
+	struct cam_icp_hw_mgr *hw_mgr = ctx_data->hw_mgr_priv;
 
 	rc = cam_icp_mgr_populate_abort_cmd(ctx_data, &abort_cmd);
 	if (rc)
@@ -4071,7 +4105,7 @@ static int cam_icp_mgr_abort_handle(struct cam_icp_hw_ctx_data *ctx_data)
 
 	reinit_completion(&ctx_data->wait_complete);
 
-	rc = hfi_write_cmd(abort_cmd);
+	rc = hfi_write_cmd(hw_mgr->hfi_handle, abort_cmd);
 	if (rc) {
 		kfree(abort_cmd);
 		return rc;
@@ -4101,6 +4135,7 @@ static int cam_icp_mgr_destroy_handle(
 	unsigned long rem_jiffies;
 	size_t packet_size;
 	struct hfi_cmd_dev_async *destroy_cmd;
+	struct cam_icp_hw_mgr *hw_mgr = ctx_data->hw_mgr_priv;
 
 	packet_size = sizeof(struct hfi_cmd_dev_async);
 
@@ -4146,7 +4181,7 @@ static int cam_icp_mgr_destroy_handle(
 
 	reinit_completion(&ctx_data->wait_complete);
 
-	rc = hfi_write_cmd(destroy_cmd);
+	rc = hfi_write_cmd(hw_mgr->hfi_handle, destroy_cmd);
 	if (rc) {
 		kfree(destroy_cmd);
 		return rc;
@@ -4160,7 +4195,7 @@ static int cam_icp_mgr_destroy_handle(
 			ctx_data->ctx_id_string);
 	if (!rem_jiffies) {
 		rc = -ETIMEDOUT;
-		cam_icp_dump_debug_info(ctx_data->hw_mgr_priv, ctx_data->abort_timed_out);
+		cam_icp_dump_debug_info(hw_mgr, ctx_data->abort_timed_out);
 	}
 	kfree(destroy_cmd);
 	return rc;
@@ -4256,7 +4291,7 @@ static unsigned long cam_icp_hw_mgr_mini_dump_cb(void *dst, unsigned long len,
 	md = (struct cam_icp_hw_mini_dump_info *)dst;
 	md->num_context = 0;
 	hw_mgr = &icp_hw_mgr[hw_mgr_idx];
-	cam_hfi_mini_dump(&md->hfi_info);
+	cam_hfi_mini_dump(hw_mgr->hfi_handle, &md->hfi_info);
 	memcpy(&md->hfi_mem_info, &hw_mgr->hfi_mem,
 		sizeof(struct icp_hfi_mem_info));
 	memcpy(&md->dev_info, &hw_mgr->dev_info,
@@ -4360,6 +4395,7 @@ static void cam_icp_mgr_device_deinit(struct cam_icp_hw_mgr *hw_mgr)
 {
 	struct cam_hw_intf *dev_intf;
 	int i, j, dev_info_idx;
+	bool send_freq_info = false;
 
 	for (i = 0; i < CAM_ICP_HW_MAX; i++) {
 		for (j = 0; j < hw_mgr->hw_dev_cnt[i]; j++) {
@@ -4369,7 +4405,11 @@ static void cam_icp_mgr_device_deinit(struct cam_icp_hw_mgr *hw_mgr)
 					cam_icp_hw_dev_type_to_name(i), j);
 				return;
 			}
-			dev_intf->hw_ops.deinit(dev_intf->hw_priv, NULL, 0);
+			if (i == CAM_ICP_HW_ICP_V1 || i == CAM_ICP_HW_ICP_V2)
+				dev_intf->hw_ops.deinit(dev_intf->hw_priv,
+					&send_freq_info, sizeof(send_freq_info));
+			else
+				dev_intf->hw_ops.deinit(dev_intf->hw_priv, NULL, 0);
 		}
 		if (CAM_ICP_IS_DEV_HW_EXIST(hw_mgr->hw_cap_mask, i) &&
 			(i >= CAM_ICP_DEV_START_IDX)) {
@@ -4397,7 +4437,7 @@ static int cam_icp_mgr_hw_close(void *hw_priv, void *hw_close_args)
 
 	cam_icp_mgr_proc_shutdown(hw_mgr);
 
-	cam_hfi_deinit();
+	cam_hfi_deinit(hw_mgr->hfi_handle);
 	cam_icp_free_hfi_mem(hw_mgr);
 
 	hw_mgr->icp_booted = false;
@@ -4410,6 +4450,7 @@ static int cam_icp_mgr_device_init(struct cam_icp_hw_mgr *hw_mgr)
 {
 	int rc = 0, i, j, dev_info_idx;
 	struct cam_hw_intf *dev_intf = NULL;
+	bool send_freq_info = false;
 
 	for (i = 0; i < CAM_ICP_HW_MAX; i++) {
 		for (j = 0; j < hw_mgr->hw_dev_cnt[i]; j++) {
@@ -4420,7 +4461,11 @@ static int cam_icp_mgr_device_init(struct cam_icp_hw_mgr *hw_mgr)
 				rc = -EINVAL;
 				goto hw_dev_deinit;
 			}
-			rc = dev_intf->hw_ops.init(dev_intf->hw_priv, NULL, 0);
+			if (i == CAM_ICP_HW_ICP_V1 || i == CAM_ICP_HW_ICP_V2)
+				rc = dev_intf->hw_ops.init(dev_intf->hw_priv,
+					&send_freq_info, sizeof(send_freq_info));
+			else
+				rc = dev_intf->hw_ops.init(dev_intf->hw_priv, NULL, 0);
 			if (rc) {
 				CAM_ERR(CAM_ICP, "Failed to init %s[%u]",
 					cam_icp_hw_dev_type_to_name(i), j);
@@ -4442,7 +4487,11 @@ hw_dev_deinit:
 	for (; i >= 0; i--) {
 		for (; j >= 0; j--) {
 			dev_intf = hw_mgr->devices[i][j];
-			dev_intf->hw_ops.deinit(dev_intf->hw_priv, NULL, 0);
+			if (i == CAM_ICP_HW_ICP_V1 || i == CAM_ICP_HW_ICP_V2)
+				dev_intf->hw_ops.deinit(dev_intf->hw_priv,
+					&send_freq_info, sizeof(send_freq_info));
+			else
+				dev_intf->hw_ops.deinit(dev_intf->hw_priv, NULL, 0);
 		}
 		if (i >= CAM_ICP_DEV_START_IDX) {
 			dev_info_idx = CAM_ICP_GET_DEV_INFO_IDX(i);
@@ -4473,7 +4522,17 @@ static int cam_icp_mgr_hfi_init(struct cam_icp_hw_mgr *hw_mgr)
 		return rc;
 	}
 
-	return cam_hfi_init(&hfi_mem, hfi_ops, icp_dev_intf->hw_priv, 0);
+	rc = cam_hfi_init(hw_mgr->hfi_handle, &hfi_mem, hfi_ops,
+		icp_dev_intf->hw_priv, 0);
+	if (rc) {
+		CAM_ERR(CAM_ICP, "Failed to init HFI rc=%d", rc);
+		return rc;
+	}
+
+	CAM_DBG(CAM_ICP, "%s hw mgr succeed hfi init with hfi handle: %d",
+		hw_mgr->hw_mgr_name, hw_mgr->hfi_handle);
+
+	return rc;
 }
 
 static int cam_icp_mgr_send_fw_init(struct cam_icp_hw_mgr *hw_mgr)
@@ -4490,6 +4549,7 @@ static int cam_icp_mgr_send_fw_init(struct cam_icp_hw_mgr *hw_mgr)
 
 	reinit_completion(&hw_mgr->icp_complete);
 	CAM_DBG(CAM_ICP, "Sending HFI init command");
+
 	rc = icp_dev_intf->hw_ops.process_cmd(icp_dev_intf->hw_priv,
 		CAM_ICP_SEND_INIT, NULL, 0);
 	if (rc) {
@@ -4552,8 +4612,7 @@ static int cam_icp_mgr_icp_resume(struct cam_icp_hw_mgr *hw_mgr)
 {
 	int rc = 0;
 	struct cam_hw_intf *icp_dev_intf = hw_mgr->icp_dev_intf;
-	bool downloadFromResume = true;
-	bool send_freq_info = true;
+	bool downloadFromResume = true, send_freq_info;
 
 	CAM_DBG(CAM_ICP, "Enter");
 
@@ -4567,6 +4626,7 @@ static int cam_icp_mgr_icp_resume(struct cam_icp_hw_mgr *hw_mgr)
 		return cam_icp_mgr_hw_open_k(hw_mgr, &downloadFromResume);
 	}
 
+	send_freq_info = true;
 	rc = icp_dev_intf->hw_ops.init(icp_dev_intf->hw_priv, &send_freq_info,
 		sizeof(send_freq_info));
 	if (rc) {
@@ -4592,7 +4652,9 @@ static int cam_icp_mgr_icp_resume(struct cam_icp_hw_mgr *hw_mgr)
 power_collapse:
 	__power_collapse(hw_mgr);
 hw_deinit:
-	icp_dev_intf->hw_ops.deinit(icp_dev_intf->hw_priv, NULL, 0);
+	send_freq_info = false;
+	icp_dev_intf->hw_ops.deinit(icp_dev_intf->hw_priv, &send_freq_info,
+		sizeof(send_freq_info));
 
 	return rc;
 }
@@ -4642,7 +4704,6 @@ static int cam_icp_mgr_hw_open(void *hw_mgr_priv, void *download_fw_args)
 	rc = cam_icp_mgr_hfi_init(hw_mgr);
 	if (rc) {
 		CAM_ERR(CAM_ICP, "Failed in hfi init, rc %d", rc);
-
 		dump_type = (CAM_ICP_DUMP_STATUS_REGISTERS | CAM_ICP_DUMP_CSR_REGISTERS);
 		hw_mgr->icp_dev_intf->hw_ops.process_cmd(hw_mgr->icp_dev_intf->hw_priv,
 			CAM_ICP_CMD_HW_REG_DUMP, &dump_type, sizeof(dump_type));
@@ -4688,7 +4749,7 @@ static int cam_icp_mgr_hw_open(void *hw_mgr_priv, void *download_fw_args)
 	return rc;
 
 fw_init_failed:
-	cam_hfi_deinit();
+	cam_hfi_deinit(hw_mgr->hfi_handle);
 hfi_init_failed:
 	cam_icp_mgr_proc_shutdown(hw_mgr);
 boot_failed:
@@ -5327,7 +5388,7 @@ static int cam_icp_process_stream_settings(
 		map_cmd_size);
 
 	reinit_completion(&ctx_data->wait_complete);
-	rc = hfi_write_cmd(async_direct);
+	rc = hfi_write_cmd(hw_mgr->hfi_handle, async_direct);
 	if (rc) {
 		CAM_ERR(CAM_ICP, "hfi write failed  rc %d", rc);
 		goto end;
@@ -6677,10 +6738,10 @@ static int cam_icp_mgr_acquire_hw(void *hw_mgr_priv, void *acquire_hw_args)
 			goto get_io_buf_failed;
 
 		if (hw_mgr->icp_debug_type)
-			hfi_set_debug_level(hw_mgr->icp_debug_type,
+			hfi_set_debug_level(hw_mgr->hfi_handle, hw_mgr->icp_debug_type,
 				hw_mgr->icp_dbg_lvl);
 
-		hfi_set_fw_dump_levels(hw_mgr->icp_fw_dump_lvl,
+		hfi_set_fw_dump_levels(hw_mgr->hfi_handle, hw_mgr->icp_fw_dump_lvl,
 			hw_mgr->icp_fw_ramdump_lvl);
 
 		rc = cam_icp_send_ubwc_cfg(hw_mgr);
@@ -7303,6 +7364,62 @@ static int cam_icp_mgr_get_device_capability(struct cam_icp_hw_mgr *hw_mgr,
 	return rc;
 }
 
+static int cam_icp_mgr_register_hfi_client(struct cam_icp_hw_mgr *hw_mgr)
+{
+
+	struct cam_hw_intf *icp_dev_intf = hw_mgr->icp_dev_intf;
+	int hfi_handle;
+	int rc;
+
+	if (!icp_dev_intf) {
+		CAM_ERR(CAM_ICP, "ICP device interface is NULL");
+		return -EINVAL;
+	}
+
+	hw_mgr->hfi_handle = HFI_HANDLE_INIT_VALUE;
+	rc = cam_hfi_register(&hw_mgr->hfi_handle);
+	if (rc) {
+		CAM_ERR(CAM_ICP, "Fail to register hw mgr as hfi client rc=%d", rc);
+		return rc;
+	}
+
+	hfi_handle = hw_mgr->hfi_handle;
+	rc = icp_dev_intf->hw_ops.process_cmd(icp_dev_intf->hw_priv, CAM_ICP_CMD_SET_HFI_HANDLE,
+		&hfi_handle, sizeof(hfi_handle));
+	if (rc) {
+		CAM_ERR(CAM_ICP, "Fail to share hfi handle to ICP core rc=%d hfi hdl: %d",
+			rc, hfi_handle);
+		cam_hfi_unregister(&hw_mgr->hfi_handle);
+		return rc;
+	}
+
+	CAM_DBG(CAM_ICP, "[%s] successfully registered as hfi client with handle: %d",
+		hw_mgr->hw_mgr_name, hfi_handle);
+
+	return 0;
+}
+
+static void cam_icp_mgr_unregister_hfi_client(struct cam_icp_hw_mgr *hw_mgr)
+{
+	struct cam_hw_intf *icp_dev_intf = hw_mgr->icp_dev_intf;
+	int rc;
+
+	rc = cam_hfi_unregister(&hw_mgr->hfi_handle);
+	if (rc) {
+		CAM_ERR(CAM_ICP, "Failed to unregister hfi client hdl: %d rc: %d",
+			hw_mgr->hfi_handle, rc);
+		return;
+	}
+
+	if (!icp_dev_intf) {
+		CAM_ERR(CAM_ICP, "ICP dev intf is NULL");
+		return;
+	}
+
+	icp_dev_intf->hw_ops.process_cmd(icp_dev_intf->hw_priv, CAM_ICP_CMD_SET_HFI_HANDLE,
+		&hw_mgr->hfi_handle, sizeof(hw_mgr->hfi_handle));
+}
+
 static int cam_icp_mgr_get_hw_mgr_name(uint32_t device_idx, char *hw_mgr_name)
 {
 	if (!hw_mgr_name) {
@@ -7417,6 +7534,12 @@ int cam_icp_hw_mgr_init(struct device_node *of_node, uint64_t *hw_mgr_hdl,
 	if (iommu_hdl)
 		*iommu_hdl = hw_mgr->iommu_hdl;
 
+	rc = cam_icp_mgr_register_hfi_client(hw_mgr);
+	if (rc) {
+		CAM_ERR(CAM_ICP, "Fail to register hw mgr as hfi handle");
+		goto icp_hfi_register_failed;
+	}
+
 	init_completion(&hw_mgr->icp_complete);
 	cam_common_register_mini_dump_cb(cam_icp_hw_mgr_mini_dump_cb, hw_mgr->hw_mgr_name,
 		&hw_mgr->hw_mgr_id);
@@ -7433,6 +7556,8 @@ int cam_icp_hw_mgr_init(struct device_node *of_node, uint64_t *hw_mgr_hdl,
 	return rc;
 
 icp_get_svs_clk_failed:
+	cam_hfi_unregister(&hw_mgr->hfi_handle);
+icp_hfi_register_failed:
 	debugfs_remove_recursive(hw_mgr->dentry);
 	hw_mgr->dentry = NULL;
 icp_debugfs_create_failed:
@@ -7465,6 +7590,8 @@ void cam_icp_hw_mgr_deinit(int device_idx)
 	CAM_DBG(CAM_ICP, "hw mgr deinit: %u icp name: %s", device_idx, hw_mgr->hw_mgr_name);
 
 	hw_mgr->dentry = NULL;
+
+	cam_icp_mgr_unregister_hfi_client(hw_mgr);
 	cam_icp_mgr_destroy_wq(hw_mgr);
 	cam_icp_mgr_free_devs(hw_mgr);
 	mutex_destroy(&hw_mgr->hw_mgr_mutex);

+ 2 - 5
drivers/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.h

@@ -60,11 +60,6 @@
 /* Used for targets >= 480 and its variants */
 #define CPAS_TITAN_IPE0_CAP_BIT 0x800
 
-#define ICP_PWR_CLP_BPS         0x00000001
-#define ICP_PWR_CLP_IPE0        0x00010000
-#define ICP_PWR_CLP_IPE1        0x00020000
-#define ICP_PWR_CLP_OFE         0x00000001
-
 #define CAM_ICP_CTX_STATE_FREE      0x0
 #define CAM_ICP_CTX_STATE_IN_USE    0x1
 #define CAM_ICP_CTX_STATE_ACQUIRED  0x2
@@ -416,6 +411,7 @@ struct cam_icp_clk_info {
  * @icp_resumed: Processor is powered on
  * @iommu_hdl: Non secure IOMMU handle
  * @iommu_sec_hdl: Secure IOMMU handle
+ * @hfi_handle: hfi handle for this ICP hw mgr
  * @hfi_mem: Memory for hfi
  * @cmd_work: Work queue for hfi commands
  * @msg_work: Work queue for hfi messages
@@ -470,6 +466,7 @@ struct cam_icp_hw_mgr {
 	bool icp_resumed;
 	int32_t iommu_hdl;
 	int32_t iommu_sec_hdl;
+	int32_t hfi_handle;
 	struct icp_hfi_mem_info hfi_mem;
 	struct cam_req_mgr_core_workq *cmd_work;
 	struct cam_req_mgr_core_workq *msg_work;

+ 14 - 2
drivers/cam_icp/icp_hw/icp_hw_mgr/include/cam_icp_hw_intf.h

@@ -67,6 +67,7 @@ enum cam_icp_cmd_type {
 	CAM_ICP_CMD_HW_DUMP,
 	CAM_ICP_CMD_HW_MINI_DUMP,
 	CAM_ICP_CMD_HW_REG_DUMP,
+	CAM_ICP_CMD_SET_HFI_HANDLE,
 	CAM_ICP_CMD_MAX,
 };
 
@@ -98,7 +99,7 @@ struct cam_icp_boot_args {
 };
 
 /**
- * struct cam_icp_clk_update_cmd - Payload for hw manager command
+ * struct cam_icp_dev_clk_update_cmd - Payload for hw manager command
  *
  * @curr_clk_rate:        clk rate to HW
  * @clk_level:            clk level corresponding to the clk rate
@@ -106,10 +107,21 @@ struct cam_icp_boot_args {
  *                        updated to the given rate
  * @dev_pc_enable:        power collpase enable flag
  */
-struct cam_icp_clk_update_cmd {
+struct cam_icp_dev_clk_update_cmd {
 	uint32_t  curr_clk_rate;
 	int32_t clk_level;
 	bool  dev_pc_enable;
 };
 
+/**
+ * struct cam_icp_ubwc_cfg_cmd - ubwc cmd to send
+ *
+ * @ubwc_cfg_dev_mask: mask to indicate which device ubwc cfg to send to fw
+ * @disable_ubwc_comp: flag to force disable ubwc
+ */
+struct cam_icp_ubwc_cfg_cmd {
+	uint32_t ubwc_cfg_dev_mask;
+	bool disable_ubwc_comp;
+};
+
 #endif

+ 55 - 11
drivers/cam_icp/icp_hw/icp_proc/icp_common/cam_icp_proc_common.c

@@ -192,33 +192,77 @@ int cam_icp_proc_mini_dump(struct cam_icp_hw_dump_args *args,
 	return 0;
 }
 
-int cam_icp_proc_ubwc_configure(struct cam_icp_ubwc_cfg ubwc_cfg,
-	uint32_t force_disable_ubwc)
+static int cam_icp_proc_validate_ubwc_cfg(struct cam_icp_ubwc_cfg *ubwc_cfg,
+	uint32_t ubwc_cfg_dev_mask)
 {
+	uint32_t found_ubwc_cfg_mask = ubwc_cfg->found_ubwc_cfg_mask;
+
+	if ((ubwc_cfg_dev_mask & BIT(CAM_ICP_DEV_IPE)) &&
+		!(found_ubwc_cfg_mask & BIT(CAM_ICP_DEV_IPE))) {
+		CAM_ERR(CAM_ICP, "IPE does not have UBWC cfg value");
+		return -ENODATA;
+	}
+
+	if ((ubwc_cfg_dev_mask & BIT(CAM_ICP_DEV_BPS)) &&
+		!(found_ubwc_cfg_mask & BIT(CAM_ICP_DEV_BPS))) {
+		CAM_ERR(CAM_ICP, "BPS does not have UBWC cfg value");
+		return -ENODATA;
+	}
+
+	if ((ubwc_cfg_dev_mask & BIT(CAM_ICP_DEV_OFE)) &&
+		!(found_ubwc_cfg_mask & BIT(CAM_ICP_DEV_OFE))) {
+		CAM_ERR(CAM_ICP, "OFE does not have UBWC cfg value");
+		return -ENODATA;
+	}
+
+	return 0;
+}
+
+int cam_icp_proc_ubwc_configure(struct cam_icp_proc_ubwc_cfg_cmd *ubwc_cfg_cmd,
+	bool force_disable_ubwc, int hfi_handle)
+{
+	struct cam_icp_ubwc_cfg *ubwc_cfg;
 	int i = 0, ddr_type, rc;
-	uint32_t ipe_ubwc_cfg[ICP_UBWC_CFG_MAX];
-	uint32_t bps_ubwc_cfg[ICP_UBWC_CFG_MAX];
+	uint32_t ipe_ubwc_cfg[ICP_UBWC_CFG_MAX] = {0};
+	uint32_t bps_ubwc_cfg[ICP_UBWC_CFG_MAX] = {0};
+	uint32_t ofe_ubwc_cfg[ICP_UBWC_CFG_MAX] = {0};
+
+	if (!ubwc_cfg_cmd) {
+		CAM_ERR(CAM_ICP, "ubwc config command is NULL");
+		return -EINVAL;
+	}
+
+	ubwc_cfg = ubwc_cfg_cmd->ubwc_cfg;
+	rc = cam_icp_proc_validate_ubwc_cfg(ubwc_cfg, ubwc_cfg_cmd->ubwc_cfg_dev_mask);
+	if (rc) {
+		CAM_ERR(CAM_ICP, "UBWC config failed validation rc:%d", rc);
+		return rc;
+	}
 
 	ddr_type = cam_get_ddr_type();
 
 	if (ddr_type == DDR_TYPE_LPDDR5 || ddr_type == DDR_TYPE_LPDDR5X)
 		i = 1;
 
-	ipe_ubwc_cfg[0] = ubwc_cfg.ipe_fetch[i];
-	ipe_ubwc_cfg[1] = ubwc_cfg.ipe_write[i];
+	ipe_ubwc_cfg[0] = ubwc_cfg->ipe_fetch[i];
+	ipe_ubwc_cfg[1] = ubwc_cfg->ipe_write[i];
+
+	bps_ubwc_cfg[0] = ubwc_cfg->bps_fetch[i];
+	bps_ubwc_cfg[1] = ubwc_cfg->bps_write[i];
 
-	bps_ubwc_cfg[0] = ubwc_cfg.bps_fetch[i];
-	bps_ubwc_cfg[1] = ubwc_cfg.bps_write[i];
+	ofe_ubwc_cfg[0] = ubwc_cfg->ofe_fetch[i];
+	ofe_ubwc_cfg[1] = ubwc_cfg->ofe_write[i];
 
 	if (force_disable_ubwc) {
 		ipe_ubwc_cfg[1] &= ~CAM_ICP_UBWC_COMP_EN;
 		bps_ubwc_cfg[1] &= ~CAM_ICP_UBWC_COMP_EN;
+		ofe_ubwc_cfg[1] &= ~CAM_ICP_UBWC_COMP_EN;
 		CAM_DBG(CAM_ICP,
-			"Force disable UBWC compression, ipe_ubwc_cfg: 0x%x, bps_ubwc_cfg: 0x%x",
-			ipe_ubwc_cfg[1], bps_ubwc_cfg[1]);
+			"Force disable UBWC compression, ipe_ubwc_cfg: 0x%x, bps_ubwc_cfg: 0x%x ofe_ubwc_cfg: 0x%x",
+			ipe_ubwc_cfg[1], bps_ubwc_cfg[1], ofe_ubwc_cfg[1]);
 	}
 
-	rc = hfi_cmd_ubwc_config_ext(ipe_ubwc_cfg, bps_ubwc_cfg);
+	rc = hfi_cmd_ubwc_config_ext(hfi_handle, ipe_ubwc_cfg, bps_ubwc_cfg, ofe_ubwc_cfg);
 	if (rc) {
 		CAM_ERR(CAM_ICP, "Failed to write UBWC configure rc=%d", rc);
 		return rc;

+ 13 - 2
drivers/cam_icp/icp_hw/icp_proc/icp_common/cam_icp_proc_common.h

@@ -20,6 +20,17 @@
 #define PC_POLL_DELAY_US        100
 #define PC_POLL_TIMEOUT_US      10000
 
+/**
+ * struct cam_icp_proc_ubwc_cfg_cmd
+ * @ubwc_cfg: UBWC cfg info parsed from DT
+ * @ubwc_cfg_dev_mask: mask to indicate which device
+ *                     ubwc cfg to send to fw
+ */
+struct cam_icp_proc_ubwc_cfg_cmd {
+	struct cam_icp_ubwc_cfg *ubwc_cfg;
+	uint32_t ubwc_cfg_dev_mask;
+};
+
 /**
  * @brief : Validate FW elf image
  */
@@ -51,7 +62,7 @@ int cam_icp_proc_mini_dump(struct cam_icp_hw_dump_args *args,
 /**
  * @brief : Update UBWC configuration for IPE and BPS
  */
-int cam_icp_proc_ubwc_configure(struct cam_icp_ubwc_cfg ubwc_cfg,
-	uint32_t force_disable_ubwc);
+int cam_icp_proc_ubwc_configure(struct cam_icp_proc_ubwc_cfg_cmd *ubwc_cfg_cmd,
+	bool force_disable_ubwc, int hfi_handle);
 
 #endif /* _CAM_ICP_UTILS_H_ */

+ 72 - 21
drivers/cam_icp/icp_hw/icp_proc/icp_common/cam_icp_soc_common.c

@@ -12,15 +12,21 @@
 #include "hfi_intf.h"
 #include "cam_icp_soc_common.h"
 
-static int __ubwc_config_get(struct device_node *np, char *name, uint32_t *cfg)
+static int __ubwc_config_get(struct device_node *np, char *name, uint32_t *cfg, bool *ubwc_listed)
 {
-	int nconfig;
-	int i, rc;
+	int nconfig, i, rc;
 
 	nconfig = of_property_count_u32_elems(np, name);
-	if (nconfig < 0 || nconfig > ICP_UBWC_CFG_MAX) {
-		CAM_ERR(CAM_ICP, "Invalid number of UBWC configs[=%d]",
-			nconfig);
+	if (nconfig < 0) {
+		CAM_DBG(CAM_ICP, "prop: %s is not listed", name);
+		*ubwc_listed = false;
+		return 0;
+	}
+	*ubwc_listed = true;
+
+	if (nconfig > ICP_UBWC_CFG_MAX) {
+		CAM_ERR(CAM_ICP, "Invalid number of UBWC configs[=%d] MAX UBWC=%d",
+			nconfig, ICP_UBWC_CFG_MAX);
 		return -EINVAL;
 	}
 
@@ -40,38 +46,83 @@ static int __ubwc_config_get(struct device_node *np, char *name, uint32_t *cfg)
 static int cam_icp_soc_ubwc_config_get(struct device_node *np,
 	struct cam_icp_soc_info *icp_soc_info)
 {
-	struct cam_icp_ubwc_cfg *ubwc_cfg_ext = NULL;
+	struct cam_icp_ubwc_cfg *ubwc_cfg_ext;
 	int rc;
 	uint32_t dev_type;
+	bool ubwc_listed, ubwc_fetch_found, ubwc_write_found;
 
 	dev_type = icp_soc_info->dev_type;
-	ubwc_cfg_ext = &icp_soc_info->uconfig.ubwc_cfg_ext;
 
-	rc = __ubwc_config_get(np, "ubwc-ipe-fetch-cfg", ubwc_cfg_ext->ipe_fetch);
-	if (rc) {
-		if (dev_type == CAM_ICP_HW_ICP_V1) {
-			rc = __ubwc_config_get(np, "ubwc-cfg", icp_soc_info->uconfig.ubwc_cfg);
-			if (rc)
-				return rc;
+	rc = __ubwc_config_get(np, "ubwc-cfg", icp_soc_info->uconfig.ubwc_cfg,
+		&ubwc_listed);
+	if (ubwc_listed) {
+		if (dev_type == CAM_ICP_HW_ICP_V1)
 			icp_soc_info->is_ubwc_cfg = true;
-		}
 		return rc;
 	}
 
+	ubwc_cfg_ext = &icp_soc_info->uconfig.ubwc_cfg_ext;
+	rc = __ubwc_config_get(np, "ubwc-ipe-fetch-cfg",
+		ubwc_cfg_ext->ipe_fetch, &ubwc_fetch_found);
+	if (rc)
+		return rc;
+
 	rc = __ubwc_config_get(np, "ubwc-ipe-write-cfg",
-		icp_soc_info->uconfig.ubwc_cfg_ext.ipe_write);
+		ubwc_cfg_ext->ipe_write, &ubwc_write_found);
 	if (rc)
 		return rc;
 
+	if (ubwc_fetch_found && ubwc_write_found)
+		ubwc_cfg_ext->found_ubwc_cfg_mask |= BIT(CAM_ICP_DEV_IPE);
+	else {
+		if (ubwc_fetch_found ^ ubwc_write_found) {
+			CAM_ERR(CAM_ICP, "Missing %s ipe ubwc config",
+				ubwc_fetch_found ? "write" : "fetch");
+			return -EINVAL;
+		}
+	}
+
 	rc = __ubwc_config_get(np, "ubwc-bps-fetch-cfg",
-		icp_soc_info->uconfig.ubwc_cfg_ext.bps_fetch);
+		ubwc_cfg_ext->bps_fetch, &ubwc_fetch_found);
 	if (rc)
 		return rc;
 
 	rc = __ubwc_config_get(np, "ubwc-bps-write-cfg",
-		icp_soc_info->uconfig.ubwc_cfg_ext.bps_write);
+		ubwc_cfg_ext->bps_write, &ubwc_write_found);
+	if (rc)
+		return rc;
 
-	return rc;
+	if (ubwc_fetch_found && ubwc_write_found)
+		ubwc_cfg_ext->found_ubwc_cfg_mask |= BIT(CAM_ICP_DEV_BPS);
+	else {
+		if (ubwc_fetch_found ^ ubwc_write_found) {
+			CAM_ERR(CAM_ICP, "Missing %s bps ubwc config",
+				ubwc_fetch_found ? "write" : "fetch");
+			return -EINVAL;
+		}
+	}
+
+	rc = __ubwc_config_get(np, "ubwc-ofe-fetch-cfg",
+		ubwc_cfg_ext->ofe_fetch, &ubwc_fetch_found);
+	if (rc)
+		return rc;
+
+	rc = __ubwc_config_get(np, "ubwc-ofe-write-cfg",
+		ubwc_cfg_ext->ofe_write, &ubwc_write_found);
+	if (rc)
+		return rc;
+
+	if (ubwc_fetch_found && ubwc_write_found)
+		ubwc_cfg_ext->found_ubwc_cfg_mask |= BIT(CAM_ICP_DEV_OFE);
+	else {
+		if (ubwc_fetch_found ^ ubwc_write_found) {
+			CAM_ERR(CAM_ICP, "Missing %s ofe ubwc config",
+				ubwc_fetch_found ? "write" : "fetch");
+			return -EINVAL;
+		}
+	}
+
+	return 0;
 }
 
 static inline void cam_icp_soc_qos_get(struct device_node *np,
@@ -201,7 +252,7 @@ int cam_icp_soc_resources_disable(struct cam_hw_soc_info *soc_info)
 }
 
 int cam_icp_soc_update_clk_rate(struct cam_hw_soc_info *soc_info,
-	int32_t clk_level)
+	int32_t clk_level, int hfi_handle)
 {
 	int32_t src_clk_idx = 0;
 	int32_t clk_rate = 0;
@@ -246,6 +297,6 @@ int cam_icp_soc_update_clk_rate(struct cam_hw_soc_info *soc_info,
 	if (rc)
 		return rc;
 
-	hfi_send_freq_info(clk_rate);
+	hfi_send_freq_info(hfi_handle, clk_rate);
 	return 0;
 }

+ 8 - 1
drivers/cam_icp/icp_hw/icp_proc/icp_common/cam_icp_soc_common.h

@@ -21,12 +21,19 @@
  * @ipe_write: UBWC configuration for IPE write.
  * @bps_fetch: UBWC configuration for BPS fetch.
  * @bps_write: UBWC configuration for BPS write.
+ * @ofe_fetch: UBWC configuration for ofe fetch.
+ * @ofe_write: UBWC configuration for ofe write.
+ * @found_ubwc_cfg_mask: mask to indicate which
+ *                      ubwc dev cfg found from DT
  */
 struct cam_icp_ubwc_cfg {
 	uint32_t ipe_fetch[ICP_UBWC_CFG_MAX];
 	uint32_t ipe_write[ICP_UBWC_CFG_MAX];
 	uint32_t bps_fetch[ICP_UBWC_CFG_MAX];
 	uint32_t bps_write[ICP_UBWC_CFG_MAX];
+	uint32_t ofe_fetch[ICP_UBWC_CFG_MAX];
+	uint32_t ofe_write[ICP_UBWC_CFG_MAX];
+	uint32_t found_ubwc_cfg_mask;
 };
 
 /**
@@ -60,6 +67,6 @@ int cam_icp_soc_resources_enable(struct cam_hw_soc_info *soc_info);
 int cam_icp_soc_resources_disable(struct cam_hw_soc_info *soc_info);
 
 int cam_icp_soc_update_clk_rate(struct cam_hw_soc_info *soc_info,
-	int32_t clk_level);
+	int32_t clk_level, int hfi_handle);
 
 #endif

+ 97 - 27
drivers/cam_icp/icp_hw/icp_proc/icp_v1_hw/cam_icp_v1_core.c

@@ -182,8 +182,8 @@ static int cam_icp_v1_fw_mini_dump(struct cam_icp_hw_dump_args *dump_args,
 		core_info->fw_buf_len);
 }
 
-int cam_icp_v1_init_hw(void *device_priv,
-	void *init_hw_args, uint32_t arg_size)
+int cam_icp_v1_init_hw(void *device_priv, void *args,
+	uint32_t arg_size)
 {
 	struct cam_hw_info *icp_v1_dev = device_priv;
 	struct cam_hw_soc_info *soc_info = NULL;
@@ -192,7 +192,7 @@ int cam_icp_v1_init_hw(void *device_priv,
 	struct cam_icp_cpas_vote cpas_vote;
 	unsigned long flags;
 	int rc = 0;
-	bool send_freq_info = (init_hw_args == NULL) ? false : *((bool *)init_hw_args);
+	bool send_freq_info;
 
 	if (!device_priv) {
 		CAM_ERR(CAM_ICP, "Invalid cam_dev_info");
@@ -202,12 +202,14 @@ int cam_icp_v1_init_hw(void *device_priv,
 	soc_info = &icp_v1_dev->soc_info;
 	core_info = (struct cam_icp_v1_device_core_info *)icp_v1_dev->core_info;
 
-	if ((!soc_info) || (!core_info)) {
-		CAM_ERR(CAM_ICP, "soc_info: %pK core_info: %pK",
-			soc_info, core_info);
+	if ((!soc_info) || (!core_info) || (!args)) {
+		CAM_ERR(CAM_ICP, "soc_info: %pK core_info: %pK args: %pK",
+			soc_info, core_info, args);
 		return -EINVAL;
 	}
 
+	send_freq_info = *((bool *)args);
+
 	spin_lock_irqsave(&icp_v1_dev->hw_lock, flags);
 	if (icp_v1_dev->hw_state == CAM_HW_STATE_POWER_UP) {
 		spin_unlock_irqrestore(&icp_v1_dev->hw_lock, flags);
@@ -256,7 +258,7 @@ int cam_icp_v1_init_hw(void *device_priv,
 			int32_t clk_rate = 0;
 
 			clk_rate = clk_get_rate(soc_info->clk[soc_info->src_clk_idx]);
-			hfi_send_freq_info(clk_rate);
+			hfi_send_freq_info(core_info->hfi_handle, clk_rate);
 		}
 	}
 
@@ -269,20 +271,22 @@ error:
 }
 
 int cam_icp_v1_deinit_hw(void *device_priv,
-	void *init_hw_args, uint32_t arg_size)
+	void *args, uint32_t arg_size)
 {
 	struct cam_hw_info *icp_v1_dev = device_priv;
 	struct cam_hw_soc_info *soc_info = NULL;
 	struct cam_icp_v1_device_core_info *core_info = NULL;
 	unsigned long flags;
 	int rc = 0;
-	bool send_freq_info = (init_hw_args == NULL) ? false : *((bool *)init_hw_args);
+	bool send_freq_info;
 
-	if (!device_priv) {
-		CAM_ERR(CAM_ICP, "Invalid cam_dev_info");
+	if (!device_priv || !args) {
+		CAM_ERR(CAM_ICP, "Invalid icp hw info is %s args is %s",
+			CAM_IS_NULL_TO_STR(icp_v1_dev), CAM_IS_NULL_TO_STR(args));
 		return -EINVAL;
 	}
 
+	send_freq_info = *((bool *)args);
 	soc_info = &icp_v1_dev->soc_info;
 	core_info = (struct cam_icp_v1_device_core_info *)icp_v1_dev->core_info;
 	if ((!soc_info) || (!core_info)) {
@@ -299,7 +303,7 @@ int cam_icp_v1_deinit_hw(void *device_priv,
 	spin_unlock_irqrestore(&icp_v1_dev->hw_lock, flags);
 
 	if (send_freq_info)
-		hfi_send_freq_info(0);
+		hfi_send_freq_info(core_info->hfi_handle, 0);
 
 	rc = cam_icp_soc_resources_disable(soc_info);
 
@@ -563,6 +567,44 @@ void cam_icp_v1_populate_hfi_ops(const struct hfi_ops **hfi_proc_ops)
 	*hfi_proc_ops = &hfi_icp_v1_ops;
 }
 
+static int cam_icp_v1_send_fw_init(struct cam_icp_v1_device_core_info *core_info)
+{
+	int rc;
+
+	if (!core_info) {
+		CAM_ERR(CAM_ICP, "Invalid core info is NULL");
+		return -EINVAL;
+	}
+
+	rc = hfi_send_system_cmd(core_info->hfi_handle, HFI_CMD_SYS_INIT, 0, 0);
+	if (rc) {
+		CAM_ERR(CAM_ICP, "Fail to send sys init command for hfi handle: %d",
+			core_info->hfi_handle);
+		return rc;
+	}
+
+	return 0;
+}
+
+static int cam_icp_v1_pc_prep(struct cam_icp_v1_device_core_info *core_info)
+{
+	int rc;
+
+	if (!core_info) {
+		CAM_ERR(CAM_ICP, "Invalid ICP core info is NULL");
+		return -EINVAL;
+	}
+
+	rc = hfi_send_system_cmd(core_info->hfi_handle, HFI_CMD_SYS_PC_PREP, 0, 0);
+	if (rc) {
+		CAM_ERR(CAM_ICP, "Fail to send PC collapse command for hfi handle: %d",
+			core_info->hfi_handle);
+		return rc;
+	}
+
+	return 0;
+}
+
 int cam_icp_v1_process_cmd(void *device_priv, uint32_t cmd_type,
 	void *cmd_args, uint32_t arg_size)
 {
@@ -599,13 +641,11 @@ int cam_icp_v1_process_cmd(void *device_priv, uint32_t cmd_type,
 		rc = cam_icp_v1_power_resume(icp_v1_dev, *((bool *)cmd_args));
 		break;
 	case CAM_ICP_SEND_INIT:
-		hfi_send_system_cmd(HFI_CMD_SYS_INIT, 0, 0);
+		rc = cam_icp_v1_send_fw_init(core_info);
 		break;
-
 	case CAM_ICP_CMD_PC_PREP:
-		hfi_send_system_cmd(HFI_CMD_SYS_PC_PREP, 0, 0);
+		rc = cam_icp_v1_pc_prep(core_info);
 		break;
-
 	case CAM_ICP_CMD_VOTE_CPAS: {
 		struct cam_icp_cpas_vote *cpas_vote = cmd_args;
 
@@ -618,6 +658,23 @@ int cam_icp_v1_process_cmd(void *device_priv, uint32_t cmd_type,
 		break;
 	}
 
+	case CAM_ICP_CMD_SET_HFI_HANDLE: {
+		if (!core_info || !cmd_args) {
+			CAM_ERR(CAM_ICP, "Core info is %s and args is %s",
+				CAM_IS_NULL_TO_STR(core_info), CAM_IS_NULL_TO_STR(cmd_args));
+			return -EINVAL;
+		}
+
+		if (arg_size != sizeof(int)) {
+			CAM_ERR(CAM_ICP, "Invalid set hfi handle command arg size:%u",
+				arg_size);
+			return -EINVAL;
+		}
+
+		core_info->hfi_handle = *((int *)cmd_args);
+		break;
+	}
+
 	case CAM_ICP_CMD_CPAS_START: {
 		struct cam_icp_cpas_vote *cpas_vote = cmd_args;
 
@@ -642,7 +699,8 @@ int cam_icp_v1_process_cmd(void *device_priv, uint32_t cmd_type,
 		}
 		break;
 	case CAM_ICP_CMD_UBWC_CFG: {
-		uint32_t disable_ubwc_comp;
+		struct cam_icp_ubwc_cfg_cmd *ubwc_cmd = cmd_args;
+		struct cam_icp_proc_ubwc_cfg_cmd ubwc_proc_cmd;
 
 		icp_soc_info = soc_info->soc_private;
 		if (!icp_soc_info) {
@@ -651,32 +709,44 @@ int cam_icp_v1_process_cmd(void *device_priv, uint32_t cmd_type,
 		}
 
 		if (!cmd_args) {
-			CAM_ERR(CAM_ICP, "Invalid args");
+			CAM_ERR(CAM_ICP, "Invalid ubwc cmd args is NULL");
 			return -EINVAL;
 		}
-		disable_ubwc_comp = *((uint32_t *)cmd_args);
 
-		if (icp_soc_info->is_ubwc_cfg)
-			rc = hfi_cmd_ubwc_config(icp_soc_info->uconfig.ubwc_cfg);
-		else
-			rc = cam_icp_proc_ubwc_configure(icp_soc_info->uconfig.ubwc_cfg_ext,
-				disable_ubwc_comp);
+		if (arg_size != sizeof(struct cam_icp_ubwc_cfg_cmd)) {
+			CAM_ERR(CAM_ICP, "Invalid ubwc cmd size:%u", arg_size);
+			return -EINVAL;
+		}
 
+		if (icp_soc_info->is_ubwc_cfg)
+			rc = hfi_cmd_ubwc_config(core_info->hfi_handle,
+				icp_soc_info->uconfig.ubwc_cfg);
+		else {
+			ubwc_proc_cmd.ubwc_cfg = &icp_soc_info->uconfig.ubwc_cfg_ext;
+			rc = cam_icp_proc_ubwc_configure(&ubwc_proc_cmd,
+				ubwc_cmd->disable_ubwc_comp, core_info->hfi_handle);
+		}
 		break;
 	}
 	case CAM_ICP_CMD_CLK_UPDATE: {
 		int32_t clk_level = 0;
 		struct cam_ahb_vote ahb_vote;
 
-		if (!cmd_args) {
-			CAM_ERR(CAM_ICP, "Invalid args");
+		if (!cmd_args || !core_info) {
+			CAM_ERR(CAM_ICP, "Invalid args: core info is %s cmd args is %s",
+				CAM_IS_NULL_TO_STR(core_info), CAM_IS_NULL_TO_STR(cmd_args));
+			return -EINVAL;
+		}
+
+		if (arg_size != sizeof(int32_t)) {
+			CAM_ERR(CAM_ICP, "Invalid icp clock update command");
 			return -EINVAL;
 		}
 
 		clk_level = *((int32_t *)cmd_args);
 		CAM_DBG(CAM_ICP,
 			"Update ICP clock to level [%d]", clk_level);
-		rc = cam_icp_soc_update_clk_rate(soc_info, clk_level);
+		rc = cam_icp_soc_update_clk_rate(soc_info, clk_level, core_info->hfi_handle);
 		if (rc)
 			CAM_ERR(CAM_ICP,
 				"Failed to update clk to level: %d rc: %d",

+ 2 - 0
drivers/cam_icp/icp_hw/icp_proc/icp_v1_hw/cam_icp_v1_core.h

@@ -38,6 +38,7 @@
  * @icp_v1_acquire: Acquire information of ICP_V1
  * @irq_cb: IRQ callback
  * @cpas_handle: CPAS handle for ICP_V1
+ * @hfi_handle: hfi handle for ICP V1
  * @hw_version: hw version of icp v1 processor
  * @cpas_start: state variable for cpas
  */
@@ -49,6 +50,7 @@ struct cam_icp_v1_device_core_info {
 	uint64_t fw_buf_len;
 	struct cam_icp_irq_cb irq_cb;
 	uint32_t cpas_handle;
+	int32_t hfi_handle;
 	bool cpas_start;
 };
 

+ 1 - 0
drivers/cam_icp/icp_hw/icp_proc/icp_v1_hw/cam_icp_v1_dev.c

@@ -175,6 +175,7 @@ static int cam_icp_v1_component_bind(struct device *dev,
 		CAM_ERR(CAM_ICP, "icp_v1 cpas registration failed");
 		goto cpas_reg_failed;
 	}
+	core_info->hfi_handle = HFI_HANDLE_INIT_VALUE;
 	icp_v1_dev->hw_state = CAM_HW_STATE_POWER_DOWN;
 	mutex_init(&icp_v1_dev->hw_mutex);
 	spin_lock_init(&icp_v1_dev->hw_lock);

+ 132 - 24
drivers/cam_icp/icp_hw/icp_proc/icp_v2_hw/cam_icp_v2_core.c

@@ -36,16 +36,34 @@ static const struct hfi_ops hfi_icp_v2_ops = {
 	.iface_addr = cam_icp_v2_iface_addr,
 };
 
-static int cam_icp_v2_ubwc_configure(struct cam_hw_soc_info *soc_info)
+static int cam_icp_v2_ubwc_configure(struct cam_hw_soc_info *soc_info,
+	struct cam_icp_v2_core_info *core_info, void *args, uint32_t arg_size)
 {
 	struct cam_icp_soc_info *soc_priv;
+	struct cam_icp_ubwc_cfg_cmd *ubwc_cmd = args;
+	struct cam_icp_proc_ubwc_cfg_cmd ubwc_proc_cmd;
 
-	if (!soc_info)
+	if (!soc_info || !core_info || !args) {
+		CAM_ERR(CAM_ICP,
+			"Invalid args: soc info is %s core info is %s cmd args is %s",
+			CAM_IS_NULL_TO_STR(soc_info), CAM_IS_NULL_TO_STR(core_info),
+			CAM_IS_NULL_TO_STR(args));
 		return -EINVAL;
+	}
+
+	if (arg_size != sizeof(struct cam_icp_ubwc_cfg_cmd)) {
+		CAM_ERR(CAM_ICP, "Invalid ubwc cfg arg size: %u",
+			arg_size);
+		return -EINVAL;
+	}
 
 	soc_priv = soc_info->soc_private;
 
-	return cam_icp_proc_ubwc_configure(soc_priv->uconfig.ubwc_cfg_ext, 0);
+	ubwc_proc_cmd.ubwc_cfg = &soc_priv->uconfig.ubwc_cfg_ext;
+	ubwc_proc_cmd.ubwc_cfg_dev_mask = ubwc_cmd->ubwc_cfg_dev_mask;
+
+	return cam_icp_proc_ubwc_configure(&ubwc_proc_cmd,
+		ubwc_cmd->disable_ubwc_comp, core_info->hfi_handle);
 }
 
 static int cam_icp_v2_cpas_vote(struct cam_icp_v2_core_info *core_info,
@@ -187,15 +205,26 @@ static int cam_icp_v2_cpas_stop(struct cam_icp_v2_core_info *core_info)
 int cam_icp_v2_hw_init(void *priv, void *args, uint32_t arg_size)
 {
 	struct cam_hw_info *icp_v2 = priv;
+	struct cam_icp_v2_core_info *core_info;
 	unsigned long flags;
 	int rc;
-	bool send_freq_info = (args == NULL) ? false : *((bool *)args);
+	bool send_freq_info;
 
-	if (!icp_v2) {
-		CAM_ERR(CAM_ICP, "ICP device info cannot be NULL");
+	if (!icp_v2 || !args) {
+		CAM_ERR(CAM_ICP,
+			"Invalid parameters: icp hw info is %s args is %s",
+			CAM_IS_NULL_TO_STR(icp_v2), CAM_IS_NULL_TO_STR(args));
 		return -EINVAL;
 	}
 
+	if (arg_size != sizeof(bool)) {
+		CAM_ERR(CAM_ICP, "Invalid hw init cmd args");
+		return -EINVAL;
+	}
+
+	send_freq_info = *((bool *)args);
+	core_info = icp_v2->core_info;
+
 	spin_lock_irqsave(&icp_v2->hw_lock, flags);
 	if (icp_v2->hw_state == CAM_HW_STATE_POWER_UP) {
 		spin_unlock_irqrestore(&icp_v2->hw_lock, flags);
@@ -216,7 +245,7 @@ int cam_icp_v2_hw_init(void *priv, void *args, uint32_t arg_size)
 			int32_t clk_rate = 0;
 
 			clk_rate = clk_get_rate(icp_v2->soc_info.clk[icp_v2->soc_info.src_clk_idx]);
-			hfi_send_freq_info(clk_rate);
+			hfi_send_freq_info(core_info->hfi_handle, clk_rate);
 		}
 	}
 
@@ -231,18 +260,29 @@ soc_fail:
 	return rc;
 }
 
-int cam_icp_v2_hw_deinit(void *priv, void *args, uint32_t arg_size)
+int cam_icp_v2_hw_deinit(void *priv, void *args,
+	uint32_t arg_size)
 {
 	struct cam_hw_info *icp_v2_info = priv;
+	struct cam_icp_v2_core_info *core_info;
 	unsigned long flags;
 	int rc;
-	bool send_freq_info = (args == NULL) ? false : *((bool *)args);
+	bool send_freq_info;
 
-	if (!icp_v2_info) {
-		CAM_ERR(CAM_ICP, "ICP device info cannot be NULL");
+	if (!icp_v2_info || !args) {
+		CAM_ERR(CAM_ICP, "ICP device info is %s cmd args is %s",
+			CAM_IS_NULL_TO_STR(icp_v2_info), CAM_IS_NULL_TO_STR(args));
 		return -EINVAL;
 	}
 
+	if (arg_size != sizeof(bool)) {
+		CAM_ERR(CAM_ICP, "Invalid hw deinit cmd args");
+		return -EINVAL;
+	}
+
+	send_freq_info = *((bool *)args);
+	core_info = icp_v2_info->core_info;
+
 	spin_lock_irqsave(&icp_v2_info->hw_lock, flags);
 	if (icp_v2_info->hw_state == CAM_HW_STATE_POWER_DOWN) {
 		spin_unlock_irqrestore(&icp_v2_info->hw_lock, flags);
@@ -251,7 +291,7 @@ int cam_icp_v2_hw_deinit(void *priv, void *args, uint32_t arg_size)
 	spin_unlock_irqrestore(&icp_v2_info->hw_lock, flags);
 
 	if (send_freq_info)
-		hfi_send_freq_info(0);
+		hfi_send_freq_info(core_info->hfi_handle, 0);
 
 	rc = cam_icp_soc_resources_disable(&icp_v2_info->soc_info);
 	if (rc)
@@ -800,15 +840,15 @@ static inline int cam_icp_v2_download_fw(struct cam_hw_info *icp_v2_info,
 }
 
 static int __cam_icp_v2_update_clk_rate(struct cam_hw_info *icp_v2_info,
-	int32_t *clk_lvl)
+	void *args, uint32_t arg_size)
 {
 	int32_t clk_level = 0, rc;
 	struct cam_ahb_vote       ahb_vote;
 	struct cam_icp_v2_core_info *core_info = NULL;
 	struct cam_hw_soc_info   *soc_info = NULL;
 
-	if (!clk_lvl) {
-		CAM_ERR(CAM_ICP, "Invalid args");
+	if (!args) {
+		CAM_ERR(CAM_ICP, "Invalid args is NULL");
 		return -EINVAL;
 	}
 
@@ -819,10 +859,15 @@ static int __cam_icp_v2_update_clk_rate(struct cam_hw_info *icp_v2_info,
 		return -EINVAL;
 	}
 
-	clk_level = *((int32_t *)clk_lvl);
+	if (arg_size != sizeof(int32_t)) {
+		CAM_ERR(CAM_ICP, "Invalid icp update clk args");
+		return -EINVAL;
+	}
+
+	clk_level = *((int32_t *)args);
 	CAM_DBG(CAM_ICP,
 		"Update ICP clock to level [%d]", clk_level);
-	rc = cam_icp_soc_update_clk_rate(soc_info, clk_level);
+	rc = cam_icp_soc_update_clk_rate(soc_info, clk_level, core_info->hfi_handle);
 	if (rc)
 		CAM_WARN(CAM_ICP,
 			"Failed to update clk to level: %d rc: %d",
@@ -851,6 +896,64 @@ static int __cam_icp_v2_fw_mini_dump(struct cam_icp_v2_core_info *core_info,
 		core_info->fw_params.fw_buf_len);
 }
 
+static int cam_icp_v2_send_fw_init(struct cam_icp_v2_core_info *core_info)
+{
+	int rc;
+
+	if (!core_info) {
+		CAM_ERR(CAM_ICP, "Core info is NULL");
+		return -EINVAL;
+	}
+
+	rc = hfi_send_system_cmd(core_info->hfi_handle, HFI_CMD_SYS_INIT, 0, 0);
+	if (rc) {
+		CAM_ERR(CAM_ICP, "Fail to send sys init command for hfi handle: %d",
+			core_info->hfi_handle);
+		return rc;
+	}
+
+	return 0;
+}
+
+static int cam_icp_v2_pc_prep(struct cam_icp_v2_core_info *core_info)
+{
+	int rc;
+
+	if (!core_info) {
+		CAM_ERR(CAM_ICP, "Invalid core info is NULL");
+		return -EINVAL;
+	}
+
+	rc = hfi_send_system_cmd(core_info->hfi_handle, HFI_CMD_SYS_PC_PREP, 0, 0);
+	if (rc) {
+		CAM_ERR(CAM_ICP, "Fail to send PC collapse command for hfi handle: %d",
+			core_info->hfi_handle);
+		return rc;
+	}
+
+	return 0;
+}
+
+int cam_icp_v2_set_hfi_handle(struct cam_icp_v2_core_info *core_info,
+	void *args, uint32_t arg_size)
+{
+	if (!core_info || !args) {
+		CAM_ERR(CAM_ICP, "Core info is %s and args is %s",
+			CAM_IS_NULL_TO_STR(core_info), CAM_IS_NULL_TO_STR(args));
+		return -EINVAL;
+	}
+
+	if (arg_size != sizeof(int)) {
+		CAM_ERR(CAM_ICP, "Invalid set hfi handle command arg size:%u",
+			arg_size);
+		return -EINVAL;
+	}
+
+	core_info->hfi_handle = *((int *)args);
+
+	return 0;
+}
+
 int cam_icp_v2_process_cmd(void *priv, uint32_t cmd_type,
 	void *args, uint32_t arg_size)
 {
@@ -863,6 +966,9 @@ int cam_icp_v2_process_cmd(void *priv, uint32_t cmd_type,
 	}
 
 	switch (cmd_type) {
+	case CAM_ICP_CMD_SET_HFI_HANDLE:
+		rc = cam_icp_v2_set_hfi_handle(icp_v2_info->core_info, args, arg_size);
+		break;
 	case CAM_ICP_CMD_PROC_SHUTDOWN:
 		rc = cam_icp_v2_shutdown(icp_v2_info);
 		break;
@@ -885,18 +991,17 @@ int cam_icp_v2_process_cmd(void *priv, uint32_t cmd_type,
 		rc = cam_icp_v2_cpas_stop(icp_v2_info->core_info);
 		break;
 	case CAM_ICP_CMD_UBWC_CFG:
-		rc = cam_icp_v2_ubwc_configure(&icp_v2_info->soc_info);
+		rc = cam_icp_v2_ubwc_configure(&icp_v2_info->soc_info,
+			icp_v2_info->core_info, args, arg_size);
 		break;
 	case CAM_ICP_SEND_INIT:
-		hfi_send_system_cmd(HFI_CMD_SYS_INIT, 0, 0);
-		rc = 0;
+		rc = cam_icp_v2_send_fw_init(icp_v2_info->core_info);
 		break;
 	case CAM_ICP_CMD_PC_PREP:
-		hfi_send_system_cmd(HFI_CMD_SYS_PC_PREP, 0, 0);
-		rc = 0;
+		rc = cam_icp_v2_pc_prep(icp_v2_info->core_info);
 		break;
 	case CAM_ICP_CMD_CLK_UPDATE: {
-		rc = __cam_icp_v2_update_clk_rate(icp_v2_info, args);
+		rc = __cam_icp_v2_update_clk_rate(icp_v2_info, args, arg_size);
 		break;
 	}
 	case CAM_ICP_CMD_HW_DUMP:
@@ -1018,6 +1123,7 @@ int cam_icp_v2_test_irq_line(void *priv)
 	struct cam_icp_v2_core_info *core_info = NULL;
 	void __iomem *irq_membase;
 	unsigned long rem_jiffies;
+	bool send_freq_info = false;
 
 	if (!icp_v2_info) {
 		CAM_ERR(CAM_ICP, "invalid ICP device info");
@@ -1042,7 +1148,7 @@ int cam_icp_v2_test_irq_line(void *priv)
 		CAM_ERR(CAM_ICP, "ICP IRQ verification timed out");
 
 	cam_io_w_mb(0, irq_membase + core_info->hw_info->ob_irq_mask);
-	cam_icp_v2_hw_deinit(priv, NULL, 0);
+	cam_icp_v2_hw_deinit(priv, &send_freq_info, sizeof(send_freq_info));
 
 	core_info->is_irq_test = false;
 
@@ -1192,5 +1298,7 @@ int cam_icp_v2_core_init(
 		rc = -EINVAL;
 	}
 
+	core_info->hfi_handle = HFI_HANDLE_INIT_VALUE;
+
 	return rc;
 }

+ 1 - 0
drivers/cam_icp/icp_hw/icp_proc/icp_v2_hw/cam_icp_v2_core.h

@@ -33,6 +33,7 @@ struct cam_icp_v2_core_info {
 	struct cam_icp_v2_hw_info *hw_info;
 	int32_t reg_base_idx[ICP_V2_BASE_MAX];
 	uint32_t cpas_handle;
+	int hfi_handle;
 	enum cam_icp_v2_reg_base irq_regbase_idx;
 	struct {
 		const struct firmware *fw_elf;

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

@@ -413,7 +413,7 @@ int cam_ipe_process_cmd(void *device_priv, uint32_t cmd_type,
 		rc = cam_ipe_handle_resume(ipe_dev);
 		break;
 	case CAM_ICP_DEV_CMD_UPDATE_CLK: {
-		struct cam_icp_clk_update_cmd *clk_upd_cmd = cmd_args;
+		struct cam_icp_dev_clk_update_cmd *clk_upd_cmd = cmd_args;
 		struct cam_ahb_vote ahb_vote;
 		uint32_t clk_rate = clk_upd_cmd->curr_clk_rate;
 		int32_t clk_level  = 0, err = 0;

+ 1 - 1
drivers/cam_icp/icp_hw/ofe_hw/ofe_core.c

@@ -417,7 +417,7 @@ int cam_ofe_process_cmd(void *device_priv, uint32_t cmd_type,
 		rc = cam_ofe_handle_resume(ofe_dev);
 		break;
 	case CAM_ICP_DEV_CMD_UPDATE_CLK: {
-		struct cam_icp_clk_update_cmd *clk_upd_cmd = cmd_args;
+		struct cam_icp_dev_clk_update_cmd *clk_upd_cmd = cmd_args;
 		struct cam_ahb_vote ahb_vote;
 		uint32_t clk_rate = clk_upd_cmd->curr_clk_rate;
 		int32_t clk_level = 0, err = 0;

Неке датотеке нису приказане због велике количине промена