Forráskód Böngészése

msm: camera: smmu: Move to ioremap APIs for using FW memory

When loading the camera FW, use the appropriate APIs
depending on the kernel version to map the FW region.

CRs-Fixed: 2564857
Change-Id: I2104b63b54bce799c8e44f36c49042de86f78c7e
Signed-off-by: Isaac J. Manjarres <[email protected]>
Signed-off-by: Karthik Jayakumar <[email protected]>
Karthik Jayakumar 5 éve
szülő
commit
50c8c09ead

+ 2 - 1
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 \

+ 1 - 0
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\

+ 6 - 2
drivers/cam_req_mgr/cam_mem_mgr.c

@@ -6,11 +6,15 @@
 #include <linux/module.h>
 #include <linux/types.h>
 #include <linux/mutex.h>
-#include <linux/msm_ion.h>
 #include <linux/slab.h>
-#include <linux/ion_kernel.h>
 #include <linux/dma-buf.h>
+#include <linux/version.h>
+
+#if KERNEL_VERSION(5, 4, 0) > LINUX_VERSION_CODE
+#include <linux/ion_kernel.h>
+#endif
 
+#include "cam_compat.h"
 #include "cam_req_mgr_util.h"
 #include "cam_mem_mgr.h"
 #include "cam_smmu_api.h"

+ 17 - 31
drivers/cam_smmu/cam_smmu_api.c

@@ -10,13 +10,18 @@
 #include <linux/iommu.h>
 #include <linux/slab.h>
 #include <linux/dma-mapping.h>
+#include <linux/of_address.h>
 #include <linux/msm_dma_iommu_mapping.h>
 #include <linux/workqueue.h>
 #include <linux/genalloc.h>
 #include <linux/debugfs.h>
+
 #include <soc/qcom/scm.h>
 #include <soc/qcom/secure_buffer.h>
+
 #include <media/cam_req_mgr.h>
+
+#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;
 	}
 

+ 71 - 0
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 <linux/dma-mapping.h>
+#include <linux/of_address.h>
+
+#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

+ 32 - 0
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 <linux/version.h>
+
+#if KERNEL_VERSION(5, 4, 0) >= LINUX_VERSION_CODE
+
+#include <linux/msm_ion.h>
+#include <linux/ion.h>
+
+#else
+
+#include <linux/msm_ion.h>
+#include <linux/ion_kernel.h>
+
+#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_ */