diff --git a/drivers/Makefile b/drivers/Makefile index 01e4e572c8..06420672da 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -9,7 +9,7 @@ ifneq (,$(filter $(CONFIG_MSM_GLOBAL_SYNX), y m)) ccflags-y += -I$(srctree)/drivers/media/platform/msm/synx endif -subdir-ccflags-y += -I$(srctree)/techpack/camera/include/uapi/camera +ccflags-y += -I$(srctree)/techpack/camera/include/uapi/camera ccflags-y += -I$(srctree) camera-y := \ @@ -26,6 +26,7 @@ camera-y := \ cam_utils/cam_debug_util.o \ cam_utils/cam_trace.o \ cam_utils/cam_common_util.o \ + cam_utils/cam_compat.o \ cam_core/cam_context.o \ cam_core/cam_context_utils.o \ cam_core/cam_node.o \ diff --git a/drivers/cam_req_mgr/Makefile b/drivers/cam_req_mgr/Makefile index 41452f89d3..2aaed1301b 100644 --- a/drivers/cam_req_mgr/Makefile +++ b/drivers/cam_req_mgr/Makefile @@ -3,6 +3,7 @@ ccflags-y += -I$(srctree)/techpack/camera/drivers/cam_core ccflags-y += -I$(srctree)/techpack/camera/drivers/cam_smmu/ ccflags-y += -I$(srctree)/techpack/camera/drivers/cam_utils +ccflags-y += -I$(srctree)/include/ ccflags-y += -I$(srctree)/ obj-$(CONFIG_SPECTRA_CAMERA) += cam_req_mgr_core.o\ diff --git a/drivers/cam_req_mgr/cam_mem_mgr.c b/drivers/cam_req_mgr/cam_mem_mgr.c index a0b1e66f8e..559a1c42b0 100644 --- a/drivers/cam_req_mgr/cam_mem_mgr.c +++ b/drivers/cam_req_mgr/cam_mem_mgr.c @@ -6,11 +6,15 @@ #include #include #include -#include #include -#include #include +#include +#if KERNEL_VERSION(5, 4, 0) > LINUX_VERSION_CODE +#include +#endif + +#include "cam_compat.h" #include "cam_req_mgr_util.h" #include "cam_mem_mgr.h" #include "cam_smmu_api.h" diff --git a/drivers/cam_smmu/cam_smmu_api.c b/drivers/cam_smmu/cam_smmu_api.c index 122ed77a79..269982f444 100644 --- a/drivers/cam_smmu/cam_smmu_api.c +++ b/drivers/cam_smmu/cam_smmu_api.c @@ -10,13 +10,18 @@ #include #include #include +#include #include #include #include #include + #include #include + #include + +#include "cam_compat.h" #include "cam_smmu_api.h" #include "cam_debug_util.h" @@ -36,13 +41,7 @@ static int g_num_pf_handled = 4; module_param(g_num_pf_handled, int, 0644); -struct firmware_alloc_info { - struct device *fw_dev; - void *fw_kva; - dma_addr_t fw_dma_hdl; -}; - -struct firmware_alloc_info icp_fw; +struct cam_fw_alloc_info icp_fw; struct cam_smmu_work_payload { int idx; @@ -1172,23 +1171,17 @@ int cam_smmu_alloc_firmware(int32_t smmu_hdl, firmware_start = iommu_cb_set.cb_info[idx].firmware_info.iova_start; CAM_DBG(CAM_SMMU, "Firmware area len from DT = %zu", firmware_len); - icp_fw.fw_kva = dma_alloc_coherent(icp_fw.fw_dev, - firmware_len, - &icp_fw.fw_dma_hdl, - GFP_KERNEL); - if (!icp_fw.fw_kva) { - CAM_ERR(CAM_SMMU, "FW memory alloc failed"); - rc = -ENOMEM; + rc = cam_reserve_icp_fw(&icp_fw, firmware_len); + if (rc) goto unlock_and_end; - } else { + else CAM_DBG(CAM_SMMU, "DMA alloc returned fw = %pK, hdl = %pK", - icp_fw.fw_kva, (void *)icp_fw.fw_dma_hdl); - } + icp_fw.fw_kva, (void *)icp_fw.fw_hdl); domain = iommu_cb_set.cb_info[idx].domain; rc = iommu_map(domain, firmware_start, - icp_fw.fw_dma_hdl, + (phys_addr_t) icp_fw.fw_hdl, firmware_len, IOMMU_READ|IOMMU_WRITE|IOMMU_PRIV); @@ -1207,10 +1200,7 @@ int cam_smmu_alloc_firmware(int32_t smmu_hdl, return rc; alloc_fail: - dma_free_coherent(icp_fw.fw_dev, - firmware_len, - icp_fw.fw_kva, - icp_fw.fw_dma_hdl); + cam_unreserve_icp_fw(&icp_fw, firmware_len); unlock_and_end: mutex_unlock(&iommu_cb_set.cb_info[idx].lock); end: @@ -1270,13 +1260,10 @@ int cam_smmu_dealloc_firmware(int32_t smmu_hdl) rc = -EINVAL; } - dma_free_coherent(icp_fw.fw_dev, - firmware_len, - icp_fw.fw_kva, - icp_fw.fw_dma_hdl); + cam_unreserve_icp_fw(&icp_fw, firmware_len); - icp_fw.fw_kva = 0; - icp_fw.fw_dma_hdl = 0; + icp_fw.fw_kva = NULL; + icp_fw.fw_hdl = 0; iommu_cb_set.cb_info[idx].is_fw_allocated = false; @@ -3184,9 +3171,8 @@ EXPORT_SYMBOL(cam_smmu_destroy_handle); static void cam_smmu_deinit_cb(struct cam_context_bank_info *cb) { - if (cb->io_support && cb->domain) { + if (cb->io_support && cb->domain) cb->domain = NULL; - } if (cb->shared_support) { gen_pool_destroy(cb->shared_mem_pool); @@ -3616,7 +3602,7 @@ static int cam_smmu_probe(struct platform_device *pdev) if (of_device_is_compatible(dev->of_node, "qcom,msm-cam-smmu-fw-dev")) { icp_fw.fw_dev = &pdev->dev; icp_fw.fw_kva = NULL; - icp_fw.fw_dma_hdl = 0; + icp_fw.fw_hdl = 0; return rc; } diff --git a/drivers/cam_utils/cam_compat.c b/drivers/cam_utils/cam_compat.c new file mode 100644 index 0000000000..72ec49b5b6 --- /dev/null +++ b/drivers/cam_utils/cam_compat.c @@ -0,0 +1,71 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2014-2019, The Linux Foundation. All rights reserved. + */ + +#include +#include + +#include "cam_compat.h" +#include "cam_debug_util.h" + +#if KERNEL_VERSION(5, 4, 0) >= LINUX_VERSION_CODE +int cam_reserve_icp_fw(struct cam_fw_alloc_info *icp_fw, size_t fw_length) +{ + int rc = 0; + struct device_node *of_node; + struct device_node *mem_node; + struct resource res; + + of_node = (icp_fw->fw_dev)->of_node; + mem_node = of_parse_phandle(of_node, "memory-region", 0); + if (!mem_node) { + rc = -ENOMEM; + CAM_ERR(CAM_SMMU, "FW memory carveout not found"); + goto end; + } + rc = of_address_to_resource(mem_node, 0, &res); + of_node_put(mem_node); + if (rc < 0) { + CAM_ERR(CAM_SMMU, "Unable to get start of FW mem carveout"); + goto end; + } + icp_fw->fw_hdl = res.start; + icp_fw->fw_kva = ioremap_wc(icp_fw->fw_hdl, fw_length); + if (!icp_fw->fw_kva) { + CAM_ERR(CAM_SMMU, "Failed to map the FW."); + rc = -ENOMEM; + goto end; + } + memset_io(icp_fw->fw_kva, 0, fw_length); + +end: + return rc; +} + +void cam_unreserve_icp_fw(struct cam_fw_alloc_info *icp_fw, size_t fw_length) +{ + iounmap(icp_fw->fw_kva); +} +#else +int cam_reserve_icp_fw(struct cam_fw_alloc_info *icp_fw, size_t fw_length) +{ + int rc = 0; + + icp_fw->fw_kva = dma_alloc_coherent(icp_fw->fw_dev, fw_length, + &icp_fw->fw_hdl, GFP_KERNEL); + + if (!icp_fw->fw_kva) { + CAM_ERR(CAM_SMMU, "FW memory alloc failed"); + rc = -ENOMEM; + } + + return rc; +} + +void cam_unreserve_icp_fw(struct cam_fw_alloc_info *icp_fw, size_t fw_length) +{ + dma_free_coherent(icp_fw->fw_dev, fw_length, icp_fw->fw_kva, + icp_fw->fw_hdl); +} +#endif diff --git a/drivers/cam_utils/cam_compat.h b/drivers/cam_utils/cam_compat.h new file mode 100644 index 0000000000..caf0ac8e15 --- /dev/null +++ b/drivers/cam_utils/cam_compat.h @@ -0,0 +1,32 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2014-2019, The Linux Foundation. All rights reserved. + */ + +#ifndef _CAM_COMPAT_H_ +#define _CAM_COMPAT_H_ + +#include + +#if KERNEL_VERSION(5, 4, 0) >= LINUX_VERSION_CODE + +#include +#include + +#else + +#include +#include + +#endif + +struct cam_fw_alloc_info { + struct device *fw_dev; + void *fw_kva; + uint64_t fw_hdl; +}; + +int cam_reserve_icp_fw(struct cam_fw_alloc_info *icp_fw, size_t fw_length); +void cam_unreserve_icp_fw(struct cam_fw_alloc_info *icp_fw, size_t fw_length); + +#endif /* _CAM_COMPAT_H_ */