aboutsummaryrefslogtreecommitdiff
path: root/drivers/iommu/apple_dart.c
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@openbsd.org>2021-10-23 16:58:05 +0200
committerTom Rini <trini@konsulko.com>2021-10-31 08:46:44 -0400
commit785cfde5b3a0d24dc293792c7c277a091c46ef3a (patch)
treea18346d77b342cf564d0116060c95202ff07a673 /drivers/iommu/apple_dart.c
parentd520e1fb7276d9d14f3cf35e028c5fdb934b049c (diff)
downloadu-boot-785cfde5b3a0d24dc293792c7c277a091c46ef3a.zip
u-boot-785cfde5b3a0d24dc293792c7c277a091c46ef3a.tar.gz
u-boot-785cfde5b3a0d24dc293792c7c277a091c46ef3a.tar.bz2
iommu: Add Apple DART driver
The DART is an IOMMU that is used on Apple's M1 SoC. This driver configures the DART such that it operates in bypass mode which is enough to support DMA for the USB3 ports integrated on the SoC. Signed-off-by: Mark Kettenis <kettenis@openbsd.org> Reviewed-by: Simon Glass <sjg@chromium.org>
Diffstat (limited to 'drivers/iommu/apple_dart.c')
-rw-r--r--drivers/iommu/apple_dart.c59
1 files changed, 59 insertions, 0 deletions
diff --git a/drivers/iommu/apple_dart.c b/drivers/iommu/apple_dart.c
new file mode 100644
index 0000000..ff8c5fa
--- /dev/null
+++ b/drivers/iommu/apple_dart.c
@@ -0,0 +1,59 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2021 Mark Kettenis <kettenis@openbsd.org>
+ */
+
+#include <common.h>
+#include <cpu_func.h>
+#include <dm.h>
+#include <asm/io.h>
+
+#define DART_PARAMS2 0x0004
+#define DART_PARAMS2_BYPASS_SUPPORT BIT(0)
+#define DART_TLB_OP 0x0020
+#define DART_TLB_OP_OPMASK (0xfff << 20)
+#define DART_TLB_OP_FLUSH (0x001 << 20)
+#define DART_TLB_OP_BUSY BIT(2)
+#define DART_TLB_OP_SIDMASK 0x0034
+#define DART_ERROR_STATUS 0x0040
+#define DART_TCR(sid) (0x0100 + 4 * (sid))
+#define DART_TCR_TRANSLATE_ENABLE BIT(7)
+#define DART_TCR_BYPASS_DART BIT(8)
+#define DART_TCR_BYPASS_DAPF BIT(12)
+#define DART_TTBR(sid, idx) (0x0200 + 16 * (sid) + 4 * (idx))
+#define DART_TTBR_VALID BIT(31)
+#define DART_TTBR_SHIFT 12
+
+static int apple_dart_probe(struct udevice *dev)
+{
+ void *base;
+ int sid, i;
+
+ base = dev_read_addr_ptr(dev);
+ if (!base)
+ return -EINVAL;
+
+ u32 params2 = readl(base + DART_PARAMS2);
+ if (params2 & DART_PARAMS2_BYPASS_SUPPORT) {
+ for (sid = 0; sid < 16; sid++) {
+ writel(DART_TCR_BYPASS_DART | DART_TCR_BYPASS_DAPF,
+ base + DART_TCR(sid));
+ for (i = 0; i < 4; i++)
+ writel(0, base + DART_TTBR(sid, i));
+ }
+ }
+
+ return 0;
+}
+
+static const struct udevice_id apple_dart_ids[] = {
+ { .compatible = "apple,t8103-dart" },
+ { /* sentinel */ }
+};
+
+U_BOOT_DRIVER(apple_dart) = {
+ .name = "apple_dart",
+ .id = UCLASS_IOMMU,
+ .of_match = apple_dart_ids,
+ .probe = apple_dart_probe
+};