[PATCH v4 5/7] iommu: Add Apple DART driver
Mark Kettenis
kettenis at openbsd.org
Sat Oct 23 16:58:05 CEST 2021
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 at openbsd.org>
Reviewed-by: Simon Glass <sjg at chromium.org>
---
arch/arm/Kconfig | 1 +
drivers/iommu/Kconfig | 10 +++++++
drivers/iommu/Makefile | 1 +
drivers/iommu/apple_dart.c | 59 ++++++++++++++++++++++++++++++++++++++
4 files changed, 71 insertions(+)
create mode 100644 drivers/iommu/apple_dart.c
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 24c68cff80..ce5c3b754c 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -933,6 +933,7 @@ config ARCH_APPLE
select DM_SERIAL
select DM_USB
select DM_VIDEO
+ select IOMMU
select LINUX_KERNEL_IMAGE_HEADER
select OF_CONTROL
select OF_BOARD
diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
index 3e35ce8fcc..dabc1f900d 100644
--- a/drivers/iommu/Kconfig
+++ b/drivers/iommu/Kconfig
@@ -14,4 +14,14 @@ config IOMMU
memory if the IOMMU has been programmed to allow access to
that memory.
+config APPLE_DART
+ bool "Apple DART support"
+ depends on IOMMU && ARCH_APPLE
+ default y
+ help
+ Enable support for the DART on Apple SoCs. The DART is Apple's
+ IOMMU implementation. The driver performs the necessary
+ configuration to put the DART into bypass mode such that it can
+ be used transparently by U-Boot.
+
endmenu
diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile
index af1c6bbb7a..e3e0900e17 100644
--- a/drivers/iommu/Makefile
+++ b/drivers/iommu/Makefile
@@ -2,4 +2,5 @@
obj-$(CONFIG_IOMMU) += iommu-uclass.o
+obj-$(CONFIG_APPLE_DART) += apple_dart.o
obj-$(CONFIG_SANDBOX) += sandbox_iommu.o
diff --git a/drivers/iommu/apple_dart.c b/drivers/iommu/apple_dart.c
new file mode 100644
index 0000000000..ff8c5fa62c
--- /dev/null
+++ b/drivers/iommu/apple_dart.c
@@ -0,0 +1,59 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2021 Mark Kettenis <kettenis at 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
+};
--
2.33.0
More information about the U-Boot
mailing list