summaryrefslogtreecommitdiff
path: root/drivers/iommu/arm-smmu-impl.c
diff options
context:
space:
mode:
authorRobin Murphy <robin.murphy@arm.com>2019-08-15 19:37:34 +0100
committerWill Deacon <will@kernel.org>2019-08-19 16:52:48 +0100
commit6d7dff62afb0c7a880860148a8984d0cddc6e589 (patch)
tree49988f93ab2d29ca54d407ce4f6e348692e39aef /drivers/iommu/arm-smmu-impl.c
parentfc058d37b3450db3e146d475f85e6afd51888997 (diff)
iommu/arm-smmu: Move Secure access quirk to implementation
Move detection of the Secure access quirk to its new home, trimming it down in the process - time has proven that boolean DT flags are neither ideal nor necessarily sufficient, so it's highly unlikely we'll ever add more, let alone enough to justify the frankly overengineered parsing machinery. Signed-off-by: Robin Murphy <robin.murphy@arm.com> Signed-off-by: Will Deacon <will@kernel.org>
Diffstat (limited to 'drivers/iommu/arm-smmu-impl.c')
-rw-r--r--drivers/iommu/arm-smmu-impl.c44
1 files changed, 44 insertions, 0 deletions
diff --git a/drivers/iommu/arm-smmu-impl.c b/drivers/iommu/arm-smmu-impl.c
index efeb6d78da17..0657c85580cb 100644
--- a/drivers/iommu/arm-smmu-impl.c
+++ b/drivers/iommu/arm-smmu-impl.c
@@ -4,10 +4,54 @@
#define pr_fmt(fmt) "arm-smmu: " fmt
+#include <linux/of.h>
+
#include "arm-smmu.h"
+static int arm_smmu_gr0_ns(int offset)
+{
+ switch(offset) {
+ case ARM_SMMU_GR0_sCR0:
+ case ARM_SMMU_GR0_sACR:
+ case ARM_SMMU_GR0_sGFSR:
+ case ARM_SMMU_GR0_sGFSYNR0:
+ case ARM_SMMU_GR0_sGFSYNR1:
+ case ARM_SMMU_GR0_sGFSYNR2:
+ return offset + 0x400;
+ default:
+ return offset;
+ }
+}
+
+static u32 arm_smmu_read_ns(struct arm_smmu_device *smmu, int page,
+ int offset)
+{
+ if (page == ARM_SMMU_GR0)
+ offset = arm_smmu_gr0_ns(offset);
+ return readl_relaxed(arm_smmu_page(smmu, page) + offset);
+}
+
+static void arm_smmu_write_ns(struct arm_smmu_device *smmu, int page,
+ int offset, u32 val)
+{
+ if (page == ARM_SMMU_GR0)
+ offset = arm_smmu_gr0_ns(offset);
+ writel_relaxed(val, arm_smmu_page(smmu, page) + offset);
+}
+
+/* Since we don't care for sGFAR, we can do without 64-bit accessors */
+const struct arm_smmu_impl calxeda_impl = {
+ .read_reg = arm_smmu_read_ns,
+ .write_reg = arm_smmu_write_ns,
+};
+
+
struct arm_smmu_device *arm_smmu_impl_init(struct arm_smmu_device *smmu)
{
+ if (of_property_read_bool(smmu->dev->of_node,
+ "calxeda,smmu-secure-config-access"))
+ smmu->impl = &calxeda_impl;
+
return smmu;
}