From 96ff2ea80bcaf100014dfd19e401fdb11a644987 Mon Sep 17 00:00:00 2001 From: Sokchetra Eung Date: Tue, 20 Sep 2022 18:07:30 -0700 Subject: [PATCH] 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 --- drivers/cam_icp/fw_inc/hfi_intf.h | 95 ++- drivers/cam_icp/fw_inc/hfi_reg.h | 4 + drivers/cam_icp/fw_inc/hfi_sys_defs.h | 5 + drivers/cam_icp/hfi.c | 605 ++++++++++++------ drivers/cam_icp/icp_hw/bps_hw/bps_core.c | 2 +- .../icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c | 209 ++++-- .../icp_hw/icp_hw_mgr/cam_icp_hw_mgr.h | 7 +- .../icp_hw_mgr/include/cam_icp_hw_intf.h | 16 +- .../icp_proc/icp_common/cam_icp_proc_common.c | 66 +- .../icp_proc/icp_common/cam_icp_proc_common.h | 15 +- .../icp_proc/icp_common/cam_icp_soc_common.c | 95 ++- .../icp_proc/icp_common/cam_icp_soc_common.h | 9 +- .../icp_proc/icp_v1_hw/cam_icp_v1_core.c | 124 +++- .../icp_proc/icp_v1_hw/cam_icp_v1_core.h | 2 + .../icp_proc/icp_v1_hw/cam_icp_v1_dev.c | 1 + .../icp_proc/icp_v2_hw/cam_icp_v2_core.c | 156 ++++- .../icp_proc/icp_v2_hw/cam_icp_v2_core.h | 1 + drivers/cam_icp/icp_hw/ipe_hw/ipe_core.c | 2 +- drivers/cam_icp/icp_hw/ofe_hw/ofe_core.c | 2 +- 19 files changed, 1046 insertions(+), 370 deletions(-) diff --git a/drivers/cam_icp/fw_inc/hfi_intf.h b/drivers/cam_icp/fw_inc/hfi_intf.h index 9d83f6b171..ebfb470804 100644 --- a/drivers/cam_icp/fw_inc/hfi_intf.h +++ b/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 - */ -int hfi_cmd_ubwc_config(uint32_t *ubwc_cfg); - -/** - * cam_hfi_resume() - function to resume - * @hfi_mem: hfi memory info * * Returns success(zero)/failure(non zero) */ -int cam_hfi_resume(struct hfi_mem_info *hfi_mem); +int hfi_cmd_ubwc_config(int client_handle, uint32_t *ubwc_cfg); + +/** + * cam_hfi_resume() - function to resume + * @client_handle: client handle to be retrieved + * + * Returns success(zero)/failure(non zero) + */ +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_ */ diff --git a/drivers/cam_icp/fw_inc/hfi_reg.h b/drivers/cam_icp/fw_inc/hfi_reg.h index 0d3ca7c444..8bede5c6ba 100644 --- a/drivers/cam_icp/fw_inc/hfi_reg.h +++ b/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 diff --git a/drivers/cam_icp/fw_inc/hfi_sys_defs.h b/drivers/cam_icp/fw_inc/hfi_sys_defs.h index aac65ede0f..2b63987c82 100644 --- a/drivers/cam_icp/fw_inc/hfi_sys_defs.h +++ b/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 diff --git a/drivers/cam_icp/hfi.c b/drivers/cam_icp/hfi.c index 198b027425..19df872264 100644 --- a/drivers/cam_icp/hfi.c +++ b/drivers/cam_icp/hfi.c @@ -27,7 +27,6 @@ #define HFI_VERSION_INFO_MAJOR_VAL 1 #define HFI_VERSION_INFO_MINOR_VAL 1 #define HFI_VERSION_INFO_STEP_VAL 0 -#define HFI_VERSION_INFO_STEP_VAL 0 #define HFI_VERSION_INFO_MAJOR_BMSK 0xFF000000 #define HFI_VERSION_INFO_MAJOR_SHFT 24 #define HFI_VERSION_INFO_MINOR_BMSK 0xFFFF00 @@ -39,11 +38,14 @@ #define HFI_POLL_DELAY_US 10 #define HFI_POLL_TIMEOUT_US 1500000 -static struct hfi_info *g_hfi; -unsigned int g_icp_mmu_hdl; +struct hfi_top_info { + uint32_t num_hfi; + struct hfi_info *hfi[HFI_NUM_MAX]; +}; + +struct hfi_top_info g_hfi; +static DEFINE_MUTEX(g_hfi_lock); -static DEFINE_MUTEX(hfi_cmd_q_mutex); -static DEFINE_MUTEX(hfi_msg_q_mutex); static int cam_hfi_presil_setup(struct hfi_mem_info *hfi_mem); static int cam_hfi_presil_set_init_request(void); @@ -72,6 +74,27 @@ static void __iomem *hfi_iface_addr(struct hfi_info *hfi) return IS_ERR_OR_NULL(ret) ? NULL : ret; } +static inline int hfi_get_client_info(int client_handle, struct hfi_info **hfi) +{ + uint32_t idx; + + idx = HFI_GET_INDEX(client_handle); + if (!IS_VALID_HFI_INDEX(idx)) { + CAM_ERR(CAM_HFI, "Invalid HFI index: %u from hdl:%d", + idx, client_handle); + return -EINVAL; + } + + *hfi = g_hfi.hfi[idx]; + if (!g_hfi.hfi[idx]) { + CAM_ERR(CAM_HFI, "HFI interface not setup for client hdl: %d", + client_handle); + return -ENODEV; + } + + return 0; +} + static void hfi_queue_dump(uint32_t *dwords, int count) { int i; @@ -96,48 +119,68 @@ static void hfi_queue_dump(uint32_t *dwords, int count) rows * 4, dwords[0], dwords[1], dwords[2]); } -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) { - struct hfi_mem_info *hfi_mem = &g_hfi->map; + struct hfi_info *hfi; + struct hfi_mem_info *hfi_mem; struct hfi_qtbl *qtbl; struct hfi_q_hdr *q_hdr; uint32_t *dwords; - int num_dwords; + int rc; + rc = hfi_get_client_info(client_handle, &hfi); + if (rc) { + CAM_ERR(CAM_HFI, "Failed to get hfi info rc: %d for hdl: %d", + rc, client_handle); + return; + } + + hfi_mem = &hfi->map; if (!hfi_mem) { - CAM_ERR(CAM_HFI, "hfi mem info NULL... unable to dump queues"); + CAM_ERR(CAM_HFI, "hfi mem info NULL... unable to dump queues for hdl: %d", + client_handle); return; } qtbl = (struct hfi_qtbl *)hfi_mem->qtbl.kva; q_hdr = &qtbl->q_hdr[Q_CMD]; dwords = (uint32_t *)hfi_mem->cmd_q.kva; - num_dwords = ICP_CMD_Q_SIZE_IN_BYTES >> BYTE_WORD_SHIFT; memcpy(dst->cmd_q, dwords, ICP_CMD_Q_SIZE_IN_BYTES); q_hdr = &qtbl->q_hdr[Q_MSG]; dwords = (uint32_t *)hfi_mem->msg_q.kva; memcpy(dst->msg_q, dwords, ICP_CMD_Q_SIZE_IN_BYTES); - dst->msg_q_state = g_hfi->msg_q_state; - dst->cmd_q_state = g_hfi->cmd_q_state; + dst->msg_q_state = hfi->msg_q_state; + dst->cmd_q_state = hfi->cmd_q_state; } -void cam_hfi_queue_dump(bool dump_queue_data) +void cam_hfi_queue_dump(int client_handle, bool dump_queue_data) { - struct hfi_mem_info *hfi_mem = &g_hfi->map; + struct hfi_info *hfi; + struct hfi_mem_info *hfi_mem; struct hfi_qtbl *qtbl; struct hfi_q_hdr *q_hdr; uint32_t *dwords; - int num_dwords; + int num_dwords, rc; + rc = hfi_get_client_info(client_handle, &hfi); + if (rc) { + CAM_ERR(CAM_HFI, "Failed to get hfi info rc: %d for hdl: %d", + rc, client_handle); + return; + } + + hfi_mem = &hfi->map; if (!hfi_mem) { - CAM_ERR(CAM_HFI, "hfi mem info NULL... unable to dump queues"); + CAM_ERR(CAM_HFI, "mem info NULL... unable to dump queues for hdl: %d", + client_handle); return; } qtbl = (struct hfi_qtbl *)hfi_mem->qtbl.kva; CAM_INFO(CAM_HFI, - "qtbl header: version=0x%08x tbl_size=%u numq=%u qhdr_size=%u", + "hfi hdl: %u qtbl header: version=0x%08x tbl_size=%u numq=%u qhdr_size=%u", + client_handle, qtbl->q_tbl_hdr.qtbl_version, qtbl->q_tbl_hdr.qtbl_size, qtbl->q_tbl_hdr.qtbl_num_q, @@ -173,42 +216,45 @@ void cam_hfi_queue_dump(bool dump_queue_data) } #ifndef CONFIG_CAM_PRESIL -int hfi_write_cmd(void *cmd_ptr) +int hfi_write_cmd(int client_handle, void *cmd_ptr) { uint32_t size_in_words, empty_space, new_write_idx, read_idx, temp; uint32_t *write_q, *write_ptr; + struct hfi_info *hfi; struct hfi_qtbl *q_tbl; struct hfi_q_hdr *q; int rc = 0; + rc = hfi_get_client_info(client_handle, &hfi); + if (rc) { + CAM_ERR(CAM_HFI, "Failed to get hfi info rc: %d for hdl: %d", + rc, client_handle); + return rc; + } + if (!cmd_ptr) { - CAM_ERR(CAM_HFI, "command is null"); + CAM_ERR(CAM_HFI, "command is null for hfi hdl: %d", + client_handle); return -EINVAL; } - mutex_lock(&hfi_cmd_q_mutex); - if (!g_hfi) { - CAM_ERR(CAM_HFI, "HFI interface not setup"); + mutex_lock(&hfi->cmd_q_lock); + if (hfi->hfi_state != HFI_READY || + !hfi->cmd_q_state) { + CAM_ERR(CAM_HFI, "Invalid hfi state: %u cmd q state: %u hfi hdl: %d", + hfi->hfi_state, hfi->cmd_q_state, client_handle); rc = -ENODEV; goto err; } - if (g_hfi->hfi_state != HFI_READY || - !g_hfi->cmd_q_state) { - CAM_ERR(CAM_HFI, "HFI state: %u, cmd q state: %u", - g_hfi->hfi_state, g_hfi->cmd_q_state); - rc = -ENODEV; - goto err; - } - - q_tbl = (struct hfi_qtbl *)g_hfi->map.qtbl.kva; + q_tbl = (struct hfi_qtbl *)hfi->map.qtbl.kva; q = &q_tbl->q_hdr[Q_CMD]; - write_q = (uint32_t *)g_hfi->map.cmd_q.kva; + write_q = (uint32_t *)hfi->map.cmd_q.kva; size_in_words = (*(uint32_t *)cmd_ptr) >> BYTE_WORD_SHIFT; if (!size_in_words) { - CAM_DBG(CAM_HFI, "failed"); + CAM_DBG(CAM_HFI, "hfi hdl: %u word size is NULL"); rc = -EINVAL; goto err; } @@ -218,7 +264,7 @@ int hfi_write_cmd(void *cmd_ptr) (q->qhdr_q_size - (q->qhdr_write_idx - read_idx)) : (read_idx - q->qhdr_write_idx); if (empty_space <= size_in_words) { - CAM_ERR(CAM_HFI, "failed: empty space %u, size_in_words %u", + CAM_ERR(CAM_HFI, "hfi hdl: %u failed: empty space %u, size_in_words %u", empty_space, size_in_words); rc = -EIO; goto err; @@ -251,18 +297,19 @@ int hfi_write_cmd(void *cmd_ptr) * firmware to process */ wmb(); - hfi_irq_raise(g_hfi); + hfi_irq_raise(hfi); /* Ensure HOST2ICP trigger is received by FW */ wmb(); err: - mutex_unlock(&hfi_cmd_q_mutex); + mutex_unlock(&hfi->cmd_q_lock); return rc; } -int hfi_read_message(uint32_t *pmsg, uint8_t q_id, +int hfi_read_message(int client_handle, uint32_t *pmsg, uint8_t q_id, uint32_t *words_read) { + struct hfi_info *hfi; struct hfi_qtbl *q_tbl_ptr; struct hfi_q_hdr *q; uint32_t new_read_idx, size_in_words, word_diff, temp; @@ -270,8 +317,15 @@ int hfi_read_message(uint32_t *pmsg, uint8_t q_id, uint32_t size_upper_bound = 0; int rc = 0; + rc = hfi_get_client_info(client_handle, &hfi); + if (rc) { + CAM_ERR(CAM_HFI, "Failed to get hfi info rc: %d for hdl:%d", + rc, client_handle); + return rc; + } + if (!pmsg) { - CAM_ERR(CAM_HFI, "Invalid msg"); + CAM_ERR(CAM_HFI, "client hdl: %d Invalid msg", client_handle); return -EINVAL; } @@ -280,36 +334,30 @@ int hfi_read_message(uint32_t *pmsg, uint8_t q_id, return -EINVAL; } - mutex_lock(&hfi_msg_q_mutex); - if (!g_hfi) { - CAM_ERR(CAM_HFI, "hfi not set up yet"); + mutex_lock(&hfi->msg_q_lock); + if (hfi->hfi_state != HFI_READY || + !hfi->msg_q_state) { + CAM_ERR(CAM_HFI, "Invalid hfi state:%u msg q state: %u hfi hdl: %d", + hfi->hfi_state, hfi->msg_q_state, client_handle); rc = -ENODEV; goto err; } - if ((g_hfi->hfi_state != HFI_READY) || - !g_hfi->msg_q_state) { - CAM_ERR(CAM_HFI, "hfi state: %u, msg q state: %u", - g_hfi->hfi_state, g_hfi->msg_q_state); - rc = -ENODEV; - goto err; - } - - q_tbl_ptr = (struct hfi_qtbl *)g_hfi->map.qtbl.kva; + q_tbl_ptr = (struct hfi_qtbl *)hfi->map.qtbl.kva; q = &q_tbl_ptr->q_hdr[q_id]; if (q->qhdr_read_idx == q->qhdr_write_idx) { - CAM_DBG(CAM_HFI, "Q not ready, state:%u, r idx:%u, w idx:%u", - g_hfi->hfi_state, q->qhdr_read_idx, q->qhdr_write_idx); + CAM_DBG(CAM_HFI, "hfi hdl: %d Q not ready, state:%u, r idx:%u, w idx:%u", + client_handle, hfi->hfi_state, q->qhdr_read_idx, q->qhdr_write_idx); rc = -EIO; goto err; } size_upper_bound = q->qhdr_q_size; if (q_id == Q_MSG) - read_q = (uint32_t *)g_hfi->map.msg_q.kva; + read_q = (uint32_t *)hfi->map.msg_q.kva; else - read_q = (uint32_t *)g_hfi->map.dbg_q.kva; + read_q = (uint32_t *)hfi->map.dbg_q.kva; read_ptr = (uint32_t *)(read_q + q->qhdr_read_idx); write_ptr = (uint32_t *)(read_q + q->qhdr_write_idx); @@ -323,8 +371,8 @@ int hfi_read_message(uint32_t *pmsg, uint8_t q_id, if ((size_in_words == 0) || (size_in_words > size_upper_bound)) { - CAM_ERR(CAM_HFI, "invalid HFI message packet size - 0x%08x", - size_in_words << BYTE_WORD_SHIFT); + CAM_ERR(CAM_HFI, "Invalid HFI message packet size - 0x%08x hfi hdl:%d", + size_in_words << BYTE_WORD_SHIFT, client_handle); q->qhdr_read_idx = q->qhdr_write_idx; rc = -EIO; goto err; @@ -349,12 +397,12 @@ int hfi_read_message(uint32_t *pmsg, uint8_t q_id, */ wmb(); err: - mutex_unlock(&hfi_msg_q_mutex); + mutex_unlock(&hfi->msg_q_lock); return rc; } #endif /* #ifndef CONFIG_CAM_PRESIL */ -int hfi_cmd_ubwc_config(uint32_t *ubwc_cfg) +int hfi_cmd_ubwc_config(int client_handle, uint32_t *ubwc_cfg) { uint8_t *prop; struct hfi_cmd_prop *dbg_prop; @@ -364,8 +412,8 @@ int hfi_cmd_ubwc_config(uint32_t *ubwc_cfg) sizeof(struct hfi_cmd_ubwc_cfg); CAM_DBG(CAM_HFI, - "size of ubwc %u, ubwc_cfg [rd-0x%x,wr-0x%x]", - size, ubwc_cfg[0], ubwc_cfg[1]); + "hfi hdl: %d size of ubwc %u, ubwc_cfg [rd-0x%x,wr-0x%x]", + client_handle, size, ubwc_cfg[0], ubwc_cfg[1]); prop = kzalloc(size, GFP_KERNEL); if (!prop) @@ -379,14 +427,14 @@ int hfi_cmd_ubwc_config(uint32_t *ubwc_cfg) dbg_prop->prop_data[1] = ubwc_cfg[0]; dbg_prop->prop_data[2] = ubwc_cfg[1]; - hfi_write_cmd(prop); + hfi_write_cmd(client_handle, prop); kfree(prop); return 0; } -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) { uint8_t *prop; struct hfi_cmd_prop *dbg_prop; @@ -396,9 +444,9 @@ int hfi_cmd_ubwc_config_ext(uint32_t *ubwc_ipe_cfg, sizeof(struct hfi_cmd_ubwc_cfg_ext); CAM_DBG(CAM_HFI, - "size of ubwc %u, ubwc_ipe_cfg[rd-0x%x,wr-0x%x] ubwc_bps_cfg[rd-0x%x,wr-0x%x]", - size, ubwc_ipe_cfg[0], ubwc_ipe_cfg[1], - ubwc_bps_cfg[0], ubwc_bps_cfg[1]); + "hfi hdl: %d size of ubwc %u, ubwc_ipe_cfg[rd-0x%x,wr-0x%x] ubwc_bps_cfg[rd-0x%x,wr-0x%x] ubwc_ofe_cfg[rd-0x%x,wr-0x%x]", + client_handle, size, ubwc_ipe_cfg[0], ubwc_ipe_cfg[1], ubwc_bps_cfg[0], + ubwc_bps_cfg[1], ubwc_ofe_cfg[0], ubwc_ofe_cfg[1]); prop = kzalloc(size, GFP_KERNEL); if (!prop) @@ -413,46 +461,28 @@ int hfi_cmd_ubwc_config_ext(uint32_t *ubwc_ipe_cfg, dbg_prop->prop_data[2] = ubwc_bps_cfg[1]; dbg_prop->prop_data[3] = ubwc_ipe_cfg[0]; dbg_prop->prop_data[4] = ubwc_ipe_cfg[1]; - - hfi_write_cmd(prop); + dbg_prop->prop_data[5] = ubwc_ofe_cfg[0]; + dbg_prop->prop_data[6] = ubwc_ofe_cfg[1]; + hfi_write_cmd(client_handle, prop); kfree(prop); return 0; } - -int hfi_enable_dev_pc(bool enable, uint32_t core_info) -{ - uint8_t *prop; - struct hfi_cmd_prop *dbg_prop; - uint32_t size = 0; - - size = sizeof(struct hfi_cmd_prop) + - sizeof(struct hfi_dev_pc); - - prop = kzalloc(size, GFP_KERNEL); - if (!prop) - return -ENOMEM; - - dbg_prop = (struct hfi_cmd_prop *)prop; - dbg_prop->size = size; - dbg_prop->pkt_type = HFI_CMD_SYS_SET_PROPERTY; - dbg_prop->num_prop = 1; - dbg_prop->prop_data[0] = HFI_PROP_SYS_IPEBPS_PC; - dbg_prop->prop_data[1] = enable; - dbg_prop->prop_data[2] = core_info; - - hfi_write_cmd(prop); - kfree(prop); - - return 0; -} - -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) { uint8_t *prop; + struct hfi_info *hfi; struct hfi_cmd_prop *dbg_prop; uint32_t size = 0, val; + int rc; + + rc = hfi_get_client_info(client_handle, &hfi); + if (rc) { + CAM_ERR(CAM_HFI, "Failed to get hfi info rc: %d for hdl: %d", + rc, client_handle); + return rc; + } val = HFI_DEBUG_MSG_LOW | HFI_DEBUG_MSG_MEDIUM | @@ -466,8 +496,8 @@ int hfi_set_debug_level(u64 icp_dbg_type, uint32_t lvl) if (lvl > val) return -EINVAL; - if (g_hfi) - g_hfi->dbg_lvl = lvl; + if (hfi) + hfi->dbg_lvl = lvl; size = sizeof(struct hfi_cmd_prop) + sizeof(struct hfi_debug); @@ -483,21 +513,31 @@ int hfi_set_debug_level(u64 icp_dbg_type, uint32_t lvl) dbg_prop->prop_data[0] = HFI_PROP_SYS_DEBUG_CFG; dbg_prop->prop_data[1] = lvl; dbg_prop->prop_data[2] = icp_dbg_type; - hfi_write_cmd(prop); + hfi_write_cmd(client_handle, prop); kfree(prop); return 0; } -int hfi_set_fw_dump_levels(uint32_t hang_dump_lvl, +int hfi_set_fw_dump_levels(int client_handle, uint32_t hang_dump_lvl, uint32_t ram_dump_lvl) { uint8_t *prop = NULL; + struct hfi_info *hfi; struct hfi_cmd_prop *fw_dump_level_switch_prop = NULL; uint32_t size = 0; + int rc; - CAM_DBG(CAM_HFI, "fw dump ENTER"); + rc = hfi_get_client_info(client_handle, &hfi); + if (rc) { + CAM_ERR(CAM_HFI, "Failed to get hfi info rc: %d for hdl: %d", + rc, client_handle); + return rc; + } + + CAM_DBG(CAM_HFI, "hfi hdl: %d fw dump ENTER", + client_handle); size = sizeof(struct hfi_cmd_prop) + sizeof(uint32_t); prop = kzalloc(size, GFP_KERNEL); @@ -512,15 +552,16 @@ int hfi_set_fw_dump_levels(uint32_t hang_dump_lvl, fw_dump_level_switch_prop->prop_data[1] = hang_dump_lvl; /* Write hang dump level */ - hfi_write_cmd(prop); + hfi_write_cmd(client_handle, prop); /* Update and write ramdump level */ fw_dump_level_switch_prop->prop_data[0] = HFI_PROP_SYS_ICP_RAMDUMP_MODE; fw_dump_level_switch_prop->prop_data[1] = ram_dump_lvl; - hfi_write_cmd(prop); + hfi_write_cmd(client_handle, prop); CAM_DBG(CAM_HFI, - "prop->size = %d prop->pkt_type = %d prop->num_prop = %d hang_dump_lvl = %u ram_dump_lvl = %u", + "hfi hdl: %d prop->size = %d prop->pkt_type = %d prop->num_prop = %d hang_dump_lvl = %u ram_dump_lvl = %u", + client_handle, fw_dump_level_switch_prop->size, fw_dump_level_switch_prop->pkt_type, fw_dump_level_switch_prop->num_prop, @@ -530,18 +571,22 @@ int hfi_set_fw_dump_levels(uint32_t hang_dump_lvl, return 0; } -int hfi_send_freq_info(int32_t freq) +int hfi_send_freq_info(int client_handle, int32_t freq) { uint8_t *prop = NULL; + struct hfi_info *hfi; struct hfi_cmd_prop *dbg_prop = NULL; uint32_t size = 0; + int rc; - if (!g_hfi) { - CAM_ERR(CAM_HFI, "HFI interface not setup"); - return -ENODEV; + rc = hfi_get_client_info(client_handle, &hfi); + if (rc) { + CAM_ERR(CAM_HFI, "Failed to get hfi info rc: %d for hdl: %d", + rc, client_handle); + return rc; } - if (!(g_hfi->dbg_lvl & HFI_DEBUG_MSG_PERF)) + if (!(hfi->dbg_lvl & HFI_DEBUG_MSG_PERF)) return -EINVAL; size = sizeof(struct hfi_cmd_prop) + sizeof(freq); @@ -556,33 +601,43 @@ int hfi_send_freq_info(int32_t freq) dbg_prop->prop_data[0] = HFI_PROP_SYS_ICP_HW_FREQUENCY; dbg_prop->prop_data[1] = freq; - CAM_DBG(CAM_HFI, "prop->size = %d\n" + CAM_DBG(CAM_HFI, + "hfi hdl: %d\n" + "prop->size = %d\n" "prop->pkt_type = %d\n" "prop->num_prop = %d\n" "prop->prop_data[0] = %d\n" "prop->prop_data[1] = %d\n" "dbg_lvl = 0x%x\n", + client_handle, dbg_prop->size, dbg_prop->pkt_type, dbg_prop->num_prop, dbg_prop->prop_data[0], dbg_prop->prop_data[1], - g_hfi->dbg_lvl); + hfi->dbg_lvl); - hfi_write_cmd(prop); + hfi_write_cmd(client_handle, prop); kfree(prop); return 0; } -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) { + int rc = 0; + + if (!IS_VALID_HFI_INDEX(client_handle)) { + CAM_ERR(CAM_HFI, "Invalid client handle: %d", client_handle); + return -EINVAL; + } + switch (type) { case HFI_CMD_SYS_INIT: { struct hfi_cmd_sys_init init; init.size = sizeof(struct hfi_cmd_sys_init); init.pkt_type = type; - hfi_write_cmd(&init); + rc = hfi_write_cmd(client_handle, &init); } break; case HFI_CMD_SYS_PC_PREP: { @@ -590,7 +645,7 @@ void hfi_send_system_cmd(uint32_t type, uint64_t data, uint32_t size) prep.size = sizeof(struct hfi_cmd_pc_prep); prep.pkt_type = type; - hfi_write_cmd(&prep); + rc = hfi_write_cmd(client_handle, &prep); } break; case HFI_CMD_SYS_SET_PROPERTY: { @@ -601,7 +656,7 @@ void hfi_send_system_cmd(uint32_t type, uint64_t data, uint32_t size) prop.pkt_type = type; prop.num_prop = 1; prop.prop_data[0] = HFI_PROP_SYS_DEBUG_CFG; - hfi_write_cmd(&prop); + rc = hfi_write_cmd(client_handle, &prop); } } break; @@ -613,7 +668,7 @@ void hfi_send_system_cmd(uint32_t type, uint64_t data, uint32_t size) ping.size = sizeof(struct hfi_cmd_ping_pkt); ping.pkt_type = type; ping.user_data = (uint64_t)data; - hfi_write_cmd(&ping); + rc = hfi_write_cmd(client_handle, &ping); } break; case HFI_CMD_SYS_RESET: { @@ -622,7 +677,7 @@ void hfi_send_system_cmd(uint32_t type, uint64_t data, uint32_t size) reset.size = sizeof(struct hfi_cmd_sys_reset_pkt); reset.pkt_type = type; reset.user_data = (uint64_t)data; - hfi_write_cmd(&reset); + rc = hfi_write_cmd(client_handle, &reset); } break; case HFI_CMD_IPEBPS_CREATE_HANDLE: { @@ -632,15 +687,18 @@ void hfi_send_system_cmd(uint32_t type, uint64_t data, uint32_t size) handle.pkt_type = type; handle.handle_type = (uint32_t)data; handle.user_data1 = 0; - hfi_write_cmd(&handle); + rc = hfi_write_cmd(client_handle, &handle); } break; case HFI_CMD_IPEBPS_ASYNC_COMMAND_INDIRECT: break; default: - CAM_ERR(CAM_HFI, "command not supported :%d", type); + CAM_ERR(CAM_HFI, "command not supported: %u client handle: %d", + type, client_handle); break; } + + return rc; } @@ -675,31 +733,44 @@ int hfi_get_hw_caps(void *query_buf) return 0; } -int cam_hfi_resume(struct hfi_mem_info *hfi_mem) +int cam_hfi_resume(int client_handle) { int rc = 0; + struct hfi_info *hfi; + struct hfi_mem_info *hfi_mem; uint32_t fw_version, status = 0; - void __iomem *icp_base = hfi_iface_addr(g_hfi); + void __iomem *icp_base = NULL; + + rc = hfi_get_client_info(client_handle, &hfi); + if (rc) { + CAM_ERR(CAM_HFI, "Failed to get hfi info rc: %d for hdl:%d", + rc, client_handle); + return rc; + } + + icp_base = hfi_iface_addr(hfi); if (!icp_base) { - CAM_ERR(CAM_HFI, "invalid HFI interface address"); + CAM_ERR(CAM_HFI, "invalid HFI interface address for hdl:%d", + client_handle); return -EINVAL; } if (cam_common_read_poll_timeout(icp_base + - HFI_REG_ICP_HOST_INIT_RESPONSE, - HFI_POLL_DELAY_US, HFI_POLL_TIMEOUT_US, - (uint32_t)UINT_MAX, ICP_INIT_RESP_SUCCESS, &status)) { - CAM_ERR(CAM_HFI, "response poll timed out: status=0x%08x", - status); - return -ETIMEDOUT; + HFI_REG_ICP_HOST_INIT_RESPONSE, + HFI_POLL_DELAY_US, HFI_POLL_TIMEOUT_US, + (uint32_t)UINT_MAX, ICP_INIT_RESP_SUCCESS, &status)) { + CAM_ERR(CAM_HFI, "response poll timed out: status=0x%08x hfi hdl: %d", + status, client_handle); + return -ETIMEDOUT; } - hfi_irq_enable(g_hfi); + hfi_irq_enable(hfi); fw_version = cam_io_r(icp_base + HFI_REG_FW_VERSION); - CAM_DBG(CAM_HFI, "fw version : [%x]", fw_version); + CAM_DBG(CAM_HFI, "hfi hdl: %d fw version : [%x]", client_handle, fw_version); + hfi_mem = &hfi->map; cam_io_w_mb((uint32_t)hfi_mem->qtbl.iova, icp_base + HFI_REG_QTBL_PTR); cam_io_w_mb((uint32_t)hfi_mem->sfr_buf.iova, icp_base + HFI_REG_SFR_PTR); @@ -763,43 +834,38 @@ int cam_hfi_resume(struct hfi_mem_info *hfi_mem) return rc; } -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_mode) { int rc = 0; uint32_t status = 0; + struct hfi_info *hfi = NULL; struct hfi_qtbl *qtbl; struct hfi_qtbl_hdr *qtbl_hdr; struct hfi_q_hdr *cmd_q_hdr, *msg_q_hdr, *dbg_q_hdr; struct sfr_buf *sfr_buffer; void __iomem *icp_base; + rc = hfi_get_client_info(client_handle, &hfi); + if (rc) { + CAM_ERR(CAM_HFI, "Failed to get hfi info rc: %d for hdl %d", + rc, client_handle); + return rc; + } + if (!hfi_mem || !hfi_ops || !priv) { CAM_ERR(CAM_HFI, - "invalid arg: hfi_mem=%pK hfi_ops=%pK priv=%pK", - hfi_mem, hfi_ops, priv); + "invalid arg: hfi_mem=%pK hfi_ops=%pK priv=%pK hfi hdl:%d", + hfi_mem, hfi_ops, priv, client_handle); return -EINVAL; } - mutex_lock(&hfi_cmd_q_mutex); - mutex_lock(&hfi_msg_q_mutex); + mutex_lock(&hfi->cmd_q_lock); + mutex_lock(&hfi->msg_q_lock); - if (!g_hfi) { - g_hfi = kzalloc(sizeof(struct hfi_info), GFP_KERNEL); - if (!g_hfi) { - rc = -ENOMEM; - goto alloc_fail; - } - } - - if (g_hfi->hfi_state != HFI_DEINIT) { - CAM_ERR(CAM_HFI, "hfi_init: invalid state"); - rc = -EINVAL; - goto regions_fail; - } - - memcpy(&g_hfi->map, hfi_mem, sizeof(g_hfi->map)); - g_hfi->hfi_state = HFI_DEINIT; + hfi->hfi_state = HFI_INIT; + memcpy(&hfi->map, hfi_mem, sizeof(hfi->map)); qtbl = (struct hfi_qtbl *)hfi_mem->qtbl.kva; qtbl_hdr = &qtbl->q_tbl_hdr; @@ -910,17 +976,18 @@ int cam_hfi_init(struct hfi_mem_info *hfi_mem, const struct hfi_ops *hfi_ops, break; default: - CAM_ERR(CAM_HFI, "Invalid event driven mode :%u", - event_driven_mode); + CAM_ERR(CAM_HFI, "Invalid event driven mode :%u for hdl:%d", + event_driven_mode, client_handle); break; } - g_hfi->ops = *hfi_ops; - g_hfi->priv = priv; + hfi->ops = *hfi_ops; + hfi->priv = priv; - icp_base = hfi_iface_addr(g_hfi); + icp_base = hfi_iface_addr(hfi); if (!icp_base) { - CAM_ERR(CAM_HFI, "invalid HFI interface address"); + CAM_ERR(CAM_HFI, "invalid HFI interface address for hdl: %d", + client_handle); rc = -EINVAL; goto regions_fail; } @@ -962,6 +1029,8 @@ int cam_hfi_init(struct hfi_mem_info *hfi_mem, const struct hfi_ops *hfi_ops, cam_io_w_mb((uint32_t)hfi_mem->hwmutex.len, icp_base + HFI_REG_DEVICE_HWMUTEX_SIZE); + CAM_DBG(CAM_HFI, "HFI handle: %d", client_handle); + CAM_DBG(CAM_HFI, "IO1 : [0x%x 0x%x] IO2 [0x%x 0x%x]", hfi_mem->io_mem.iova, hfi_mem->io_mem.len, hfi_mem->io_mem2.iova, hfi_mem->io_mem2.len); @@ -992,9 +1061,9 @@ int cam_hfi_init(struct hfi_mem_info *hfi_mem, const struct hfi_ops *hfi_ops, cam_hfi_presil_set_init_request(); if (cam_common_read_poll_timeout(icp_base + - HFI_REG_ICP_HOST_INIT_RESPONSE, - HFI_POLL_DELAY_US, HFI_POLL_TIMEOUT_US, - (uint32_t)UINT_MAX, ICP_INIT_RESP_SUCCESS, &status)) { + HFI_REG_ICP_HOST_INIT_RESPONSE, + HFI_POLL_DELAY_US, HFI_POLL_TIMEOUT_US, + (uint32_t)UINT_MAX, ICP_INIT_RESP_SUCCESS, &status)) { CAM_ERR(CAM_HFI, "response poll timed out: status=0x%08x", status); rc = -ETIMEDOUT; @@ -1004,49 +1073,162 @@ int cam_hfi_init(struct hfi_mem_info *hfi_mem, const struct hfi_ops *hfi_ops, CAM_DBG(CAM_HFI, "ICP fw version: 0x%x", cam_io_r(icp_base + HFI_REG_FW_VERSION)); - g_hfi->hfi_state = HFI_READY; - g_hfi->cmd_q_state = true; - g_hfi->msg_q_state = true; + hfi->cmd_q_state = true; + hfi->msg_q_state = true; + hfi->hfi_state = HFI_READY; - hfi_irq_enable(g_hfi); + hfi_irq_enable(hfi); - mutex_unlock(&hfi_cmd_q_mutex); - mutex_unlock(&hfi_msg_q_mutex); + mutex_unlock(&hfi->cmd_q_lock); + mutex_unlock(&hfi->msg_q_lock); return rc; + regions_fail: - kfree(g_hfi); - g_hfi = NULL; -alloc_fail: - mutex_unlock(&hfi_cmd_q_mutex); - mutex_unlock(&hfi_msg_q_mutex); + mutex_unlock(&hfi->cmd_q_lock); + mutex_unlock(&hfi->msg_q_lock); return rc; } -void cam_hfi_deinit(void) +void cam_hfi_deinit(int client_handle) { + struct hfi_info *hfi; + int rc; + + rc = hfi_get_client_info(client_handle, &hfi); + if (rc) { + CAM_ERR(CAM_HFI, "Failed to get hfi info rc: %d for hdl: %d", + rc, client_handle); + return; + } + if (cam_presil_mode_enabled()) { - CAM_DBG(CAM_HFI, "SYS_RESET Needed in presil for back to back hfi_init success"); - hfi_send_system_cmd(HFI_CMD_SYS_RESET, 0, 0); + CAM_DBG(CAM_HFI, + "HFI hdl: %d SYS_RESET Needed in presil for back to back hfi_init success", + client_handle); + hfi_send_system_cmd(client_handle, HFI_CMD_SYS_RESET, 0, 0); } - mutex_lock(&hfi_cmd_q_mutex); - mutex_lock(&hfi_msg_q_mutex); + mutex_lock(&hfi->cmd_q_lock); + mutex_lock(&hfi->msg_q_lock); - if (!g_hfi) { - CAM_ERR(CAM_HFI, "hfi path not established yet"); - goto err; + hfi->hfi_state = HFI_DEINIT; + hfi->cmd_q_state = false; + hfi->msg_q_state = false; + + mutex_unlock(&hfi->cmd_q_lock); + mutex_unlock(&hfi->msg_q_lock); + + memset(&hfi->map, 0, sizeof(struct hfi_mem_info)); + memset(&hfi->ops, 0, sizeof(struct hfi_ops)); + hfi->smem_size = 0; + hfi->uncachedheap_size = 0; + memset(hfi->msgpacket_buf, 0, sizeof(ICP_HFI_MAX_MSG_SIZE_IN_WORDS)); + hfi->priv = NULL; + hfi->dbg_lvl = 0; +} + +static int hfi_get_free_index(uint32_t *free_index) +{ + int i; + + for (i = 0; i < HFI_NUM_MAX; i++) { + if (!g_hfi.hfi[i]) { + *free_index = i; + return 0; + } } - g_hfi->cmd_q_state = false; - g_hfi->msg_q_state = false; + return -EUSERS; +} - cam_free_clear((void *)g_hfi); - g_hfi = NULL; +int cam_hfi_register(int *client_handle) +{ + struct hfi_info *hfi = NULL; + uint32_t hfi_index; + int rc = 0; -err: - mutex_unlock(&hfi_cmd_q_mutex); - mutex_unlock(&hfi_msg_q_mutex); + if (!client_handle) { + CAM_ERR(CAM_HFI, "Client handle is NULL"); + return -EINVAL; + } + + mutex_lock(&g_hfi_lock); + if (IS_VALID_HFI_INDEX(*client_handle)) { + rc = hfi_get_client_info(*client_handle, &hfi); + if (rc) { + CAM_ERR(CAM_HFI, "Unable to retrieve existing hfi info for handle:%d", + *client_handle); + rc = -EINVAL; + goto failed_hfi_register; + } + CAM_ERR(CAM_HFI, "HFI client handle:%d is already established", + *client_handle); + rc = -EINVAL; + goto failed_hfi_register; + } + + rc = hfi_get_free_index(&hfi_index); + if (rc) { + CAM_ERR(CAM_HFI, "No available hfi slots rc:%d", rc); + goto failed_hfi_register; + } + + hfi = kzalloc(sizeof(struct hfi_info), GFP_KERNEL); + if (!hfi) { + rc = -ENOMEM; + goto failed_hfi_register; + } + + if (hfi->hfi_state != HFI_DEINIT) { + CAM_ERR(CAM_HFI, "hfi_init: invalid state: %u hfi idx: %u", + hfi->hfi_state, hfi_index); + rc = -EINVAL; + goto hfi_failed_state; + } + + g_hfi.hfi[hfi_index] = hfi; + g_hfi.num_hfi++; + *client_handle = HFI_GET_CLIENT_HANDLE(hfi_index); + mutex_unlock(&g_hfi_lock); + + mutex_init(&hfi->cmd_q_lock); + mutex_init(&hfi->msg_q_lock); + + return rc; + +hfi_failed_state: + kfree(hfi); +failed_hfi_register: + mutex_unlock(&g_hfi_lock); + return rc; +} + +int cam_hfi_unregister(int *client_handle) +{ + struct hfi_info *hfi; + uint32_t idx; + int rc; + + rc = hfi_get_client_info(*client_handle, &hfi); + if (rc) { + CAM_ERR(CAM_HFI, "Failed to get hfi info rc: %d for hdl: %d", + rc, client_handle); + return rc; + } + + mutex_lock(&g_hfi_lock); + mutex_destroy(&hfi->msg_q_lock); + mutex_destroy(&hfi->cmd_q_lock); + cam_free_clear((void *)hfi); + idx = HFI_GET_INDEX(*client_handle); + g_hfi.hfi[idx] = NULL; + g_hfi.num_hfi--; + mutex_unlock(&g_hfi_lock); + + *client_handle = HFI_HANDLE_INIT_VALUE; + + return 0; } @@ -1079,48 +1261,67 @@ static int cam_hfi_presil_set_init_request(void) return 0; } -int hfi_write_cmd(void *cmd_ptr) +int hfi_write_cmd(int client_handle, void *cmd_ptr) { + struct hfi_info *hfi; int presil_rc = CAM_PRESIL_BLOCKED; int rc = 0; + rc = hfi_get_client_info(client_handle, &hfi); + if (rc) { + CAM_ERR(CAM_HFI, "Failed to get hfi info rc: %d for hdl:%d", + rc, client_handle); + return rc; + } + if (!cmd_ptr) { - CAM_ERR(CAM_HFI, "command is null"); + CAM_ERR(CAM_HFI, "command is null for hfi hdl:%d", client_handle); return -EINVAL; } - mutex_lock(&hfi_cmd_q_mutex); + mutex_lock(&hfi->cmd_q_lock); presil_rc = cam_presil_hfi_write_cmd(cmd_ptr, (*(uint32_t *)cmd_ptr), CAM_PRESIL_CLIENT_ID_CAMERA); if ((presil_rc != CAM_PRESIL_SUCCESS) && (presil_rc != CAM_PRESIL_BLOCKED)) { - CAM_ERR(CAM_HFI, "failed presil rc %d", presil_rc); + CAM_ERR(CAM_HFI, "hfi hdl: %d failed presil rc %d", + client_handle, presil_rc); rc = -EINVAL; } else { - CAM_DBG(CAM_HFI, "presil rc %d", presil_rc); + CAM_DBG(CAM_HFI, "hfi hdl: %d presil rc %d", + client_handle, presil_rc); } - mutex_unlock(&hfi_cmd_q_mutex); + mutex_unlock(&hfi->cmd_q_lock); return rc; } -int hfi_read_message(uint32_t *pmsg, uint8_t q_id, +int hfi_read_message(int client_handle, uint32_t *pmsg, uint8_t q_id, uint32_t *words_read) { + struct hfi_info *hfi; int presil_rc = CAM_PRESIL_BLOCKED; int rc = 0; + rc = hfi_get_client_info(client_handle, &hfi); + if (rc) { + CAM_ERR(CAM_HFI, "Failed to get hfi info rc: %d for hdl: %d", + rc, client_handle); + return rc; + } + if (!pmsg) { - CAM_ERR(CAM_HFI, "Invalid msg"); + CAM_ERR(CAM_HFI, "Invalid msg for hdl: %d", client_handle); return -EINVAL; } if (q_id > Q_DBG) { - CAM_ERR(CAM_HFI, "Invalid q :%u", q_id); + CAM_ERR(CAM_HFI, "Invalid q :%u hdl: %d", + q_id, client_handle); return -EINVAL; } - mutex_lock(&hfi_msg_q_mutex); + mutex_lock(&hfi->msg_q_lock); memset(pmsg, 0x0, sizeof(uint32_t) * 256 /* ICP_MSG_BUF_SIZE */); *words_read = 0; @@ -1129,13 +1330,13 @@ int hfi_read_message(uint32_t *pmsg, uint8_t q_id, CAM_PRESIL_CLIENT_ID_CAMERA); if ((presil_rc != CAM_PRESIL_SUCCESS) && (presil_rc != CAM_PRESIL_BLOCKED)) { - CAM_ERR(CAM_HFI, "failed presil rc %d", presil_rc); + CAM_ERR(CAM_HFI, "hfi hdl: %d failed presil rc %d", client_handle, presil_rc); rc = -EINVAL; } else { - CAM_DBG(CAM_HFI, "presil rc %d", presil_rc); + CAM_DBG(CAM_HFI, "hfi hdl: %d presil rc %d", client_handle, presil_rc); } - mutex_unlock(&hfi_msg_q_mutex); + mutex_unlock(&hfi->msg_q_lock); return rc; } #else diff --git a/drivers/cam_icp/icp_hw/bps_hw/bps_core.c b/drivers/cam_icp/icp_hw/bps_hw/bps_core.c index b6509908ac..e7bbda9803 100644 --- a/drivers/cam_icp/icp_hw/bps_hw/bps_core.c +++ b/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; diff --git a/drivers/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c b/drivers/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c index 177c88be9b..38110f0ed6 100644 --- a/drivers/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c +++ b/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); diff --git a/drivers/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.h b/drivers/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.h index 4b91a75cf4..b6cbe39730 100644 --- a/drivers/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.h +++ b/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; diff --git a/drivers/cam_icp/icp_hw/icp_hw_mgr/include/cam_icp_hw_intf.h b/drivers/cam_icp/icp_hw/icp_hw_mgr/include/cam_icp_hw_intf.h index f665a84ba4..c74efb5e62 100644 --- a/drivers/cam_icp/icp_hw/icp_hw_mgr/include/cam_icp_hw_intf.h +++ b/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 diff --git a/drivers/cam_icp/icp_hw/icp_proc/icp_common/cam_icp_proc_common.c b/drivers/cam_icp/icp_hw/icp_proc/icp_common/cam_icp_proc_common.c index 3eff930d12..b7728529d7 100644 --- a/drivers/cam_icp/icp_hw/icp_proc/icp_common/cam_icp_proc_common.c +++ b/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; diff --git a/drivers/cam_icp/icp_hw/icp_proc/icp_common/cam_icp_proc_common.h b/drivers/cam_icp/icp_hw/icp_proc/icp_common/cam_icp_proc_common.h index 0e25570430..fb06b6f236 100644 --- a/drivers/cam_icp/icp_hw/icp_proc/icp_common/cam_icp_proc_common.h +++ b/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_ */ diff --git a/drivers/cam_icp/icp_hw/icp_proc/icp_common/cam_icp_soc_common.c b/drivers/cam_icp/icp_hw/icp_proc/icp_common/cam_icp_soc_common.c index e528703b1f..d8281cbad9 100644 --- a/drivers/cam_icp/icp_hw/icp_proc/icp_common/cam_icp_soc_common.c +++ b/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; } - rc = __ubwc_config_get(np, "ubwc-ipe-write-cfg", - icp_soc_info->uconfig.ubwc_cfg_ext.ipe_write); + 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", + 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; } diff --git a/drivers/cam_icp/icp_hw/icp_proc/icp_common/cam_icp_soc_common.h b/drivers/cam_icp/icp_hw/icp_proc/icp_common/cam_icp_soc_common.h index b92980f9b7..3dcfe942dc 100644 --- a/drivers/cam_icp/icp_hw/icp_proc/icp_common/cam_icp_soc_common.h +++ b/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 diff --git a/drivers/cam_icp/icp_hw/icp_proc/icp_v1_hw/cam_icp_v1_core.c b/drivers/cam_icp/icp_hw/icp_proc/icp_v1_hw/cam_icp_v1_core.c index b6687b6760..18a43fa837 100644 --- a/drivers/cam_icp/icp_hw/icp_proc/icp_v1_hw/cam_icp_v1_core.c +++ b/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; + } + + if (arg_size != sizeof(struct cam_icp_ubwc_cfg_cmd)) { + CAM_ERR(CAM_ICP, "Invalid ubwc cmd size:%u", arg_size); 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); - + 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", diff --git a/drivers/cam_icp/icp_hw/icp_proc/icp_v1_hw/cam_icp_v1_core.h b/drivers/cam_icp/icp_hw/icp_proc/icp_v1_hw/cam_icp_v1_core.h index 16fffba643..296d4b8962 100644 --- a/drivers/cam_icp/icp_hw/icp_proc/icp_v1_hw/cam_icp_v1_core.h +++ b/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; }; diff --git a/drivers/cam_icp/icp_hw/icp_proc/icp_v1_hw/cam_icp_v1_dev.c b/drivers/cam_icp/icp_hw/icp_proc/icp_v1_hw/cam_icp_v1_dev.c index dbf40bbc71..579383626f 100644 --- a/drivers/cam_icp/icp_hw/icp_proc/icp_v1_hw/cam_icp_v1_dev.c +++ b/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); diff --git a/drivers/cam_icp/icp_hw/icp_proc/icp_v2_hw/cam_icp_v2_core.c b/drivers/cam_icp/icp_hw/icp_proc/icp_v2_hw/cam_icp_v2_core.c index 96629786b4..a0143ef756 100644 --- a/drivers/cam_icp/icp_hw/icp_proc/icp_v2_hw/cam_icp_v2_core.c +++ b/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; } diff --git a/drivers/cam_icp/icp_hw/icp_proc/icp_v2_hw/cam_icp_v2_core.h b/drivers/cam_icp/icp_hw/icp_proc/icp_v2_hw/cam_icp_v2_core.h index 2ba1d9d057..0075239cf5 100644 --- a/drivers/cam_icp/icp_hw/icp_proc/icp_v2_hw/cam_icp_v2_core.h +++ b/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; diff --git a/drivers/cam_icp/icp_hw/ipe_hw/ipe_core.c b/drivers/cam_icp/icp_hw/ipe_hw/ipe_core.c index 16be391e8b..dd06ba6cb9 100644 --- a/drivers/cam_icp/icp_hw/ipe_hw/ipe_core.c +++ b/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; diff --git a/drivers/cam_icp/icp_hw/ofe_hw/ofe_core.c b/drivers/cam_icp/icp_hw/ofe_hw/ofe_core.c index 54db513926..5d91e2dc13 100644 --- a/drivers/cam_icp/icp_hw/ofe_hw/ofe_core.c +++ b/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;