]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
iommu/arm-smmu: Add implementation infrastructure
authorRobin Murphy <robin.murphy@arm.com>
Thu, 15 Aug 2019 18:37:33 +0000 (19:37 +0100)
committerWill Deacon <will@kernel.org>
Mon, 19 Aug 2019 15:52:47 +0000 (16:52 +0100)
Add some nascent infrastructure for handling implementation-specific
details outside the flow of the architectural code. This will allow us
to keep mutually-incompatible vendor-specific hooks in their own files
where the respective interested parties can maintain them with minimal
chance of conflicts. As somewhat of a template, we'll start with a
general place to collect the relatively trivial existing quirks.

Signed-off-by: Robin Murphy <robin.murphy@arm.com>
Signed-off-by: Will Deacon <will@kernel.org>
MAINTAINERS
drivers/iommu/Makefile
drivers/iommu/arm-smmu-impl.c [new file with mode: 0644]
drivers/iommu/arm-smmu.c
drivers/iommu/arm-smmu.h

index 783569e3c4b48752c3555e9bee6fbc87adad5117..289fb0654c8b109b7796e26c1109c023235f5217 100644 (file)
@@ -1350,8 +1350,7 @@ M:        Will Deacon <will@kernel.org>
 R:     Robin Murphy <robin.murphy@arm.com>
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 S:     Maintained
-F:     drivers/iommu/arm-smmu.c
-F:     drivers/iommu/arm-smmu-v3.c
+F:     drivers/iommu/arm-smmu*
 F:     drivers/iommu/io-pgtable-arm.c
 F:     drivers/iommu/io-pgtable-arm-v7s.c
 
index f13f36ae1af652836254ba07315f99303fba6f88..a2729aadd300fa7b9f20d40edaa46d61f1a3b0c7 100644 (file)
@@ -13,7 +13,7 @@ obj-$(CONFIG_MSM_IOMMU) += msm_iommu.o
 obj-$(CONFIG_AMD_IOMMU) += amd_iommu.o amd_iommu_init.o
 obj-$(CONFIG_AMD_IOMMU_DEBUGFS) += amd_iommu_debugfs.o
 obj-$(CONFIG_AMD_IOMMU_V2) += amd_iommu_v2.o
-obj-$(CONFIG_ARM_SMMU) += arm-smmu.o
+obj-$(CONFIG_ARM_SMMU) += arm-smmu.o arm-smmu-impl.o
 obj-$(CONFIG_ARM_SMMU_V3) += arm-smmu-v3.o
 obj-$(CONFIG_DMAR_TABLE) += dmar.o
 obj-$(CONFIG_INTEL_IOMMU) += intel-iommu.o intel-pasid.o
diff --git a/drivers/iommu/arm-smmu-impl.c b/drivers/iommu/arm-smmu-impl.c
new file mode 100644 (file)
index 0000000..efeb6d7
--- /dev/null
@@ -0,0 +1,13 @@
+// SPDX-License-Identifier: GPL-2.0-only
+// Miscellaneous Arm SMMU implementation and integration quirks
+// Copyright (C) 2019 Arm Limited
+
+#define pr_fmt(fmt) "arm-smmu: " fmt
+
+#include "arm-smmu.h"
+
+
+struct arm_smmu_device *arm_smmu_impl_init(struct arm_smmu_device *smmu)
+{
+       return smmu;
+}
index f3b8301a305925b4e08962a6f3707f5cde7b119d..1e81531828301dc7813b3f40895f021fb076ae2c 100644 (file)
@@ -19,7 +19,6 @@
 
 #include <linux/acpi.h>
 #include <linux/acpi_iort.h>
-#include <linux/atomic.h>
 #include <linux/bitfield.h>
 #include <linux/delay.h>
 #include <linux/dma-iommu.h>
@@ -29,7 +28,6 @@
 #include <linux/io.h>
 #include <linux/io-64-nonatomic-hi-lo.h>
 #include <linux/io-pgtable.h>
-#include <linux/iommu.h>
 #include <linux/iopoll.h>
 #include <linux/init.h>
 #include <linux/moduleparam.h>
@@ -41,7 +39,6 @@
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
 #include <linux/slab.h>
-#include <linux/spinlock.h>
 
 #include <linux/amba/bus.h>
 #include <linux/fsl/mc.h>
