]> git.dujemihanovic.xyz Git - u-boot.git/commitdiff
iommu: Add Apple DART driver
authorMark Kettenis <kettenis@openbsd.org>
Sat, 23 Oct 2021 14:58:05 +0000 (16:58 +0200)
committerTom Rini <trini@konsulko.com>
Sun, 31 Oct 2021 12:46:44 +0000 (08:46 -0400)
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>
arch/arm/Kconfig
drivers/iommu/Kconfig
drivers/iommu/Makefile
drivers/iommu/apple_dart.c [new file with mode: 0644]

index 293e3e392835e9bb604dfd4013908ad960af46fa..b4808d4c752f45029be7b28a8663aa27af12acda 100644 (file)
@@ -931,6 +931,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
index 3e35ce8fcc8586f93202e69400edc7dc79e2e4cd..dabc1f900d583aea386454578088bc0b2c269f26 100644 (file)
@@ -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
index af1c6bbb7ac54f0c9b263f534110b484c528999c..e3e0900e1703ce16291ac709f5d0a57e7dc2c919 100644 (file)
@@ -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 (file)
index 0000000..ff8c5fa
--- /dev/null
@@ -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
+};