#include "msm_iommu_hw-v1.h"
#include <linux/qcom_iommu.h>
#include "msm_iommu_perfmon.h"
+#include <linux/qcom_scm.h>
static const struct of_device_id msm_iommu_ctx_match_table[];
return 0;
}
+#define SCM_SVC_MP 0xc
+#define MAXIMUM_VIRT_SIZE (300 * SZ_1M)
+#define MAKE_VERSION(major, minor, patch) \
+ (((major & 0x3FF) << 22) | ((minor & 0x3FF) << 12) | (patch & 0xFFF))
+
+static int msm_iommu_sec_ptbl_init(struct device *dev)
+{
+ int psize[2] = {0, 0};
+ unsigned int spare = 0;
+ int ret;
+ int version;
+ void *cpu_addr;
+ dma_addr_t paddr;
+ DEFINE_DMA_ATTRS(attrs);
+ static bool allocated = false;
+
+ if (allocated)
+ return 0;
+
+ version = qcom_scm_get_feat_version(SCM_SVC_MP);
+
+ if (version >= MAKE_VERSION(1, 1, 1)) {
+ ret = qcom_scm_iommu_set_cp_pool_size(MAXIMUM_VIRT_SIZE, 0);
+ if (ret) {
+ dev_err(dev, "failed setting max virtual size (%d)\n",
+ ret);
+ return ret;
+ }
+ }
+
+ ret = qcom_scm_iommu_secure_ptbl_size(spare, psize);
+ if (ret) {
+ dev_err(dev, "failed to get iommu secure pgtable size (%d)\n",
+ ret);
+ return ret;
+ }
+
+ if (psize[1]) {
+ dev_err(dev, "failed to get iommu secure pgtable size (%d)\n",
+ ret);
+ return psize[1];
+ }
+
+ dev_info(dev, "iommu sec: pgtable size: %d\n", psize[0]);
+
+ dma_set_attr(DMA_ATTR_NO_KERNEL_MAPPING, &attrs);
+
+ cpu_addr = dma_alloc_attrs(dev, psize[0], &paddr, GFP_KERNEL, &attrs);
+ if (!cpu_addr) {
+ dev_err(dev, "failed to allocate %d bytes for pgtable\n",
+ psize[0]);
+ return -ENOMEM;
+ }
+
+ ret = qcom_scm_iommu_secure_ptbl_init(paddr, psize[0], spare);
+ if (ret) {
+ dev_err(dev, "failed to init iommu pgtable (%d)\n", ret);
+ goto free_mem;
+ }
+
+ allocated = true;
+
+ return 0;
+
+free_mem:
+ dma_free_attrs(dev, psize[0], cpu_addr, paddr, &attrs);
+ return ret;
+}
+
static int msm_iommu_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
dev_info(dev, "device %s (model: %d) mapped at %p, with %d ctx banks\n",
drvdata->name, drvdata->model, drvdata->base, drvdata->ncb);
+ if (drvdata->sec_id != -1) {
+ ret = msm_iommu_sec_ptbl_init(dev);
+ if (ret)
+ return ret;
+ }
+
platform_set_drvdata(pdev, drvdata);
pmon_info = msm_iommu_pm_alloc(dev);
/* commands for SCM_SVC_UTIL */
#define IOMMU_DUMP_SMMU_FAULT_REGS 0X0C
-#define MAXIMUM_VIRT_SIZE (300*SZ_1M)
-
-
-#define MAKE_VERSION(major, minor, patch) \
- (((major & 0x3FF) << 22) | ((minor & 0x3FF) << 12) | (patch & 0xFFF))
-
+#define SCM_SVC_MP 0xc
static struct iommu_access_ops *iommu_access_ops;
static int is_secure;
return ret;
}
-#define SCM_SVC_MP 0xc
-
-static int msm_iommu_sec_ptbl_init(void)
-{
- struct device_node *np;
- int psize[2] = {0, 0};
- unsigned int spare = 0;
- int ret;
- int version;
- /* Use a dummy device for dma_alloc_attrs allocation */
- struct device dev = { 0 };
- void *cpu_addr;
- dma_addr_t paddr;
- DEFINE_DMA_ATTRS(attrs);
-
- for_each_matching_node(np, msm_smmu_list)
- if (of_find_property(np, "qcom,iommu-secure-id", NULL) &&
- of_device_is_available(np))
- break;
-
- if (!np)
- return 0;
-
- of_node_put(np);
-
- version = qcom_scm_get_feat_version(SCM_SVC_MP);
-
- if (version >= MAKE_VERSION(1, 1, 1)) {
- ret = qcom_scm_iommu_set_cp_pool_size(MAXIMUM_VIRT_SIZE, 0);
- if (ret) {
- pr_err("scm call IOMMU_SET_CP_POOL_SIZE failed\n");
- goto fail;
- }
- }
-
- ret = qcom_scm_iommu_secure_ptbl_size(spare, psize);
- if (ret) {
- pr_err("scm call IOMMU_SECURE_PTBL_SIZE failed\n");
- goto fail;
- }
-
- pr_err("iommu sec: psize[0]: %d, psize[1]: %d\n", psize[0], psize[1]);
-
- if (psize[1]) {
- pr_err("scm call IOMMU_SECURE_PTBL_SIZE failed\n");
- goto fail;
- }
-
- dma_set_attr(DMA_ATTR_NO_KERNEL_MAPPING, &attrs);
- dev.coherent_dma_mask = DMA_BIT_MASK(sizeof(dma_addr_t) * 8);
-
- cpu_addr = dma_alloc_attrs(&dev, psize[0], &paddr, GFP_KERNEL, &attrs);
- if (!cpu_addr) {
- pr_err("%s: Failed to allocate %d bytes for PTBL\n",
- __func__, psize[0]);
- ret = -ENOMEM;
- goto fail;
- }
-
- ret = qcom_scm_iommu_secure_ptbl_init(paddr, psize[0], spare);
-
- if (ret) {
- pr_err("scm call IOMMU_SECURE_PTBL_INIT failed (%d)\n", ret);
- goto fail_mem;
- }
-
- return 0;
-
-fail_mem:
- dma_free_attrs(&dev, psize[0], cpu_addr, paddr, &attrs);
-fail:
- return ret;
-}
-
int msm_iommu_sec_program_iommu(struct msm_iommu_drvdata *drvdata,
struct msm_iommu_ctx_drvdata *ctx_drvdata)
{
return ret;
}
- ret = msm_iommu_sec_ptbl_init();
-
- return ret;
+ return 0;
}
subsys_initcall(msm_iommu_sec_init);