@@ -66,9 +63,6 @@
 #define TLB_LOOP_TIMEOUT               1000000 /* 1s! */
 #define TLB_SPIN_COUNT                 10
 
-/* Maximum number of context banks per SMMU */
-#define ARM_SMMU_MAX_CBS               128
-
 #define MSI_IOVA_BASE                  0x8000000
 #define MSI_IOVA_LENGTH                        0x100000
 
@@ -86,19 +80,6 @@ module_param(disable_bypass, bool, S_IRUGO);
 MODULE_PARM_DESC(disable_bypass,
        "Disable bypass streams such that incoming transactions from devices that are not attached to an iommu domain will report an abort back to the device and will not be allowed to pass through the SMMU.");
 
-enum arm_smmu_arch_version {
-       ARM_SMMU_V1,
-       ARM_SMMU_V1_64K,
-       ARM_SMMU_V2,
-};
-
-enum arm_smmu_implementation {
-       GENERIC_SMMU,
-       ARM_MMU500,
-       CAVIUM_SMMUV2,
-       QCOM_SMMUV2,
-};
-
 struct arm_smmu_s2cr {
        struct iommu_group              *group;
        int                             count;
@@ -136,65 +117,6 @@ struct arm_smmu_master_cfg {
 #define for_each_cfg_sme(fw, i, idx) \
        for (i = 0; idx = fwspec_smendx(fw, i), i < fw->num_ids; ++i)
 
-struct arm_smmu_device {
-       struct device                   *dev;
-
-       void __iomem                    *base;
-       unsigned int                    numpage;
-       unsigned int                    pgshift;
-
-#define ARM_SMMU_FEAT_COHERENT_WALK    (1 << 0)
-#define ARM_SMMU_FEAT_STREAM_MATCH     (1 << 1)
-#define ARM_SMMU_FEAT_TRANS_S1         (1 << 2)
-#define ARM_SMMU_FEAT_TRANS_S2         (1 << 3)
-#define ARM_SMMU_FEAT_TRANS_NESTED     (1 << 4)
-#define ARM_SMMU_FEAT_TRANS_OPS                (1 << 5)
-#define ARM_SMMU_FEAT_VMID16           (1 << 6)
-#define ARM_SMMU_FEAT_FMT_AARCH64_4K   (1 << 7)
-#define ARM_SMMU_FEAT_FMT_AARCH64_16K  (1 << 8)
-#define ARM_SMMU_FEAT_FMT_AARCH64_64K  (1 << 9)
-#define ARM_SMMU_FEAT_FMT_AARCH32_L    (1 << 10)
-#define ARM_SMMU_FEAT_FMT_AARCH32_S    (1 << 11)
-#define ARM_SMMU_FEAT_EXIDS            (1 << 12)
-       u32                             features;
-
-#define ARM_SMMU_OPT_SECURE_CFG_ACCESS (1 << 0)
-       u32                             options;
-       enum arm_smmu_arch_version      version;
-       enum arm_smmu_implementation    model;
-
-       u32                             num_context_banks;
-       u32                             num_s2_context_banks;
-       DECLARE_BITMAP(context_map, ARM_SMMU_MAX_CBS);
-       struct arm_smmu_cb              *cbs;
-       atomic_t                        irptndx;
-
-       u32                             num_mapping_groups;
-       u16                             streamid_mask;
-       u16                             smr_mask_mask;
-       struct arm_smmu_smr             *smrs;
-       struct arm_smmu_s2cr            *s2crs;
-       struct mutex                    stream_map_mutex;
-
-       unsigned long                   va_size;
-       unsigned long                   ipa_size;
-       unsigned long                   pa_size;
-       unsigned long                   pgsize_bitmap;
-
-       u32                             num_global_irqs;
-       u32                             num_context_irqs;
-       unsigned int                    *irqs;
-       struct clk_bulk_data            *clks;
-       int                             num_clks;
-
-       u32                             cavium_id_base; /* Specific to Cavium */
-
-       spinlock_t                      global_sync_lock;
-
-       /* IOMMU core code handle */
-       struct iommu_device             iommu;
-};
-
 enum arm_smmu_context_fmt {
        ARM_SMMU_CTX_FMT_NONE,
        ARM_SMMU_CTX_FMT_AARCH64,
@@ -2233,6 +2155,10 @@ static int arm_smmu_device_probe(struct platform_device *pdev)
        if (err)
                return err;
 
+       smmu = arm_smmu_impl_init(smmu);
+       if (IS_ERR(smmu))
+               return PTR_ERR(smmu);
+
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        ioaddr = res->start;
        smmu->base = devm_ioremap_resource(dev, res);
index ccc3097a4247eac6a10cac9839382b51c27a2e7f..6fea0b0b7e519dec922557563353e01df8a65e2d 100644 (file)
 #ifndef _ARM_SMMU_H
 #define _ARM_SMMU_H
 
+#include <linux/atomic.h>
 #include <linux/bits.h>
+#include <linux/clk.h>
+#include <linux/device.h>
+#include <linux/iommu.h>
+#include <linux/mutex.h>
+#include <linux/spinlock.h>
+#include <linux/types.h>
 
 /* Configuration registers */
 #define ARM_SMMU_GR0_sCR0              0x0
@@ -194,4 +201,86 @@ enum arm_smmu_cbar_type {
 #define ARM_SMMU_CB_ATSR               0x8f0
 #define ATSR_ACTIVE                    BIT(0)
 
+
+/* Maximum number of context banks per SMMU */
+#define ARM_SMMU_MAX_CBS               128
+
+
+/* Shared driver definitions */
+enum arm_smmu_arch_version {
+       ARM_SMMU_V1,
+       ARM_SMMU_V1_64K,
+       ARM_SMMU_V2,
+};
+
+enum arm_smmu_implementation {
+       GENERIC_SMMU,
+       ARM_MMU500,
+       CAVIUM_SMMUV2,
+       QCOM_SMMUV2,
+};
+
+struct arm_smmu_device {
+       struct device                   *dev;
+
+       void __iomem                    *base;
+       unsigned int                    numpage;
+       unsigned int                    pgshift;
+
+#define ARM_SMMU_FEAT_COHERENT_WALK    (1 << 0)
+#define ARM_SMMU_FEAT_STREAM_MATCH     (1 << 1)
+#define ARM_SMMU_FEAT_TRANS_S1         (1 << 2)
+#define ARM_SMMU_FEAT_TRANS_S2         (1 << 3)
+#define ARM_SMMU_FEAT_TRANS_NESTED     (1 << 4)
+#define ARM_SMMU_FEAT_TRANS_OPS                (1 << 5)
+#define ARM_SMMU_FEAT_VMID16           (1 << 6)
+#define ARM_SMMU_FEAT_FMT_AARCH64_4K   (1 << 7)
+#define ARM_SMMU_FEAT_FMT_AARCH64_16K  (1 << 8)
+#define ARM_SMMU_FEAT_FMT_AARCH64_64K  (1 << 9)
+#define ARM_SMMU_FEAT_FMT_AARCH32_L    (1 << 10)
+#define ARM_SMMU_FEAT_FMT_AARCH32_S    (1 << 11)
+#define ARM_SMMU_FEAT_EXIDS            (1 << 12)
+       u32                             features;
+
+#define ARM_SMMU_OPT_SECURE_CFG_ACCESS (1 << 0)
+       u32                             options;
+       enum arm_smmu_arch_version      version;
+       enum arm_smmu_implementation    model;
+
+       u32                             num_context_banks;
+       u32                             num_s2_context_banks;
+       DECLARE_BITMAP(context_map, ARM_SMMU_MAX_CBS);
+       struct arm_smmu_cb              *cbs;
+       atomic_t                        irptndx;
+
+       u32                             num_mapping_groups;
+       u16                             streamid_mask;
+       u16                             smr_mask_mask;
+       struct arm_smmu_smr             *smrs;
+       struct arm_smmu_s2cr            *s2crs;
+       struct mutex                    stream_map_mutex;
+
+       unsigned long                   va_size;
+       unsigned long                   ipa_size;
+       unsigned long                   pa_size;
+       unsigned long                   pgsize_bitmap;
+
+       u32                             num_global_irqs;
+       u32                             num_context_irqs;
+       unsigned int                    *irqs;
+       struct clk_bulk_data            *clks;
+       int                             num_clks;
+
+       u32                             cavium_id_base; /* Specific to Cavium */
+
+       spinlock_t                      global_sync_lock;
+
+       /* IOMMU core code handle */
+       struct iommu_device             iommu;
+};
+
+
+/* Implementation details, yay! */
+struct arm_smmu_device *arm_smmu_impl_init(struct arm_smmu_device *smmu);
+
 #endif /* _ARM_SMMU_H */