diff --git a/Kbuild b/Kbuild index 6832debf1d..5e78ceffe7 100644 --- a/Kbuild +++ b/Kbuild @@ -162,19 +162,19 @@ camera-$(CONFIG_SPECTRA_ICP) += \ drivers/cam_icp/icp_hw/ipe_hw/ipe_dev.o \ drivers/cam_icp/icp_hw/ipe_hw/ipe_core.o \ drivers/cam_icp/icp_hw/ipe_hw/ipe_soc.o \ - drivers/cam_icp/icp_hw/a5_hw/a5_dev.o \ - drivers/cam_icp/icp_hw/a5_hw/a5_core.o \ - drivers/cam_icp/icp_hw/a5_hw/a5_soc.o \ - drivers/cam_icp/icp_hw/lx7_hw/lx7_dev.o \ - drivers/cam_icp/icp_hw/lx7_hw/lx7_core.o \ - drivers/cam_icp/icp_hw/lx7_hw/lx7_soc.o \ + drivers/cam_icp/icp_hw/icp_proc/icp_v1_hw/cam_icp_v1_dev.o \ + drivers/cam_icp/icp_hw/icp_proc/icp_v1_hw/cam_icp_v1_core.o \ + drivers/cam_icp/icp_hw/icp_proc/icp_v2_hw/cam_icp_v2_dev.o \ + drivers/cam_icp/icp_hw/icp_proc/icp_v2_hw/cam_icp_v2_core.o \ + drivers/cam_icp/icp_hw/icp_proc/icp_common/cam_icp_proc_common.o \ + drivers/cam_icp/icp_hw/icp_proc/icp_common/cam_icp_soc_common.o \ + drivers/cam_icp/icp_hw/icp_proc/cam_icp_proc.o \ drivers/cam_icp/icp_hw/bps_hw/bps_dev.o \ drivers/cam_icp/icp_hw/bps_hw/bps_core.o \ drivers/cam_icp/icp_hw/bps_hw/bps_soc.o \ drivers/cam_icp/cam_icp_subdev.o \ drivers/cam_icp/cam_icp_context.o \ - drivers/cam_icp/hfi.o \ - drivers/cam_icp/utils/cam_icp_utils.o + drivers/cam_icp/hfi.o camera-$(CONFIG_SPECTRA_JPEG) += \ drivers/cam_jpeg/jpeg_hw/jpeg_enc_hw/jpeg_enc_dev.o \ diff --git a/drivers/cam_icp/hfi.c b/drivers/cam_icp/hfi.c index 62d38a8d79..14b69a56a8 100644 --- a/drivers/cam_icp/hfi.c +++ b/drivers/cam_icp/hfi.c @@ -1052,7 +1052,7 @@ static int cam_hfi_presil_setup(struct hfi_mem_info *hfi_mem) static int cam_hfi_presil_set_init_request(void) { CAM_DBG(CAM_PRESIL, "notifying pchost to start HFI init..."); - cam_presil_send_event(CAM_PRESIL_EVENT_HFI_REG_A5_HW_VERSION_TO_START_HFI_INIT, 0xFF); + cam_presil_send_event(CAM_PRESIL_EVENT_HFI_REG_ICP_V1_HW_VERSION_TO_START_HFI_INIT, 0xFF); CAM_DBG(CAM_PRESIL, "got done with PCHOST HFI init..."); return 0; diff --git a/drivers/cam_icp/icp_hw/a5_hw/a5_core.h b/drivers/cam_icp/icp_hw/a5_hw/a5_core.h deleted file mode 100644 index 3aca1a5c77..0000000000 --- a/drivers/cam_icp/icp_hw/a5_hw/a5_core.h +++ /dev/null @@ -1,98 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved. - */ - -#ifndef CAM_A5_CORE_H -#define CAM_A5_CORE_H - -#include -#include -#include -#include -#include "cam_a5_hw_intf.h" - -#define A5_QGIC_BASE 0 -#define A5_SIERRA_BASE 1 -#define A5_CSR_BASE 2 - -#define A5_HOST_INT 0x1 -#define A5_WDT_0 0x2 -#define A5_WDT_1 0x4 - -#define ICP_SIERRA_A5_CSR_ACCESS 0x3C - -#define ELF_GUARD_PAGE (2 * 1024 * 1024) - -struct cam_a5_device_hw_info { - uint32_t hw_ver; - uint32_t nsec_reset; - uint32_t a5_control; - uint32_t a5_host_int_en; - uint32_t a5_host_int; - uint32_t a5_host_int_clr; - uint32_t a5_host_int_status; - uint32_t a5_host_int_set; - uint32_t host_a5_int; - uint32_t fw_version; - uint32_t init_req; - uint32_t init_response; - uint32_t shared_mem_ptr; - uint32_t shared_mem_size; - uint32_t qtbl_ptr; - uint32_t uncached_heap_ptr; - uint32_t uncached_heap_size; - uint32_t a5_status; -}; - -/** - * struct cam_a5_device_hw_info - * @a5_hw_info: A5 hardware info - * @fw_elf: start address of fw start with elf header - * @fw: start address of fw blob - * @fw_buf: smmu alloc/mapped fw buffer - * @fw_buf_len: fw buffer length - * @query_cap: A5 query info from firmware - * @a5_acquire: Acquire information of A5 - * @irq_cb: IRQ callback - * @cpas_handle: CPAS handle for A5 - * @cpast_start: state variable for cpas - */ -struct cam_a5_device_core_info { - struct cam_a5_device_hw_info *a5_hw_info; - const struct firmware *fw_elf; - void *fw; - uint32_t fw_buf; - uintptr_t fw_kva_addr; - uint64_t fw_buf_len; - struct cam_icp_a5_query_cap query_cap; - struct cam_icp_a5_acquire_dev a5_acquire[8]; - struct cam_icp_irq_cb irq_cb; - uint32_t cpas_handle; - bool cpas_start; -}; - -int cam_a5_init_hw(void *device_priv, - void *init_hw_args, uint32_t arg_size); -int cam_a5_deinit_hw(void *device_priv, - void *init_hw_args, uint32_t arg_size); -int cam_a5_process_cmd(void *device_priv, uint32_t cmd_type, - void *cmd_args, uint32_t arg_size); - -irqreturn_t cam_a5_irq(int irq_num, void *data); - -void cam_a5_irq_raise(void *priv); -void cam_a5_irq_enable(void *priv); -void __iomem *cam_a5_iface_addr(void *priv); - -/** - * @brief : API to register a5 hw to platform framework. - * @return struct platform_device pointer on on success, or ERR_PTR() on error. - */ -int cam_a5_init_module(void); - -/** - * @brief : API to remove a5 hw from platform framework. - */ -void cam_a5_exit_module(void); -#endif /* CAM_A5_CORE_H */ diff --git a/drivers/cam_icp/icp_hw/a5_hw/a5_dev.c b/drivers/cam_icp/icp_hw/a5_hw/a5_dev.c deleted file mode 100644 index 64d02a7d5b..0000000000 --- a/drivers/cam_icp/icp_hw/a5_hw/a5_dev.c +++ /dev/null @@ -1,275 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved. - */ - -#include -#include -#include -#include -#include -#include "a5_core.h" -#include "a5_soc.h" -#include "cam_io_util.h" -#include "cam_hw.h" -#include "cam_hw_intf.h" -#include "cam_a5_hw_intf.h" -#include "cam_icp_hw_mgr_intf.h" -#include "cam_cpas_api.h" -#include "cam_debug_util.h" -#include "camera_main.h" - -struct a5_soc_info cam_a5_soc_info; -EXPORT_SYMBOL(cam_a5_soc_info); - -struct cam_a5_device_hw_info cam_a5_hw_info = { - .hw_ver = 0x0, - .nsec_reset = 0x4, - .a5_control = 0x8, - .a5_host_int_en = 0x10, - .a5_host_int = 0x14, - .a5_host_int_clr = 0x18, - .a5_host_int_status = 0x1c, - .a5_host_int_set = 0x20, - .host_a5_int = 0x30, - .fw_version = 0x44, - .init_req = 0x48, - .init_response = 0x4c, - .shared_mem_ptr = 0x50, - .shared_mem_size = 0x54, - .qtbl_ptr = 0x58, - .uncached_heap_ptr = 0x5c, - .uncached_heap_size = 0x60, - .a5_status = 0x200, -}; -EXPORT_SYMBOL(cam_a5_hw_info); - -static bool cam_a5_cpas_cb(uint32_t client_handle, void *userdata, - struct cam_cpas_irq_data *irq_data) -{ - bool error_handled = false; - - if (!irq_data) - return error_handled; - - switch (irq_data->irq_type) { - case CAM_CAMNOC_IRQ_IPE_BPS_UBWC_DECODE_ERROR: - CAM_ERR_RATE_LIMIT(CAM_ICP, - "IPE/BPS UBWC Decode error type=%d status=%x thr_err=%d, fcl_err=%d, len_md_err=%d, format_err=%d", - irq_data->irq_type, - irq_data->u.dec_err.decerr_status.value, - irq_data->u.dec_err.decerr_status.thr_err, - irq_data->u.dec_err.decerr_status.fcl_err, - irq_data->u.dec_err.decerr_status.len_md_err, - irq_data->u.dec_err.decerr_status.format_err); - error_handled = true; - break; - case CAM_CAMNOC_IRQ_IPE_BPS_UBWC_ENCODE_ERROR: - CAM_ERR_RATE_LIMIT(CAM_ICP, - "IPE/BPS UBWC Encode error type=%d status=%x", - irq_data->irq_type, - irq_data->u.enc_err.encerr_status.value); - error_handled = true; - break; - default: - break; - } - - return error_handled; -} - -int cam_a5_register_cpas(struct cam_hw_soc_info *soc_info, - struct cam_a5_device_core_info *core_info, - uint32_t hw_idx) -{ - struct cam_cpas_register_params cpas_register_params; - int rc; - - cpas_register_params.dev = &soc_info->pdev->dev; - memcpy(cpas_register_params.identifier, "icp", sizeof("icp")); - cpas_register_params.cam_cpas_client_cb = cam_a5_cpas_cb; - cpas_register_params.cell_index = hw_idx; - cpas_register_params.userdata = NULL; - - rc = cam_cpas_register_client(&cpas_register_params); - if (rc < 0) { - CAM_ERR(CAM_ICP, "failed: %d", rc); - return rc; - } - - core_info->cpas_handle = cpas_register_params.client_handle; - return rc; -} - -static int cam_a5_component_bind(struct device *dev, - struct device *master_dev, void *data) -{ - int rc = 0; - struct cam_hw_info *a5_dev = NULL; - struct cam_hw_intf *a5_dev_intf = NULL; - const struct of_device_id *match_dev = NULL; - struct cam_a5_device_core_info *core_info = NULL; - struct cam_a5_device_hw_info *hw_info = NULL; - struct platform_device *pdev = to_platform_device(dev); - - a5_dev_intf = kzalloc(sizeof(struct cam_hw_intf), GFP_KERNEL); - if (!a5_dev_intf) - return -ENOMEM; - - of_property_read_u32(pdev->dev.of_node, - "cell-index", &a5_dev_intf->hw_idx); - - a5_dev = kzalloc(sizeof(struct cam_hw_info), GFP_KERNEL); - if (!a5_dev) { - rc = -ENOMEM; - goto a5_dev_alloc_failure; - } - - a5_dev->soc_info.pdev = pdev; - a5_dev->soc_info.dev = &pdev->dev; - a5_dev->soc_info.dev_name = pdev->name; - a5_dev_intf->hw_priv = a5_dev; - a5_dev_intf->hw_ops.init = cam_a5_init_hw; - a5_dev_intf->hw_ops.deinit = cam_a5_deinit_hw; - a5_dev_intf->hw_ops.process_cmd = cam_a5_process_cmd; - a5_dev_intf->hw_type = CAM_ICP_DEV_A5; - - CAM_DBG(CAM_ICP, "type %d index %d", - a5_dev_intf->hw_type, - a5_dev_intf->hw_idx); - - platform_set_drvdata(pdev, a5_dev_intf); - - a5_dev->core_info = kzalloc(sizeof(struct cam_a5_device_core_info), - GFP_KERNEL); - if (!a5_dev->core_info) { - rc = -ENOMEM; - goto core_info_alloc_failure; - } - core_info = (struct cam_a5_device_core_info *)a5_dev->core_info; - - match_dev = of_match_device(pdev->dev.driver->of_match_table, - &pdev->dev); - if (!match_dev) { - CAM_ERR(CAM_ICP, "No a5 hardware info"); - rc = -EINVAL; - goto match_err; - } - hw_info = (struct cam_a5_device_hw_info *)match_dev->data; - core_info->a5_hw_info = hw_info; - - a5_dev->soc_info.soc_private = &cam_a5_soc_info; - - rc = cam_a5_init_soc_resources(&a5_dev->soc_info, cam_a5_irq, - a5_dev); - if (rc < 0) { - CAM_ERR(CAM_ICP, "failed to init_soc"); - goto init_soc_failure; - } - - CAM_DBG(CAM_ICP, "soc info : %pK", - (void *)&a5_dev->soc_info); - rc = cam_a5_register_cpas(&a5_dev->soc_info, - core_info, a5_dev_intf->hw_idx); - if (rc < 0) { - CAM_ERR(CAM_ICP, "a5 cpas registration failed"); - goto cpas_reg_failed; - } - a5_dev->hw_state = CAM_HW_STATE_POWER_DOWN; - mutex_init(&a5_dev->hw_mutex); - spin_lock_init(&a5_dev->hw_lock); - init_completion(&a5_dev->hw_complete); - - CAM_DBG(CAM_ICP, "A5:%d component bound successfully", - a5_dev_intf->hw_idx); - return 0; - -cpas_reg_failed: - cam_a5_deinit_soc_resources(&a5_dev->soc_info); -init_soc_failure: -match_err: - kfree(a5_dev->core_info); -core_info_alloc_failure: - kfree(a5_dev); -a5_dev_alloc_failure: - kfree(a5_dev_intf); - - return rc; - -} - -static void cam_a5_component_unbind(struct device *dev, - struct device *master_dev, void *data) -{ - struct cam_hw_info *a5_dev = NULL; - struct cam_hw_intf *a5_dev_intf = NULL; - struct cam_a5_device_core_info *core_info = NULL; - struct platform_device *pdev = to_platform_device(dev); - - a5_dev_intf = platform_get_drvdata(pdev); - a5_dev = a5_dev_intf->hw_priv; - core_info = (struct cam_a5_device_core_info *)a5_dev->core_info; - cam_cpas_unregister_client(core_info->cpas_handle); - cam_a5_deinit_soc_resources(&a5_dev->soc_info); - memset(&cam_a5_soc_info, 0, sizeof(struct a5_soc_info)); - kfree(a5_dev->core_info); - a5_dev->core_info = NULL; - kfree(a5_dev); - kfree(a5_dev_intf); -} - -const static struct component_ops cam_a5_component_ops = { - .bind = cam_a5_component_bind, - .unbind = cam_a5_component_unbind, -}; - -int cam_a5_probe(struct platform_device *pdev) -{ - int rc = 0; - - CAM_DBG(CAM_ICP, "Adding A5 component"); - rc = component_add(&pdev->dev, &cam_a5_component_ops); - if (rc) - CAM_ERR(CAM_ICP, "failed to add component rc: %d", rc); - - return rc; -} - -static int cam_a5_remove(struct platform_device *pdev) -{ - component_del(&pdev->dev, &cam_a5_component_ops); - return 0; -} - -static const struct of_device_id cam_a5_dt_match[] = { - { - .compatible = "qcom,cam-a5", - .data = &cam_a5_hw_info, - }, - {} -}; -MODULE_DEVICE_TABLE(of, cam_a5_dt_match); - -struct platform_driver cam_a5_driver = { - .probe = cam_a5_probe, - .remove = cam_a5_remove, - .driver = { - .name = "cam-a5", - .owner = THIS_MODULE, - .of_match_table = cam_a5_dt_match, - .suppress_bind_attrs = true, - }, -}; - -int cam_a5_init_module(void) -{ - return platform_driver_register(&cam_a5_driver); -} - -void cam_a5_exit_module(void) -{ - platform_driver_unregister(&cam_a5_driver); -} - -MODULE_DESCRIPTION("CAM A5 driver"); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/cam_icp/icp_hw/a5_hw/a5_reg.h b/drivers/cam_icp/icp_hw/a5_hw/a5_reg.h deleted file mode 100644 index 0a8e38d9ad..0000000000 --- a/drivers/cam_icp/icp_hw/a5_hw/a5_reg.h +++ /dev/null @@ -1,37 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Copyright (c) 2020, The Linux Foundation. All rights reserved. - */ - -#ifndef _CAM_A5_REG_H_ -#define _CAM_A5_REG_H_ - -#define ICP_SIERRA_A5_CSR_NSEC_RESET 0x4 -#define A5_CSR_FUNC_RESET (1 << 4) -#define A5_CSR_DBG_RESET (1 << 3) -#define A5_CSR_CPU_RESET (1 << 2) - -#define ICP_SIERRA_A5_CSR_A5_CONTROL 0x8 -#define A5_CSR_DBGSWENABLE (1 << 22) -#define A5_CSR_EDBGRQ (1 << 14) -#define A5_CSR_EN_CLKGATE_WFI (1 << 12) -#define A5_CSR_A5_CPU_EN (1 << 9) -#define A5_CSR_WAKE_UP_EN (1 << 4) - -#define A5_CSR_FULL_DBG_EN (A5_CSR_DBGSWENABLE | A5_CSR_EDBGRQ) -#define A5_CSR_FULL_CPU_EN (A5_CSR_A5_CPU_EN | \ - A5_CSR_WAKE_UP_EN | \ - A5_CSR_EN_CLKGATE_WFI) - -#define ICP_SIERRA_A5_CSR_A2HOSTINTEN 0x10 -#define A5_WDT_WS1EN (1 << 2) -#define A5_WDT_WS0EN (1 << 1) -#define A5_A2HOSTINTEN (1 << 0) - -#define ICP_SIERRA_A5_CSR_HOST2ICPINT 0x30 -#define A5_HOSTINT (1 << 0) - -#define ICP_SIERRA_A5_CSR_A5_STATUS 0x200 -#define A5_CSR_A5_STANDBYWFI (1 << 7) - -#endif /* _CAM_A5_REG_H_ */ diff --git a/drivers/cam_icp/icp_hw/a5_hw/a5_soc.c b/drivers/cam_icp/icp_hw/a5_hw/a5_soc.c deleted file mode 100644 index 5e50aa337b..0000000000 --- a/drivers/cam_icp/icp_hw/a5_hw/a5_soc.c +++ /dev/null @@ -1,260 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved. - * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. - */ - -#include -#include -#include -#include -#include -#include "a5_soc.h" -#include "cam_soc_util.h" -#include "cam_debug_util.h" -#include "hfi_intf.h" - -static int cam_a5_get_dt_properties(struct cam_hw_soc_info *soc_info) -{ - int rc = 0, i; - const char *fw_name; - struct a5_soc_info *a5_soc_info; - struct device_node *of_node = NULL; - struct platform_device *pdev = NULL; - struct a5_ubwc_cfg_ext *ubwc_cfg_ext = NULL; - int num_ubwc_cfg; - - pdev = soc_info->pdev; - of_node = pdev->dev.of_node; - - rc = cam_soc_util_get_dt_properties(soc_info); - if (rc < 0) { - CAM_ERR(CAM_ICP, "get a5 dt prop is failed"); - return rc; - } - - a5_soc_info = soc_info->soc_private; - - rc = of_property_read_string(of_node, "fw_name", &fw_name); - if (rc < 0) { - CAM_ERR(CAM_ICP, "fw_name read failed"); - goto end; - } - - a5_soc_info->fw_name = fw_name; - - rc = of_property_read_u32(of_node, "qos-val", - &a5_soc_info->a5_qos_val); - if (rc < 0) { - CAM_WARN(CAM_ICP, "QoS need not be set"); - a5_soc_info->a5_qos_val = 0; - } - - ubwc_cfg_ext = &a5_soc_info->uconfig.ubwc_cfg_ext; - num_ubwc_cfg = of_property_count_u32_elems(of_node, - "ubwc-ipe-fetch-cfg"); - if ((num_ubwc_cfg < 0) || (num_ubwc_cfg > ICP_UBWC_MAX)) { - CAM_DBG(CAM_ICP, "wrong ubwc_ipe_fetch_cfg: %d", num_ubwc_cfg); - rc = num_ubwc_cfg; - goto ubwc_ex_cfg; - } - - for (i = 0; i < num_ubwc_cfg; i++) { - rc = of_property_read_u32_index(of_node, "ubwc-ipe-fetch-cfg", - i, &ubwc_cfg_ext->ubwc_ipe_fetch_cfg[i]); - if (rc < 0) { - CAM_ERR(CAM_ICP, - "unable to read ubwc_ipe_fetch_cfg values"); - goto end; - } - } - - num_ubwc_cfg = of_property_count_u32_elems(of_node, - "ubwc-ipe-write-cfg"); - if ((num_ubwc_cfg < 0) || (num_ubwc_cfg > ICP_UBWC_MAX)) { - CAM_ERR(CAM_ICP, "wrong ubwc_ipe_write_cfg: %d", num_ubwc_cfg); - rc = num_ubwc_cfg; - goto end; - } - - for (i = 0; i < num_ubwc_cfg; i++) { - rc = of_property_read_u32_index(of_node, "ubwc-ipe-write-cfg", - i, &ubwc_cfg_ext->ubwc_ipe_write_cfg[i]); - if (rc < 0) { - CAM_ERR(CAM_ICP, - "unable to read ubwc_ipe_write_cfg values"); - goto end; - } - } - - num_ubwc_cfg = of_property_count_u32_elems(of_node, - "ubwc-bps-fetch-cfg"); - if ((num_ubwc_cfg < 0) || (num_ubwc_cfg > ICP_UBWC_MAX)) { - CAM_ERR(CAM_ICP, "wrong ubwc_bps_fetch_cfg: %d", num_ubwc_cfg); - rc = num_ubwc_cfg; - goto end; - } - - for (i = 0; i < num_ubwc_cfg; i++) { - rc = of_property_read_u32_index(of_node, "ubwc-bps-fetch-cfg", - i, &ubwc_cfg_ext->ubwc_bps_fetch_cfg[i]); - if (rc < 0) { - CAM_ERR(CAM_ICP, - "unable to read ubwc_bps_fetch_cfg values"); - goto end; - } - } - - num_ubwc_cfg = of_property_count_u32_elems(of_node, - "ubwc-bps-write-cfg"); - if ((num_ubwc_cfg < 0) || (num_ubwc_cfg > ICP_UBWC_MAX)) { - CAM_ERR(CAM_ICP, "wrong ubwc_bps_write_cfg: %d", num_ubwc_cfg); - rc = num_ubwc_cfg; - goto end; - } - - for (i = 0; i < num_ubwc_cfg; i++) { - rc = of_property_read_u32_index(of_node, "ubwc-bps-write-cfg", - i, &ubwc_cfg_ext->ubwc_bps_write_cfg[i]); - if (rc < 0) { - CAM_ERR(CAM_ICP, - "unable to read ubwc_bps_write_cfg values"); - goto end; - } - } - - a5_soc_info->ubwc_config_ext = true; - CAM_DBG(CAM_ICP, "read ubwc_cfg_ext for ipe/bps"); - return rc; - -ubwc_ex_cfg: - num_ubwc_cfg = of_property_count_u32_elems(of_node, "ubwc-cfg"); - if ((num_ubwc_cfg < 0) || (num_ubwc_cfg > ICP_UBWC_MAX)) { - CAM_ERR(CAM_ICP, "wrong ubwc_cfg: %d", num_ubwc_cfg); - rc = num_ubwc_cfg; - goto end; - } - - for (i = 0; i < num_ubwc_cfg; i++) { - rc = of_property_read_u32_index(of_node, "ubwc-cfg", - i, &a5_soc_info->uconfig.ubwc_cfg[i]); - if (rc < 0) { - CAM_ERR(CAM_ICP, "unable to read ubwc_cfg values"); - break; - } - } - -end: - return rc; -} - -static int cam_a5_request_platform_resource( - struct cam_hw_soc_info *soc_info, - irq_handler_t a5_irq_handler, void *irq_data) -{ - int rc = 0; - - rc = cam_soc_util_request_platform_resource(soc_info, a5_irq_handler, - irq_data); - - return rc; -} - -int cam_a5_init_soc_resources(struct cam_hw_soc_info *soc_info, - irq_handler_t a5_irq_handler, void *irq_data) -{ - int rc = 0; - - rc = cam_a5_get_dt_properties(soc_info); - if (rc < 0) - return rc; - - rc = cam_a5_request_platform_resource(soc_info, a5_irq_handler, - irq_data); - if (rc < 0) - return rc; - - return rc; -} - -void cam_a5_deinit_soc_resources(struct cam_hw_soc_info *soc_info) -{ - int rc = 0; - - rc = cam_soc_util_release_platform_resource(soc_info); - if (rc) - CAM_WARN(CAM_ICP, "release platform resources fail"); -} - -int cam_a5_enable_soc_resources(struct cam_hw_soc_info *soc_info) -{ - int rc = 0; - - rc = cam_soc_util_enable_platform_resource(soc_info, true, - CAM_SVS_VOTE, true); - if (rc) - CAM_ERR(CAM_ICP, "enable platform failed"); - - return rc; -} - -int cam_a5_disable_soc_resources(struct cam_hw_soc_info *soc_info) -{ - int rc = 0; - - rc = cam_soc_util_disable_platform_resource(soc_info, true, true); - if (rc) - CAM_ERR(CAM_ICP, "disable platform failed"); - - return rc; -} - -int cam_a5_update_clk_rate(struct cam_hw_soc_info *soc_info, - int32_t clk_level) -{ - int32_t src_clk_idx = 0; - int32_t clk_rate = 0; - int rc = 0; - - if (!soc_info) { - CAM_ERR(CAM_ICP, "Invalid args"); - return -EINVAL; - } - - if ((clk_level < 0) || (clk_level >= CAM_MAX_VOTE)) { - CAM_ERR(CAM_ICP, "clock level %d is not valid", - clk_level); - return -EINVAL; - } - - if (!soc_info->clk_level_valid[clk_level]) { - CAM_ERR(CAM_ICP, - "Clock level %d not supported", - clk_level); - return -EINVAL; - } - - src_clk_idx = soc_info->src_clk_idx; - if ((src_clk_idx < 0) || (src_clk_idx >= CAM_SOC_MAX_CLK)) { - CAM_WARN(CAM_ICP, "src_clk not defined for %s", - soc_info->dev_name); - return -EINVAL; - } - - clk_rate = soc_info->clk_rate[clk_level][src_clk_idx]; - if ((soc_info->clk_level_valid[CAM_TURBO_VOTE]) && - (soc_info->clk_rate[CAM_TURBO_VOTE][src_clk_idx] != 0) && - (clk_rate > soc_info->clk_rate[CAM_TURBO_VOTE][src_clk_idx])) { - CAM_DBG(CAM_ICP, "clk_rate %d greater than max, reset to %d", - clk_rate, - soc_info->clk_rate[CAM_TURBO_VOTE][src_clk_idx]); - clk_rate = soc_info->clk_rate[CAM_TURBO_VOTE][src_clk_idx]; - } - - rc = cam_soc_util_set_src_clk_rate(soc_info, clk_rate); - if (rc) - return rc; - - hfi_send_freq_info(clk_rate); - return 0; -} diff --git a/drivers/cam_icp/icp_hw/a5_hw/a5_soc.h b/drivers/cam_icp/icp_hw/a5_hw/a5_soc.h deleted file mode 100644 index 3c962ce01f..0000000000 --- a/drivers/cam_icp/icp_hw/a5_hw/a5_soc.h +++ /dev/null @@ -1,41 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved. - */ - -#ifndef CAM_A5_SOC_H -#define CAM_A5_SOC_H - -#include "cam_soc_util.h" - -#define ICP_UBWC_MAX 2 - -struct a5_ubwc_cfg_ext { - uint32_t ubwc_ipe_fetch_cfg[ICP_UBWC_MAX]; - uint32_t ubwc_ipe_write_cfg[ICP_UBWC_MAX]; - uint32_t ubwc_bps_fetch_cfg[ICP_UBWC_MAX]; - uint32_t ubwc_bps_write_cfg[ICP_UBWC_MAX]; -}; - -struct a5_soc_info { - const char *fw_name; - bool ubwc_config_ext; - uint32_t a5_qos_val; - union { - uint32_t ubwc_cfg[ICP_UBWC_MAX]; - struct a5_ubwc_cfg_ext ubwc_cfg_ext; - } uconfig; -}; - -int cam_a5_init_soc_resources(struct cam_hw_soc_info *soc_info, - irq_handler_t a5_irq_handler, void *irq_data); - -void cam_a5_deinit_soc_resources(struct cam_hw_soc_info *soc_info); - -int cam_a5_enable_soc_resources(struct cam_hw_soc_info *soc_info); - -int cam_a5_disable_soc_resources(struct cam_hw_soc_info *soc_info); - -int cam_a5_update_clk_rate(struct cam_hw_soc_info *soc_info, - int32_t clk_level); -#endif 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 5a818bd050..b28ebf7a71 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 @@ -27,7 +27,6 @@ #include "cam_hw_mgr_intf.h" #include "cam_icp_hw_mgr_intf.h" #include "cam_icp_hw_mgr.h" -#include "cam_a5_hw_intf.h" #include "cam_bps_hw_intf.h" #include "cam_ipe_hw_intf.h" #include "cam_smmu_api.h" @@ -37,8 +36,6 @@ #include "hfi_session_defs.h" #include "hfi_sys_defs.h" #include "cam_req_mgr_workq.h" -#include "a5_core.h" -#include "lx7_core.h" #include "hfi_sys_defs.h" #include "cam_debug_util.h" #include "cam_soc_util.h" @@ -47,6 +44,7 @@ #include "cam_common_util.h" #include "cam_mem_mgr_api.h" #include "cam_presil_hw_access.h" +#include "cam_icp_proc.h" #define ICP_WORKQ_TASK_CMD_TYPE 1 #define ICP_WORKQ_TASK_MSG_TYPE 2 @@ -56,18 +54,6 @@ #define ICP_DEVICE_IDLE_TIMEOUT 400 -static const struct hfi_ops hfi_a5_ops = { - .irq_raise = cam_a5_irq_raise, - .irq_enable = cam_a5_irq_enable, - .iface_addr = cam_a5_iface_addr, -}; - -static const struct hfi_ops hfi_lx7_ops = { - .irq_raise = cam_lx7_irq_raise, - .irq_enable = cam_lx7_irq_enable, - .iface_addr = cam_lx7_iface_addr, -}; - static struct cam_icp_hw_mgr icp_hw_mgr; static void cam_icp_mgr_process_dbg_buf(unsigned int debug_lvl); @@ -1525,7 +1511,7 @@ static int cam_icp_update_clk_rate(struct cam_icp_hw_mgr *hw_mgr, &clk_upd_cmd, sizeof(clk_upd_cmd)); } - /* update a5 clock */ + /* update ICP Proc clock */ CAM_DBG(CAM_PERF, "Update ICP clk to level [%d]", clk_upd_cmd.clk_level); icp_dev_intf->hw_ops.process_cmd(icp_dev_intf->hw_priv, @@ -4232,6 +4218,7 @@ static int cam_icp_mgr_hfi_init(struct cam_icp_hw_mgr *hw_mgr) struct cam_hw_info *icp_dev = NULL; struct hfi_mem_info hfi_mem; const struct hfi_ops *hfi_ops; + int rc; icp_dev_intf = hw_mgr->icp_dev_intf; if (!icp_dev_intf) { @@ -4299,10 +4286,11 @@ static int cam_icp_mgr_hfi_init(struct cam_icp_hw_mgr *hw_mgr) hfi_mem.fw_uncached.iova = icp_hw_mgr.hfi_mem.fw_uncached.iova; hfi_mem.fw_uncached.len = icp_hw_mgr.hfi_mem.fw_uncached.len; - if (icp_dev_intf->hw_type == CAM_ICP_DEV_LX7) - hfi_ops = &hfi_lx7_ops; - else - hfi_ops = &hfi_a5_ops; + rc = cam_icp_get_hfi_device_ops(icp_dev_intf->hw_type, &hfi_ops); + if (rc) { + CAM_ERR(CAM_ICP, "Fail to get HFI device ops rc: %d", rc); + return rc; + } return cam_hfi_init(&hfi_mem, hfi_ops, icp_dev, 0); } @@ -6591,29 +6579,18 @@ end: static int cam_icp_mgr_alloc_devs(struct device_node *np) { - struct cam_hw_intf **devices; + struct cam_hw_intf **devices = NULL; int rc, icp_hw_type; uint32_t num; memset(icp_hw_mgr.devices, 0, sizeof(icp_hw_mgr.devices)); - if (!of_property_read_u32(np, "num-a5", &num)) { - icp_hw_type = CAM_ICP_DEV_A5; - } else if (!of_property_read_u32(np, "num-lx7", &num)) { - icp_hw_type = CAM_ICP_DEV_LX7; - } else { - CAM_ERR(CAM_ICP, "missing processor device num prop"); - return -ENODEV; - } + rc = cam_icp_alloc_processor_devs(np, &icp_hw_type, &devices); - devices = kcalloc(num, sizeof(*devices), GFP_KERNEL); - if (!devices) { - CAM_ERR(CAM_ICP, "icp device allocation failed"); - return -ENOMEM; + if (rc) { + CAM_ERR(CAM_ICP, "ICP proc devices allocation failed rc=%d", rc); + return rc; } - - CAM_DBG(CAM_ICP, "allocated device iface for %s", - icp_hw_type == CAM_ICP_DEV_A5 ? "A5" : "LX7"); icp_hw_mgr.devices[icp_hw_type] = devices; rc = of_property_read_u32(np, "num-ipe", &num); @@ -6730,13 +6707,10 @@ static int cam_icp_mgr_init_devs(struct device_node *np) rc = -EINVAL; goto free_devices; } - icp_hw_mgr.devices[iface->hw_type][iface->hw_idx] = iface; } - icp_hw_mgr.icp_dev_intf = icp_hw_mgr.devices[CAM_ICP_DEV_A5] ? - icp_hw_mgr.devices[CAM_ICP_DEV_A5][0] : - icp_hw_mgr.devices[CAM_ICP_DEV_LX7][0]; + icp_hw_mgr.icp_dev_intf = CAM_ICP_GET_PROC_DEV_INTF(icp_hw_mgr.devices); icp_hw_mgr.bps_dev_intf = icp_hw_mgr.devices[CAM_ICP_DEV_BPS][0]; icp_hw_mgr.ipe0_dev_intf = icp_hw_mgr.devices[CAM_ICP_DEV_IPE][0]; 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 a4df276164..f7b89f1db7 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 @@ -13,7 +13,6 @@ #include "cam_icp_hw_intf.h" #include "cam_hw_mgr_intf.h" #include "cam_hw_intf.h" -#include "cam_a5_hw_intf.h" #include "hfi_session_defs.h" #include "hfi_intf.h" #include "cam_req_mgr_workq.h" diff --git a/drivers/cam_icp/icp_hw/icp_hw_mgr/include/cam_a5_hw_intf.h b/drivers/cam_icp/icp_hw/icp_hw_mgr/include/cam_a5_hw_intf.h deleted file mode 100644 index 6acd59bfbc..0000000000 --- a/drivers/cam_icp/icp_hw/icp_hw_mgr/include/cam_a5_hw_intf.h +++ /dev/null @@ -1,46 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved. - */ - -#ifndef CAM_A5_HW_INTF_H -#define CAM_A5_HW_INTF_H - -#include -#include -#include -#include "cam_hw_mgr_intf.h" -#include "cam_icp_hw_intf.h" - -/** - * struct cam_icp_a5_query_cap - ICP query device capability payload - * @fw_version: firmware version info - * @api_version: api version info - * @num_ipe: number of ipes - * @num_bps: number of bps - * @num_dev: number of device capabilities in dev_caps - * @reserved: reserved - * @dev_ver: returned device capability array - * @CAM_QUERY_CAP IOCTL - */ -struct cam_icp_a5_query_cap { - struct cam_icp_ver fw_version; - struct cam_icp_ver api_version; - uint32_t num_ipe; - uint32_t num_bps; - uint32_t num_dev; - uint32_t reserved; - struct cam_icp_dev_ver dev_ver[CAM_ICP_DEV_TYPE_MAX]; -}; - -struct cam_icp_a5_acquire_dev { - uint32_t ctx_id; - struct cam_icp_acquire_dev_info icp_acquire_info; - struct cam_icp_res_info icp_out_acquire_info[2]; - uint32_t fw_handle; -}; - -struct cam_icp_a5_test_irq { - uint32_t test_irq; -}; -#endif /* CAM_A5_HW_INTF_H */ 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 bebc11e1d7..4cddfdbad2 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 @@ -23,9 +23,11 @@ #define CAM_ICP_DUMP_STATUS_REGISTERS BIT(0) #define CAM_ICP_DUMP_CSR_REGISTERS BIT(1) +#define CAM_ICP_MAX_ICP_DEV_TYPE 2 + enum cam_icp_hw_type { - CAM_ICP_DEV_A5, - CAM_ICP_DEV_LX7, + CAM_ICP_DEV_ICP_V1, + CAM_ICP_DEV_ICP_V2, CAM_ICP_DEV_IPE, CAM_ICP_DEV_BPS, CAM_ICP_DEV_MAX, diff --git a/drivers/cam_icp/icp_hw/icp_proc/cam_icp_proc.c b/drivers/cam_icp/icp_hw/icp_proc/cam_icp_proc.c new file mode 100644 index 0000000000..e70813b2f0 --- /dev/null +++ b/drivers/cam_icp/icp_hw/icp_proc/cam_icp_proc.c @@ -0,0 +1,104 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + */ + +#include "cam_debug_util.h" +#include "cam_icp_proc.h" + +static int cam_icp_get_device_num(uint32_t dev_type, uint32_t *num_dev) +{ + int rc = 0; + + switch (dev_type) { + case CAM_ICP_DEV_ICP_V1: + *num_dev = cam_icp_v1_get_device_num(); + break; + case CAM_ICP_DEV_ICP_V2: + *num_dev = cam_icp_v2_get_device_num(); + break; + default: + CAM_ERR(CAM_ICP, "Invalid dev type: %d", dev_type); + rc = -EINVAL; + } + + return rc; +} + +int cam_icp_alloc_processor_devs(struct device_node *np, int *icp_hw_type, + struct cam_hw_intf ***devices) +{ + uint32_t num_icp_found = 0, num_icp_listed; + int rc, i; + + if (!np) { + CAM_ERR(CAM_ICP, "Invalid device node"); + return -EINVAL; + } + + rc = of_property_read_u32(np, "num-icp", &num_icp_listed); + if (rc) { + CAM_ERR(CAM_ICP, "read num-icp failed rc=%d", rc); + return -ENODEV; + } + + if (!num_icp_listed) { + CAM_ERR(CAM_ICP, "No ICP device %d", num_icp_listed); + return -EINVAL; + } + + for (i = 0; i < CAM_ICP_MAX_ICP_DEV_TYPE; i++) { + rc = cam_icp_get_device_num(i, &num_icp_found); + if (rc) + return rc; + + if (num_icp_found) { + *icp_hw_type = i; + break; + } + } + + if (i == CAM_ICP_MAX_ICP_DEV_TYPE) { + CAM_ERR(CAM_ICP, "No ICP device probed"); + return -ENODEV; + } + + if (num_icp_listed != num_icp_found) { + CAM_ERR(CAM_ICP, + "number of ICP devices do not match num_icp_listed: %d num_icp_found: %d", + num_icp_listed, num_icp_found); + return -EINVAL; + } + + *devices = kcalloc(num_icp_listed, sizeof(**devices), GFP_KERNEL); + if (!(*devices)) { + CAM_ERR(CAM_ICP, + "ICP device memory allocation failed. Num devices: %u", + num_icp_listed); + return -ENOMEM; + } + + CAM_DBG(CAM_ICP, "allocated device iface for %s", + *icp_hw_type == CAM_ICP_DEV_ICP_V1 ? "ICP_V1" : "ICP_V2"); + + return rc; +} + +int cam_icp_get_hfi_device_ops(uint32_t hw_type, const struct hfi_ops **hfi_proc_ops) +{ + int rc = 0; + + switch (hw_type) { + case CAM_ICP_DEV_ICP_V1: + cam_icp_v1_populate_hfi_ops(hfi_proc_ops); + break; + case CAM_ICP_DEV_ICP_V2: + cam_icp_v2_populate_hfi_ops(hfi_proc_ops); + break; + default: + rc = -EINVAL; + CAM_ERR(CAM_ICP, "Invalid ICP device type: %u", hw_type); + } + + return rc; +} diff --git a/drivers/cam_icp/icp_hw/icp_proc/cam_icp_proc.h b/drivers/cam_icp/icp_hw/icp_proc/cam_icp_proc.h new file mode 100644 index 0000000000..3316114315 --- /dev/null +++ b/drivers/cam_icp/icp_hw/icp_proc/cam_icp_proc.h @@ -0,0 +1,34 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + */ + +#include "cam_icp_v1_core.h" +#include "cam_icp_v2_core.h" +#include "hfi_intf.h" + +#define CAM_ICP_GET_PROC_DEV_INTF(devices) \ +(devices[CAM_ICP_DEV_ICP_V1] ? devices[CAM_ICP_DEV_ICP_V1][0] : \ + devices[CAM_ICP_DEV_ICP_V2][0]) + +/** + * @brief : Get ICP device type (ICP_V1/ICP_V2/...) + */ +int cam_icp_alloc_processor_devs(struct device_node *np, int *icp_hw_type, + struct cam_hw_intf ***devices); + +/** + * @brief : Get device operations per device type + */ +int cam_icp_get_hfi_device_ops(uint32_t hw_type, const struct hfi_ops **hif_ops); + +/** + * @brief : Get number of icp_v2 hw instances + */ +uint32_t cam_icp_v2_get_device_num(void); + +/** + * @brief : Get number of icp_v1 hw instances + */ +uint32_t cam_icp_v1_get_device_num(void); + diff --git a/drivers/cam_icp/utils/cam_icp_utils.c b/drivers/cam_icp/icp_hw/icp_proc/icp_common/cam_icp_proc_common.c similarity index 54% rename from drivers/cam_icp/utils/cam_icp_utils.c rename to drivers/cam_icp/icp_hw/icp_proc/icp_common/cam_icp_proc_common.c index 900eed01b1..3eff930d12 100644 --- a/drivers/cam_icp/utils/cam_icp_utils.c +++ b/drivers/cam_icp/icp_hw/icp_proc/icp_common/cam_icp_proc_common.c @@ -1,9 +1,13 @@ // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2021, The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. */ -#include "cam_icp_utils.h" +#include "cam_icp_proc_common.h" +#include "cam_compat.h" +#include "cam_icp_hw_intf.h" +#include "hfi_intf.h" int32_t cam_icp_validate_fw(const uint8_t *elf, uint32_t machine_id) @@ -71,7 +75,7 @@ int32_t cam_icp_get_fw_size( continue; seg_mem_size = (prg_hdr->p_memsz + prg_hdr->p_align - 1) & - ~(prg_hdr->p_align - 1); + ~(prg_hdr->p_align - 1); seg_mem_size += prg_hdr->p_paddr; CAM_DBG(CAM_ICP, "memsz:%x align:%x addr:%x seg_mem_size:%x", (int)prg_hdr->p_memsz, (int)prg_hdr->p_align, @@ -128,3 +132,97 @@ int32_t cam_icp_program_fw(const uint8_t *elf, return rc; } + +int cam_icp_proc_cpas_vote(uint32_t cpas_handle, + struct cam_icp_cpas_vote *vote) +{ + int rc; + + if (!vote) + return -EINVAL; + + if (vote->ahb_vote_valid) { + rc = cam_cpas_update_ahb_vote(cpas_handle, &vote->ahb_vote); + if (rc) { + CAM_ERR(CAM_ICP, "AHB vote update failed rc=%d", rc); + return rc; + } + } + + if (vote->axi_vote_valid) { + rc = cam_cpas_update_axi_vote(cpas_handle, &vote->axi_vote); + if (rc) { + CAM_ERR(CAM_ICP, "AXI vote update failed rc=%d", rc); + return rc; + } + } + + return 0; +} + +int cam_icp_proc_mini_dump(struct cam_icp_hw_dump_args *args, + uintptr_t fw_kva_addr, uint64_t fw_buf_len) +{ + u8 *dest; + u8 *src; + struct cam_icp_hw_dump_args *dump_args = args; + + if (!dump_args) { + CAM_ERR(CAM_ICP, "Invalid param %pK", dump_args); + return -EINVAL; + } + + if (!fw_kva_addr || !dump_args->cpu_addr) { + CAM_ERR(CAM_ICP, "invalid params %pK, 0x%zx", + fw_kva_addr, dump_args->cpu_addr); + return -EINVAL; + } + + if (dump_args->buf_len < fw_buf_len) { + CAM_WARN(CAM_ICP, "Insufficient Len %lu fw_len %llu", + dump_args->buf_len, fw_buf_len); + return -ENOSPC; + } + + dest = (u8 *)dump_args->cpu_addr; + src = (u8 *)fw_kva_addr; + memcpy_fromio(dest, src, fw_buf_len); + dump_args->offset = fw_buf_len; + + return 0; +} + +int cam_icp_proc_ubwc_configure(struct cam_icp_ubwc_cfg ubwc_cfg, + uint32_t force_disable_ubwc) +{ + int i = 0, ddr_type, rc; + uint32_t ipe_ubwc_cfg[ICP_UBWC_CFG_MAX]; + uint32_t bps_ubwc_cfg[ICP_UBWC_CFG_MAX]; + + 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]; + + bps_ubwc_cfg[0] = ubwc_cfg.bps_fetch[i]; + bps_ubwc_cfg[1] = ubwc_cfg.bps_write[i]; + + if (force_disable_ubwc) { + ipe_ubwc_cfg[1] &= ~CAM_ICP_UBWC_COMP_EN; + bps_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]); + } + + rc = hfi_cmd_ubwc_config_ext(ipe_ubwc_cfg, bps_ubwc_cfg); + if (rc) { + CAM_ERR(CAM_ICP, "Failed to write UBWC configure rc=%d", rc); + return rc; + } + + return 0; +} 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 new file mode 100644 index 0000000000..0e25570430 --- /dev/null +++ b/drivers/cam_icp/icp_hw/icp_proc/icp_common/cam_icp_proc_common.h @@ -0,0 +1,57 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2021, The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + */ + +#ifndef _CAM_ICP_UTILS_H_ +#define _CAM_ICP_UTILS_H_ + +#include +#include +#include + +#include "cam_debug_util.h" +#include "cam_cpas_api.h" +#include "cam_icp_hw_mgr_intf.h" +#include "cam_icp_soc_common.h" + +#define ICP_FW_NAME_MAX_SIZE 32 +#define PC_POLL_DELAY_US 100 +#define PC_POLL_TIMEOUT_US 10000 + +/** + * @brief : Validate FW elf image + */ +int32_t cam_icp_validate_fw(const uint8_t *elf, uint32_t machine_id); + +/** + * @brief : Get FW elf size + */ +int32_t cam_icp_get_fw_size(const uint8_t *elf, uint32_t *fw_size); + +/** + * @brief : Program FW memory + */ +int32_t cam_icp_program_fw(const uint8_t *elf, + uintptr_t fw_kva_addr); + +/** + * @brief : Update ahb and axi votes + */ +int cam_icp_proc_cpas_vote(uint32_t cpas_handle, + struct cam_icp_cpas_vote *vote); + +/** + * @brief : dump FW memory into mini dump + */ +int cam_icp_proc_mini_dump(struct cam_icp_hw_dump_args *args, + uintptr_t fw_kva_addr, uint64_t fw_buf_len); + +/** + * @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); + +#endif /* _CAM_ICP_UTILS_H_ */ diff --git a/drivers/cam_icp/icp_hw/lx7_hw/lx7_soc.c b/drivers/cam_icp/icp_hw/icp_proc/icp_common/cam_icp_soc_common.c similarity index 53% rename from drivers/cam_icp/icp_hw/lx7_hw/lx7_soc.c rename to drivers/cam_icp/icp_hw/icp_proc/icp_common/cam_icp_soc_common.c index 78df267819..602257ffaf 100644 --- a/drivers/cam_icp/icp_hw/lx7_hw/lx7_soc.c +++ b/drivers/cam_icp/icp_hw/icp_proc/icp_common/cam_icp_soc_common.c @@ -9,28 +9,26 @@ #include "cam_debug_util.h" #include "cam_soc_util.h" -#include "lx7_soc.h" #include "hfi_intf.h" +#include "cam_icp_soc_common.h" static int __ubwc_config_get(struct device_node *np, char *name, uint32_t *cfg) { int nconfig; - int i; + int i, rc; nconfig = of_property_count_u32_elems(np, name); - if (nconfig < 0 || nconfig > UBWC_CONFIG_MAX) { - CAM_ERR(CAM_ICP, "invalid number of UBWC configs[=%d]", + if (nconfig < 0 || nconfig > ICP_UBWC_CFG_MAX) { + CAM_ERR(CAM_ICP, "Invalid number of UBWC configs[=%d]", nconfig); return -EINVAL; } for (i = 0; i < nconfig; i++) { - int rc; - rc = of_property_read_u32_index(np, name, i, &cfg[i]); if (rc) { CAM_ERR(CAM_ICP, - "node %pOF has no valid %s prop at index=%d", + "Node %pOF has no valid %s prop at index=%d", np, name, i); return rc; } @@ -39,51 +37,90 @@ static int __ubwc_config_get(struct device_node *np, char *name, uint32_t *cfg) return 0; } -static int cam_lx7_ubwc_config_get(struct lx7_soc_info *lx7_soc_info, - struct device_node *np) +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; int rc; + uint32_t dev_type; - rc = __ubwc_config_get(np, "ubwc-ipe-fetch-cfg", - lx7_soc_info->ubwc_cfg.ipe_fetch); - if (rc) + 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_DEV_ICP_V1) { + rc = __ubwc_config_get(np, "ubwc-cfg", icp_soc_info->uconfig.ubwc_cfg); + if (rc) + return rc; + icp_soc_info->is_ubwc_cfg = true; + } return rc; + } rc = __ubwc_config_get(np, "ubwc-ipe-write-cfg", - lx7_soc_info->ubwc_cfg.ipe_write); + icp_soc_info->uconfig.ubwc_cfg_ext.ipe_write); if (rc) return rc; rc = __ubwc_config_get(np, "ubwc-bps-fetch-cfg", - lx7_soc_info->ubwc_cfg.bps_fetch); + icp_soc_info->uconfig.ubwc_cfg_ext.bps_fetch); if (rc) return rc; rc = __ubwc_config_get(np, "ubwc-bps-write-cfg", - lx7_soc_info->ubwc_cfg.bps_write); - if (rc) - return rc; + icp_soc_info->uconfig.ubwc_cfg_ext.bps_write); - return 0; + return rc; } -static inline void cam_lx7_qos_get( - struct lx7_soc_info *lx7_soc_info, - struct device_node *np) +static inline void cam_icp_soc_qos_get(struct device_node *np, + struct cam_icp_soc_info *icp_soc_info) { - int rc; - - rc = of_property_read_u32(np, "qos-val", - &lx7_soc_info->icp_qos_val); - if (rc < 0) { - CAM_WARN(CAM_ICP, "QoS need not be set"); - lx7_soc_info->icp_qos_val = 0; + if (of_property_read_u32(np, "qos-val", &icp_soc_info->qos_val)) { + CAM_WARN(CAM_ICP, "QoS not set for device: %d", + icp_soc_info->dev_type); + icp_soc_info->qos_val = 0; } } -static int cam_lx7_dt_properties_get(struct cam_hw_soc_info *soc_info) +static int cam_icp_soc_get_hw_version(struct device_node *np, + struct cam_icp_soc_info *icp_soc_info) { int rc; + uint32_t version; + + rc = of_property_read_u32(np, "icp-version", &version); + if (rc) { + CAM_ERR(CAM_ICP, "read icp-version failed rc=%d", rc); + return -ENODEV; + } + + switch (version) { + case CAM_ICP_V1_VERSION: + case CAM_ICP_V2_VERSION: + icp_soc_info->hw_version = version; + break; + default: + CAM_ERR(CAM_ICP, "Invalid ICP version: %u", version); + rc = -ENODEV; + } + return rc; +} + +static int cam_icp_soc_dt_properties_get(struct cam_hw_soc_info *soc_info) +{ + struct cam_icp_soc_info *icp_soc_info; + struct device_node *np; + int rc; + + if (!soc_info->soc_private) { + CAM_ERR(CAM_ICP, "soc private is NULL"); + return -EINVAL; + } + + icp_soc_info = (struct cam_icp_soc_info *)soc_info->soc_private; + np = soc_info->pdev->dev.of_node; rc = cam_soc_util_get_dt_properties(soc_info); if (rc) { @@ -91,25 +128,29 @@ static int cam_lx7_dt_properties_get(struct cam_hw_soc_info *soc_info) return rc; } - rc = cam_lx7_ubwc_config_get(soc_info->soc_private, - soc_info->pdev->dev.of_node); + rc = cam_icp_soc_ubwc_config_get(np, icp_soc_info); if (rc) { CAM_ERR(CAM_ICP, "failed to get UBWC config props rc=%d", rc); return rc; } - cam_lx7_qos_get(soc_info->soc_private, - soc_info->pdev->dev.of_node); + cam_icp_soc_qos_get(np, icp_soc_info); + + rc = cam_icp_soc_get_hw_version(np, icp_soc_info); + if (rc) { + CAM_ERR(CAM_ICP, "Get ICP HW version failed"); + return rc; + } return 0; } -int cam_lx7_soc_resources_init(struct cam_hw_soc_info *soc_info, - irq_handler_t handler, void *data) +int cam_icp_soc_resources_init(struct cam_hw_soc_info *soc_info, + irq_handler_t handler, void *data) { int rc; - rc = cam_lx7_dt_properties_get(soc_info); + rc = cam_icp_soc_dt_properties_get(soc_info); if (rc) return rc; @@ -123,7 +164,7 @@ int cam_lx7_soc_resources_init(struct cam_hw_soc_info *soc_info, return 0; } -int cam_lx7_soc_resources_deinit(struct cam_hw_soc_info *soc_info) +int cam_icp_soc_resources_deinit(struct cam_hw_soc_info *soc_info) { int rc; @@ -135,19 +176,19 @@ int cam_lx7_soc_resources_deinit(struct cam_hw_soc_info *soc_info) return rc; } -int cam_lx7_soc_resources_enable(struct cam_hw_soc_info *soc_info) +int cam_icp_soc_resources_enable(struct cam_hw_soc_info *soc_info) { int rc = 0; rc = cam_soc_util_enable_platform_resource(soc_info, true, - CAM_SVS_VOTE, true); + CAM_SVS_VOTE, true); if (rc) CAM_ERR(CAM_ICP, "failed to enable soc resources rc=%d", rc); return rc; } -int cam_lx7_soc_resources_disable(struct cam_hw_soc_info *soc_info) +int cam_icp_soc_resources_disable(struct cam_hw_soc_info *soc_info) { int rc = 0; @@ -158,7 +199,7 @@ int cam_lx7_soc_resources_disable(struct cam_hw_soc_info *soc_info) return rc; } -int cam_lx7_update_clk_rate(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 src_clk_idx = 0; @@ -166,7 +207,7 @@ int cam_lx7_update_clk_rate(struct cam_hw_soc_info *soc_info, int rc = 0; if (!soc_info) { - CAM_ERR(CAM_ICP, "Invalid args"); + CAM_ERR(CAM_ICP, "Invalid soc_info"); return -EINVAL; } 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 new file mode 100644 index 0000000000..f145d1460c --- /dev/null +++ b/drivers/cam_icp/icp_hw/icp_proc/icp_common/cam_icp_soc_common.h @@ -0,0 +1,64 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2021, The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + */ + +#ifndef CAM_ICP_SOC_COMMON_H +#define CAM_ICP_SOC_COMMON_H + +#include "cam_soc_util.h" +#include "cam_icp_hw_intf.h" + +#define ICP_UBWC_CFG_MAX 2 +#define CAM_ICP_V1_VERSION 0x0100 +#define CAM_ICP_V2_VERSION 0x0200 + +/** + * struct cam_icp_ubwc_cfg - ICP ubwc cfg + * @ipe_fetch: UBWC configuration for IPE fetch. + * @ipe_write: UBWC configuration for IPE write. + * @bps_fetch: UBWC configuration for BPS fetch. + * @bps_write: UBWC configuration for BPS write. + */ +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]; +}; + +/** + * struct cam_icp_soc_info - ICP soc info + * @dev_type: Device type. + * @qos_val: QOS value. + * @hw_version: hw version. + * @uconfig: union of ubwc_cfg_ext and ubwc_cfg. ubwc_cfg may + * be used in icp_v1 for older chipsets. icp_v2 only + * uses ubwc_cfg_ext. + * @is_ubwc_cfg: indicate if ubwc_cfg is used. + */ +struct cam_icp_soc_info { + enum cam_icp_hw_type dev_type; + uint32_t qos_val; + uint32_t hw_version; + union { + uint32_t ubwc_cfg[ICP_UBWC_CFG_MAX]; + struct cam_icp_ubwc_cfg ubwc_cfg_ext; + } uconfig; + bool is_ubwc_cfg; +}; + +int cam_icp_soc_resources_init(struct cam_hw_soc_info *soc_info, + irq_handler_t irq_handler, void *irq_data); + +int cam_icp_soc_resources_deinit(struct cam_hw_soc_info *soc_info); + +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); + +#endif diff --git a/drivers/cam_icp/icp_hw/a5_hw/a5_core.c b/drivers/cam_icp/icp_hw/icp_proc/icp_v1_hw/cam_icp_v1_core.c similarity index 50% rename from drivers/cam_icp/icp_hw/a5_hw/a5_core.c rename to drivers/cam_icp/icp_hw/icp_proc/icp_v1_hw/cam_icp_v1_core.c index 89b61f5cd4..a93f17e1be 100644 --- a/drivers/cam_icp/icp_hw/a5_hw/a5_core.c +++ b/drivers/cam_icp/icp_hw/icp_proc/icp_v1_hw/cam_icp_v1_core.c @@ -15,82 +15,71 @@ #include #include "cam_io_util.h" -#include "cam_a5_hw_intf.h" #include "cam_hw.h" #include "cam_hw_intf.h" -#include "a5_core.h" -#include "a5_reg.h" -#include "a5_soc.h" +#include "cam_icp_v1_core.h" +#include "cam_icp_v1_reg.h" #include "cam_soc_util.h" #include "cam_io_util.h" -#include "hfi_intf.h" #include "hfi_sys_defs.h" #include "cam_icp_hw_mgr_intf.h" #include "cam_cpas_api.h" #include "cam_debug_util.h" -#include "cam_icp_utils.h" +#include "cam_icp_proc_common.h" #include "cam_common_util.h" #include "cam_compat.h" +#include "cam_icp_soc_common.h" -#define PC_POLL_DELAY_US 100 -#define PC_POLL_TIMEOUT_US 10000 +static const struct hfi_ops hfi_icp_v1_ops = { + .irq_raise = cam_icp_v1_irq_raise, + .irq_enable = cam_icp_v1_irq_enable, + .iface_addr = cam_icp_v1_iface_addr, +}; -#define A5_GEN_PURPOSE_REG_OFFSET 0x40 - -static int cam_a5_cpas_vote(struct cam_a5_device_core_info *core_info, +static int cam_icp_v1_cpas_vote(struct cam_icp_v1_device_core_info *core_info, struct cam_icp_cpas_vote *cpas_vote) { - int rc = 0; + if (!core_info) + return -EINVAL; - if (cpas_vote->ahb_vote_valid) - rc = cam_cpas_update_ahb_vote(core_info->cpas_handle, - &cpas_vote->ahb_vote); - - if (cpas_vote->axi_vote_valid) - rc = cam_cpas_update_axi_vote(core_info->cpas_handle, - &cpas_vote->axi_vote); - - if (rc) - CAM_ERR(CAM_ICP, "cpas vote is failed: %d", rc); - - return rc; + return cam_icp_proc_cpas_vote(core_info->cpas_handle, cpas_vote); } -static int32_t cam_a5_download_fw(void *device_priv) +static int32_t cam_icp_v1_download_fw(void *device_priv) { int32_t rc = 0; uint32_t fw_size; const uint8_t *fw_start = NULL; - struct cam_hw_info *a5_dev = device_priv; + struct cam_hw_info *icp_v1_dev = device_priv; struct cam_hw_soc_info *soc_info = NULL; - struct cam_a5_device_core_info *core_info = NULL; - struct cam_a5_device_hw_info *hw_info = NULL; + struct cam_icp_v1_device_core_info *core_info = NULL; struct platform_device *pdev = NULL; - struct a5_soc_info *cam_a5_soc_info = NULL; + const char *firmware_name = NULL; if (!device_priv) { CAM_ERR(CAM_ICP, "Invalid cam_dev_info"); return -EINVAL; } - soc_info = &a5_dev->soc_info; - core_info = (struct cam_a5_device_core_info *)a5_dev->core_info; - hw_info = core_info->a5_hw_info; + soc_info = &icp_v1_dev->soc_info; + core_info = (struct cam_icp_v1_device_core_info *)icp_v1_dev->core_info; pdev = soc_info->pdev; - cam_a5_soc_info = soc_info->soc_private; - if (cam_a5_soc_info->fw_name) { - CAM_INFO(CAM_ICP, "Downloading firmware %s", - cam_a5_soc_info->fw_name); + rc = of_property_read_string(pdev->dev.of_node, "fw_name", &firmware_name); + if (rc) { + CAM_INFO(CAM_ICP, + "FW image name not found. Use default name: CAMERA_ICP.elf"); rc = firmware_request_nowarn(&core_info->fw_elf, - cam_a5_soc_info->fw_name, &pdev->dev); + "CAMERA_ICP.elf", &pdev->dev); if (rc) { CAM_ERR(CAM_ICP, "Failed to locate fw: %d", rc); return rc; } } else { + CAM_INFO(CAM_ICP, "Downloading firmware %s", + firmware_name); rc = firmware_request_nowarn(&core_info->fw_elf, - "CAMERA_ICP.elf", &pdev->dev); + firmware_name, &pdev->dev); if (rc) { CAM_ERR(CAM_ICP, "Failed to locate fw: %d", rc); return rc; @@ -134,9 +123,9 @@ fw_download_failed: return rc; } -static int cam_a5_fw_dump( +static int cam_icp_v1_fw_dump( struct cam_icp_hw_dump_args *dump_args, - struct cam_a5_device_core_info *core_info) + struct cam_icp_v1_device_core_info *core_info) { u8 *dest; u8 *src; @@ -145,12 +134,12 @@ static int cam_a5_fw_dump( if (!core_info || !dump_args) { CAM_ERR(CAM_ICP, "invalid params %pK %pK", - core_info, dump_args); + core_info, dump_args); return -EINVAL; } if (!core_info->fw_kva_addr || !dump_args->cpu_addr) { CAM_ERR(CAM_ICP, "invalid params %pK, 0x%zx", - core_info->fw_kva_addr, dump_args->cpu_addr); + core_info->fw_kva_addr, dump_args->cpu_addr); return -EINVAL; } @@ -181,44 +170,25 @@ static int cam_a5_fw_dump( return 0; } -static int cam_a5_fw_mini_dump( - struct cam_icp_hw_dump_args *dump_args, - struct cam_a5_device_core_info *core_info) +static int cam_icp_v1_fw_mini_dump(struct cam_icp_hw_dump_args *dump_args, + struct cam_icp_v1_device_core_info *core_info) { - u8 *dest; - u8 *src; - - if (!core_info || !dump_args) { - CAM_ERR(CAM_ICP, "invalid params %pK %pK", core_info, dump_args); + if (!core_info) { + CAM_ERR(CAM_ICP, "Invalid param %pK", core_info); return -EINVAL; } - if (!core_info->fw_kva_addr || !dump_args->cpu_addr) { - CAM_ERR(CAM_ICP, "invalid params %pK, 0x%zx", core_info->fw_kva_addr, - dump_args->cpu_addr); - return -EINVAL; - } - - if (dump_args->buf_len < core_info->fw_buf_len) { - CAM_WARN(CAM_ICP, "Insufficient Len %lu fw_len %llu", - dump_args->buf_len, core_info->fw_buf_len); - return -ENOSPC; - } - - dest = (u8 *)dump_args->cpu_addr; - src = (u8 *)core_info->fw_kva_addr; - memcpy_fromio(dest, src, core_info->fw_buf_len); - dump_args->offset = core_info->fw_buf_len; - return 0; + return cam_icp_proc_mini_dump(dump_args, core_info->fw_kva_addr, + core_info->fw_buf_len); } -int cam_a5_init_hw(void *device_priv, +int cam_icp_v1_init_hw(void *device_priv, void *init_hw_args, uint32_t arg_size) { - struct cam_hw_info *a5_dev = device_priv; + struct cam_hw_info *icp_v1_dev = device_priv; struct cam_hw_soc_info *soc_info = NULL; - struct cam_a5_device_core_info *core_info = NULL; - struct a5_soc_info *a5_soc_info; + struct cam_icp_v1_device_core_info *core_info = NULL; + struct cam_icp_soc_info *icp_v1_soc_info; struct cam_icp_cpas_vote cpas_vote; unsigned long flags; int rc = 0; @@ -229,8 +199,8 @@ int cam_a5_init_hw(void *device_priv, return -EINVAL; } - soc_info = &a5_dev->soc_info; - core_info = (struct cam_a5_device_core_info *)a5_dev->core_info; + 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", @@ -238,14 +208,14 @@ int cam_a5_init_hw(void *device_priv, return -EINVAL; } - spin_lock_irqsave(&a5_dev->hw_lock, flags); - if (a5_dev->hw_state == CAM_HW_STATE_POWER_UP) { - spin_unlock_irqrestore(&a5_dev->hw_lock, flags); + 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); return 0; } - spin_unlock_irqrestore(&a5_dev->hw_lock, flags); + spin_unlock_irqrestore(&icp_v1_dev->hw_lock, flags); - a5_soc_info = soc_info->soc_private; + icp_v1_soc_info = soc_info->soc_private; cpas_vote.ahb_vote.type = CAM_VOTE_ABSOLUTE; cpas_vote.ahb_vote.vote.level = CAM_LOWSVS_VOTE; @@ -273,7 +243,7 @@ int cam_a5_init_hw(void *device_priv, } core_info->cpas_start = true; - rc = cam_a5_enable_soc_resources(soc_info); + rc = cam_icp_soc_resources_enable(soc_info); if (rc) { CAM_ERR(CAM_ICP, "soc enable is failed: %d", rc); if (cam_cpas_stop(core_info->cpas_handle)) @@ -281,11 +251,11 @@ int cam_a5_init_hw(void *device_priv, else core_info->cpas_start = false; } else { - CAM_DBG(CAM_ICP, "a5_qos %d", a5_soc_info->a5_qos_val); - if (a5_soc_info->a5_qos_val) - cam_io_w_mb(a5_soc_info->a5_qos_val, - soc_info->reg_map[A5_SIERRA_BASE].mem_base + - ICP_SIERRA_A5_CSR_ACCESS); + CAM_DBG(CAM_ICP, "icp_v1_qos %d", icp_v1_soc_info->qos_val); + if (icp_v1_soc_info->qos_val) + cam_io_w_mb(icp_v1_soc_info->qos_val, + soc_info->reg_map[ICP_V1_BASE].mem_base + + ICP_V1_CSR_ACCESS); if (send_freq_info) { int32_t clk_rate = 0; @@ -294,20 +264,20 @@ int cam_a5_init_hw(void *device_priv, } } - spin_lock_irqsave(&a5_dev->hw_lock, flags); - a5_dev->hw_state = CAM_HW_STATE_POWER_UP; - spin_unlock_irqrestore(&a5_dev->hw_lock, flags); + spin_lock_irqsave(&icp_v1_dev->hw_lock, flags); + icp_v1_dev->hw_state = CAM_HW_STATE_POWER_UP; + spin_unlock_irqrestore(&icp_v1_dev->hw_lock, flags); error: return rc; } -int cam_a5_deinit_hw(void *device_priv, +int cam_icp_v1_deinit_hw(void *device_priv, void *init_hw_args, uint32_t arg_size) { - struct cam_hw_info *a5_dev = device_priv; + struct cam_hw_info *icp_v1_dev = device_priv; struct cam_hw_soc_info *soc_info = NULL; - struct cam_a5_device_core_info *core_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); @@ -317,25 +287,26 @@ int cam_a5_deinit_hw(void *device_priv, return -EINVAL; } - soc_info = &a5_dev->soc_info; - core_info = (struct cam_a5_device_core_info *)a5_dev->core_info; + 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); return -EINVAL; } - spin_lock_irqsave(&a5_dev->hw_lock, flags); - if (a5_dev->hw_state == CAM_HW_STATE_POWER_DOWN) { - spin_unlock_irqrestore(&a5_dev->hw_lock, flags); + spin_lock_irqsave(&icp_v1_dev->hw_lock, flags); + if (icp_v1_dev->hw_state == CAM_HW_STATE_POWER_DOWN) { + spin_unlock_irqrestore(&icp_v1_dev->hw_lock, flags); return 0; } - spin_unlock_irqrestore(&a5_dev->hw_lock, flags); + spin_unlock_irqrestore(&icp_v1_dev->hw_lock, flags); if (send_freq_info) hfi_send_freq_info(0); - rc = cam_a5_disable_soc_resources(soc_info); + rc = cam_icp_soc_resources_disable(soc_info); + if (rc) CAM_ERR(CAM_ICP, "soc disable is failed: %d", rc); @@ -346,56 +317,56 @@ int cam_a5_deinit_hw(void *device_priv, core_info->cpas_start = false; } - spin_lock_irqsave(&a5_dev->hw_lock, flags); - a5_dev->hw_state = CAM_HW_STATE_POWER_DOWN; - spin_unlock_irqrestore(&a5_dev->hw_lock, flags); + spin_lock_irqsave(&icp_v1_dev->hw_lock, flags); + icp_v1_dev->hw_state = CAM_HW_STATE_POWER_DOWN; + spin_unlock_irqrestore(&icp_v1_dev->hw_lock, flags); return rc; } -static int cam_a5_power_resume(struct cam_hw_info *a5_info, bool debug_enabled) +static int cam_icp_v1_power_resume(struct cam_hw_info *icp_v1_info, bool debug_enabled) { - uint32_t val = A5_CSR_FULL_CPU_EN; + uint32_t val = ICP_V1_CSR_FULL_CPU_EN; void __iomem *base; struct cam_hw_soc_info *soc_info = NULL; - struct a5_soc_info *a5_soc_info; + struct cam_icp_soc_info *icp_v1_soc_info; - if (!a5_info) { - CAM_ERR(CAM_ICP, "invalid A5 device info"); + if (!icp_v1_info) { + CAM_ERR(CAM_ICP, "Invalid ICP device info"); return -EINVAL; } - base = a5_info->soc_info.reg_map[A5_SIERRA_BASE].mem_base; - soc_info = &a5_info->soc_info; - a5_soc_info = soc_info->soc_private; + base = icp_v1_info->soc_info.reg_map[ICP_V1_BASE].mem_base; + soc_info = &icp_v1_info->soc_info; + icp_v1_soc_info = soc_info->soc_private; - cam_io_w_mb(A5_CSR_A5_CPU_EN, base + ICP_SIERRA_A5_CSR_A5_CONTROL); - cam_io_w_mb(A5_CSR_FUNC_RESET, base + ICP_SIERRA_A5_CSR_NSEC_RESET); + cam_io_w_mb(ICP_V1_CSR_CPU_EN, base + ICP_V1_CSR_CONTROL); + cam_io_w_mb(ICP_V1_CSR_FUNC_RESET, base + ICP_V1_CSR_NSEC_RESET); if (debug_enabled) - val |= A5_CSR_FULL_DBG_EN; + val |= ICP_V1_CSR_FULL_DBG_EN; - cam_io_w_mb(val, base + ICP_SIERRA_A5_CSR_A5_CONTROL); - cam_io_w_mb(a5_soc_info->a5_qos_val, - base + ICP_SIERRA_A5_CSR_ACCESS); + cam_io_w_mb(val, base + ICP_V1_CSR_CONTROL); + cam_io_w_mb(icp_v1_soc_info->qos_val, + base + ICP_V1_CSR_ACCESS); - CAM_DBG(CAM_ICP, "a5 qos-val : 0x%x", - cam_io_r_mb(base + ICP_SIERRA_A5_CSR_ACCESS)); + CAM_DBG(CAM_ICP, "icp_v1 qos-val : 0x%x", + cam_io_r_mb(base + ICP_V1_CSR_ACCESS)); return 0; } -static int cam_a5_power_collapse(struct cam_hw_info *a5_info) +static int cam_icp_v1_power_collapse(struct cam_hw_info *icp_v1_info) { uint32_t val, status = 0; void __iomem *base; - if (!a5_info) { - CAM_ERR(CAM_ICP, "invalid A5 device info"); + if (!icp_v1_info) { + CAM_ERR(CAM_ICP, "invalid ICP device info"); return -EINVAL; } - base = a5_info->soc_info.reg_map[A5_SIERRA_BASE].mem_base; + base = icp_v1_info->soc_info.reg_map[ICP_V1_BASE].mem_base; /** * Need to poll here to confirm that FW has triggered WFI @@ -404,107 +375,106 @@ static int cam_a5_power_collapse(struct cam_hw_info *a5_info) */ if (cam_common_read_poll_timeout(base + - ICP_SIERRA_A5_CSR_A5_STATUS, - PC_POLL_DELAY_US, PC_POLL_TIMEOUT_US, - A5_CSR_A5_STANDBYWFI, - A5_CSR_A5_STANDBYWFI, &status)) { + ICP_V1_CSR_STATUS, + PC_POLL_DELAY_US, PC_POLL_TIMEOUT_US, + ICP_V1_CSR_STANDBYWFI, + ICP_V1_CSR_STANDBYWFI, &status)) { CAM_ERR(CAM_ICP, "WFI poll timed out: status=0x%08x", status); return -ETIMEDOUT; } - val = cam_io_r(base + ICP_SIERRA_A5_CSR_A5_CONTROL); - val &= ~(A5_CSR_A5_CPU_EN | A5_CSR_WAKE_UP_EN); - cam_io_w_mb(val, base + ICP_SIERRA_A5_CSR_A5_CONTROL); + val = cam_io_r(base + ICP_V1_CSR_CONTROL); + val &= ~(ICP_V1_CSR_CPU_EN | ICP_V1_CSR_WAKE_UP_EN); + cam_io_w_mb(val, base + ICP_V1_CSR_CONTROL); return 0; } -static void prepare_boot(struct cam_hw_info *a5_dev, - struct cam_icp_boot_args *args) +static void prepare_boot(struct cam_hw_info *icp_v1_dev, + struct cam_icp_boot_args *args) { - struct cam_a5_device_core_info *core_info = a5_dev->core_info; + struct cam_icp_v1_device_core_info *core_info = icp_v1_dev->core_info; unsigned long flags; core_info->fw_buf = args->firmware.iova; core_info->fw_kva_addr = args->firmware.kva; core_info->fw_buf_len = args->firmware.len; - spin_lock_irqsave(&a5_dev->hw_lock, flags); + spin_lock_irqsave(&icp_v1_dev->hw_lock, flags); core_info->irq_cb.data = args->irq_cb.data; core_info->irq_cb.cb = args->irq_cb.cb; - spin_unlock_irqrestore(&a5_dev->hw_lock, flags); + spin_unlock_irqrestore(&icp_v1_dev->hw_lock, flags); } -static void prepare_shutdown(struct cam_hw_info *a5_dev) +static void prepare_shutdown(struct cam_hw_info *icp_v1_dev) { - struct cam_a5_device_core_info *core_info = a5_dev->core_info; + struct cam_icp_v1_device_core_info *core_info = icp_v1_dev->core_info; unsigned long flags; core_info->fw_buf = 0; core_info->fw_kva_addr = 0; core_info->fw_buf_len = 0; - spin_lock_irqsave(&a5_dev->hw_lock, flags); + spin_lock_irqsave(&icp_v1_dev->hw_lock, flags); core_info->irq_cb.data = NULL; core_info->irq_cb.cb = NULL; - spin_unlock_irqrestore(&a5_dev->hw_lock, flags); + spin_unlock_irqrestore(&icp_v1_dev->hw_lock, flags); } -static int cam_a5_boot(struct cam_hw_info *a5_dev, - struct cam_icp_boot_args *args, size_t arg_size) +static int cam_icp_v1_boot(struct cam_hw_info *icp_v1_dev, + struct cam_icp_boot_args *args, size_t arg_size) { int rc; - if (!a5_dev || !args) { + if (!icp_v1_dev || !args) { CAM_ERR(CAM_ICP, - "invalid args: a5_dev=%pK args=%pK", - a5_dev, args); + "Invalid args: icp_v1_dev=%pK args=%pK", + icp_v1_dev, args); return -EINVAL; } if (arg_size != sizeof(struct cam_icp_boot_args)) { - CAM_ERR(CAM_ICP, "invalid boot args size"); + CAM_ERR(CAM_ICP, "Invalid boot args size"); return -EINVAL; } - prepare_boot(a5_dev, args); + prepare_boot(icp_v1_dev, args); - rc = cam_a5_download_fw(a5_dev); + rc = cam_icp_v1_download_fw(icp_v1_dev); if (rc) { CAM_ERR(CAM_ICP, "firmware download failed rc=%d", rc); goto err; } - rc = cam_a5_power_resume(a5_dev, args->debug_enabled); + rc = cam_icp_v1_power_resume(icp_v1_dev, args->debug_enabled); if (rc) { - CAM_ERR(CAM_ICP, "A5 boot failed rc=%d", rc); + CAM_ERR(CAM_ICP, "ICP boot failed rc=%d", rc); goto err; } return 0; err: - prepare_shutdown(a5_dev); + prepare_shutdown(icp_v1_dev); return rc; } -static int cam_a5_shutdown(struct cam_hw_info *a5_dev) +static int cam_icp_v1_shutdown(struct cam_hw_info *icp_v1_dev) { - if (!a5_dev) { - CAM_ERR(CAM_ICP, "invalid A5 device info"); + if (!icp_v1_dev) { + CAM_ERR(CAM_ICP, "invalid ICP device info"); return -EINVAL; } - prepare_shutdown(a5_dev); - cam_a5_power_collapse(a5_dev); + prepare_shutdown(icp_v1_dev); + cam_icp_v1_power_collapse(icp_v1_dev); return 0; } -irqreturn_t cam_a5_irq(int irq_num, void *data) +irqreturn_t cam_icp_v1_irq(int irq_num, void *data) { - struct cam_hw_info *a5_dev = data; + struct cam_hw_info *icp_v1_dev = data; struct cam_hw_soc_info *soc_info = NULL; - struct cam_a5_device_core_info *core_info = NULL; - struct cam_a5_device_hw_info *hw_info = NULL; + struct cam_icp_v1_device_core_info *core_info = NULL; uint32_t irq_status = 0; bool recover = false; @@ -513,95 +483,98 @@ irqreturn_t cam_a5_irq(int irq_num, void *data) return IRQ_HANDLED; } - spin_lock(&a5_dev->hw_lock); - if (a5_dev->hw_state == CAM_HW_STATE_POWER_DOWN) { + spin_lock(&icp_v1_dev->hw_lock); + if (icp_v1_dev->hw_state == CAM_HW_STATE_POWER_DOWN) { CAM_WARN(CAM_ICP, "ICP HW powered off"); - spin_unlock(&a5_dev->hw_lock); + spin_unlock(&icp_v1_dev->hw_lock); return IRQ_HANDLED; } - spin_unlock(&a5_dev->hw_lock); + spin_unlock(&icp_v1_dev->hw_lock); - soc_info = &a5_dev->soc_info; - core_info = (struct cam_a5_device_core_info *)a5_dev->core_info; - hw_info = core_info->a5_hw_info; + soc_info = &icp_v1_dev->soc_info; + core_info = (struct cam_icp_v1_device_core_info *)icp_v1_dev->core_info; - irq_status = cam_io_r_mb(soc_info->reg_map[A5_SIERRA_BASE].mem_base + - core_info->a5_hw_info->a5_host_int_status); + irq_status = cam_io_r_mb(soc_info->reg_map[ICP_V1_BASE].mem_base + + ICP_V1_HOST_INT_STATUS); cam_io_w_mb(irq_status, - soc_info->reg_map[A5_SIERRA_BASE].mem_base + - core_info->a5_hw_info->a5_host_int_clr); + soc_info->reg_map[ICP_V1_BASE].mem_base + ICP_V1_HOST_INT_CLR); - if ((irq_status & A5_WDT_0) || - (irq_status & A5_WDT_1)) { - CAM_ERR_RATE_LIMIT(CAM_ICP, "watch dog interrupt from A5"); + if ((irq_status & ICP_V1_WDT_0) || + (irq_status & ICP_V1_WDT_1)) { + CAM_ERR_RATE_LIMIT(CAM_ICP, "watch dog interrupt from ICP"); recover = true; } - spin_lock(&a5_dev->hw_lock); + spin_lock(&icp_v1_dev->hw_lock); if (core_info->irq_cb.cb) - core_info->irq_cb.cb(core_info->irq_cb.data, - recover); - spin_unlock(&a5_dev->hw_lock); + core_info->irq_cb.cb(core_info->irq_cb.data, recover); + spin_unlock(&icp_v1_dev->hw_lock); return IRQ_HANDLED; } -void cam_a5_irq_raise(void *priv) +void cam_icp_v1_irq_raise(void *priv) { - struct cam_hw_info *a5_info = priv; + struct cam_hw_info *icp_v1_info = priv; - if (!a5_info) { - CAM_ERR(CAM_ICP, "invalid A5 device info"); + if (!icp_v1_info) { + CAM_ERR(CAM_ICP, "invalid ICP device info"); return; } - cam_io_w_mb(A5_HOSTINT, - a5_info->soc_info.reg_map[A5_SIERRA_BASE].mem_base + - ICP_SIERRA_A5_CSR_HOST2ICPINT); + cam_io_w_mb(ICP_V1_HOSTINT, + icp_v1_info->soc_info.reg_map[ICP_V1_BASE].mem_base + + ICP_V1_CSR_HOST2ICPINT); } -void cam_a5_irq_enable(void *priv) +void cam_icp_v1_irq_enable(void *priv) { - struct cam_hw_info *a5_info = priv; + struct cam_hw_info *icp_v1_info = priv; - if (!a5_info) { - CAM_ERR(CAM_ICP, "invalid A5 device info"); + if (!icp_v1_info) { + CAM_ERR(CAM_ICP, "invalid ICP device info"); return; } - cam_io_w_mb(A5_WDT_WS0EN | A5_A2HOSTINTEN, - a5_info->soc_info.reg_map[A5_SIERRA_BASE].mem_base + - ICP_SIERRA_A5_CSR_A2HOSTINTEN); + cam_io_w_mb(ICP_V1_WDT_WS0EN | ICP_V1_A2HOSTINTEN, + icp_v1_info->soc_info.reg_map[ICP_V1_BASE].mem_base + + ICP_V1_CSR_A2HOSTINTEN); } -void __iomem *cam_a5_iface_addr(void *priv) +void __iomem *cam_icp_v1_iface_addr(void *priv) { - struct cam_hw_info *a5_info = priv; + struct cam_hw_info *icp_v1_info = priv; void __iomem *base; - if (!a5_info) { - CAM_ERR(CAM_ICP, "invalid A5 device info"); + if (!icp_v1_info) { + CAM_ERR(CAM_ICP, "invalid ICP device info"); return ERR_PTR(-EINVAL); } - base = a5_info->soc_info.reg_map[A5_SIERRA_BASE].mem_base; + base = icp_v1_info->soc_info.reg_map[ICP_V1_BASE].mem_base; - return base + A5_GEN_PURPOSE_REG_OFFSET; + return base + ICP_V1_GEN_PURPOSE_REG_OFFSET; } -int cam_a5_process_cmd(void *device_priv, uint32_t cmd_type, +void cam_icp_v1_populate_hfi_ops(const struct hfi_ops **hfi_proc_ops) +{ + if (!hfi_proc_ops) { + CAM_ERR(CAM_ICP, "Invalid hfi ops argument"); + return; + } + + *hfi_proc_ops = &hfi_icp_v1_ops; +} + +int cam_icp_v1_process_cmd(void *device_priv, uint32_t cmd_type, void *cmd_args, uint32_t arg_size) { - struct cam_hw_info *a5_dev = device_priv; + struct cam_hw_info *icp_v1_dev = device_priv; struct cam_hw_soc_info *soc_info = NULL; - struct cam_a5_device_core_info *core_info = NULL; - struct cam_a5_device_hw_info *hw_info = NULL; - struct a5_soc_info *a5_soc = NULL; - uint32_t ubwc_ipe_cfg[ICP_UBWC_MAX] = {0}; - uint32_t ubwc_bps_cfg[ICP_UBWC_MAX] = {0}; - uint32_t index = 0; - int rc = 0, ddr_type = 0; + struct cam_icp_v1_device_core_info *core_info = NULL; + struct cam_icp_soc_info *icp_soc_info = NULL; + int rc = 0; if (!device_priv) { CAM_ERR(CAM_ICP, "Invalid arguments"); @@ -613,22 +586,21 @@ int cam_a5_process_cmd(void *device_priv, uint32_t cmd_type, return -EINVAL; } - soc_info = &a5_dev->soc_info; - core_info = (struct cam_a5_device_core_info *)a5_dev->core_info; - hw_info = core_info->a5_hw_info; + soc_info = &icp_v1_dev->soc_info; + core_info = (struct cam_icp_v1_device_core_info *)icp_v1_dev->core_info; switch (cmd_type) { case CAM_ICP_CMD_PROC_SHUTDOWN: - rc = cam_a5_shutdown(device_priv); + rc = cam_icp_v1_shutdown(device_priv); break; case CAM_ICP_CMD_PROC_BOOT: - rc = cam_a5_boot(device_priv, cmd_args, arg_size); + rc = cam_icp_v1_boot(device_priv, cmd_args, arg_size); break; case CAM_ICP_CMD_POWER_COLLAPSE: - rc = cam_a5_power_collapse(a5_dev); + rc = cam_icp_v1_power_collapse(icp_v1_dev); break; case CAM_ICP_CMD_POWER_RESUME: - rc = cam_a5_power_resume(a5_dev, *((bool *)cmd_args)); + 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); @@ -646,7 +618,7 @@ int cam_a5_process_cmd(void *device_priv, uint32_t cmd_type, return -EINVAL; } - cam_a5_cpas_vote(core_info, cpas_vote); + cam_icp_v1_cpas_vote(core_info, cpas_vote); break; } @@ -660,8 +632,8 @@ int cam_a5_process_cmd(void *device_priv, uint32_t cmd_type, if (!core_info->cpas_start) { rc = cam_cpas_start(core_info->cpas_handle, - &cpas_vote->ahb_vote, - &cpas_vote->axi_vote); + &cpas_vote->ahb_vote, + &cpas_vote->axi_vote); core_info->cpas_start = true; } break; @@ -674,12 +646,11 @@ int cam_a5_process_cmd(void *device_priv, uint32_t cmd_type, } break; case CAM_ICP_CMD_UBWC_CFG: { - struct a5_ubwc_cfg_ext *ubwc_cfg_ext = NULL; - uint32_t *disable_ubwc_comp; + uint32_t disable_ubwc_comp; - a5_soc = soc_info->soc_private; - if (!a5_soc) { - CAM_ERR(CAM_ICP, "A5 private soc info is NULL"); + icp_soc_info = soc_info->soc_private; + if (!icp_soc_info) { + CAM_ERR(CAM_ICP, "ICP private soc info is NULL"); return -EINVAL; } @@ -687,37 +658,13 @@ int cam_a5_process_cmd(void *device_priv, uint32_t cmd_type, CAM_ERR(CAM_ICP, "Invalid args"); return -EINVAL; } + disable_ubwc_comp = *((uint32_t *)cmd_args); - disable_ubwc_comp = (uint32_t *)cmd_args; - - if (a5_soc->ubwc_config_ext) { - /* Invoke kernel API to determine DDR type */ - ddr_type = cam_get_ddr_type(); - if ((ddr_type == DDR_TYPE_LPDDR5) || - (ddr_type == DDR_TYPE_LPDDR5X)) - index = 1; - - ubwc_cfg_ext = &a5_soc->uconfig.ubwc_cfg_ext; - ubwc_ipe_cfg[0] = - ubwc_cfg_ext->ubwc_ipe_fetch_cfg[index]; - ubwc_ipe_cfg[1] = - ubwc_cfg_ext->ubwc_ipe_write_cfg[index]; - ubwc_bps_cfg[0] = - ubwc_cfg_ext->ubwc_bps_fetch_cfg[index]; - ubwc_bps_cfg[1] = - ubwc_cfg_ext->ubwc_bps_write_cfg[index]; - if (*disable_ubwc_comp) { - ubwc_ipe_cfg[1] &= ~CAM_ICP_UBWC_COMP_EN; - ubwc_bps_cfg[1] &= ~CAM_ICP_UBWC_COMP_EN; - CAM_DBG(CAM_ICP, - "Force disable UBWC compression, ubwc_ipe_cfg: 0x%x, ubwc_bps_cfg: 0x%x", - ubwc_ipe_cfg[1], ubwc_bps_cfg[1]); - } - rc = hfi_cmd_ubwc_config_ext(&ubwc_ipe_cfg[0], - &ubwc_bps_cfg[0]); - } else { - rc = hfi_cmd_ubwc_config(a5_soc->uconfig.ubwc_cfg); - } + 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); break; } @@ -733,7 +680,7 @@ int cam_a5_process_cmd(void *device_priv, uint32_t cmd_type, clk_level = *((int32_t *)cmd_args); CAM_DBG(CAM_ICP, "Update ICP clock to level [%d]", clk_level); - rc = cam_a5_update_clk_rate(soc_info, clk_level); + rc = cam_icp_soc_update_clk_rate(soc_info, clk_level); if (rc) CAM_ERR(CAM_ICP, "Failed to update clk to level: %d rc: %d", @@ -748,14 +695,14 @@ int cam_a5_process_cmd(void *device_priv, uint32_t cmd_type, case CAM_ICP_CMD_HW_DUMP: { struct cam_icp_hw_dump_args *dump_args = cmd_args; - rc = cam_a5_fw_dump(dump_args, core_info); + rc = cam_icp_v1_fw_dump(dump_args, core_info); break; } case CAM_ICP_CMD_HW_MINI_DUMP: { struct cam_icp_hw_dump_args *dump_args = cmd_args; - rc = cam_a5_fw_mini_dump(dump_args, core_info); + rc = cam_icp_v1_fw_mini_dump(dump_args, core_info); break; } case CAM_ICP_CMD_HW_REG_DUMP: { 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 new file mode 100644 index 0000000000..16fffba643 --- /dev/null +++ b/drivers/cam_icp/icp_hw/icp_proc/icp_v1_hw/cam_icp_v1_core.h @@ -0,0 +1,69 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + */ + +#ifndef CAM_ICP_V1_CORE_H +#define CAM_ICP_V1_CORE_H + +#include +#include +#include +#include + +#include "cam_icp_hw_intf.h" +#include "hfi_intf.h" + +#define ICP_V1_QGIC_BASE 0 +#define ICP_V1_BASE 1 +#define ICP_V1_CSR_BASE 2 + +#define ICP_V1_HOST_INT 0x1 +#define ICP_V1_WDT_0 0x2 +#define ICP_V1_WDT_1 0x4 + +#define ICP_V1_CSR_ACCESS 0x3C + +#define ELF_GUARD_PAGE (2 * 1024 * 1024) + +/** + * struct cam_icp_v1_device_hw_info + * @icp_v1_hw_info: ICP_V1 hardware info + * @fw_elf: start address of fw start with elf header + * @fw: start address of fw blob + * @fw_buf: smmu alloc/mapped fw buffer + * @fw_buf_len: fw buffer length + * @query_cap: ICP_V1 query info from firmware + * @icp_v1_acquire: Acquire information of ICP_V1 + * @irq_cb: IRQ callback + * @cpas_handle: CPAS handle for ICP_V1 + * @hw_version: hw version of icp v1 processor + * @cpas_start: state variable for cpas + */ +struct cam_icp_v1_device_core_info { + const struct firmware *fw_elf; + void *fw; + uint32_t fw_buf; + uintptr_t fw_kva_addr; + uint64_t fw_buf_len; + struct cam_icp_irq_cb irq_cb; + uint32_t cpas_handle; + bool cpas_start; +}; + +int cam_icp_v1_init_hw(void *device_priv, + void *init_hw_args, uint32_t arg_size); +int cam_icp_v1_deinit_hw(void *device_priv, + void *init_hw_args, uint32_t arg_size); +int cam_icp_v1_process_cmd(void *device_priv, uint32_t cmd_type, + void *cmd_args, uint32_t arg_size); + +irqreturn_t cam_icp_v1_irq(int irq_num, void *data); + +void cam_icp_v1_irq_raise(void *priv); +void cam_icp_v1_irq_enable(void *priv); +void __iomem *cam_icp_v1_iface_addr(void *priv); +void cam_icp_v1_populate_hfi_ops(const struct hfi_ops **hfi_proc_ops); + +#endif /* CAM_ICP_V1_CORE_H */ 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 new file mode 100644 index 0000000000..eb6a837aa6 --- /dev/null +++ b/drivers/cam_icp/icp_hw/icp_proc/icp_v1_hw/cam_icp_v1_dev.c @@ -0,0 +1,279 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + */ + +#include +#include +#include +#include +#include +#include "cam_icp_v1_core.h" +#include "cam_io_util.h" +#include "cam_hw.h" +#include "cam_hw_intf.h" +#include "cam_icp_hw_mgr_intf.h" +#include "cam_cpas_api.h" +#include "cam_debug_util.h" +#include "camera_main.h" +#include "cam_icp_soc_common.h" +#include "cam_icp_v1_dev.h" + +static int max_icp_v1_hw_idx = -1; + +uint32_t cam_icp_v1_get_device_num(void) +{ + return max_icp_v1_hw_idx + 1; +} + +static bool cam_icp_v1_cpas_cb(uint32_t client_handle, void *userdata, + struct cam_cpas_irq_data *irq_data) +{ + bool error_handled = false; + + if (!irq_data) + return error_handled; + + switch (irq_data->irq_type) { + case CAM_CAMNOC_IRQ_IPE_BPS_UBWC_DECODE_ERROR: + CAM_ERR_RATE_LIMIT(CAM_ICP, + "IPE/BPS UBWC Decode error type=%d status=%x thr_err=%d, fcl_err=%d, len_md_err=%d, format_err=%d", + irq_data->irq_type, + irq_data->u.dec_err.decerr_status.value, + irq_data->u.dec_err.decerr_status.thr_err, + irq_data->u.dec_err.decerr_status.fcl_err, + irq_data->u.dec_err.decerr_status.len_md_err, + irq_data->u.dec_err.decerr_status.format_err); + error_handled = true; + break; + case CAM_CAMNOC_IRQ_IPE_BPS_UBWC_ENCODE_ERROR: + CAM_ERR_RATE_LIMIT(CAM_ICP, + "IPE/BPS UBWC Encode error type=%d status=%x", + irq_data->irq_type, + irq_data->u.enc_err.encerr_status.value); + error_handled = true; + break; + default: + break; + } + + return error_handled; +} + +int cam_icp_v1_register_cpas(struct cam_hw_soc_info *soc_info, + struct cam_icp_v1_device_core_info *core_info, uint32_t hw_idx) +{ + struct cam_cpas_register_params cpas_register_params; + int rc; + + cpas_register_params.dev = &soc_info->pdev->dev; + memcpy(cpas_register_params.identifier, "icp", sizeof("icp")); + cpas_register_params.cam_cpas_client_cb = cam_icp_v1_cpas_cb; + cpas_register_params.cell_index = hw_idx; + cpas_register_params.userdata = NULL; + + rc = cam_cpas_register_client(&cpas_register_params); + if (rc < 0) { + CAM_ERR(CAM_ICP, "failed: %d", rc); + return rc; + } + + core_info->cpas_handle = cpas_register_params.client_handle; + return rc; +} + +static inline void cam_icp_v1_soc_info_deinit(struct cam_hw_soc_info *soc_info) +{ + kfree(soc_info->soc_private); +} + +static int cam_icp_v1_soc_info_init(struct cam_hw_soc_info *soc_info, + struct platform_device *pdev) +{ + struct cam_icp_soc_info *icp_soc_info = NULL; + + icp_soc_info = kzalloc(sizeof(*icp_soc_info), GFP_KERNEL); + if (!icp_soc_info) + return -ENOMEM; + + soc_info->pdev = pdev; + soc_info->dev = &pdev->dev; + soc_info->dev_name = pdev->name; + soc_info->soc_private = icp_soc_info; + + icp_soc_info->dev_type = CAM_ICP_DEV_ICP_V1; + + return 0; +} + +static int cam_icp_v1_component_bind(struct device *dev, + struct device *master_dev, void *data) +{ + int rc = 0; + struct cam_hw_info *icp_v1_dev = NULL; + struct cam_hw_intf *icp_v1_dev_intf = NULL; + const struct of_device_id *match_dev = NULL; + struct cam_icp_v1_device_core_info *core_info = NULL; + struct platform_device *pdev = to_platform_device(dev); + + icp_v1_dev_intf = kzalloc(sizeof(struct cam_hw_intf), GFP_KERNEL); + if (!icp_v1_dev_intf) + return -ENOMEM; + + of_property_read_u32(pdev->dev.of_node, + "cell-index", &icp_v1_dev_intf->hw_idx); + + icp_v1_dev = kzalloc(sizeof(struct cam_hw_info), GFP_KERNEL); + if (!icp_v1_dev) { + rc = -ENOMEM; + goto icp_v1_dev_alloc_failure; + } + + icp_v1_dev_intf->hw_priv = icp_v1_dev; + icp_v1_dev_intf->hw_ops.init = cam_icp_v1_init_hw; + icp_v1_dev_intf->hw_ops.deinit = cam_icp_v1_deinit_hw; + icp_v1_dev_intf->hw_ops.process_cmd = cam_icp_v1_process_cmd; + icp_v1_dev_intf->hw_type = CAM_ICP_DEV_ICP_V1; + + CAM_DBG(CAM_ICP, "type %d index %d", + icp_v1_dev_intf->hw_type, + icp_v1_dev_intf->hw_idx); + + platform_set_drvdata(pdev, icp_v1_dev_intf); + + core_info = kzalloc(sizeof(struct cam_icp_v1_device_core_info), + GFP_KERNEL); + if (!core_info) { + rc = -ENOMEM; + goto core_info_alloc_failure; + } + icp_v1_dev->core_info = core_info; + + match_dev = of_match_device(pdev->dev.driver->of_match_table, + &pdev->dev); + if (!match_dev) { + CAM_ERR(CAM_ICP, "No icp_v1 hardware info"); + rc = -EINVAL; + goto match_err; + } + + rc = cam_icp_v1_soc_info_init(&icp_v1_dev->soc_info, pdev); + if (rc) + goto init_soc_failure; + + rc = cam_icp_soc_resources_init(&icp_v1_dev->soc_info, cam_icp_v1_irq, + icp_v1_dev); + if (rc < 0) { + CAM_ERR(CAM_ICP, "failed to init_soc"); + goto init_soc_failure; + } + + rc = cam_icp_v1_register_cpas(&icp_v1_dev->soc_info, + core_info, icp_v1_dev_intf->hw_idx); + if (rc < 0) { + CAM_ERR(CAM_ICP, "icp_v1 cpas registration failed"); + goto cpas_reg_failed; + } + 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); + init_completion(&icp_v1_dev->hw_complete); + + if ((int)(icp_v1_dev_intf->hw_idx) > max_icp_v1_hw_idx) + max_icp_v1_hw_idx = icp_v1_dev_intf->hw_idx; + + CAM_DBG(CAM_ICP, "ICP_V1:%u component bound successfully", + icp_v1_dev_intf->hw_idx); + + return 0; + +cpas_reg_failed: + cam_icp_soc_resources_deinit(&icp_v1_dev->soc_info); +init_soc_failure: + cam_icp_v1_soc_info_deinit(&icp_v1_dev->soc_info); +match_err: + kfree(core_info); +core_info_alloc_failure: + kfree(icp_v1_dev); +icp_v1_dev_alloc_failure: + kfree(icp_v1_dev_intf); + + return rc; +} + +static void cam_icp_v1_component_unbind(struct device *dev, + struct device *master_dev, void *data) +{ + struct cam_hw_info *icp_v1_dev = NULL; + struct cam_hw_intf *icp_v1_dev_intf = NULL; + struct cam_icp_v1_device_core_info *core_info = NULL; + struct platform_device *pdev = to_platform_device(dev); + + icp_v1_dev_intf = platform_get_drvdata(pdev); + icp_v1_dev = icp_v1_dev_intf->hw_priv; + core_info = (struct cam_icp_v1_device_core_info *)icp_v1_dev->core_info; + + cam_cpas_unregister_client(core_info->cpas_handle); + cam_icp_soc_resources_deinit(&icp_v1_dev->soc_info); + cam_icp_v1_soc_info_deinit(&icp_v1_dev->soc_info); + + max_icp_v1_hw_idx = -1; + + kfree(icp_v1_dev->core_info); + kfree(icp_v1_dev); + kfree(icp_v1_dev_intf); +} + +static const struct component_ops cam_icp_v1_component_ops = { + .bind = cam_icp_v1_component_bind, + .unbind = cam_icp_v1_component_unbind, +}; + +int cam_icp_v1_probe(struct platform_device *pdev) +{ + int rc = 0; + + CAM_DBG(CAM_ICP, "Adding ICP_V1 component"); + rc = component_add(&pdev->dev, &cam_icp_v1_component_ops); + if (rc) + CAM_ERR(CAM_ICP, "failed to add component rc: %d", rc); + + return rc; +} + +static int cam_icp_v1_remove(struct platform_device *pdev) +{ + component_del(&pdev->dev, &cam_icp_v1_component_ops); + return 0; +} + +static const struct of_device_id cam_icp_v1_dt_match[] = { + {.compatible = "qcom,cam-icp_v1",}, + {}, +}; +MODULE_DEVICE_TABLE(of, cam_icp_v1_dt_match); + +struct platform_driver cam_icp_v1_driver = { + .probe = cam_icp_v1_probe, + .remove = cam_icp_v1_remove, + .driver = { + .name = "cam-icp_v1", + .owner = THIS_MODULE, + .of_match_table = cam_icp_v1_dt_match, + .suppress_bind_attrs = true, + }, +}; + +int cam_icp_v1_init_module(void) +{ + return platform_driver_register(&cam_icp_v1_driver); +} + +void cam_icp_v1_exit_module(void) +{ + platform_driver_unregister(&cam_icp_v1_driver); +} + +MODULE_DESCRIPTION("CAM ICP_V1 driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/cam_icp/icp_hw/icp_proc/icp_v1_hw/cam_icp_v1_dev.h b/drivers/cam_icp/icp_hw/icp_proc/icp_v1_hw/cam_icp_v1_dev.h new file mode 100644 index 0000000000..e05fad7aed --- /dev/null +++ b/drivers/cam_icp/icp_hw/icp_proc/icp_v1_hw/cam_icp_v1_dev.h @@ -0,0 +1,20 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + */ + +#ifndef _CAM_ICP_V1_DEV_H_ +#define _CAM_ICP_V1_DEV_H_ + +/** + * @brief : API to register icp_v1 hw to platform framework. + * @return struct platform_device pointer on success, or ERR_PTR() on error. + */ +int cam_icp_v1_init_module(void); + +/** + * @brief : API to remove icp_v1 hw from platform framework. + */ +void cam_icp_v1_exit_module(void); + +#endif /* _CAM_ICP_V1_DEV_H_ */ diff --git a/drivers/cam_icp/icp_hw/icp_proc/icp_v1_hw/cam_icp_v1_reg.h b/drivers/cam_icp/icp_hw/icp_proc/icp_v1_hw/cam_icp_v1_reg.h new file mode 100644 index 0000000000..343a869fa9 --- /dev/null +++ b/drivers/cam_icp/icp_hw/icp_proc/icp_v1_hw/cam_icp_v1_reg.h @@ -0,0 +1,50 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + */ + +#ifndef _CAM_ICP_V1_REG_H_ +#define _CAM_ICP_V1_REG_H_ + +#define ICP_V1_CSR_NSEC_RESET 0x4 +#define ICP_V1_GEN_PURPOSE_REG_OFFSET 0x40 +#define ICP_V1_CSR_FUNC_RESET (1 << 4) +#define ICP_V1_CSR_DBG_RESET (1 << 3) +#define ICP_V1_CSR_CPU_RESET (1 << 2) + +#define ICP_V1_CSR_CONTROL 0x8 +#define ICP_V1_CSR_DBGSWENABLE (1 << 22) +#define ICP_V1_CSR_EDBGRQ (1 << 14) +#define ICP_V1_CSR_EN_CLKGATE_WFI (1 << 12) +#define ICP_V1_CSR_CPU_EN (1 << 9) +#define ICP_V1_CSR_WAKE_UP_EN (1 << 4) + +#define ICP_V1_CSR_FULL_DBG_EN (ICP_V1_CSR_DBGSWENABLE | ICP_V1_CSR_EDBGRQ) +#define ICP_V1_CSR_FULL_CPU_EN (ICP_V1_CSR_CPU_EN | \ + ICP_V1_CSR_WAKE_UP_EN | \ + ICP_V1_CSR_EN_CLKGATE_WFI) + +#define ICP_V1_CSR_A2HOSTINTEN 0x10 +#define ICP_V1_WDT_WS1EN (1 << 2) +#define ICP_V1_WDT_WS0EN (1 << 1) +#define ICP_V1_A2HOSTINTEN (1 << 0) + +#define ICP_V1_CSR_HOST2ICPINT 0x30 +#define ICP_V1_HOSTINT (1 << 0) +#define ICP_V1_HOST_INT_CLR 0x18 +#define ICP_V1_HOST_INT_STATUS 0x1c +#define ICP_V1_HOST_INT_SET 0x20 + +#define ICP_V1_CSR_STATUS 0x200 +#define ICP_V1_CSR_STANDBYWFI (1 << 7) + +#define ICP_V1_INIT_REQ 0x48 +#define ICP_V1_INIT_RESPONSE 0x4c +#define ICP_V1_SHARED_MEM_PTR 0x50 +#define ICP_V1_SHARED_MEM_SIZE 0x54 +#define ICP_V1_QTBL_PTR 0x58 +#define ICP_V1_UNCACHED_HEAP_PTR 0x5c +#define ICP_V1_UNCACHED_HEAP_SIZE 0x60 + +#endif /* _CAM_ICP_V1_REG_H_ */ diff --git a/drivers/cam_icp/icp_hw/lx7_hw/lx7_core.c b/drivers/cam_icp/icp_hw/icp_proc/icp_v2_hw/cam_icp_v2_core.c similarity index 52% rename from drivers/cam_icp/icp_hw/lx7_hw/lx7_core.c rename to drivers/cam_icp/icp_hw/icp_proc/icp_v2_hw/cam_icp_v2_core.c index 49d6c9b27a..af2855e61c 100644 --- a/drivers/cam_icp/icp_hw/lx7_hw/lx7_core.c +++ b/drivers/cam_icp/icp_hw/icp_proc/icp_v2_hw/cam_icp_v2_core.c @@ -16,88 +16,50 @@ #include "cam_icp_hw_intf.h" #include "hfi_intf.h" #include "hfi_sys_defs.h" -#include "cam_icp_utils.h" -#include "lx7_core.h" -#include "lx7_reg.h" -#include "lx7_soc.h" +#include "cam_icp_proc_common.h" +#include "cam_icp_v2_core.h" +#include "cam_icp_v2_reg.h" #include "cam_common_util.h" #include "cam_compat.h" #include "cam_presil_hw_access.h" +#include "cam_icp_soc_common.h" #define TZ_STATE_SUSPEND 0 #define TZ_STATE_RESUME 1 #define ICP_FW_NAME_MAX_SIZE 32 -#define PC_POLL_DELAY_US 100 -#define PC_POLL_TIMEOUT_US 10000 +#define ICP_V2_IRQ_TEST_TIMEOUT 1000 -#define LX7_IRQ_TEST_TIMEOUT 1000 +static const struct hfi_ops hfi_icp_v2_ops = { + .irq_raise = cam_icp_v2_irq_raise, + .irq_enable = cam_icp_v2_irq_enable, + .iface_addr = cam_icp_v2_iface_addr, +}; -static int cam_lx7_ubwc_configure(struct cam_hw_soc_info *soc_info) +static int cam_icp_v2_ubwc_configure(struct cam_hw_soc_info *soc_info) { - int i = 0, rc, ddr_type; - struct lx7_soc_info *soc_priv; - uint32_t ipe_ubwc_cfg[UBWC_CONFIG_MAX]; - uint32_t bps_ubwc_cfg[UBWC_CONFIG_MAX]; + struct cam_icp_soc_info *soc_priv; - if (!soc_info || !soc_info->soc_private) { - CAM_ERR(CAM_ICP, "invalid LX7 soc info"); + if (!soc_info) return -EINVAL; - } soc_priv = soc_info->soc_private; - ddr_type = cam_get_ddr_type(); - if (ddr_type == DDR_TYPE_LPDDR5 || ddr_type == DDR_TYPE_LPDDR5X) - i = 1; - - ipe_ubwc_cfg[0] = soc_priv->ubwc_cfg.ipe_fetch[i]; - ipe_ubwc_cfg[1] = soc_priv->ubwc_cfg.ipe_write[i]; - - bps_ubwc_cfg[0] = soc_priv->ubwc_cfg.bps_fetch[i]; - bps_ubwc_cfg[1] = soc_priv->ubwc_cfg.bps_write[i]; - - rc = hfi_cmd_ubwc_config_ext(ipe_ubwc_cfg, bps_ubwc_cfg); - if (rc) { - CAM_ERR(CAM_ICP, "failed to write UBWC config rc=%d", rc); - return rc; - } - - return 0; + return cam_icp_proc_ubwc_configure(soc_priv->uconfig.ubwc_cfg_ext, 0); } -static int cam_lx7_cpas_vote(struct cam_lx7_core_info *core_info, - struct cam_icp_cpas_vote *vote) +static int cam_icp_v2_cpas_vote(struct cam_icp_v2_core_info *core_info, + struct cam_icp_cpas_vote *vote) { - int rc; - - if (!core_info || !vote) + if (!core_info) return -EINVAL; - if (vote->ahb_vote_valid) { - rc = cam_cpas_update_ahb_vote(core_info->cpas_handle, - &vote->ahb_vote); - if (rc) { - CAM_ERR(CAM_ICP, "AHB vote update failed rc=%d", rc); - return rc; - } - } - - if (vote->axi_vote_valid) { - rc = cam_cpas_update_axi_vote(core_info->cpas_handle, - &vote->axi_vote); - if (rc) { - CAM_ERR(CAM_ICP, "AXI vote update failed rc=%d", rc); - return rc; - } - } - - return 0; + return cam_icp_proc_cpas_vote(core_info->cpas_handle, vote); } -static bool cam_lx7_cpas_cb(uint32_t handle, void *user_data, - struct cam_cpas_irq_data *irq_data) +static bool cam_icp_v2_cpas_cb(uint32_t handle, void *user_data, + struct cam_cpas_irq_data *irq_data) { bool ret = false; (void)user_data; @@ -108,13 +70,13 @@ static bool cam_lx7_cpas_cb(uint32_t handle, void *user_data, switch (irq_data->irq_type) { case CAM_CAMNOC_IRQ_IPE_BPS_UBWC_DECODE_ERROR: CAM_ERR_RATE_LIMIT(CAM_ICP, - "IPE/BPS UBWC decode error status=0x%08x", - irq_data->u.dec_err.decerr_status.value); + "IPE/BPS UBWC decode error status=0x%08x", + irq_data->u.dec_err.decerr_status.value); ret = true; case CAM_CAMNOC_IRQ_IPE_BPS_UBWC_ENCODE_ERROR: CAM_ERR_RATE_LIMIT(CAM_ICP, - "IPE/BPS UBWC encode error status=0x%08x", - irq_data->u.enc_err.encerr_status.value); + "IPE/BPS UBWC encode error status=0x%08x", + irq_data->u.enc_err.encerr_status.value); ret = true; default: CAM_ERR(CAM_ICP, "unhandled irq_type=%d", irq_data->irq_type); @@ -124,21 +86,21 @@ static bool cam_lx7_cpas_cb(uint32_t handle, void *user_data, return ret; } -int cam_lx7_cpas_register(struct cam_hw_intf *lx7_intf) +int cam_icp_v2_cpas_register(struct cam_hw_intf *icp_v2_intf) { struct cam_cpas_register_params params; - struct cam_hw_info *lx7_info; - struct cam_lx7_core_info *core_info; + struct cam_hw_info *icp_v2_info; + struct cam_icp_v2_core_info *core_info; int rc; - if (!lx7_intf) + if (!icp_v2_intf) return -EINVAL; - lx7_info = lx7_intf->hw_priv; + icp_v2_info = icp_v2_intf->hw_priv; - params.dev = lx7_info->soc_info.dev; - params.cell_index = lx7_intf->hw_idx; - params.cam_cpas_client_cb = cam_lx7_cpas_cb; + params.dev = icp_v2_info->soc_info.dev; + params.cell_index = icp_v2_intf->hw_idx; + params.cam_cpas_client_cb = cam_icp_v2_cpas_cb; params.userdata = NULL; strlcpy(params.identifier, "icp", CAM_HW_IDENTIFIER_LENGTH); @@ -147,28 +109,28 @@ int cam_lx7_cpas_register(struct cam_hw_intf *lx7_intf) if (rc) return rc; - core_info = lx7_info->core_info; + core_info = icp_v2_info->core_info; core_info->cpas_handle = params.client_handle; return rc; } -int cam_lx7_cpas_unregister(struct cam_hw_intf *lx7_intf) +int cam_icp_v2_cpas_unregister(struct cam_hw_intf *icp_v2_intf) { - struct cam_hw_info *lx7_info; - struct cam_lx7_core_info *core_info; + struct cam_hw_info *icp_v2_info; + struct cam_icp_v2_core_info *core_info; - if (!lx7_intf) + if (!icp_v2_intf) return -EINVAL; - lx7_info = lx7_intf->hw_priv; - core_info = lx7_info->core_info; + icp_v2_info = icp_v2_intf->hw_priv; + core_info = icp_v2_info->core_info; return cam_cpas_unregister_client(core_info->cpas_handle); } -static int __lx7_cpas_start(struct cam_lx7_core_info *core_info, - struct cam_icp_cpas_vote *vote) +static int __icp_v2_cpas_start(struct cam_icp_v2_core_info *core_info, + struct cam_icp_cpas_vote *vote) { int rc; @@ -176,7 +138,7 @@ static int __lx7_cpas_start(struct cam_lx7_core_info *core_info, return -EINVAL; rc = cam_cpas_start(core_info->cpas_handle, - &vote->ahb_vote, &vote->axi_vote); + &vote->ahb_vote, &vote->axi_vote); if (rc) { CAM_ERR(CAM_ICP, "failed to start cpas rc=%d", rc); return rc; @@ -187,7 +149,7 @@ static int __lx7_cpas_start(struct cam_lx7_core_info *core_info, return 0; } -static int cam_lx7_cpas_start(struct cam_lx7_core_info *core_info) +static int cam_icp_v2_cpas_start(struct cam_icp_v2_core_info *core_info) { struct cam_icp_cpas_vote vote; @@ -203,10 +165,10 @@ static int cam_lx7_cpas_start(struct cam_lx7_core_info *core_info) vote.axi_vote.axi_path[0].ddr_ab_bw = CAM_ICP_BW_BYTES_VOTE; vote.axi_vote.axi_path[0].ddr_ib_bw = CAM_ICP_BW_BYTES_VOTE; - return __lx7_cpas_start(core_info, &vote); + return __icp_v2_cpas_start(core_info, &vote); } -static int cam_lx7_cpas_stop(struct cam_lx7_core_info *core_info) +static int cam_icp_v2_cpas_stop(struct cam_icp_v2_core_info *core_info) { int rc; @@ -224,30 +186,30 @@ static int cam_lx7_cpas_stop(struct cam_lx7_core_info *core_info) return 0; } -int cam_lx7_hw_init(void *priv, void *args, uint32_t arg_size) +int cam_icp_v2_hw_init(void *priv, void *args, uint32_t arg_size) { - struct cam_hw_info *lx7 = priv; + struct cam_hw_info *icp_v2 = priv; unsigned long flags; int rc; bool send_freq_info = (args == NULL) ? false : *((bool *)args); - if (!lx7) { - CAM_ERR(CAM_ICP, "LX7 device info cannot be NULL"); + if (!icp_v2) { + CAM_ERR(CAM_ICP, "ICP device info cannot be NULL"); return -EINVAL; } - spin_lock_irqsave(&lx7->hw_lock, flags); - if (lx7->hw_state == CAM_HW_STATE_POWER_UP) { - spin_unlock_irqrestore(&lx7->hw_lock, flags); + 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); return 0; } - spin_unlock_irqrestore(&lx7->hw_lock, flags); + spin_unlock_irqrestore(&icp_v2->hw_lock, flags); - rc = cam_lx7_cpas_start(lx7->core_info); + rc = cam_icp_v2_cpas_start(icp_v2->core_info); if (rc) return rc; - rc = cam_lx7_soc_resources_enable(&lx7->soc_info); + rc = cam_icp_soc_resources_enable(&icp_v2->soc_info); if (rc) { CAM_ERR(CAM_ICP, "failed to enable soc resources rc=%d", rc); goto soc_fail; @@ -255,64 +217,64 @@ int cam_lx7_hw_init(void *priv, void *args, uint32_t arg_size) if (send_freq_info) { int32_t clk_rate = 0; - clk_rate = clk_get_rate(lx7->soc_info.clk[lx7->soc_info.src_clk_idx]); + clk_rate = clk_get_rate(icp_v2->soc_info.clk[icp_v2->soc_info.src_clk_idx]); hfi_send_freq_info(clk_rate); } } - spin_lock_irqsave(&lx7->hw_lock, flags); - lx7->hw_state = CAM_HW_STATE_POWER_UP; - spin_unlock_irqrestore(&lx7->hw_lock, flags); + spin_lock_irqsave(&icp_v2->hw_lock, flags); + icp_v2->hw_state = CAM_HW_STATE_POWER_UP; + spin_unlock_irqrestore(&icp_v2->hw_lock, flags); return 0; soc_fail: - cam_lx7_cpas_stop(lx7->core_info); + cam_icp_v2_cpas_stop(icp_v2->core_info); return rc; } -int cam_lx7_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 *lx7_info = priv; + struct cam_hw_info *icp_v2_info = priv; unsigned long flags; int rc; bool send_freq_info = (args == NULL) ? false : *((bool *)args); - if (!lx7_info) { - CAM_ERR(CAM_ICP, "LX7 device info cannot be NULL"); + if (!icp_v2_info) { + CAM_ERR(CAM_ICP, "ICP device info cannot be NULL"); return -EINVAL; } - spin_lock_irqsave(&lx7_info->hw_lock, flags); - if (lx7_info->hw_state == CAM_HW_STATE_POWER_DOWN) { - spin_unlock_irqrestore(&lx7_info->hw_lock, flags); + 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); return 0; } - spin_unlock_irqrestore(&lx7_info->hw_lock, flags); + spin_unlock_irqrestore(&icp_v2_info->hw_lock, flags); if (send_freq_info) hfi_send_freq_info(0); - rc = cam_lx7_soc_resources_disable(&lx7_info->soc_info); + rc = cam_icp_soc_resources_disable(&icp_v2_info->soc_info); if (rc) CAM_WARN(CAM_ICP, "failed to disable soc resources rc=%d", rc); - rc = cam_lx7_cpas_stop(lx7_info->core_info); + rc = cam_icp_v2_cpas_stop(icp_v2_info->core_info); if (rc) CAM_WARN(CAM_ICP, "cpas stop failed rc=%d", rc); - spin_lock_irqsave(&lx7_info->hw_lock, flags); - lx7_info->hw_state = CAM_HW_STATE_POWER_DOWN; - spin_unlock_irqrestore(&lx7_info->hw_lock, flags); + spin_lock_irqsave(&icp_v2_info->hw_lock, flags); + icp_v2_info->hw_state = CAM_HW_STATE_POWER_DOWN; + spin_unlock_irqrestore(&icp_v2_info->hw_lock, flags); return rc; } -static void prepare_boot(struct cam_hw_info *lx7_info, - struct cam_icp_boot_args *args) +static void prepare_boot(struct cam_hw_info *icp_v2_info, + struct cam_icp_boot_args *args) { - struct cam_lx7_core_info *core_info = lx7_info->core_info; + struct cam_icp_v2_core_info *core_info = icp_v2_info->core_info; unsigned long flags; if (!args->use_sec_pil) { @@ -321,82 +283,81 @@ static void prepare_boot(struct cam_hw_info *lx7_info, core_info->fw_params.fw_buf_len = args->firmware.len; } - spin_lock_irqsave(&lx7_info->hw_lock, flags); + spin_lock_irqsave(&icp_v2_info->hw_lock, flags); core_info->irq_cb.data = args->irq_cb.data; core_info->irq_cb.cb = args->irq_cb.cb; - spin_unlock_irqrestore(&lx7_info->hw_lock, flags); + spin_unlock_irqrestore(&icp_v2_info->hw_lock, flags); } -static void prepare_shutdown(struct cam_hw_info *lx7_info) +static void prepare_shutdown(struct cam_hw_info *icp_v2_info) { - struct cam_lx7_core_info *core_info = lx7_info->core_info; + struct cam_icp_v2_core_info *core_info = icp_v2_info->core_info; unsigned long flags; core_info->fw_params.fw_buf = 0x0; core_info->fw_params.fw_kva_addr = 0x0; core_info->fw_params.fw_buf_len = 0x0; - spin_lock_irqsave(&lx7_info->hw_lock, flags); + spin_lock_irqsave(&icp_v2_info->hw_lock, flags); core_info->irq_cb.data = NULL; core_info->irq_cb.cb = NULL; - spin_unlock_irqrestore(&lx7_info->hw_lock, flags); + spin_unlock_irqrestore(&icp_v2_info->hw_lock, flags); } /* Used if ICP_SYS is not protected */ -static int __cam_lx7_power_collapse(struct cam_hw_info *lx7_info) +static int __cam_icp_v2_power_collapse(struct cam_hw_info *icp_v2_info) { uint32_t status = 0; void __iomem *base; - if (!lx7_info) { - CAM_ERR(CAM_ICP, "invalid lx7 dev info"); + if (!icp_v2_info) { + CAM_ERR(CAM_ICP, "invalid ICP dev info"); return -EINVAL; } - base = lx7_info->soc_info.reg_map[LX7_SYS_BASE].mem_base; + base = icp_v2_info->soc_info.reg_map[ICP_V2_SYS_BASE].mem_base; /** * Need to poll here to confirm that FW has triggered WFI * and Host can then proceed. No interrupt is expected * from FW at this time. */ - if (cam_common_read_poll_timeout(base + ICP_LX7_SYS_STATUS, + if (cam_common_read_poll_timeout(base + ICP_V2_SYS_STATUS, PC_POLL_DELAY_US, PC_POLL_TIMEOUT_US, - ICP_LX7_STANDBYWFI, ICP_LX7_STANDBYWFI, + ICP_V2_STANDBYWFI, ICP_V2_STANDBYWFI, &status)) { CAM_ERR(CAM_ICP, "WFI poll timed out: status=0x%08x", status); return -ETIMEDOUT; } - cam_io_w_mb(0x0, base + ICP_LX7_SYS_CONTROL); + cam_io_w_mb(0x0, base + ICP_V2_SYS_CONTROL); return 0; } /* Used if ICP_SYS is not protected */ -static int __cam_lx7_power_resume(struct cam_hw_info *lx7_info) +static int __cam_icp_v2_power_resume(struct cam_hw_info *icp_v2_info) { void __iomem *base; - struct lx7_soc_info *soc_priv; - struct cam_hw_soc_info *soc_info; + struct cam_icp_soc_info *soc_priv; + struct cam_hw_soc_info *soc_info; - if (!lx7_info) { - CAM_ERR(CAM_ICP, "invalid lx7 dev info"); + if (!icp_v2_info) { + CAM_ERR(CAM_ICP, "invalid ICP dev info"); return -EINVAL; } - soc_info = &lx7_info->soc_info; + soc_info = &icp_v2_info->soc_info; soc_priv = soc_info->soc_private; - base = lx7_info->soc_info.reg_map[LX7_SYS_BASE].mem_base; + base = icp_v2_info->soc_info.reg_map[ICP_V2_SYS_BASE].mem_base; - cam_io_w_mb(ICP_LX7_FUNC_RESET, - base + ICP_LX7_SYS_RESET); + cam_io_w_mb(ICP_V2_FUNC_RESET, + base + ICP_V2_SYS_RESET); - if (soc_priv->icp_qos_val) - cam_io_w_mb(soc_priv->icp_qos_val, - base + ICP_LX7_SYS_ACCESS); + if (soc_priv->qos_val) + cam_io_w_mb(soc_priv->qos_val, base + ICP_V2_SYS_ACCESS); - cam_io_w_mb(ICP_LX7_EN_CPU, - base + ICP_LX7_SYS_CONTROL); + cam_io_w_mb(ICP_V2_EN_CPU, + base + ICP_V2_SYS_CONTROL); return 0; } @@ -410,9 +371,9 @@ static int32_t __cam_non_sec_load_fw(void *device_priv) char firmware_name[ICP_FW_NAME_MAX_SIZE] = {0}; const char *fw_name; const uint8_t *fw_start = NULL; - struct cam_hw_info *lx7_dev = device_priv; + struct cam_hw_info *icp_v2_dev = device_priv; struct cam_hw_soc_info *soc_info = NULL; - struct cam_lx7_core_info *core_info = NULL; + struct cam_icp_v2_core_info *core_info = NULL; struct platform_device *pdev = NULL; if (!device_priv) { @@ -420,8 +381,8 @@ static int32_t __cam_non_sec_load_fw(void *device_priv) return -EINVAL; } - soc_info = &lx7_dev->soc_info; - core_info = (struct cam_lx7_core_info *)lx7_dev->core_info; + soc_info = &icp_v2_dev->soc_info; + core_info = (struct cam_icp_v2_core_info *)icp_v2_dev->core_info; pdev = soc_info->pdev; /** @@ -493,10 +454,10 @@ fw_download_failed: return rc; } #else /* #ifndef CONFIG_CAM_PRESIL */ -static int __cam_non_sec_load_fw(struct cam_hw_info *lx7_info) +static int __cam_non_sec_load_fw(struct cam_hw_info *icp_v2_info) { - if (!lx7_info) { - CAM_ERR(CAM_ICP, "invalid lx7 dev info"); + if (!icp_v2_info) { + CAM_ERR(CAM_ICP, "Invalid ICP dev info"); return -EINVAL; } @@ -507,17 +468,17 @@ static int __cam_non_sec_load_fw(struct cam_hw_info *lx7_info) #endif /* #ifndef CONFIG_CAM_PRESIL */ /* Used for non secure FW load */ -static int cam_lx7_non_sec_boot( - struct cam_hw_info *lx7_info, +static int cam_icp_v2_non_sec_boot( + struct cam_hw_info *icp_v2_info, struct cam_icp_boot_args *args, uint32_t arg_size) { int rc; - if (!lx7_info || !args) { + if (!icp_v2_info || !args) { CAM_ERR(CAM_ICP, - "invalid args: lx7_dev=%pK args=%pK", - lx7_info, args); + "invalid args: icp_v2_dev=%pK args=%pK", + icp_v2_info, args); return -EINVAL; } @@ -526,30 +487,30 @@ static int cam_lx7_non_sec_boot( return -EINVAL; } - if (lx7_info->soc_info.num_mem_block != LX7_BASE_MAX) { + if (icp_v2_info->soc_info.num_mem_block != ICP_V2_BASE_MAX) { CAM_ERR(CAM_ICP, "check ICP SYS reg config in DT.."); return -EINVAL; } - prepare_boot(lx7_info, args); + prepare_boot(icp_v2_info, args); - rc = __cam_non_sec_load_fw(lx7_info); + rc = __cam_non_sec_load_fw(icp_v2_info); if (rc) { CAM_ERR(CAM_ICP, "firmware download failed rc=%d", rc); goto err; } - rc = __cam_lx7_power_resume(lx7_info); + rc = __cam_icp_v2_power_resume(icp_v2_info); if (rc) { - CAM_ERR(CAM_ICP, "lx7 boot failed rc=%d", rc); + CAM_ERR(CAM_ICP, "ICP boot failed rc=%d", rc); goto err; } return 0; err: - prepare_shutdown(lx7_info); + prepare_shutdown(icp_v2_info); return rc; } @@ -645,20 +606,19 @@ out: } #endif -static int cam_lx7_boot(struct cam_hw_info *lx7_info, - struct cam_icp_boot_args *args, - uint32_t arg_size) +static int cam_icp_v2_boot(struct cam_hw_info *icp_v2_info, + struct cam_icp_boot_args *args, uint32_t arg_size) { int rc; - struct cam_lx7_core_info *core_info = NULL; + struct cam_icp_v2_core_info *core_info = NULL; if (!IS_REACHABLE(CONFIG_QCOM_MDT_LOADER)) return -EOPNOTSUPP; - if (!lx7_info || !args) { + if (!icp_v2_info || !args) { CAM_ERR(CAM_ICP, - "invalid args: lx7_info=%pK args=%pK", - lx7_info, args); + "invalid args: icp_v2_info=%pK args=%pK", + icp_v2_info, args); return -EINVAL; } @@ -667,11 +627,11 @@ static int cam_lx7_boot(struct cam_hw_info *lx7_info, return -EINVAL; } - core_info = (struct cam_lx7_core_info *)lx7_info->core_info; - prepare_boot(lx7_info, args); + core_info = (struct cam_icp_v2_core_info *)icp_v2_info->core_info; + prepare_boot(icp_v2_info, args); #if IS_REACHABLE(CONFIG_QCOM_MDT_LOADER) - rc = __load_firmware(lx7_info->soc_info.pdev); + rc = __load_firmware(icp_v2_info->soc_info.pdev); if (rc) { CAM_ERR(CAM_ICP, "firmware loading failed rc=%d", rc); goto err; @@ -687,52 +647,52 @@ static int cam_lx7_boot(struct cam_hw_info *lx7_info, core_info->use_sec_pil = true; return 0; err: - prepare_shutdown(lx7_info); + prepare_shutdown(icp_v2_info); return rc; } -static int cam_lx7_shutdown(struct cam_hw_info *lx7_info) +static int cam_icp_v2_shutdown(struct cam_hw_info *icp_v2_info) { int rc = 0; - struct cam_lx7_core_info *core_info = - (struct cam_lx7_core_info *)lx7_info->core_info; + struct cam_icp_v2_core_info *core_info = + (struct cam_icp_v2_core_info *)icp_v2_info->core_info; - prepare_shutdown(lx7_info); + prepare_shutdown(icp_v2_info); if (core_info->use_sec_pil) rc = qcom_scm_pas_shutdown(CAM_FW_PAS_ID); else { void __iomem *base; - base = lx7_info->soc_info.reg_map[LX7_SYS_BASE].mem_base; - cam_io_w_mb(0x0, base + ICP_LX7_SYS_CONTROL); + base = icp_v2_info->soc_info.reg_map[ICP_V2_SYS_BASE].mem_base; + cam_io_w_mb(0x0, base + ICP_V2_SYS_CONTROL); } core_info->use_sec_pil = false; return rc; } -static void __cam_lx7_core_reg_dump( - struct cam_hw_info *lx7_info, uint32_t dump_type) +static void __cam_icp_v2_core_reg_dump( + struct cam_hw_info *icp_v2_info, uint32_t dump_type) { int i; size_t len = 0; char log_info[512]; - void __iomem *cirq_base = lx7_info->soc_info.reg_map[LX7_CIRQ_BASE].mem_base; - void __iomem *csr_base = lx7_info->soc_info.reg_map[LX7_CSR_BASE].mem_base; - void __iomem *csr_gp_base = csr_base + LX7_GEN_PURPOSE_REG_OFFSET; + void __iomem *cirq_base = icp_v2_info->soc_info.reg_map[ICP_V2_CIRQ_BASE].mem_base; + void __iomem *csr_base = icp_v2_info->soc_info.reg_map[ICP_V2_CSR_BASE].mem_base; + void __iomem *csr_gp_base = csr_base + ICP_V2_GEN_PURPOSE_REG_OFFSET; if (dump_type & CAM_ICP_DUMP_STATUS_REGISTERS) CAM_INFO(CAM_ICP, "CIRQ IB_status0:0x%x IB_Status1:0x%x PFault:0x%x CSR debug_status:0x%x debug_ctrl:0x%x", - cam_io_r_mb(cirq_base + ICP_LX7_CIRQ_IB_STATUS0), - cam_io_r_mb(cirq_base + ICP_LX7_CIRQ_IB_STATUS1), - cam_io_r_mb(cirq_base + ICP_LX7_CIRQ_PFAULT_INFO), - cam_io_r_mb(csr_base + LX7_CSR_DBG_STATUS_REG_OFFSET), - cam_io_r_mb(csr_base + LX7_CSR_DBG_CTRL_REG_OFFSET)); + cam_io_r_mb(cirq_base + ICP_V2_CIRQ_IB_STATUS0), + cam_io_r_mb(cirq_base + ICP_V2_CIRQ_IB_STATUS1), + cam_io_r_mb(cirq_base + ICP_V2_CIRQ_PFAULT_INFO), + cam_io_r_mb(csr_base + ICP_V2_CSR_DBG_STATUS_REG_OFFSET), + cam_io_r_mb(csr_base + ICP_V2_CSR_DBG_CTRL_REG_OFFSET)); if (dump_type & CAM_ICP_DUMP_CSR_REGISTERS) { - for (i = 0; i < LX7_CSR_GP_REG_COUNT;) { + for (i = 0; i < ICP_V2_CSR_GP_REG_COUNT;) { CAM_INFO_BUF(CAM_ICP, log_info, 512, &len, "GP_%d: 0x%x GP_%d: 0x%x GP_%d: 0x%x GP_%d: 0x%x", i, cam_io_r_mb(csr_gp_base + (i << 2)), @@ -747,13 +707,12 @@ static void __cam_lx7_core_reg_dump( } /* API controls collapse/resume of ICP */ -static int cam_lx7_core_control( - struct cam_hw_info *lx7_info, +static int cam_icp_v2_core_control(struct cam_hw_info *icp_v2_info, uint32_t state) { int rc = 0; - struct cam_lx7_core_info *core_info = - (struct cam_lx7_core_info *)lx7_info->core_info; + struct cam_icp_v2_core_info *core_info = + (struct cam_icp_v2_core_info *)icp_v2_info->core_info; if (core_info->use_sec_pil) { rc = qcom_scm_set_remote_state(state, CAM_FW_PAS_ID); @@ -761,49 +720,46 @@ static int cam_lx7_core_control( CAM_ERR(CAM_ICP, "remote state set to %s failed rc=%d", (state == TZ_STATE_RESUME ? "resume" : "suspend"), rc); - __cam_lx7_core_reg_dump(lx7_info, CAM_ICP_DUMP_STATUS_REGISTERS); + __cam_icp_v2_core_reg_dump(icp_v2_info, CAM_ICP_DUMP_STATUS_REGISTERS); } } else { if (state == TZ_STATE_RESUME) { - rc = __cam_lx7_power_resume(lx7_info); + rc = __cam_icp_v2_power_resume(icp_v2_info); if (rc) - CAM_ERR(CAM_ICP, "lx7 resume failed rc=%d", rc); + CAM_ERR(CAM_ICP, "ICP resume failed rc=%d", rc); } else { - rc = __cam_lx7_power_collapse(lx7_info); + rc = __cam_icp_v2_power_collapse(icp_v2_info); if (rc) - CAM_ERR(CAM_ICP, "lx7 collapse failed rc=%d", rc); + CAM_ERR(CAM_ICP, "ICP collapse failed rc=%d", rc); } } return rc; } -static inline int cam_lx7_download_fw( - struct cam_hw_info *lx7_info, - struct cam_icp_boot_args *args, - uint32_t arg_size) +static inline int cam_icp_v2_download_fw(struct cam_hw_info *icp_v2_info, + struct cam_icp_boot_args *args, uint32_t arg_size) { int rc; CAM_INFO(CAM_ICP, "Loading Secure PIL : %s", CAM_BOOL_TO_YESNO(args->use_sec_pil)); if (args->use_sec_pil) - rc = cam_lx7_boot( - lx7_info, args, arg_size); + rc = cam_icp_v2_boot( + icp_v2_info, args, arg_size); else - rc = cam_lx7_non_sec_boot( - lx7_info, args, arg_size); + rc = cam_icp_v2_non_sec_boot( + icp_v2_info, args, arg_size); return rc; } -static int __cam_lx7_update_clk_rate( - struct cam_hw_info *lx7_info, +static int __cam_icp_v2_update_clk_rate(struct cam_hw_info *icp_v2_info, int32_t *clk_lvl) { int32_t clk_level = 0, rc; struct cam_ahb_vote ahb_vote; - struct cam_lx7_core_info *core_info = NULL; + struct cam_icp_v2_core_info *core_info = NULL; struct cam_hw_soc_info *soc_info = NULL; if (!clk_lvl) { @@ -811,8 +767,8 @@ static int __cam_lx7_update_clk_rate( return -EINVAL; } - soc_info = &lx7_info->soc_info; - core_info = lx7_info->core_info; + soc_info = &icp_v2_info->soc_info; + core_info = icp_v2_info->core_info; if (!core_info || !soc_info) { CAM_ERR(CAM_ICP, "Invalid args"); return -EINVAL; @@ -821,7 +777,7 @@ static int __cam_lx7_update_clk_rate( clk_level = *((int32_t *)clk_lvl); CAM_DBG(CAM_ICP, "Update ICP clock to level [%d]", clk_level); - rc = cam_lx7_update_clk_rate(soc_info, clk_level); + rc = cam_icp_soc_update_clk_rate(soc_info, clk_level); if (rc) CAM_WARN(CAM_ICP, "Failed to update clk to level: %d rc: %d", @@ -838,73 +794,53 @@ static int __cam_lx7_update_clk_rate( return rc; } -static int __cam_lx7_fw_mini_dump( - struct cam_lx7_core_info *core_info, - struct cam_icp_hw_dump_args *args) +static int __cam_icp_v2_fw_mini_dump(struct cam_icp_v2_core_info *core_info, + struct cam_icp_hw_dump_args *args) { - u8 *dest; - u8 *src; - struct cam_icp_hw_dump_args *dump_args = args; - - if (!core_info || !dump_args) { - CAM_ERR(CAM_ICP, "invalid params %pK %pK", core_info, dump_args); + if (!core_info) { + CAM_ERR(CAM_ICP, "Invalid param %pK", core_info); return -EINVAL; } - if (!core_info->fw_params.fw_kva_addr || !dump_args->cpu_addr) { - CAM_ERR(CAM_ICP, "invalid params %pK, 0x%zx", - core_info->fw_params.fw_kva_addr, dump_args->cpu_addr); - return -EINVAL; - } - - if (dump_args->buf_len < core_info->fw_params.fw_buf_len) { - CAM_WARN(CAM_ICP, "Insufficient Len %lu fw_len %llu", - dump_args->buf_len, core_info->fw_params.fw_buf_len); - return -ENOSPC; - } - - dest = (u8 *)dump_args->cpu_addr; - src = (u8 *)core_info->fw_params.fw_kva_addr; - memcpy_fromio(dest, src, core_info->fw_params.fw_buf_len); - dump_args->offset = core_info->fw_params.fw_buf_len; - return 0; + return cam_icp_proc_mini_dump(args, core_info->fw_params.fw_kva_addr, + core_info->fw_params.fw_buf_len); } -int cam_lx7_process_cmd(void *priv, uint32_t cmd_type, - void *args, uint32_t arg_size) +int cam_icp_v2_process_cmd(void *priv, uint32_t cmd_type, + void *args, uint32_t arg_size) { - struct cam_hw_info *lx7_info = priv; + struct cam_hw_info *icp_v2_info = priv; int rc = -EINVAL; - if (!lx7_info) { - CAM_ERR(CAM_ICP, "LX7 device info cannot be NULL"); + if (!icp_v2_info) { + CAM_ERR(CAM_ICP, "ICP device info cannot be NULL"); return -EINVAL; } switch (cmd_type) { case CAM_ICP_CMD_PROC_SHUTDOWN: - rc = cam_lx7_shutdown(lx7_info); + rc = cam_icp_v2_shutdown(icp_v2_info); break; case CAM_ICP_CMD_PROC_BOOT: - rc = cam_lx7_download_fw(lx7_info, args, arg_size); + rc = cam_icp_v2_download_fw(icp_v2_info, args, arg_size); break; case CAM_ICP_CMD_POWER_COLLAPSE: - rc = cam_lx7_core_control(lx7_info, TZ_STATE_SUSPEND); + rc = cam_icp_v2_core_control(icp_v2_info, TZ_STATE_SUSPEND); break; case CAM_ICP_CMD_POWER_RESUME: - rc = cam_lx7_core_control(lx7_info, TZ_STATE_RESUME); + rc = cam_icp_v2_core_control(icp_v2_info, TZ_STATE_RESUME); break; case CAM_ICP_CMD_VOTE_CPAS: - rc = cam_lx7_cpas_vote(lx7_info->core_info, args); + rc = cam_icp_v2_cpas_vote(icp_v2_info->core_info, args); break; case CAM_ICP_CMD_CPAS_START: - rc = __lx7_cpas_start(lx7_info->core_info, args); + rc = __icp_v2_cpas_start(icp_v2_info->core_info, args); break; case CAM_ICP_CMD_CPAS_STOP: - rc = cam_lx7_cpas_stop(lx7_info->core_info); + rc = cam_icp_v2_cpas_stop(icp_v2_info->core_info); break; case CAM_ICP_CMD_UBWC_CFG: - rc = cam_lx7_ubwc_configure(&lx7_info->soc_info); + rc = cam_icp_v2_ubwc_configure(&icp_v2_info->soc_info); break; case CAM_ICP_SEND_INIT: hfi_send_system_cmd(HFI_CMD_SYS_INIT, 0, 0); @@ -915,15 +851,15 @@ int cam_lx7_process_cmd(void *priv, uint32_t cmd_type, rc = 0; break; case CAM_ICP_CMD_CLK_UPDATE: { - rc = __cam_lx7_update_clk_rate(lx7_info, args); + rc = __cam_icp_v2_update_clk_rate(icp_v2_info, args); break; } case CAM_ICP_CMD_HW_DUMP: - /* Not supported for lx7 */ + /* Not supported for ICP_V2 */ rc = 0; break; case CAM_ICP_CMD_HW_MINI_DUMP: { - rc = __cam_lx7_fw_mini_dump(lx7_info->core_info, args); + rc = __cam_icp_v2_fw_mini_dump(icp_v2_info->core_info, args); break; } case CAM_ICP_CMD_HW_REG_DUMP: { @@ -935,7 +871,7 @@ int cam_lx7_process_cmd(void *priv, uint32_t cmd_type, } dump_type = *(uint32_t *) args; - __cam_lx7_core_reg_dump(lx7_info, dump_type); + __cam_icp_v2_core_reg_dump(icp_v2_info, dump_type); rc = 0; break; } @@ -947,131 +883,141 @@ int cam_lx7_process_cmd(void *priv, uint32_t cmd_type, return rc; } -irqreturn_t cam_lx7_handle_irq(int irq_num, void *data) +irqreturn_t cam_icp_v2_handle_irq(int irq_num, void *data) { - struct cam_hw_info *lx7_info = data; - struct cam_lx7_core_info *core_info = NULL; + struct cam_hw_info *icp_v2_info = data; + struct cam_icp_v2_core_info *core_info = NULL; bool recover = false; uint32_t status = 0; void __iomem *cirq_base; - if (!lx7_info) { - CAM_ERR(CAM_ICP, "invalid LX7 device info"); + if (!icp_v2_info) { + CAM_ERR(CAM_ICP, "invalid ICP device info"); return IRQ_NONE; } - core_info = lx7_info->core_info; - cirq_base = lx7_info->soc_info.reg_map[LX7_CIRQ_BASE].mem_base; + core_info = icp_v2_info->core_info; + cirq_base = icp_v2_info->soc_info.reg_map[ICP_V2_CIRQ_BASE].mem_base; - status = cam_io_r_mb(cirq_base + ICP_LX7_CIRQ_OB_STATUS); + status = cam_io_r_mb(cirq_base + ICP_V2_CIRQ_OB_STATUS); - cam_io_w_mb(status, cirq_base + ICP_LX7_CIRQ_OB_CLEAR); - cam_io_w_mb(LX7_IRQ_CLEAR_CMD, cirq_base + ICP_LX7_CIRQ_OB_IRQ_CMD); + cam_io_w_mb(status, cirq_base + ICP_V2_CIRQ_OB_CLEAR); + cam_io_w_mb(ICP_V2_IRQ_CLEAR_CMD, cirq_base + ICP_V2_CIRQ_OB_IRQ_CMD); if (core_info->is_irq_test) { - CAM_INFO(CAM_ICP, "LX7 IRQ verified (status=0x%x)", status); + CAM_INFO(CAM_ICP, "ICP_V2 IRQ verified (status=0x%x)", status); core_info->is_irq_test = false; - complete(&lx7_info->hw_complete); + complete(&icp_v2_info->hw_complete); return IRQ_HANDLED; } - if (status & LX7_WDT_BITE_WS0) { + if (status & ICP_V2_WDT_BITE_WS0) { /* WD clear sequence - SW listens only to WD0 */ cam_io_w_mb(0x0, - lx7_info->soc_info.reg_map[LX7_WD0_BASE].mem_base + - ICP_LX7_WD_CTRL); + icp_v2_info->soc_info.reg_map[ICP_V2_WD0_BASE].mem_base + + ICP_V2_WD_CTRL); cam_io_w_mb(0x1, - lx7_info->soc_info.reg_map[LX7_WD0_BASE].mem_base + - ICP_LX7_WD_INTCLR); - CAM_ERR_RATE_LIMIT(CAM_ICP, "Fatal: Watchdog Bite from LX7"); + icp_v2_info->soc_info.reg_map[ICP_V2_WD0_BASE].mem_base + + ICP_V2_WD_INTCLR); + CAM_ERR_RATE_LIMIT(CAM_ICP, "Fatal: Watchdog Bite from ICP"); recover = true; } - spin_lock(&lx7_info->hw_lock); + spin_lock(&icp_v2_info->hw_lock); if (core_info->irq_cb.cb) core_info->irq_cb.cb(core_info->irq_cb.data, - recover); - spin_unlock(&lx7_info->hw_lock); + recover); + spin_unlock(&icp_v2_info->hw_lock); return IRQ_HANDLED; } -void cam_lx7_irq_raise(void *priv) +void cam_icp_v2_irq_raise(void *priv) { - struct cam_hw_info *lx7_info = priv; + struct cam_hw_info *icp_v2_info = priv; - if (!lx7_info) { - CAM_ERR(CAM_ICP, "invalid LX7 device info"); + if (!icp_v2_info) { + CAM_ERR(CAM_ICP, "Invalid ICP device info"); return; } - cam_io_w_mb(LX7_HOST2ICPINT, - lx7_info->soc_info.reg_map[LX7_CIRQ_BASE].mem_base + - ICP_LX7_CIRQ_HOST2ICPINT); + cam_io_w_mb(ICP_V2_HOST2ICPINT, + icp_v2_info->soc_info.reg_map[ICP_V2_CIRQ_BASE].mem_base + + ICP_V2_CIRQ_HOST2ICPINT); } -void cam_lx7_irq_enable(void *priv) +void cam_icp_v2_irq_enable(void *priv) { - struct cam_hw_info *lx7_info = priv; + struct cam_hw_info *icp_v2_info = priv; - if (!lx7_info) { - CAM_ERR(CAM_ICP, "invalid LX7 device info"); + if (!icp_v2_info) { + CAM_ERR(CAM_ICP, "Invalid ICP device info"); return; } - cam_io_w_mb(LX7_WDT_BITE_WS0 | LX7_ICP2HOSTINT, - lx7_info->soc_info.reg_map[LX7_CIRQ_BASE].mem_base + - ICP_LX7_CIRQ_OB_MASK); + cam_io_w_mb(ICP_V2_WDT_BITE_WS0 | ICP_V2_ICP2HOSTINT, + icp_v2_info->soc_info.reg_map[ICP_V2_CIRQ_BASE].mem_base + + ICP_V2_CIRQ_OB_MASK); } -int cam_lx7_test_irq_line(void *priv) +int cam_icp_v2_test_irq_line(void *priv) { - struct cam_hw_info *lx7_info = priv; - struct cam_lx7_core_info *core_info = NULL; + struct cam_hw_info *icp_v2_info = priv; + struct cam_icp_v2_core_info *core_info = NULL; void __iomem *cirq_membase; unsigned long rem_jiffies; - if (!lx7_info) { - CAM_ERR(CAM_ICP, "invalid LX7 device info"); + if (!icp_v2_info) { + CAM_ERR(CAM_ICP, "invalid ICP device info"); return -EINVAL; } - core_info = lx7_info->core_info; - cirq_membase = lx7_info->soc_info.reg_map[LX7_CIRQ_BASE].mem_base; + core_info = icp_v2_info->core_info; + cirq_membase = icp_v2_info->soc_info.reg_map[ICP_V2_CIRQ_BASE].mem_base; - reinit_completion(&lx7_info->hw_complete); + reinit_completion(&icp_v2_info->hw_complete); core_info->is_irq_test = true; - cam_lx7_hw_init(priv, NULL, 0); + cam_icp_v2_hw_init(priv, NULL, 0); - cam_io_w_mb(LX7_WDT_BARK_WS0, cirq_membase + ICP_LX7_CIRQ_OB_MASK); - cam_io_w_mb(LX7_WDT_BARK_WS0, cirq_membase + ICP_LX7_CIRQ_OB_SET); - cam_io_w_mb(LX7_IRQ_SET_CMD, cirq_membase + ICP_LX7_CIRQ_OB_IRQ_CMD); + cam_io_w_mb(ICP_V2_WDT_BARK_WS0, cirq_membase + ICP_V2_CIRQ_OB_MASK); + cam_io_w_mb(ICP_V2_WDT_BARK_WS0, cirq_membase + ICP_V2_CIRQ_OB_SET); + cam_io_w_mb(ICP_V2_IRQ_SET_CMD, cirq_membase + ICP_V2_CIRQ_OB_IRQ_CMD); - rem_jiffies = cam_common_wait_for_completion_timeout(&lx7_info->hw_complete, - msecs_to_jiffies(LX7_IRQ_TEST_TIMEOUT)); + rem_jiffies = cam_common_wait_for_completion_timeout(&icp_v2_info->hw_complete, + msecs_to_jiffies(ICP_V2_IRQ_TEST_TIMEOUT)); if (!rem_jiffies) - CAM_ERR(CAM_ICP, "LX7 IRQ verification timed out"); + CAM_ERR(CAM_ICP, "ICP IRQ verification timed out"); - cam_io_w_mb(0, cirq_membase + ICP_LX7_CIRQ_OB_MASK); - cam_lx7_hw_deinit(priv, NULL, 0); + cam_io_w_mb(0, cirq_membase + ICP_V2_CIRQ_OB_MASK); + cam_icp_v2_hw_deinit(priv, NULL, 0); core_info->is_irq_test = false; return 0; } -void __iomem *cam_lx7_iface_addr(void *priv) +void __iomem *cam_icp_v2_iface_addr(void *priv) { - struct cam_hw_info *lx7_info = priv; + struct cam_hw_info *icp_v2_info = priv; void __iomem *base; - if (!lx7_info) { - CAM_ERR(CAM_ICP, "invalid LX7 device info"); + if (!icp_v2_info) { + CAM_ERR(CAM_ICP, "invalid icp device info"); return ERR_PTR(-EINVAL); } - base = lx7_info->soc_info.reg_map[LX7_CSR_BASE].mem_base; + base = icp_v2_info->soc_info.reg_map[ICP_V2_CSR_BASE].mem_base; - return base + LX7_GEN_PURPOSE_REG_OFFSET; + return base + ICP_V2_GEN_PURPOSE_REG_OFFSET; +} + +void cam_icp_v2_populate_hfi_ops(const struct hfi_ops **hfi_proc_ops) +{ + if (!hfi_proc_ops) { + CAM_ERR(CAM_ICP, "Invalid hfi ops argument"); + return; + } + + *hfi_proc_ops = &hfi_icp_v2_ops; } 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 new file mode 100644 index 0000000000..7505f9631c --- /dev/null +++ b/drivers/cam_icp/icp_hw/icp_proc/icp_v2_hw/cam_icp_v2_core.h @@ -0,0 +1,56 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2021, The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + */ + +#ifndef _CAM_ICP_V2_CORE_H_ +#define _CAM_ICP_V2_CORE_H_ + +#include "cam_hw_intf.h" +#include "cam_icp_hw_intf.h" +#include "hfi_intf.h" + +#define UNSUPPORTED_PROC_PAS_ID 30 +#define CAM_FW_PAS_ID 33 + +enum cam_icp_v2_reg_base { + ICP_V2_CSR_BASE, + ICP_V2_CIRQ_BASE, + ICP_V2_WD0_BASE, + ICP_V2_SYS_BASE, + ICP_V2_BASE_MAX, +}; + +struct cam_icp_v2_core_info { + struct cam_icp_irq_cb irq_cb; + uint32_t cpas_handle; + bool cpas_start; + bool use_sec_pil; + bool is_irq_test; + struct { + const struct firmware *fw_elf; + void *fw; + uint32_t fw_buf; + uintptr_t fw_kva_addr; + uint64_t fw_buf_len; + } fw_params; +}; + +int cam_icp_v2_hw_init(void *priv, void *args, uint32_t arg_size); +int cam_icp_v2_hw_deinit(void *priv, void *args, uint32_t arg_size); +int cam_icp_v2_process_cmd(void *priv, uint32_t cmd_type, + void *args, uint32_t arg_size); +int cam_icp_v2_test_irq_line(void *priv); + +int cam_icp_v2_cpas_register(struct cam_hw_intf *icp_v2_intf); +int cam_icp_v2_cpas_unregister(struct cam_hw_intf *icp_v2_intf); + +irqreturn_t cam_icp_v2_handle_irq(int irq_num, void *data); + +void cam_icp_v2_irq_raise(void *priv); +void cam_icp_v2_irq_enable(void *priv); +void __iomem *cam_icp_v2_iface_addr(void *priv); +void cam_icp_v2_populate_hfi_ops(const struct hfi_ops **hfi_proc_ops); + +#endif /* _CAM_ICP_V2_CORE_H_ */ diff --git a/drivers/cam_icp/icp_hw/icp_proc/icp_v2_hw/cam_icp_v2_dev.c b/drivers/cam_icp/icp_hw/icp_proc/icp_v2_hw/cam_icp_v2_dev.c new file mode 100644 index 0000000000..3e274f6531 --- /dev/null +++ b/drivers/cam_icp/icp_hw/icp_proc/icp_v2_hw/cam_icp_v2_dev.c @@ -0,0 +1,195 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2021, The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + */ + +#include +#include +#include + +#include "camera_main.h" +#include "cam_debug_util.h" +#include "cam_hw.h" +#include "cam_hw_intf.h" +#include "cam_icp_hw_intf.h" +#include "cam_icp_v2_core.h" +#include "cam_icp_soc_common.h" + +static int max_icp_v2_hw_idx = -1; + +uint32_t cam_icp_v2_get_device_num(void) +{ + return max_icp_v2_hw_idx + 1; +} + +static int cam_icp_v2_soc_info_init(struct cam_hw_soc_info *soc_info, + struct platform_device *pdev) +{ + struct cam_icp_soc_info *icp_soc_info = NULL; + + icp_soc_info = kzalloc(sizeof(*icp_soc_info), GFP_KERNEL); + if (!icp_soc_info) + return -ENOMEM; + + soc_info->pdev = pdev; + soc_info->dev = &pdev->dev; + soc_info->dev_name = pdev->name; + soc_info->soc_private = icp_soc_info; + + icp_soc_info->dev_type = CAM_ICP_DEV_ICP_V2; + + return 0; +} + +static inline void cam_icp_v2_soc_info_deinit(struct cam_hw_soc_info *soc_info) +{ + kfree(soc_info->soc_private); +} + +static int cam_icp_v2_component_bind(struct device *dev, + struct device *mdev, void *data) +{ + int rc = 0; + struct cam_hw_intf *icp_v2_intf = NULL; + struct cam_hw_info *icp_v2_info = NULL; + struct cam_icp_v2_core_info *core_info = NULL; + struct platform_device *pdev = to_platform_device(dev); + + icp_v2_intf = kzalloc(sizeof(*icp_v2_intf), GFP_KERNEL); + if (!icp_v2_intf) + return -ENOMEM; + + icp_v2_info = kzalloc(sizeof(*icp_v2_info), GFP_KERNEL); + if (!icp_v2_info) { + rc = -ENOMEM; + goto free_hw_intf; + } + + core_info = kzalloc(sizeof(*core_info), GFP_KERNEL); + if (!core_info) { + rc = -ENOMEM; + goto free_hw_info; + } + + icp_v2_info->core_info = core_info; + + rc = cam_icp_v2_soc_info_init(&icp_v2_info->soc_info, pdev); + if (rc) + goto free_core_info; + + mutex_init(&icp_v2_info->hw_mutex); + spin_lock_init(&icp_v2_info->hw_lock); + init_completion(&icp_v2_info->hw_complete); + + rc = cam_icp_soc_resources_init(&icp_v2_info->soc_info, + cam_icp_v2_handle_irq, icp_v2_info); + if (rc) { + CAM_ERR(CAM_ICP, "soc resources init failed rc=%d", rc); + goto free_soc_info; + } + + icp_v2_intf->hw_priv = icp_v2_info; + icp_v2_intf->hw_type = CAM_ICP_DEV_ICP_V2; + icp_v2_intf->hw_idx = icp_v2_info->soc_info.index; + icp_v2_intf->hw_ops.init = cam_icp_v2_hw_init; + icp_v2_intf->hw_ops.deinit = cam_icp_v2_hw_deinit; + icp_v2_intf->hw_ops.process_cmd = cam_icp_v2_process_cmd; + icp_v2_intf->hw_ops.test_irq_line = cam_icp_v2_test_irq_line; + + rc = cam_icp_v2_cpas_register(icp_v2_intf); + if (rc) { + CAM_ERR(CAM_ICP, "cpas registration failed rc=%d", rc); + goto res_deinit; + } + + if ((int)(icp_v2_intf->hw_idx) > max_icp_v2_hw_idx) + max_icp_v2_hw_idx = icp_v2_intf->hw_idx; + + platform_set_drvdata(pdev, icp_v2_intf); + + return 0; + +res_deinit: + cam_icp_soc_resources_deinit(&icp_v2_info->soc_info); +free_soc_info: + cam_icp_v2_soc_info_deinit(&icp_v2_info->soc_info); +free_core_info: + kfree(core_info); +free_hw_info: + kfree(icp_v2_info); +free_hw_intf: + kfree(icp_v2_intf); + + return rc; +} + +static void cam_icp_v2_component_unbind(struct device *dev, + struct device *mdev, void *data) +{ + struct platform_device *pdev = to_platform_device(dev); + struct cam_hw_intf *icp_v2_intf = platform_get_drvdata(pdev); + struct cam_hw_info *icp_v2_info = icp_v2_intf->hw_priv; + + cam_icp_v2_cpas_unregister(icp_v2_intf); + cam_icp_soc_resources_deinit(&icp_v2_info->soc_info); + cam_icp_v2_soc_info_deinit(&icp_v2_info->soc_info); + + max_icp_v2_hw_idx = -1; + + kfree(icp_v2_info->core_info); + kfree(icp_v2_info); + kfree(icp_v2_intf); +} + +static const struct component_ops cam_icp_v2_component_ops = { + .bind = cam_icp_v2_component_bind, + .unbind = cam_icp_v2_component_unbind, +}; + +static const struct of_device_id cam_icp_v2_match[] = { + { .compatible = "qcom,cam-icp_v2"}, + {}, +}; +MODULE_DEVICE_TABLE(of, cam_icp_v2_match); + +static int cam_icp_v2_driver_probe(struct platform_device *pdev) +{ + int rc; + + rc = component_add(&pdev->dev, &cam_icp_v2_component_ops); + if (rc) + CAM_ERR(CAM_ICP, "cam-icp_v2 component add failed rc=%d", rc); + + return rc; +} + +static int cam_icp_v2_driver_remove(struct platform_device *pdev) +{ + component_del(&pdev->dev, &cam_icp_v2_component_ops); + + return 0; +} + +struct platform_driver cam_icp_v2_driver = { + .probe = cam_icp_v2_driver_probe, + .remove = cam_icp_v2_driver_remove, + .driver = { + .name = "cam-icp_v2", + .of_match_table = cam_icp_v2_match, + .suppress_bind_attrs = true, + }, +}; + +int cam_icp_v2_init_module(void) +{ + return platform_driver_register(&cam_icp_v2_driver); +} + +void cam_icp_v2_exit_module(void) +{ + platform_driver_unregister(&cam_icp_v2_driver); +} + +MODULE_DESCRIPTION("Camera ICP_V2 driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/cam_icp/icp_hw/icp_proc/icp_v2_hw/cam_icp_v2_dev.h b/drivers/cam_icp/icp_hw/icp_proc/icp_v2_hw/cam_icp_v2_dev.h new file mode 100644 index 0000000000..adae7c04de --- /dev/null +++ b/drivers/cam_icp/icp_hw/icp_proc/icp_v2_hw/cam_icp_v2_dev.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2021, The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + */ + +#ifndef _CAM_ICP_V2_DEV_H_ +#define _CAM_ICP_V2_DEV_H_ + +int cam_icp_v2_init_module(void); +void cam_icp_v2_exit_module(void); + +#endif /* _CAM_ICP_V2_DEV_H_ */ diff --git a/drivers/cam_icp/icp_hw/icp_proc/icp_v2_hw/cam_icp_v2_reg.h b/drivers/cam_icp/icp_hw/icp_proc/icp_v2_hw/cam_icp_v2_reg.h new file mode 100644 index 0000000000..77fdd2a98b --- /dev/null +++ b/drivers/cam_icp/icp_hw/icp_proc/icp_v2_hw/cam_icp_v2_reg.h @@ -0,0 +1,52 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2021, The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + */ + +#ifndef _CAM_ICP_V2_REG_H_ +#define _CAM_ICP_V2_REG_H_ + +/* ICP CSR info */ +#define ICP_V2_GEN_PURPOSE_REG_OFFSET 0x20 +#define ICP_V2_CSR_DBG_STATUS_REG_OFFSET 0xC0 +#define ICP_V2_CSR_DBG_CTRL_REG_OFFSET 0xC4 +#define ICP_V2_CSR_GP_REG_COUNT 0x18 + +/* ICP_SYS - Protected reg space defined in AC policy */ +#define ICP_V2_SYS_RESET 0x0 +#define ICP_V2_SYS_CONTROL 0x4 +#define ICP_V2_SYS_STATUS 0xC +#define ICP_V2_SYS_ACCESS 0x10 + +#define ICP_V2_STANDBYWFI (1 << 7) +#define ICP_V2_EN_CPU (1 << 9) +#define ICP_V2_FUNC_RESET (1 << 4) + +#define ICP_V2_CIRQ_OB_MASK 0x0 +#define ICP_V2_CIRQ_OB_CLEAR 0x4 +#define ICP_V2_CIRQ_OB_SET 0x8 +#define ICP_V2_CIRQ_OB_STATUS 0xc + +/* ICP WD reg space */ +#define ICP_V2_WD_CTRL 0x8 +#define ICP_V2_WD_INTCLR 0xC + +/* These bitfields are shared by OB_MASK, OB_CLEAR, OB_STATUS */ +#define ICP_V2_WDT_BITE_WS1 (1 << 6) +#define ICP_V2_WDT_BARK_WS1 (1 << 5) +#define ICP_V2_WDT_BITE_WS0 (1 << 4) +#define ICP_V2_WDT_BARK_WS0 (1 << 3) +#define ICP_V2_ICP2HOSTINT (1 << 2) + +#define ICP_V2_CIRQ_OB_IRQ_CMD 0x10 +#define ICP_V2_IRQ_CLEAR_CMD (1 << 1) +#define ICP_V2_IRQ_SET_CMD (1 << 0) + +#define ICP_V2_CIRQ_IB_STATUS0 0x70 +#define ICP_V2_CIRQ_IB_STATUS1 0x74 +#define ICP_V2_CIRQ_HOST2ICPINT 0x124 +#define ICP_V2_CIRQ_PFAULT_INFO 0x128 +#define ICP_V2_HOST2ICPINT (1 << 0) + +#endif /* _CAM_ICP_V2_REG_H_ */ diff --git a/drivers/cam_icp/icp_hw/lx7_hw/lx7_core.h b/drivers/cam_icp/icp_hw/lx7_hw/lx7_core.h deleted file mode 100644 index 74842617a6..0000000000 --- a/drivers/cam_icp/icp_hw/lx7_hw/lx7_core.h +++ /dev/null @@ -1,54 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Copyright (c) 2021, The Linux Foundation. All rights reserved. - * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. - */ - -#ifndef _CAM_LX7_CORE_H_ -#define _CAM_LX7_CORE_H_ - -#include "cam_hw_intf.h" -#include "cam_icp_hw_intf.h" - -#define UNSUPPORTED_PROC_PAS_ID 30 -#define CAM_FW_PAS_ID 33 - -enum cam_lx7_reg_base { - LX7_CSR_BASE, - LX7_CIRQ_BASE, - LX7_WD0_BASE, - LX7_SYS_BASE, - LX7_BASE_MAX, -}; - -struct cam_lx7_core_info { - struct cam_icp_irq_cb irq_cb; - uint32_t cpas_handle; - bool cpas_start; - bool use_sec_pil; - bool is_irq_test; - struct { - const struct firmware *fw_elf; - void *fw; - uint32_t fw_buf; - uintptr_t fw_kva_addr; - uint64_t fw_buf_len; - } fw_params; -}; - -int cam_lx7_hw_init(void *priv, void *args, uint32_t arg_size); -int cam_lx7_hw_deinit(void *priv, void *args, uint32_t arg_size); -int cam_lx7_process_cmd(void *priv, uint32_t cmd_type, - void *args, uint32_t arg_size); -int cam_lx7_test_irq_line(void *priv); - -int cam_lx7_cpas_register(struct cam_hw_intf *lx7_intf); -int cam_lx7_cpas_unregister(struct cam_hw_intf *lx7_intf); - -irqreturn_t cam_lx7_handle_irq(int irq_num, void *data); - -void cam_lx7_irq_raise(void *priv); -void cam_lx7_irq_enable(void *priv); -void __iomem *cam_lx7_iface_addr(void *priv); - -#endif /* _CAM_LX7_CORE_H_ */ diff --git a/drivers/cam_icp/icp_hw/lx7_hw/lx7_dev.c b/drivers/cam_icp/icp_hw/lx7_hw/lx7_dev.c deleted file mode 100644 index ebfdd62da3..0000000000 --- a/drivers/cam_icp/icp_hw/lx7_hw/lx7_dev.c +++ /dev/null @@ -1,166 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (c) 2021, The Linux Foundation. All rights reserved. - * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. - */ - -#include -#include -#include - -#include "camera_main.h" -#include "cam_debug_util.h" -#include "cam_hw.h" -#include "cam_hw_intf.h" -#include "cam_icp_hw_intf.h" -#include "lx7_core.h" -#include "lx7_soc.h" - -static int cam_lx7_component_bind(struct device *dev, - struct device *mdev, void *data) -{ - int rc = 0; - struct cam_hw_intf *lx7_intf = NULL; - struct cam_hw_info *lx7_info = NULL; - struct lx7_soc_info *lx7_soc_info = NULL; - struct cam_lx7_core_info *core_info = NULL; - struct platform_device *pdev = to_platform_device(dev); - - lx7_intf = kzalloc(sizeof(*lx7_intf), GFP_KERNEL); - if (!lx7_intf) - return -ENOMEM; - - lx7_info = kzalloc(sizeof(*lx7_info), GFP_KERNEL); - if (!lx7_info) { - rc = -ENOMEM; - goto free_hw_intf; - } - - lx7_soc_info = kzalloc(sizeof(*lx7_soc_info), GFP_KERNEL); - if (!lx7_soc_info) { - rc = -ENOMEM; - goto free_hw_info; - } - - core_info = kzalloc(sizeof(*core_info), GFP_KERNEL); - if (!core_info) { - rc = -ENOMEM; - goto free_soc_info; - } - - lx7_info->core_info = core_info; - lx7_info->soc_info.pdev = pdev; - lx7_info->soc_info.dev = &pdev->dev; - lx7_info->soc_info.dev_name = pdev->name; - lx7_info->soc_info.soc_private = lx7_soc_info; - - mutex_init(&lx7_info->hw_mutex); - spin_lock_init(&lx7_info->hw_lock); - init_completion(&lx7_info->hw_complete); - - rc = cam_lx7_soc_resources_init(&lx7_info->soc_info, - cam_lx7_handle_irq, lx7_info); - if (rc) { - CAM_ERR(CAM_ICP, "soc resources init failed rc=%d", rc); - goto free_core_info; - } - - lx7_intf->hw_priv = lx7_info; - lx7_intf->hw_type = CAM_ICP_DEV_LX7; - lx7_intf->hw_idx = lx7_info->soc_info.index; - lx7_intf->hw_ops.init = cam_lx7_hw_init; - lx7_intf->hw_ops.deinit = cam_lx7_hw_deinit; - lx7_intf->hw_ops.process_cmd = cam_lx7_process_cmd; - lx7_intf->hw_ops.test_irq_line = cam_lx7_test_irq_line; - - rc = cam_lx7_cpas_register(lx7_intf); - if (rc) { - CAM_ERR(CAM_ICP, "cpas registration failed rc=%d", rc); - goto res_deinit; - } - - platform_set_drvdata(pdev, lx7_intf); - - return 0; - -res_deinit: - cam_lx7_soc_resources_deinit(&lx7_info->soc_info); -free_core_info: - kfree(core_info); -free_soc_info: - kfree(lx7_soc_info); -free_hw_info: - kfree(lx7_info); -free_hw_intf: - kfree(lx7_intf); - - return rc; -} - -static void cam_lx7_component_unbind(struct device *dev, - struct device *mdev, void *data) -{ - struct platform_device *pdev = to_platform_device(dev); - struct cam_hw_intf *lx7_intf = platform_get_drvdata(pdev); - struct cam_hw_info *lx7_info = lx7_intf->hw_priv; - - cam_lx7_cpas_unregister(lx7_intf); - cam_lx7_soc_resources_deinit(&lx7_info->soc_info); - - kfree(lx7_info->core_info); - kfree(lx7_info->soc_info.soc_private); - kfree(lx7_info); - kfree(lx7_intf); -} - -static const struct component_ops cam_lx7_component_ops = { - .bind = cam_lx7_component_bind, - .unbind = cam_lx7_component_unbind, -}; - -static const struct of_device_id cam_lx7_match[] = { - { .compatible = "qcom,cam-lx7"}, - {}, -}; -MODULE_DEVICE_TABLE(of, cam_lx7_match); - -static int cam_lx7_driver_probe(struct platform_device *pdev) -{ - int rc; - - rc = component_add(&pdev->dev, &cam_lx7_component_ops); - if (rc) - CAM_ERR(CAM_ICP, "cam-lx7 component add failed rc=%d", rc); - - return rc; -} - -static int cam_lx7_driver_remove(struct platform_device *pdev) -{ - component_del(&pdev->dev, &cam_lx7_component_ops); - - return 0; -} - -struct platform_driver cam_lx7_driver = { - .probe = cam_lx7_driver_probe, - .remove = cam_lx7_driver_remove, - .driver = { - .name = "cam-lx7", - .of_match_table = cam_lx7_match, - .suppress_bind_attrs = true, - }, -}; - -int cam_lx7_init_module(void) -{ - return platform_driver_register(&cam_lx7_driver); -} - -void cam_lx7_exit_module(void) -{ - platform_driver_unregister(&cam_lx7_driver); -} - -MODULE_DESCRIPTION("Camera LX7 driver"); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/cam_icp/icp_hw/lx7_hw/lx7_dev.h b/drivers/cam_icp/icp_hw/lx7_hw/lx7_dev.h deleted file mode 100644 index d96d638f3b..0000000000 --- a/drivers/cam_icp/icp_hw/lx7_hw/lx7_dev.h +++ /dev/null @@ -1,12 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Copyright (c) 2021, The Linux Foundation. All rights reserved. - */ - -#ifndef _CAM_LX7_DEV_H_ -#define _CAM_LX7_DEV_H_ - -int cam_lx7_init_module(void); -void cam_lx7_exit_module(void); - -#endif /* _CAM_LX7_DEV_H_ */ diff --git a/drivers/cam_icp/icp_hw/lx7_hw/lx7_reg.h b/drivers/cam_icp/icp_hw/lx7_hw/lx7_reg.h deleted file mode 100644 index 489e91f285..0000000000 --- a/drivers/cam_icp/icp_hw/lx7_hw/lx7_reg.h +++ /dev/null @@ -1,52 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Copyright (c) 2021, The Linux Foundation. All rights reserved. - * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. - */ - -#ifndef _CAM_LX7_REG_H_ -#define _CAM_LX7_REG_H_ - -/* ICP CSR info */ -#define LX7_GEN_PURPOSE_REG_OFFSET 0x20 -#define LX7_CSR_DBG_STATUS_REG_OFFSET 0xC0 -#define LX7_CSR_DBG_CTRL_REG_OFFSET 0xC4 -#define LX7_CSR_GP_REG_COUNT 0x18 - -/* ICP_SYS - Protected reg space defined in AC policy */ -#define ICP_LX7_SYS_RESET 0x0 -#define ICP_LX7_SYS_CONTROL 0x4 -#define ICP_LX7_SYS_STATUS 0xC -#define ICP_LX7_SYS_ACCESS 0x10 - -#define ICP_LX7_STANDBYWFI (1 << 7) -#define ICP_LX7_EN_CPU (1 << 9) -#define ICP_LX7_FUNC_RESET (1 << 4) - -#define ICP_LX7_CIRQ_OB_MASK 0x0 -#define ICP_LX7_CIRQ_OB_CLEAR 0x4 -#define ICP_LX7_CIRQ_OB_SET 0x8 -#define ICP_LX7_CIRQ_OB_STATUS 0xc - -/* ICP WD reg space */ -#define ICP_LX7_WD_CTRL 0x8 -#define ICP_LX7_WD_INTCLR 0xC - -/* These bitfields are shared by OB_MASK, OB_CLEAR, OB_STATUS */ -#define LX7_WDT_BITE_WS1 (1 << 6) -#define LX7_WDT_BARK_WS1 (1 << 5) -#define LX7_WDT_BITE_WS0 (1 << 4) -#define LX7_WDT_BARK_WS0 (1 << 3) -#define LX7_ICP2HOSTINT (1 << 2) - -#define ICP_LX7_CIRQ_OB_IRQ_CMD 0x10 -#define LX7_IRQ_CLEAR_CMD (1 << 1) -#define LX7_IRQ_SET_CMD (1 << 0) - -#define ICP_LX7_CIRQ_IB_STATUS0 0x70 -#define ICP_LX7_CIRQ_IB_STATUS1 0x74 -#define ICP_LX7_CIRQ_HOST2ICPINT 0x124 -#define ICP_LX7_CIRQ_PFAULT_INFO 0x128 -#define LX7_HOST2ICPINT (1 << 0) - -#endif /* _CAM_LX7_REG_H_ */ diff --git a/drivers/cam_icp/icp_hw/lx7_hw/lx7_soc.h b/drivers/cam_icp/icp_hw/lx7_hw/lx7_soc.h deleted file mode 100644 index 7658cd6d76..0000000000 --- a/drivers/cam_icp/icp_hw/lx7_hw/lx7_soc.h +++ /dev/null @@ -1,35 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Copyright (c) 2021, The Linux Foundation. All rights reserved. - */ - -#ifndef _CAM_LX7_SOC_H_ -#define _CAM_LX7_SOC_H_ - -#include - -#include "cam_soc_util.h" - -#define UBWC_CONFIG_MAX 2 - -struct lx7_soc_info { - uint32_t icp_qos_val; - struct { - uint32_t ipe_fetch[UBWC_CONFIG_MAX]; - uint32_t ipe_write[UBWC_CONFIG_MAX]; - uint32_t bps_fetch[UBWC_CONFIG_MAX]; - uint32_t bps_write[UBWC_CONFIG_MAX]; - } ubwc_cfg; -}; - -int cam_lx7_soc_resources_init(struct cam_hw_soc_info *soc_info, - irq_handler_t irq_handler, - void *irq_data); -int cam_lx7_soc_resources_deinit(struct cam_hw_soc_info *soc_info); - -int cam_lx7_soc_resources_enable(struct cam_hw_soc_info *soc_info); -int cam_lx7_soc_resources_disable(struct cam_hw_soc_info *soc_info); -int cam_lx7_update_clk_rate(struct cam_hw_soc_info *soc_info, - int32_t clk_level); - -#endif /* _CAM_LX7_SOC_H_ */ diff --git a/drivers/cam_icp/utils/cam_icp_utils.h b/drivers/cam_icp/utils/cam_icp_utils.h deleted file mode 100644 index ccde507184..0000000000 --- a/drivers/cam_icp/utils/cam_icp_utils.h +++ /dev/null @@ -1,31 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Copyright (c) 2021, The Linux Foundation. All rights reserved. - */ - -#ifndef _CAM_ICP_UTILS_H_ -#define _CAM_ICP_UTILS_H_ - -#include -#include -#include - -#include "cam_debug_util.h" - -/** - * @brief : Validate FW elf image - */ -int32_t cam_icp_validate_fw(const uint8_t *elf, uint32_t machine_id); - -/** - * @brief : Get FW elf size - */ -int32_t cam_icp_get_fw_size(const uint8_t *elf, uint32_t *fw_size); - -/** - * @brief : Program FW memory - */ -int32_t cam_icp_program_fw(const uint8_t *elf, - uintptr_t fw_kva_addr); - -#endif /* _CAM_ICP_UTILS_H_ */ diff --git a/drivers/cam_presil/inc/cam_presil_hw_access.h b/drivers/cam_presil/inc/cam_presil_hw_access.h index 5e86399c82..583f890192 100644 --- a/drivers/cam_presil/inc/cam_presil_hw_access.h +++ b/drivers/cam_presil/inc/cam_presil_hw_access.h @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2021, The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. */ #ifndef _CAM_PRESIL_HW_ACCESS_H_ @@ -12,14 +13,14 @@ #define CAM_PRESIL_CLIENT_ID_EVA 0x2 /* presil events to carry shared values from HW-KMD to PC-HOST CSim Wrapper */ -#define CAM_PRESIL_EVENT_HFI_REG_BASE 0x600 +#define CAM_PRESIL_EVENT_HFI_REG_BASE 0x600 #define CAM_PRESIL_EVENT_HFI_REG(n) (CAM_PRESIL_EVENT_HFI_REG_BASE + (n * 4)) -#define CAM_PRESIL_EVENT_HFI_REG_CMD_Q_IOVA CAM_PRESIL_EVENT_HFI_REG(1) -#define CAM_PRESIL_EVENT_HFI_REG_MSG_Q_IOVA CAM_PRESIL_EVENT_HFI_REG(2) -#define CAM_PRESIL_EVENT_HFI_REG_DBG_Q_IOVA CAM_PRESIL_EVENT_HFI_REG(3) -#define CAM_PRESIL_EVENT_HFI_REG_SFR_LEN CAM_PRESIL_EVENT_HFI_REG(4) -#define CAM_PRESIL_EVENT_HFI_REG_A5_HW_VERSION_TO_START_HFI_INIT CAM_PRESIL_EVENT_HFI_REG(13) -#define CAM_PRESIL_EVENT_HFI_REG_ON_FIRST_REG_START_FW_DOWNLOAD 0x638 /* write FF to start */ +#define CAM_PRESIL_EVENT_HFI_REG_CMD_Q_IOVA CAM_PRESIL_EVENT_HFI_REG(1) +#define CAM_PRESIL_EVENT_HFI_REG_MSG_Q_IOVA CAM_PRESIL_EVENT_HFI_REG(2) +#define CAM_PRESIL_EVENT_HFI_REG_DBG_Q_IOVA CAM_PRESIL_EVENT_HFI_REG(3) +#define CAM_PRESIL_EVENT_HFI_REG_SFR_LEN CAM_PRESIL_EVENT_HFI_REG(4) +#define CAM_PRESIL_EVENT_HFI_REG_ICP_V1_HW_VERSION_TO_START_HFI_INIT CAM_PRESIL_EVENT_HFI_REG(13) +#define CAM_PRESIL_EVENT_HFI_REG_ON_FIRST_REG_START_FW_DOWNLOAD 0x638 /* write FF to start */ /* diff --git a/drivers/camera_main.c b/drivers/camera_main.c index 8fa521292e..0786f85e53 100644 --- a/drivers/camera_main.c +++ b/drivers/camera_main.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2019-2021, The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. */ #include #include @@ -26,8 +27,8 @@ #include "cam_tpg_dev.h" #include "cam_flash_dev.h" -#include "a5_core.h" -#include "lx7_dev.h" +#include "cam_icp_v1_dev.h" +#include "cam_icp_v2_dev.h" #include "ipe_core.h" #include "bps_core.h" #include "cam_icp_subdev.h" @@ -118,8 +119,8 @@ static const struct camera_submodule_component camera_sensor[] = { static const struct camera_submodule_component camera_icp[] = { #ifdef CONFIG_SPECTRA_ICP - {&cam_a5_init_module, &cam_a5_exit_module}, - {&cam_lx7_init_module, &cam_lx7_exit_module}, + {&cam_icp_v1_init_module, &cam_icp_v1_exit_module}, + {&cam_icp_v2_init_module, &cam_icp_v2_exit_module}, {&cam_ipe_init_module, &cam_ipe_exit_module}, {&cam_bps_init_module, &cam_bps_exit_module}, {&cam_icp_init_module, &cam_icp_exit_module}, diff --git a/drivers/camera_main.h b/drivers/camera_main.h index ee72ea5d18..c8db2a2e5b 100644 --- a/drivers/camera_main.h +++ b/drivers/camera_main.h @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. */ #ifndef CAMERA_MAIN_H @@ -47,8 +48,8 @@ extern struct platform_driver cam_flash_platform_driver; #endif #endif #ifdef CONFIG_SPECTRA_ICP -extern struct platform_driver cam_a5_driver; -extern struct platform_driver cam_lx7_driver; +extern struct platform_driver cam_icp_v1_driver; +extern struct platform_driver cam_icp_v2_driver; extern struct platform_driver cam_ipe_driver; extern struct platform_driver cam_bps_driver; extern struct platform_driver cam_icp_driver; @@ -118,8 +119,8 @@ static struct platform_driver *const cam_component_platform_drivers[] = { #endif #endif #ifdef CONFIG_SPECTRA_ICP - &cam_a5_driver, - &cam_lx7_driver, + &cam_icp_v1_driver, + &cam_icp_v2_driver, &cam_ipe_driver, &cam_bps_driver, &cam_icp_driver,