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 <isaacm@codeaurora.org>
Signed-off-by: Karthik Jayakumar <kjayakum@codeaurora.org>
This commit is contained in:
Karthik Jayakumar
2019-11-04 15:24:08 -08:00
parent 8a40a542fd
commit 50c8c09ead
6 changed files with 129 additions and 34 deletions

View File

@@ -9,7 +9,7 @@ ifneq (,$(filter $(CONFIG_MSM_GLOBAL_SYNX), y m))
ccflags-y += -I$(srctree)/drivers/media/platform/msm/synx ccflags-y += -I$(srctree)/drivers/media/platform/msm/synx
endif endif
subdir-ccflags-y += -I$(srctree)/techpack/camera/include/uapi/camera ccflags-y += -I$(srctree)/techpack/camera/include/uapi/camera
ccflags-y += -I$(srctree) ccflags-y += -I$(srctree)
camera-y := \ camera-y := \
@@ -26,6 +26,7 @@ camera-y := \
cam_utils/cam_debug_util.o \ cam_utils/cam_debug_util.o \
cam_utils/cam_trace.o \ cam_utils/cam_trace.o \
cam_utils/cam_common_util.o \ cam_utils/cam_common_util.o \
cam_utils/cam_compat.o \
cam_core/cam_context.o \ cam_core/cam_context.o \
cam_core/cam_context_utils.o \ cam_core/cam_context_utils.o \
cam_core/cam_node.o \ cam_core/cam_node.o \

View File

@@ -3,6 +3,7 @@
ccflags-y += -I$(srctree)/techpack/camera/drivers/cam_core 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_smmu/
ccflags-y += -I$(srctree)/techpack/camera/drivers/cam_utils ccflags-y += -I$(srctree)/techpack/camera/drivers/cam_utils
ccflags-y += -I$(srctree)/include/
ccflags-y += -I$(srctree)/ ccflags-y += -I$(srctree)/
obj-$(CONFIG_SPECTRA_CAMERA) += cam_req_mgr_core.o\ obj-$(CONFIG_SPECTRA_CAMERA) += cam_req_mgr_core.o\

View File

@@ -6,11 +6,15 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/types.h> #include <linux/types.h>
#include <linux/mutex.h> #include <linux/mutex.h>
#include <linux/msm_ion.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/ion_kernel.h>
#include <linux/dma-buf.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_req_mgr_util.h"
#include "cam_mem_mgr.h" #include "cam_mem_mgr.h"
#include "cam_smmu_api.h" #include "cam_smmu_api.h"

View File

@@ -10,13 +10,18 @@
#include <linux/iommu.h> #include <linux/iommu.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/dma-mapping.h> #include <linux/dma-mapping.h>
#include <linux/of_address.h>
#include <linux/msm_dma_iommu_mapping.h> #include <linux/msm_dma_iommu_mapping.h>
#include <linux/workqueue.h> #include <linux/workqueue.h>
#include <linux/genalloc.h> #include <linux/genalloc.h>
#include <linux/debugfs.h> #include <linux/debugfs.h>
#include <soc/qcom/scm.h> #include <soc/qcom/scm.h>
#include <soc/qcom/secure_buffer.h> #include <soc/qcom/secure_buffer.h>
#include <media/cam_req_mgr.h> #include <media/cam_req_mgr.h>
#include "cam_compat.h"
#include "cam_smmu_api.h" #include "cam_smmu_api.h"
#include "cam_debug_util.h" #include "cam_debug_util.h"
@@ -36,13 +41,7 @@
static int g_num_pf_handled = 4; static int g_num_pf_handled = 4;
module_param(g_num_pf_handled, int, 0644); module_param(g_num_pf_handled, int, 0644);
struct firmware_alloc_info { struct cam_fw_alloc_info icp_fw;
struct device *fw_dev;
void *fw_kva;
dma_addr_t fw_dma_hdl;
};
struct firmware_alloc_info icp_fw;
struct cam_smmu_work_payload { struct cam_smmu_work_payload {
int idx; 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; firmware_start = iommu_cb_set.cb_info[idx].firmware_info.iova_start;
CAM_DBG(CAM_SMMU, "Firmware area len from DT = %zu", firmware_len); CAM_DBG(CAM_SMMU, "Firmware area len from DT = %zu", firmware_len);
icp_fw.fw_kva = dma_alloc_coherent(icp_fw.fw_dev, rc = cam_reserve_icp_fw(&icp_fw, firmware_len);
firmware_len, if (rc)
&icp_fw.fw_dma_hdl,
GFP_KERNEL);
if (!icp_fw.fw_kva) {
CAM_ERR(CAM_SMMU, "FW memory alloc failed");
rc = -ENOMEM;
goto unlock_and_end; goto unlock_and_end;
} else { else
CAM_DBG(CAM_SMMU, "DMA alloc returned fw = %pK, hdl = %pK", 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; domain = iommu_cb_set.cb_info[idx].domain;
rc = iommu_map(domain, rc = iommu_map(domain,
firmware_start, firmware_start,
icp_fw.fw_dma_hdl, (phys_addr_t) icp_fw.fw_hdl,
firmware_len, firmware_len,
IOMMU_READ|IOMMU_WRITE|IOMMU_PRIV); IOMMU_READ|IOMMU_WRITE|IOMMU_PRIV);
@@ -1207,10 +1200,7 @@ int cam_smmu_alloc_firmware(int32_t smmu_hdl,
return rc; return rc;
alloc_fail: alloc_fail:
dma_free_coherent(icp_fw.fw_dev, cam_unreserve_icp_fw(&icp_fw, firmware_len);
firmware_len,
icp_fw.fw_kva,
icp_fw.fw_dma_hdl);
unlock_and_end: unlock_and_end:
mutex_unlock(&iommu_cb_set.cb_info[idx].lock); mutex_unlock(&iommu_cb_set.cb_info[idx].lock);
end: end:
@@ -1270,13 +1260,10 @@ int cam_smmu_dealloc_firmware(int32_t smmu_hdl)
rc = -EINVAL; rc = -EINVAL;
} }
dma_free_coherent(icp_fw.fw_dev, cam_unreserve_icp_fw(&icp_fw, firmware_len);
firmware_len,
icp_fw.fw_kva,
icp_fw.fw_dma_hdl);
icp_fw.fw_kva = 0; icp_fw.fw_kva = NULL;
icp_fw.fw_dma_hdl = 0; icp_fw.fw_hdl = 0;
iommu_cb_set.cb_info[idx].is_fw_allocated = false; 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) 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; cb->domain = NULL;
}
if (cb->shared_support) { if (cb->shared_support) {
gen_pool_destroy(cb->shared_mem_pool); 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")) { if (of_device_is_compatible(dev->of_node, "qcom,msm-cam-smmu-fw-dev")) {
icp_fw.fw_dev = &pdev->dev; icp_fw.fw_dev = &pdev->dev;
icp_fw.fw_kva = NULL; icp_fw.fw_kva = NULL;
icp_fw.fw_dma_hdl = 0; icp_fw.fw_hdl = 0;
return rc; return rc;
} }

View File

@@ -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

View File

@@ -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_ */