[PATCH v2 0/7] Apple M1 Support

This series adds basic support for Apple's M1 SoC to U-Boot. This builds a basic U-Boot that can be used as a payload for the m1n1 boot loader being developed by the Asahi Linux project.
The goal here is to privide an UEFI interface on these machines that allows booting various open source OSes. This initial series provides support for the serial port, framebuffer and the USB 3.1 Type-C ports. It can boot a support OS (e.g. OpenBSD/arm64) from a USB disk.
This version attempts to address most comments. It doesn't add a proper WDT/sysreset driver yet since I prefer to do that once the device tree bindings for that have been ironed out.
ChangeLog:
v2: - Add IOMMU uclass and use it for the DART driver - Cut back DART driver to only support bypass mode - Rework the S5P serial support to use more DT stuff - Update preliminary device trees
Mark Kettenis (7): iommu: Add IOMMU uclass test: Add tests for IOMMU uclass arm: apple: Add initial support for Apple's M1 SoC serial: s5p: Add Apple M1 support iommu: Add Apple DART driver arm: dts: apple: Add preliminary device trees doc: board: apple: Add Apple M1 documentation
arch/arm/Kconfig | 23 + arch/arm/Makefile | 1 + arch/arm/dts/Makefile | 4 + arch/arm/dts/t8103-j274.dts | 135 +++++ arch/arm/dts/t8103-j293.dts | 97 +++ arch/arm/dts/t8103.dtsi | 560 ++++++++++++++++++ arch/arm/include/asm/arch-m1/uart.h | 41 ++ arch/arm/mach-apple/Kconfig | 18 + arch/arm/mach-apple/Makefile | 4 + arch/arm/mach-apple/board.c | 161 +++++ arch/arm/mach-apple/lowlevel_init.S | 17 + arch/sandbox/dts/test.dts | 6 + configs/apple_m1_defconfig | 19 + configs/sandbox64_defconfig | 1 + configs/sandbox_defconfig | 1 + configs/sandbox_flattree_defconfig | 1 + configs/sandbox_noinst_defconfig | 1 + configs/sandbox_spl_defconfig | 1 + doc/board/apple/index.rst | 9 + doc/board/apple/m1.rst | 56 ++ doc/board/index.rst | 1 + drivers/Kconfig | 2 + drivers/Makefile | 1 + drivers/core/device.c | 8 + drivers/iommu/Kconfig | 23 + drivers/iommu/Makefile | 6 + drivers/iommu/apple_dart.c | 59 ++ drivers/iommu/iommu-uclass.c | 45 ++ drivers/iommu/sandbox_iommu.c | 18 + drivers/serial/Kconfig | 4 +- drivers/serial/serial_s5p.c | 104 +++- include/configs/apple.h | 38 ++ include/dm/uclass-id.h | 1 + .../interrupt-controller/apple-aic.h | 15 + include/dt-bindings/pinctrl/apple.h | 13 + include/dt-bindings/spmi/spmi.h | 10 + include/iommu.h | 16 + test/dm/Makefile | 1 + test/dm/iommu.c | 28 + 39 files changed, 1525 insertions(+), 24 deletions(-) create mode 100644 arch/arm/dts/t8103-j274.dts create mode 100644 arch/arm/dts/t8103-j293.dts create mode 100644 arch/arm/dts/t8103.dtsi create mode 100644 arch/arm/include/asm/arch-m1/uart.h create mode 100644 arch/arm/mach-apple/Kconfig create mode 100644 arch/arm/mach-apple/Makefile create mode 100644 arch/arm/mach-apple/board.c create mode 100644 arch/arm/mach-apple/lowlevel_init.S create mode 100644 configs/apple_m1_defconfig create mode 100644 doc/board/apple/index.rst create mode 100644 doc/board/apple/m1.rst create mode 100644 drivers/iommu/Kconfig create mode 100644 drivers/iommu/Makefile create mode 100644 drivers/iommu/apple_dart.c create mode 100644 drivers/iommu/iommu-uclass.c create mode 100644 drivers/iommu/sandbox_iommu.c create mode 100644 include/configs/apple.h create mode 100644 include/dt-bindings/interrupt-controller/apple-aic.h create mode 100644 include/dt-bindings/pinctrl/apple.h create mode 100644 include/dt-bindings/spmi/spmi.h create mode 100644 include/iommu.h create mode 100644 test/dm/iommu.c

This uclass is intended to manage IOMMUs on systems where the IOMMUs are not in bypass mode by default. In that case U-Boot cannot ignore the IOMMUs if it wants to use devices that need to do DMA and sit behind such an IOMMU.
This initial IOMMU uclass implementation does not implement and device ops and is intended for IOMMUs that have a bypass mode that does not require address translation. Support for IOMMUs that do require address translation is planned and device ops will be defined when support for such IOMMUs will be added.
Signed-off-by: Mark Kettenis kettenis@openbsd.org --- drivers/Kconfig | 2 ++ drivers/Makefile | 1 + drivers/core/device.c | 8 +++++++ drivers/iommu/Kconfig | 13 +++++++++++ drivers/iommu/Makefile | 3 +++ drivers/iommu/iommu-uclass.c | 45 ++++++++++++++++++++++++++++++++++++ include/dm/uclass-id.h | 1 + include/iommu.h | 16 +++++++++++++ 8 files changed, 89 insertions(+) create mode 100644 drivers/iommu/Kconfig create mode 100644 drivers/iommu/Makefile create mode 100644 drivers/iommu/iommu-uclass.c create mode 100644 include/iommu.h
diff --git a/drivers/Kconfig b/drivers/Kconfig index 417d6f88c2..b26ca8cf70 100644 --- a/drivers/Kconfig +++ b/drivers/Kconfig @@ -50,6 +50,8 @@ source "drivers/i2c/Kconfig"
source "drivers/input/Kconfig"
+source "drivers/iommu/Kconfig" + source "drivers/led/Kconfig"
source "drivers/mailbox/Kconfig" diff --git a/drivers/Makefile b/drivers/Makefile index fd218c9056..166aeb9817 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -109,6 +109,7 @@ obj-y += mtd/ obj-y += pwm/ obj-y += reset/ obj-y += input/ +obj-y += iommu/ # SOC specific infrastructure drivers. obj-y += smem/ obj-y += thermal/ diff --git a/drivers/core/device.c b/drivers/core/device.c index 29668f6fb3..5f480ad443 100644 --- a/drivers/core/device.c +++ b/drivers/core/device.c @@ -28,6 +28,7 @@ #include <dm/uclass.h> #include <dm/uclass-internal.h> #include <dm/util.h> +#include <iommu.h> #include <linux/err.h> #include <linux/list.h> #include <power-domain.h> @@ -543,6 +544,13 @@ int device_probe(struct udevice *dev) goto fail; }
+ if (CONFIG_IS_ENABLED(IOMMU) && dev->parent && + (device_get_uclass_id(dev) != UCLASS_IOMMU)) { + ret = dev_iommu_probe(dev); + if (ret) + goto fail; + } + ret = device_get_dma_constraints(dev); if (ret) goto fail; diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig new file mode 100644 index 0000000000..8cb377560e --- /dev/null +++ b/drivers/iommu/Kconfig @@ -0,0 +1,13 @@ +# +# IOMMU devices +# + +menu "IOMMU device drivers" + +config IOMMU + bool "Enable Driver Model for IOMMU drivers" + depends on DM + help + Enable driver model for IOMMU devices. + +endmenu diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile new file mode 100644 index 0000000000..f1ceb10150 --- /dev/null +++ b/drivers/iommu/Makefile @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: GPL-2.0+ + +obj-$(CONFIG_IOMMU) += iommu-uclass.o diff --git a/drivers/iommu/iommu-uclass.c b/drivers/iommu/iommu-uclass.c new file mode 100644 index 0000000000..5c55df3066 --- /dev/null +++ b/drivers/iommu/iommu-uclass.c @@ -0,0 +1,45 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2021 Mark Kettenis kettenis@openbsd.org + */ + +#define LOG_CATEGORY UCLASS_IOMMU + +#include <common.h> +#include <dm.h> + +#if (CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)) +int dev_iommu_probe(struct udevice *dev) +{ + struct ofnode_phandle_args args; + struct udevice *dev_iommu; + int i, count, ret = 0; + + count = dev_count_phandle_with_args(dev, "iommus", + "#iommu-cells", 0); + for (i = 0; i < count; i++) { + ret = dev_read_phandle_with_args(dev, "iommus", + "#iommu-cells", 0, i, &args); + if (ret) { + debug("%s: dev_read_phandle_with_args failed: %d\n", + __func__, ret); + return ret; + } + + ret = uclass_get_device_by_ofnode(UCLASS_IOMMU, args.node, + &dev_iommu); + if (ret) { + debug("%s: uclass_get_device_by_ofnode failed: %d\n", + __func__, ret); + return ret; + } + } + + return 0; +} +#endif + +UCLASS_DRIVER(iommu) = { + .id = UCLASS_IOMMU, + .name = "iommu", +}; diff --git a/include/dm/uclass-id.h b/include/dm/uclass-id.h index e7edd409f3..56aa981613 100644 --- a/include/dm/uclass-id.h +++ b/include/dm/uclass-id.h @@ -61,6 +61,7 @@ enum uclass_id { UCLASS_I2C_MUX, /* I2C multiplexer */ UCLASS_I2S, /* I2S bus */ UCLASS_IDE, /* IDE device */ + UCLASS_IOMMU, /* IOMMU */ UCLASS_IRQ, /* Interrupt controller */ UCLASS_KEYBOARD, /* Keyboard input device */ UCLASS_LED, /* Light-emitting diode (LED) */ diff --git a/include/iommu.h b/include/iommu.h new file mode 100644 index 0000000000..d17a06a6f3 --- /dev/null +++ b/include/iommu.h @@ -0,0 +1,16 @@ +#ifndef _IOMMU_H +#define _IOMMU_H + +struct udevice; + +#if (CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)) && \ + CONFIG_IS_ENABLED(IOMMU) +int dev_iommu_probe(struct udevice *dev); +#else +static inline int dev_iommu_probe(struct udevice *dev) +{ + return 0; +} +#endif + +#endif

Hi Mark,
On Sun, 3 Oct 2021 at 12:31, Mark Kettenis kettenis@openbsd.org wrote:
This uclass is intended to manage IOMMUs on systems where the IOMMUs are not in bypass mode by default. In that case U-Boot cannot ignore the IOMMUs if it wants to use devices that need to do DMA and sit behind such an IOMMU.
This initial IOMMU uclass implementation does not implement and device ops and is intended for IOMMUs that have a bypass mode that does not require address translation. Support for IOMMUs that do require address translation is planned and device ops will be defined when support for such IOMMUs will be added.
Signed-off-by: Mark Kettenis kettenis@openbsd.org
drivers/Kconfig | 2 ++ drivers/Makefile | 1 + drivers/core/device.c | 8 +++++++ drivers/iommu/Kconfig | 13 +++++++++++ drivers/iommu/Makefile | 3 +++ drivers/iommu/iommu-uclass.c | 45 ++++++++++++++++++++++++++++++++++++ include/dm/uclass-id.h | 1 + include/iommu.h | 16 +++++++++++++ 8 files changed, 89 insertions(+) create mode 100644 drivers/iommu/Kconfig create mode 100644 drivers/iommu/Makefile create mode 100644 drivers/iommu/iommu-uclass.c create mode 100644 include/iommu.h
diff --git a/drivers/Kconfig b/drivers/Kconfig index 417d6f88c2..b26ca8cf70 100644 --- a/drivers/Kconfig +++ b/drivers/Kconfig @@ -50,6 +50,8 @@ source "drivers/i2c/Kconfig"
source "drivers/input/Kconfig"
+source "drivers/iommu/Kconfig"
source "drivers/led/Kconfig"
source "drivers/mailbox/Kconfig" diff --git a/drivers/Makefile b/drivers/Makefile index fd218c9056..166aeb9817 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -109,6 +109,7 @@ obj-y += mtd/ obj-y += pwm/ obj-y += reset/ obj-y += input/ +obj-y += iommu/ # SOC specific infrastructure drivers. obj-y += smem/ obj-y += thermal/ diff --git a/drivers/core/device.c b/drivers/core/device.c index 29668f6fb3..5f480ad443 100644 --- a/drivers/core/device.c +++ b/drivers/core/device.c @@ -28,6 +28,7 @@ #include <dm/uclass.h> #include <dm/uclass-internal.h> #include <dm/util.h> +#include <iommu.h> #include <linux/err.h> #include <linux/list.h> #include <power-domain.h> @@ -543,6 +544,13 @@ int device_probe(struct udevice *dev) goto fail; }
if (CONFIG_IS_ENABLED(IOMMU) && dev->parent &&
(device_get_uclass_id(dev) != UCLASS_IOMMU)) {
ret = dev_iommu_probe(dev);
if (ret)
goto fail;
}
ret = device_get_dma_constraints(dev); if (ret) goto fail;
diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig new file mode 100644 index 0000000000..8cb377560e --- /dev/null +++ b/drivers/iommu/Kconfig @@ -0,0 +1,13 @@ +# +# IOMMU devices +#
+menu "IOMMU device drivers"
+config IOMMU
bool "Enable Driver Model for IOMMU drivers"
depends on DM
help
Enable driver model for IOMMU devices.
Need at least three lines. What is an IOMMU? How does it relate to other devices?
+endmenu diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile new file mode 100644 index 0000000000..f1ceb10150 --- /dev/null +++ b/drivers/iommu/Makefile @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: GPL-2.0+
+obj-$(CONFIG_IOMMU) += iommu-uclass.o diff --git a/drivers/iommu/iommu-uclass.c b/drivers/iommu/iommu-uclass.c new file mode 100644 index 0000000000..5c55df3066 --- /dev/null +++ b/drivers/iommu/iommu-uclass.c @@ -0,0 +1,45 @@ +// SPDX-License-Identifier: GPL-2.0+ +/*
- Copyright (C) 2021 Mark Kettenis kettenis@openbsd.org
- */
+#define LOG_CATEGORY UCLASS_IOMMU
+#include <common.h> +#include <dm.h>
+#if (CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)) +int dev_iommu_probe(struct udevice *dev)
Can we rename to dev_iommus_enable()? I like to keep probe for use by DM itself so it is confusing to talk about probing in a context other than probing a single device.
+{
struct ofnode_phandle_args args;
struct udevice *dev_iommu;
int i, count, ret = 0;
count = dev_count_phandle_with_args(dev, "iommus",
"#iommu-cells", 0);
Do you have a binding file you can add to docs/device-tree-bindings ?
for (i = 0; i < count; i++) {
ret = dev_read_phandle_with_args(dev, "iommus",
"#iommu-cells", 0, i, &args);
if (ret) {
debug("%s: dev_read_phandle_with_args failed: %d\n",
__func__, ret);
return ret;
}
ret = uclass_get_device_by_ofnode(UCLASS_IOMMU, args.node,
&dev_iommu);
if (ret) {
debug("%s: uclass_get_device_by_ofnode failed: %d\n",
__func__, ret);
return ret;
}
}
return 0;
+} +#endif
+UCLASS_DRIVER(iommu) = {
.id = UCLASS_IOMMU,
.name = "iommu",
+}; diff --git a/include/dm/uclass-id.h b/include/dm/uclass-id.h index e7edd409f3..56aa981613 100644 --- a/include/dm/uclass-id.h +++ b/include/dm/uclass-id.h @@ -61,6 +61,7 @@ enum uclass_id { UCLASS_I2C_MUX, /* I2C multiplexer */ UCLASS_I2S, /* I2S bus */ UCLASS_IDE, /* IDE device */
UCLASS_IOMMU, /* IOMMU */ UCLASS_IRQ, /* Interrupt controller */ UCLASS_KEYBOARD, /* Keyboard input device */ UCLASS_LED, /* Light-emitting diode (LED) */
diff --git a/include/iommu.h b/include/iommu.h new file mode 100644 index 0000000000..d17a06a6f3 --- /dev/null +++ b/include/iommu.h @@ -0,0 +1,16 @@ +#ifndef _IOMMU_H +#define _IOMMU_H
+struct udevice;
+#if (CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)) && \
CONFIG_IS_ENABLED(IOMMU)
+int dev_iommu_probe(struct udevice *dev); +#else +static inline int dev_iommu_probe(struct udevice *dev) +{
return 0;
+} +#endif
+#endif
2.33.0
Regards, Simon

From: Simon Glass sjg@chromium.org Date: Mon, 11 Oct 2021 11:00:34 -0600
Hi Mark,
On Sun, 3 Oct 2021 at 12:31, Mark Kettenis kettenis@openbsd.org wrote:
This uclass is intended to manage IOMMUs on systems where the IOMMUs are not in bypass mode by default. In that case U-Boot cannot ignore the IOMMUs if it wants to use devices that need to do DMA and sit behind such an IOMMU.
This initial IOMMU uclass implementation does not implement and device ops and is intended for IOMMUs that have a bypass mode that does not require address translation. Support for IOMMUs that do require address translation is planned and device ops will be defined when support for such IOMMUs will be added.
Signed-off-by: Mark Kettenis kettenis@openbsd.org
drivers/Kconfig | 2 ++ drivers/Makefile | 1 + drivers/core/device.c | 8 +++++++ drivers/iommu/Kconfig | 13 +++++++++++ drivers/iommu/Makefile | 3 +++ drivers/iommu/iommu-uclass.c | 45 ++++++++++++++++++++++++++++++++++++ include/dm/uclass-id.h | 1 + include/iommu.h | 16 +++++++++++++ 8 files changed, 89 insertions(+) create mode 100644 drivers/iommu/Kconfig create mode 100644 drivers/iommu/Makefile create mode 100644 drivers/iommu/iommu-uclass.c create mode 100644 include/iommu.h
diff --git a/drivers/Kconfig b/drivers/Kconfig index 417d6f88c2..b26ca8cf70 100644 --- a/drivers/Kconfig +++ b/drivers/Kconfig @@ -50,6 +50,8 @@ source "drivers/i2c/Kconfig"
source "drivers/input/Kconfig"
+source "drivers/iommu/Kconfig"
source "drivers/led/Kconfig"
source "drivers/mailbox/Kconfig" diff --git a/drivers/Makefile b/drivers/Makefile index fd218c9056..166aeb9817 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -109,6 +109,7 @@ obj-y += mtd/ obj-y += pwm/ obj-y += reset/ obj-y += input/ +obj-y += iommu/ # SOC specific infrastructure drivers. obj-y += smem/ obj-y += thermal/ diff --git a/drivers/core/device.c b/drivers/core/device.c index 29668f6fb3..5f480ad443 100644 --- a/drivers/core/device.c +++ b/drivers/core/device.c @@ -28,6 +28,7 @@ #include <dm/uclass.h> #include <dm/uclass-internal.h> #include <dm/util.h> +#include <iommu.h> #include <linux/err.h> #include <linux/list.h> #include <power-domain.h> @@ -543,6 +544,13 @@ int device_probe(struct udevice *dev) goto fail; }
if (CONFIG_IS_ENABLED(IOMMU) && dev->parent &&
(device_get_uclass_id(dev) != UCLASS_IOMMU)) {
ret = dev_iommu_probe(dev);
if (ret)
goto fail;
}
ret = device_get_dma_constraints(dev); if (ret) goto fail;
diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig new file mode 100644 index 0000000000..8cb377560e --- /dev/null +++ b/drivers/iommu/Kconfig @@ -0,0 +1,13 @@ +# +# IOMMU devices +#
+menu "IOMMU device drivers"
+config IOMMU
bool "Enable Driver Model for IOMMU drivers"
depends on DM
help
Enable driver model for IOMMU devices.
Need at least three lines. What is an IOMMU? How does it relate to other devices?
Not sure if I can describe what an IOMMU is in just a few lines, but I'll try.
+endmenu diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile new file mode 100644 index 0000000000..f1ceb10150 --- /dev/null +++ b/drivers/iommu/Makefile @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: GPL-2.0+
+obj-$(CONFIG_IOMMU) += iommu-uclass.o diff --git a/drivers/iommu/iommu-uclass.c b/drivers/iommu/iommu-uclass.c new file mode 100644 index 0000000000..5c55df3066 --- /dev/null +++ b/drivers/iommu/iommu-uclass.c @@ -0,0 +1,45 @@ +// SPDX-License-Identifier: GPL-2.0+ +/*
- Copyright (C) 2021 Mark Kettenis kettenis@openbsd.org
- */
+#define LOG_CATEGORY UCLASS_IOMMU
+#include <common.h> +#include <dm.h>
+#if (CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)) +int dev_iommu_probe(struct udevice *dev)
Can we rename to dev_iommus_enable()? I like to keep probe for use by DM itself so it is confusing to talk about probing in a context other than probing a single device.
Sure. That was one of the names I considered myself when writing the code.
+{
struct ofnode_phandle_args args;
struct udevice *dev_iommu;
int i, count, ret = 0;
count = dev_count_phandle_with_args(dev, "iommus",
"#iommu-cells", 0);
Do you have a binding file you can add to docs/device-tree-bindings ?
The binding is available in Documentation/bindings/iommu/iommu.txt in the Linux tree. But I don't think copying it into the u-boot tree makes sense. It will just get out of date. Especially because this will hopefully be converted into a proper DT schema in the near future.
for (i = 0; i < count; i++) {
ret = dev_read_phandle_with_args(dev, "iommus",
"#iommu-cells", 0, i, &args);
if (ret) {
debug("%s: dev_read_phandle_with_args failed: %d\n",
__func__, ret);
return ret;
}
ret = uclass_get_device_by_ofnode(UCLASS_IOMMU, args.node,
&dev_iommu);
if (ret) {
debug("%s: uclass_get_device_by_ofnode failed: %d\n",
__func__, ret);
return ret;
}
}
return 0;
+} +#endif
+UCLASS_DRIVER(iommu) = {
.id = UCLASS_IOMMU,
.name = "iommu",
+}; diff --git a/include/dm/uclass-id.h b/include/dm/uclass-id.h index e7edd409f3..56aa981613 100644 --- a/include/dm/uclass-id.h +++ b/include/dm/uclass-id.h @@ -61,6 +61,7 @@ enum uclass_id { UCLASS_I2C_MUX, /* I2C multiplexer */ UCLASS_I2S, /* I2S bus */ UCLASS_IDE, /* IDE device */
UCLASS_IOMMU, /* IOMMU */ UCLASS_IRQ, /* Interrupt controller */ UCLASS_KEYBOARD, /* Keyboard input device */ UCLASS_LED, /* Light-emitting diode (LED) */
diff --git a/include/iommu.h b/include/iommu.h new file mode 100644 index 0000000000..d17a06a6f3 --- /dev/null +++ b/include/iommu.h @@ -0,0 +1,16 @@ +#ifndef _IOMMU_H +#define _IOMMU_H
+struct udevice;
+#if (CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)) && \
CONFIG_IS_ENABLED(IOMMU)
+int dev_iommu_probe(struct udevice *dev); +#else +static inline int dev_iommu_probe(struct udevice *dev) +{
return 0;
+} +#endif
+#endif
2.33.0
Regards, Simon

Hi Mark,
On Thu, 14 Oct 2021 at 13:35, Mark Kettenis mark.kettenis@xs4all.nl wrote:
From: Simon Glass sjg@chromium.org Date: Mon, 11 Oct 2021 11:00:34 -0600
Hi Mark,
On Sun, 3 Oct 2021 at 12:31, Mark Kettenis kettenis@openbsd.org wrote:
This uclass is intended to manage IOMMUs on systems where the IOMMUs are not in bypass mode by default. In that case U-Boot cannot ignore the IOMMUs if it wants to use devices that need to do DMA and sit behind such an IOMMU.
This initial IOMMU uclass implementation does not implement and device ops and is intended for IOMMUs that have a bypass mode that does not require address translation. Support for IOMMUs that do require address translation is planned and device ops will be defined when support for such IOMMUs will be added.
Signed-off-by: Mark Kettenis kettenis@openbsd.org
drivers/Kconfig | 2 ++ drivers/Makefile | 1 + drivers/core/device.c | 8 +++++++ drivers/iommu/Kconfig | 13 +++++++++++ drivers/iommu/Makefile | 3 +++ drivers/iommu/iommu-uclass.c | 45 ++++++++++++++++++++++++++++++++++++ include/dm/uclass-id.h | 1 + include/iommu.h | 16 +++++++++++++ 8 files changed, 89 insertions(+) create mode 100644 drivers/iommu/Kconfig create mode 100644 drivers/iommu/Makefile create mode 100644 drivers/iommu/iommu-uclass.c create mode 100644 include/iommu.h
diff --git a/drivers/Kconfig b/drivers/Kconfig index 417d6f88c2..b26ca8cf70 100644 --- a/drivers/Kconfig +++ b/drivers/Kconfig @@ -50,6 +50,8 @@ source "drivers/i2c/Kconfig"
source "drivers/input/Kconfig"
+source "drivers/iommu/Kconfig"
source "drivers/led/Kconfig"
source "drivers/mailbox/Kconfig" diff --git a/drivers/Makefile b/drivers/Makefile index fd218c9056..166aeb9817 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -109,6 +109,7 @@ obj-y += mtd/ obj-y += pwm/ obj-y += reset/ obj-y += input/ +obj-y += iommu/ # SOC specific infrastructure drivers. obj-y += smem/ obj-y += thermal/ diff --git a/drivers/core/device.c b/drivers/core/device.c index 29668f6fb3..5f480ad443 100644 --- a/drivers/core/device.c +++ b/drivers/core/device.c @@ -28,6 +28,7 @@ #include <dm/uclass.h> #include <dm/uclass-internal.h> #include <dm/util.h> +#include <iommu.h> #include <linux/err.h> #include <linux/list.h> #include <power-domain.h> @@ -543,6 +544,13 @@ int device_probe(struct udevice *dev) goto fail; }
if (CONFIG_IS_ENABLED(IOMMU) && dev->parent &&
(device_get_uclass_id(dev) != UCLASS_IOMMU)) {
ret = dev_iommu_probe(dev);
if (ret)
goto fail;
}
ret = device_get_dma_constraints(dev); if (ret) goto fail;
diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig new file mode 100644 index 0000000000..8cb377560e --- /dev/null +++ b/drivers/iommu/Kconfig @@ -0,0 +1,13 @@ +# +# IOMMU devices +#
+menu "IOMMU device drivers"
+config IOMMU
bool "Enable Driver Model for IOMMU drivers"
depends on DM
help
Enable driver model for IOMMU devices.
Need at least three lines. What is an IOMMU? How does it relate to other devices?
Not sure if I can describe what an IOMMU is in just a few lines, but I'll try.
+endmenu diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile new file mode 100644 index 0000000000..f1ceb10150 --- /dev/null +++ b/drivers/iommu/Makefile @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: GPL-2.0+
+obj-$(CONFIG_IOMMU) += iommu-uclass.o diff --git a/drivers/iommu/iommu-uclass.c b/drivers/iommu/iommu-uclass.c new file mode 100644 index 0000000000..5c55df3066 --- /dev/null +++ b/drivers/iommu/iommu-uclass.c @@ -0,0 +1,45 @@ +// SPDX-License-Identifier: GPL-2.0+ +/*
- Copyright (C) 2021 Mark Kettenis kettenis@openbsd.org
- */
+#define LOG_CATEGORY UCLASS_IOMMU
+#include <common.h> +#include <dm.h>
+#if (CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)) +int dev_iommu_probe(struct udevice *dev)
Can we rename to dev_iommus_enable()? I like to keep probe for use by DM itself so it is confusing to talk about probing in a context other than probing a single device.
Sure. That was one of the names I considered myself when writing the code.
+{
struct ofnode_phandle_args args;
struct udevice *dev_iommu;
int i, count, ret = 0;
count = dev_count_phandle_with_args(dev, "iommus",
"#iommu-cells", 0);
Do you have a binding file you can add to docs/device-tree-bindings ?
The binding is available in Documentation/bindings/iommu/iommu.txt in the Linux tree. But I don't think copying it into the u-boot tree makes sense. It will just get out of date. Especially because this will hopefully be converted into a proper DT schema in the near future.
We do plan to sync these at some point, so don't worry about that. We have bigger problems than the bindings.
But without this it is not discoverable in U-Boot so no one knows what the driver is referring to.
Regards, Simon

From: Simon Glass sjg@chromium.org Date: Thu, 14 Oct 2021 14:20:21 -0600
Hi Mark,
On Thu, 14 Oct 2021 at 13:35, Mark Kettenis mark.kettenis@xs4all.nl wrote:
From: Simon Glass sjg@chromium.org Date: Mon, 11 Oct 2021 11:00:34 -0600
Hi Mark,
On Sun, 3 Oct 2021 at 12:31, Mark Kettenis kettenis@openbsd.org wrote:
This uclass is intended to manage IOMMUs on systems where the IOMMUs are not in bypass mode by default. In that case U-Boot cannot ignore the IOMMUs if it wants to use devices that need to do DMA and sit behind such an IOMMU.
This initial IOMMU uclass implementation does not implement and device ops and is intended for IOMMUs that have a bypass mode that does not require address translation. Support for IOMMUs that do require address translation is planned and device ops will be defined when support for such IOMMUs will be added.
Signed-off-by: Mark Kettenis kettenis@openbsd.org
drivers/Kconfig | 2 ++ drivers/Makefile | 1 + drivers/core/device.c | 8 +++++++ drivers/iommu/Kconfig | 13 +++++++++++ drivers/iommu/Makefile | 3 +++ drivers/iommu/iommu-uclass.c | 45 ++++++++++++++++++++++++++++++++++++ include/dm/uclass-id.h | 1 + include/iommu.h | 16 +++++++++++++ 8 files changed, 89 insertions(+) create mode 100644 drivers/iommu/Kconfig create mode 100644 drivers/iommu/Makefile create mode 100644 drivers/iommu/iommu-uclass.c create mode 100644 include/iommu.h
diff --git a/drivers/Kconfig b/drivers/Kconfig index 417d6f88c2..b26ca8cf70 100644 --- a/drivers/Kconfig +++ b/drivers/Kconfig @@ -50,6 +50,8 @@ source "drivers/i2c/Kconfig"
source "drivers/input/Kconfig"
+source "drivers/iommu/Kconfig"
source "drivers/led/Kconfig"
source "drivers/mailbox/Kconfig" diff --git a/drivers/Makefile b/drivers/Makefile index fd218c9056..166aeb9817 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -109,6 +109,7 @@ obj-y += mtd/ obj-y += pwm/ obj-y += reset/ obj-y += input/ +obj-y += iommu/ # SOC specific infrastructure drivers. obj-y += smem/ obj-y += thermal/ diff --git a/drivers/core/device.c b/drivers/core/device.c index 29668f6fb3..5f480ad443 100644 --- a/drivers/core/device.c +++ b/drivers/core/device.c @@ -28,6 +28,7 @@ #include <dm/uclass.h> #include <dm/uclass-internal.h> #include <dm/util.h> +#include <iommu.h> #include <linux/err.h> #include <linux/list.h> #include <power-domain.h> @@ -543,6 +544,13 @@ int device_probe(struct udevice *dev) goto fail; }
if (CONFIG_IS_ENABLED(IOMMU) && dev->parent &&
(device_get_uclass_id(dev) != UCLASS_IOMMU)) {
ret = dev_iommu_probe(dev);
if (ret)
goto fail;
}
ret = device_get_dma_constraints(dev); if (ret) goto fail;
diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig new file mode 100644 index 0000000000..8cb377560e --- /dev/null +++ b/drivers/iommu/Kconfig @@ -0,0 +1,13 @@ +# +# IOMMU devices +#
+menu "IOMMU device drivers"
+config IOMMU
bool "Enable Driver Model for IOMMU drivers"
depends on DM
help
Enable driver model for IOMMU devices.
Need at least three lines. What is an IOMMU? How does it relate to other devices?
Not sure if I can describe what an IOMMU is in just a few lines, but I'll try.
+endmenu diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile new file mode 100644 index 0000000000..f1ceb10150 --- /dev/null +++ b/drivers/iommu/Makefile @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: GPL-2.0+
+obj-$(CONFIG_IOMMU) += iommu-uclass.o diff --git a/drivers/iommu/iommu-uclass.c b/drivers/iommu/iommu-uclass.c new file mode 100644 index 0000000000..5c55df3066 --- /dev/null +++ b/drivers/iommu/iommu-uclass.c @@ -0,0 +1,45 @@ +// SPDX-License-Identifier: GPL-2.0+ +/*
- Copyright (C) 2021 Mark Kettenis kettenis@openbsd.org
- */
+#define LOG_CATEGORY UCLASS_IOMMU
+#include <common.h> +#include <dm.h>
+#if (CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)) +int dev_iommu_probe(struct udevice *dev)
Can we rename to dev_iommus_enable()? I like to keep probe for use by DM itself so it is confusing to talk about probing in a context other than probing a single device.
Sure. That was one of the names I considered myself when writing the code.
+{
struct ofnode_phandle_args args;
struct udevice *dev_iommu;
int i, count, ret = 0;
count = dev_count_phandle_with_args(dev, "iommus",
"#iommu-cells", 0);
Do you have a binding file you can add to docs/device-tree-bindings ?
The binding is available in Documentation/bindings/iommu/iommu.txt in the Linux tree. But I don't think copying it into the u-boot tree makes sense. It will just get out of date. Especially because this will hopefully be converted into a proper DT schema in the near future.
We do plan to sync these at some point, so don't worry about that. We have bigger problems than the bindings.
Well, at this point they're so much out of date that I don't look there unless I'm looking for someting that I know to be u-boot specific.
But without this it is not discoverable in U-Boot so no one knows what the driver is referring to.
Really? The canonical place for device tree bindings that aren't part of the device tree specification itself *is* the Linux kernel tree.

Hi Mark,
On Thu, 14 Oct 2021 at 14:51, Mark Kettenis mark.kettenis@xs4all.nl wrote:
From: Simon Glass sjg@chromium.org Date: Thu, 14 Oct 2021 14:20:21 -0600
Hi Mark,
On Thu, 14 Oct 2021 at 13:35, Mark Kettenis mark.kettenis@xs4all.nl wrote:
From: Simon Glass sjg@chromium.org Date: Mon, 11 Oct 2021 11:00:34 -0600
Hi Mark,
On Sun, 3 Oct 2021 at 12:31, Mark Kettenis kettenis@openbsd.org wrote:
This uclass is intended to manage IOMMUs on systems where the IOMMUs are not in bypass mode by default. In that case U-Boot cannot ignore the IOMMUs if it wants to use devices that need to do DMA and sit behind such an IOMMU.
This initial IOMMU uclass implementation does not implement and device ops and is intended for IOMMUs that have a bypass mode that does not require address translation. Support for IOMMUs that do require address translation is planned and device ops will be defined when support for such IOMMUs will be added.
Signed-off-by: Mark Kettenis kettenis@openbsd.org
drivers/Kconfig | 2 ++ drivers/Makefile | 1 + drivers/core/device.c | 8 +++++++ drivers/iommu/Kconfig | 13 +++++++++++ drivers/iommu/Makefile | 3 +++ drivers/iommu/iommu-uclass.c | 45 ++++++++++++++++++++++++++++++++++++ include/dm/uclass-id.h | 1 + include/iommu.h | 16 +++++++++++++ 8 files changed, 89 insertions(+) create mode 100644 drivers/iommu/Kconfig create mode 100644 drivers/iommu/Makefile create mode 100644 drivers/iommu/iommu-uclass.c create mode 100644 include/iommu.h
diff --git a/drivers/Kconfig b/drivers/Kconfig index 417d6f88c2..b26ca8cf70 100644 --- a/drivers/Kconfig +++ b/drivers/Kconfig @@ -50,6 +50,8 @@ source "drivers/i2c/Kconfig"
source "drivers/input/Kconfig"
+source "drivers/iommu/Kconfig"
source "drivers/led/Kconfig"
source "drivers/mailbox/Kconfig" diff --git a/drivers/Makefile b/drivers/Makefile index fd218c9056..166aeb9817 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -109,6 +109,7 @@ obj-y += mtd/ obj-y += pwm/ obj-y += reset/ obj-y += input/ +obj-y += iommu/ # SOC specific infrastructure drivers. obj-y += smem/ obj-y += thermal/ diff --git a/drivers/core/device.c b/drivers/core/device.c index 29668f6fb3..5f480ad443 100644 --- a/drivers/core/device.c +++ b/drivers/core/device.c @@ -28,6 +28,7 @@ #include <dm/uclass.h> #include <dm/uclass-internal.h> #include <dm/util.h> +#include <iommu.h> #include <linux/err.h> #include <linux/list.h> #include <power-domain.h> @@ -543,6 +544,13 @@ int device_probe(struct udevice *dev) goto fail; }
if (CONFIG_IS_ENABLED(IOMMU) && dev->parent &&
(device_get_uclass_id(dev) != UCLASS_IOMMU)) {
ret = dev_iommu_probe(dev);
if (ret)
goto fail;
}
ret = device_get_dma_constraints(dev); if (ret) goto fail;
diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig new file mode 100644 index 0000000000..8cb377560e --- /dev/null +++ b/drivers/iommu/Kconfig @@ -0,0 +1,13 @@ +# +# IOMMU devices +#
+menu "IOMMU device drivers"
+config IOMMU
bool "Enable Driver Model for IOMMU drivers"
depends on DM
help
Enable driver model for IOMMU devices.
Need at least three lines. What is an IOMMU? How does it relate to other devices?
Not sure if I can describe what an IOMMU is in just a few lines, but I'll try.
+endmenu diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile new file mode 100644 index 0000000000..f1ceb10150 --- /dev/null +++ b/drivers/iommu/Makefile @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: GPL-2.0+
+obj-$(CONFIG_IOMMU) += iommu-uclass.o diff --git a/drivers/iommu/iommu-uclass.c b/drivers/iommu/iommu-uclass.c new file mode 100644 index 0000000000..5c55df3066 --- /dev/null +++ b/drivers/iommu/iommu-uclass.c @@ -0,0 +1,45 @@ +// SPDX-License-Identifier: GPL-2.0+ +/*
- Copyright (C) 2021 Mark Kettenis kettenis@openbsd.org
- */
+#define LOG_CATEGORY UCLASS_IOMMU
+#include <common.h> +#include <dm.h>
+#if (CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)) +int dev_iommu_probe(struct udevice *dev)
Can we rename to dev_iommus_enable()? I like to keep probe for use by DM itself so it is confusing to talk about probing in a context other than probing a single device.
Sure. That was one of the names I considered myself when writing the code.
+{
struct ofnode_phandle_args args;
struct udevice *dev_iommu;
int i, count, ret = 0;
count = dev_count_phandle_with_args(dev, "iommus",
"#iommu-cells", 0);
Do you have a binding file you can add to docs/device-tree-bindings ?
The binding is available in Documentation/bindings/iommu/iommu.txt in the Linux tree. But I don't think copying it into the u-boot tree makes sense. It will just get out of date. Especially because this will hopefully be converted into a proper DT schema in the near future.
We do plan to sync these at some point, so don't worry about that. We have bigger problems than the bindings.
Well, at this point they're so much out of date that I don't look there unless I'm looking for someting that I know to be u-boot specific.
But without this it is not discoverable in U-Boot so no one knows what the driver is referring to.
Really? The canonical place for device tree bindings that aren't part of the device tree specification itself *is* the Linux kernel tree.
Yes please, these should be in the U-Boot tree at this point. If they move out of the kernel into some other repo then we can revisit it. I don't really understand your reluctance. I hope that what you say will be true at some point, but as you probably know there are some U-Boot bindings which are not in that repo.
Regards, Simon

From: Simon Glass sjg@chromium.org Date: Thu, 14 Oct 2021 14:55:19 -0600
Hi Mark,
On Thu, 14 Oct 2021 at 14:51, Mark Kettenis mark.kettenis@xs4all.nl wrote:
From: Simon Glass sjg@chromium.org Date: Thu, 14 Oct 2021 14:20:21 -0600
Hi Mark,
On Thu, 14 Oct 2021 at 13:35, Mark Kettenis mark.kettenis@xs4all.nl wrote:
From: Simon Glass sjg@chromium.org Date: Mon, 11 Oct 2021 11:00:34 -0600
Hi Mark,
On Sun, 3 Oct 2021 at 12:31, Mark Kettenis kettenis@openbsd.org wrote:
This uclass is intended to manage IOMMUs on systems where the IOMMUs are not in bypass mode by default. In that case U-Boot cannot ignore the IOMMUs if it wants to use devices that need to do DMA and sit behind such an IOMMU.
This initial IOMMU uclass implementation does not implement and device ops and is intended for IOMMUs that have a bypass mode that does not require address translation. Support for IOMMUs that do require address translation is planned and device ops will be defined when support for such IOMMUs will be added.
Signed-off-by: Mark Kettenis kettenis@openbsd.org
drivers/Kconfig | 2 ++ drivers/Makefile | 1 + drivers/core/device.c | 8 +++++++ drivers/iommu/Kconfig | 13 +++++++++++ drivers/iommu/Makefile | 3 +++ drivers/iommu/iommu-uclass.c | 45 ++++++++++++++++++++++++++++++++++++ include/dm/uclass-id.h | 1 + include/iommu.h | 16 +++++++++++++ 8 files changed, 89 insertions(+) create mode 100644 drivers/iommu/Kconfig create mode 100644 drivers/iommu/Makefile create mode 100644 drivers/iommu/iommu-uclass.c create mode 100644 include/iommu.h
diff --git a/drivers/Kconfig b/drivers/Kconfig index 417d6f88c2..b26ca8cf70 100644 --- a/drivers/Kconfig +++ b/drivers/Kconfig @@ -50,6 +50,8 @@ source "drivers/i2c/Kconfig"
source "drivers/input/Kconfig"
+source "drivers/iommu/Kconfig"
source "drivers/led/Kconfig"
source "drivers/mailbox/Kconfig" diff --git a/drivers/Makefile b/drivers/Makefile index fd218c9056..166aeb9817 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -109,6 +109,7 @@ obj-y += mtd/ obj-y += pwm/ obj-y += reset/ obj-y += input/ +obj-y += iommu/ # SOC specific infrastructure drivers. obj-y += smem/ obj-y += thermal/ diff --git a/drivers/core/device.c b/drivers/core/device.c index 29668f6fb3..5f480ad443 100644 --- a/drivers/core/device.c +++ b/drivers/core/device.c @@ -28,6 +28,7 @@ #include <dm/uclass.h> #include <dm/uclass-internal.h> #include <dm/util.h> +#include <iommu.h> #include <linux/err.h> #include <linux/list.h> #include <power-domain.h> @@ -543,6 +544,13 @@ int device_probe(struct udevice *dev) goto fail; }
if (CONFIG_IS_ENABLED(IOMMU) && dev->parent &&
(device_get_uclass_id(dev) != UCLASS_IOMMU)) {
ret = dev_iommu_probe(dev);
if (ret)
goto fail;
}
ret = device_get_dma_constraints(dev); if (ret) goto fail;
diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig new file mode 100644 index 0000000000..8cb377560e --- /dev/null +++ b/drivers/iommu/Kconfig @@ -0,0 +1,13 @@ +# +# IOMMU devices +#
+menu "IOMMU device drivers"
+config IOMMU
bool "Enable Driver Model for IOMMU drivers"
depends on DM
help
Enable driver model for IOMMU devices.
Need at least three lines. What is an IOMMU? How does it relate to other devices?
Not sure if I can describe what an IOMMU is in just a few lines, but I'll try.
+endmenu diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile new file mode 100644 index 0000000000..f1ceb10150 --- /dev/null +++ b/drivers/iommu/Makefile @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: GPL-2.0+
+obj-$(CONFIG_IOMMU) += iommu-uclass.o diff --git a/drivers/iommu/iommu-uclass.c b/drivers/iommu/iommu-uclass.c new file mode 100644 index 0000000000..5c55df3066 --- /dev/null +++ b/drivers/iommu/iommu-uclass.c @@ -0,0 +1,45 @@ +// SPDX-License-Identifier: GPL-2.0+ +/*
- Copyright (C) 2021 Mark Kettenis kettenis@openbsd.org
- */
+#define LOG_CATEGORY UCLASS_IOMMU
+#include <common.h> +#include <dm.h>
+#if (CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)) +int dev_iommu_probe(struct udevice *dev)
Can we rename to dev_iommus_enable()? I like to keep probe for use by DM itself so it is confusing to talk about probing in a context other than probing a single device.
Sure. That was one of the names I considered myself when writing the code.
+{
struct ofnode_phandle_args args;
struct udevice *dev_iommu;
int i, count, ret = 0;
count = dev_count_phandle_with_args(dev, "iommus",
"#iommu-cells", 0);
Do you have a binding file you can add to docs/device-tree-bindings ?
The binding is available in Documentation/bindings/iommu/iommu.txt in the Linux tree. But I don't think copying it into the u-boot tree makes sense. It will just get out of date. Especially because this will hopefully be converted into a proper DT schema in the near future.
We do plan to sync these at some point, so don't worry about that. We have bigger problems than the bindings.
Well, at this point they're so much out of date that I don't look there unless I'm looking for someting that I know to be u-boot specific.
But without this it is not discoverable in U-Boot so no one knows what the driver is referring to.
Really? The canonical place for device tree bindings that aren't part of the device tree specification itself *is* the Linux kernel tree.
Yes please, these should be in the U-Boot tree at this point. If they move out of the kernel into some other repo then we can revisit it. I don't really understand your reluctance. I hope that what you say will be true at some point, but as you probably know there are some U-Boot bindings which are not in that repo.
Should I still add my Signed-off-by on files copied verbatim from the Linux kernel sources?

Hi Mark,
On Thu, 14 Oct 2021 at 15:11, Mark Kettenis mark.kettenis@xs4all.nl wrote:
From: Simon Glass sjg@chromium.org Date: Thu, 14 Oct 2021 14:55:19 -0600
Hi Mark,
On Thu, 14 Oct 2021 at 14:51, Mark Kettenis mark.kettenis@xs4all.nl wrote:
From: Simon Glass sjg@chromium.org Date: Thu, 14 Oct 2021 14:20:21 -0600
Hi Mark,
On Thu, 14 Oct 2021 at 13:35, Mark Kettenis mark.kettenis@xs4all.nl wrote:
From: Simon Glass sjg@chromium.org Date: Mon, 11 Oct 2021 11:00:34 -0600
Hi Mark,
On Sun, 3 Oct 2021 at 12:31, Mark Kettenis kettenis@openbsd.org wrote: > > This uclass is intended to manage IOMMUs on systems where the > IOMMUs are not in bypass mode by default. In that case U-Boot > cannot ignore the IOMMUs if it wants to use devices that need > to do DMA and sit behind such an IOMMU. > > This initial IOMMU uclass implementation does not implement and > device ops and is intended for IOMMUs that have a bypass mode > that does not require address translation. Support for IOMMUs > that do require address translation is planned and device ops > will be defined when support for such IOMMUs will be added. > > Signed-off-by: Mark Kettenis kettenis@openbsd.org > --- > drivers/Kconfig | 2 ++ > drivers/Makefile | 1 + > drivers/core/device.c | 8 +++++++ > drivers/iommu/Kconfig | 13 +++++++++++ > drivers/iommu/Makefile | 3 +++ > drivers/iommu/iommu-uclass.c | 45 ++++++++++++++++++++++++++++++++++++ > include/dm/uclass-id.h | 1 + > include/iommu.h | 16 +++++++++++++ > 8 files changed, 89 insertions(+) > create mode 100644 drivers/iommu/Kconfig > create mode 100644 drivers/iommu/Makefile > create mode 100644 drivers/iommu/iommu-uclass.c > create mode 100644 include/iommu.h > > diff --git a/drivers/Kconfig b/drivers/Kconfig > index 417d6f88c2..b26ca8cf70 100644 > --- a/drivers/Kconfig > +++ b/drivers/Kconfig > @@ -50,6 +50,8 @@ source "drivers/i2c/Kconfig" > > source "drivers/input/Kconfig" > > +source "drivers/iommu/Kconfig" > + > source "drivers/led/Kconfig" > > source "drivers/mailbox/Kconfig" > diff --git a/drivers/Makefile b/drivers/Makefile > index fd218c9056..166aeb9817 100644 > --- a/drivers/Makefile > +++ b/drivers/Makefile > @@ -109,6 +109,7 @@ obj-y += mtd/ > obj-y += pwm/ > obj-y += reset/ > obj-y += input/ > +obj-y += iommu/ > # SOC specific infrastructure drivers. > obj-y += smem/ > obj-y += thermal/ > diff --git a/drivers/core/device.c b/drivers/core/device.c > index 29668f6fb3..5f480ad443 100644 > --- a/drivers/core/device.c > +++ b/drivers/core/device.c > @@ -28,6 +28,7 @@ > #include <dm/uclass.h> > #include <dm/uclass-internal.h> > #include <dm/util.h> > +#include <iommu.h> > #include <linux/err.h> > #include <linux/list.h> > #include <power-domain.h> > @@ -543,6 +544,13 @@ int device_probe(struct udevice *dev) > goto fail; > } > > + if (CONFIG_IS_ENABLED(IOMMU) && dev->parent && > + (device_get_uclass_id(dev) != UCLASS_IOMMU)) { > + ret = dev_iommu_probe(dev); > + if (ret) > + goto fail; > + } > + > ret = device_get_dma_constraints(dev); > if (ret) > goto fail; > diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig > new file mode 100644 > index 0000000000..8cb377560e > --- /dev/null > +++ b/drivers/iommu/Kconfig > @@ -0,0 +1,13 @@ > +# > +# IOMMU devices > +# > + > +menu "IOMMU device drivers" > + > +config IOMMU > + bool "Enable Driver Model for IOMMU drivers" > + depends on DM > + help > + Enable driver model for IOMMU devices.
Need at least three lines. What is an IOMMU? How does it relate to other devices?
Not sure if I can describe what an IOMMU is in just a few lines, but I'll try.
> + > +endmenu > diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile > new file mode 100644 > index 0000000000..f1ceb10150 > --- /dev/null > +++ b/drivers/iommu/Makefile > @@ -0,0 +1,3 @@ > +# SPDX-License-Identifier: GPL-2.0+ > + > +obj-$(CONFIG_IOMMU) += iommu-uclass.o > diff --git a/drivers/iommu/iommu-uclass.c b/drivers/iommu/iommu-uclass.c > new file mode 100644 > index 0000000000..5c55df3066 > --- /dev/null > +++ b/drivers/iommu/iommu-uclass.c > @@ -0,0 +1,45 @@ > +// SPDX-License-Identifier: GPL-2.0+ > +/* > + * Copyright (C) 2021 Mark Kettenis kettenis@openbsd.org > + */ > + > +#define LOG_CATEGORY UCLASS_IOMMU > + > +#include <common.h> > +#include <dm.h> > + > +#if (CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)) > +int dev_iommu_probe(struct udevice *dev)
Can we rename to dev_iommus_enable()? I like to keep probe for use by DM itself so it is confusing to talk about probing in a context other than probing a single device.
Sure. That was one of the names I considered myself when writing the code.
> +{ > + struct ofnode_phandle_args args; > + struct udevice *dev_iommu; > + int i, count, ret = 0; > + > + count = dev_count_phandle_with_args(dev, "iommus", > + "#iommu-cells", 0);
Do you have a binding file you can add to docs/device-tree-bindings ?
The binding is available in Documentation/bindings/iommu/iommu.txt in the Linux tree. But I don't think copying it into the u-boot tree makes sense. It will just get out of date. Especially because this will hopefully be converted into a proper DT schema in the near future.
We do plan to sync these at some point, so don't worry about that. We have bigger problems than the bindings.
Well, at this point they're so much out of date that I don't look there unless I'm looking for someting that I know to be u-boot specific.
But without this it is not discoverable in U-Boot so no one knows what the driver is referring to.
Really? The canonical place for device tree bindings that aren't part of the device tree specification itself *is* the Linux kernel tree.
Yes please, these should be in the U-Boot tree at this point. If they move out of the kernel into some other repo then we can revisit it. I don't really understand your reluctance. I hope that what you say will be true at some point, but as you probably know there are some U-Boot bindings which are not in that repo.
Should I still add my Signed-off-by on files copied verbatim from the Linux kernel sources?
Yes that's my understanding..."The Signed-off-by: tag indicates that the signer was involved in the development of the patch, or that he/she was in the patch's delivery path"
That's why I sometimes add a tag when applying a patch, e.g. if I make a minor tweak.
Regards, Simon

Add a set of tests for the IOMMU uclass.
Signed-off-by: Mark Kettenis kettenis@openbsd.org --- arch/sandbox/dts/test.dts | 6 ++++++ configs/sandbox64_defconfig | 1 + configs/sandbox_defconfig | 1 + configs/sandbox_flattree_defconfig | 1 + configs/sandbox_noinst_defconfig | 1 + configs/sandbox_spl_defconfig | 1 + drivers/iommu/Makefile | 2 ++ drivers/iommu/sandbox_iommu.c | 18 ++++++++++++++++++ test/dm/Makefile | 1 + test/dm/iommu.c | 28 ++++++++++++++++++++++++++++ 10 files changed, 60 insertions(+) create mode 100644 drivers/iommu/sandbox_iommu.c create mode 100644 test/dm/iommu.c
diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts index 962bdbe556..ce561c17ef 100644 --- a/arch/sandbox/dts/test.dts +++ b/arch/sandbox/dts/test.dts @@ -752,6 +752,11 @@ vss-microvolts = <0>; };
+ iommu: iommu@0 { + compatible = "sandbox,iommu"; + #iommu-cells = <0>; + }; + irq: irq { compatible = "sandbox,irq"; interrupt-controller; @@ -1199,6 +1204,7 @@
usb_1: usb@1 { compatible = "sandbox,usb"; + iommus = <&iommu>; hub { compatible = "usb-hub"; usb,device-class = <9>; diff --git a/configs/sandbox64_defconfig b/configs/sandbox64_defconfig index f7098b4969..54893dc303 100644 --- a/configs/sandbox64_defconfig +++ b/configs/sandbox64_defconfig @@ -129,6 +129,7 @@ CONFIG_SPL_I2C_MUX=y CONFIG_I2C_ARB_GPIO_CHALLENGE=y CONFIG_CROS_EC_KEYB=y CONFIG_I8042_KEYB=y +CONFIG_IOMMU=y CONFIG_LED=y CONFIG_LED_BLINK=y CONFIG_LED_GPIO=y diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig index ea08a9e5bd..e7726b6de9 100644 --- a/configs/sandbox_defconfig +++ b/configs/sandbox_defconfig @@ -166,6 +166,7 @@ CONFIG_SPL_I2C_MUX=y CONFIG_I2C_ARB_GPIO_CHALLENGE=y CONFIG_CROS_EC_KEYB=y CONFIG_I8042_KEYB=y +CONFIG_IOMMU=y CONFIG_LED=y CONFIG_LED_BLINK=y CONFIG_LED_GPIO=y diff --git a/configs/sandbox_flattree_defconfig b/configs/sandbox_flattree_defconfig index a6e2544dc1..fc831253ec 100644 --- a/configs/sandbox_flattree_defconfig +++ b/configs/sandbox_flattree_defconfig @@ -106,6 +106,7 @@ CONFIG_SPL_I2C_MUX=y CONFIG_I2C_ARB_GPIO_CHALLENGE=y CONFIG_CROS_EC_KEYB=y CONFIG_I8042_KEYB=y +CONFIG_IOMMU=y CONFIG_LED=y CONFIG_LED_BLINK=y CONFIG_LED_GPIO=y diff --git a/configs/sandbox_noinst_defconfig b/configs/sandbox_noinst_defconfig index 88443f5ab2..d1b82821eb 100644 --- a/configs/sandbox_noinst_defconfig +++ b/configs/sandbox_noinst_defconfig @@ -125,6 +125,7 @@ CONFIG_I2C_MUX=y CONFIG_I2C_ARB_GPIO_CHALLENGE=y CONFIG_CROS_EC_KEYB=y CONFIG_I8042_KEYB=y +CONFIG_IOMMU=y CONFIG_LED=y CONFIG_LED_BLINK=y CONFIG_LED_GPIO=y diff --git a/configs/sandbox_spl_defconfig b/configs/sandbox_spl_defconfig index 77dd83cf6f..d91cac492b 100644 --- a/configs/sandbox_spl_defconfig +++ b/configs/sandbox_spl_defconfig @@ -127,6 +127,7 @@ CONFIG_I2C_MUX=y CONFIG_I2C_ARB_GPIO_CHALLENGE=y CONFIG_CROS_EC_KEYB=y CONFIG_I8042_KEYB=y +CONFIG_IOMMU=y CONFIG_LED=y CONFIG_LED_BLINK=y CONFIG_LED_GPIO=y diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile index f1ceb10150..af1c6bbb7a 100644 --- a/drivers/iommu/Makefile +++ b/drivers/iommu/Makefile @@ -1,3 +1,5 @@ # SPDX-License-Identifier: GPL-2.0+
obj-$(CONFIG_IOMMU) += iommu-uclass.o + +obj-$(CONFIG_SANDBOX) += sandbox_iommu.o diff --git a/drivers/iommu/sandbox_iommu.c b/drivers/iommu/sandbox_iommu.c new file mode 100644 index 0000000000..c8161a40ae --- /dev/null +++ b/drivers/iommu/sandbox_iommu.c @@ -0,0 +1,18 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2021 Mark Kettenis kettenis@openbsd.org + */ + +#include <common.h> +#include <dm.h> + +static const struct udevice_id sandbox_iommu_ids[] = { + { .compatible = "sandbox,iommu" }, + { /* sentinel */ } +}; + +U_BOOT_DRIVER(sandbox_iommu) = { + .name = "sandbox_iommu", + .id = UCLASS_IOMMU, + .of_match = sandbox_iommu_ids, +}; diff --git a/test/dm/Makefile b/test/dm/Makefile index 55162e9499..7de013f636 100644 --- a/test/dm/Makefile +++ b/test/dm/Makefile @@ -48,6 +48,7 @@ obj-$(CONFIG_DM_I2C) += i2c.o obj-$(CONFIG_SOUND) += i2s.o obj-y += irq.o obj-$(CONFIG_CLK_K210_SET_RATE) += k210_pll.o +obj-$(CONFIG_IOMMU) += iommu.o obj-$(CONFIG_LED) += led.o obj-$(CONFIG_DM_MAILBOX) += mailbox.o obj-$(CONFIG_DM_MDIO) += mdio.o diff --git a/test/dm/iommu.c b/test/dm/iommu.c new file mode 100644 index 0000000000..94174a7482 --- /dev/null +++ b/test/dm/iommu.c @@ -0,0 +1,28 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2021 Mark Kettenis kettenis@openbsd.org + */ + +#include <common.h> +#include <dm.h> +#include <dm/test.h> +#include <dm/uclass-internal.h> +#include <iommu.h> +#include <test/test.h> +#include <test/ut.h> + +static int dm_test_iommu(struct unit_test_state *uts) +{ + struct udevice *dev; + + ut_assertok(uclass_find_device(UCLASS_IOMMU, 0, &dev)); + ut_assert(!(dev_get_flags(dev) & DM_FLAG_ACTIVATED)); + + /* Probing USB probes the IOMMU through the "iommus" property */ + ut_assertok(uclass_probe_all(UCLASS_USB)); + ut_assert(dev_get_flags(dev) & DM_FLAG_ACTIVATED); + + return 0; +} + +DM_TEST(dm_test_iommu, UT_TESTF_SCAN_FDT);

On Sun, 3 Oct 2021 at 12:31, Mark Kettenis kettenis@openbsd.org wrote:
Add a set of tests for the IOMMU uclass.
Signed-off-by: Mark Kettenis kettenis@openbsd.org
arch/sandbox/dts/test.dts | 6 ++++++ configs/sandbox64_defconfig | 1 + configs/sandbox_defconfig | 1 + configs/sandbox_flattree_defconfig | 1 + configs/sandbox_noinst_defconfig | 1 + configs/sandbox_spl_defconfig | 1 + drivers/iommu/Makefile | 2 ++ drivers/iommu/sandbox_iommu.c | 18 ++++++++++++++++++ test/dm/Makefile | 1 + test/dm/iommu.c | 28 ++++++++++++++++++++++++++++ 10 files changed, 60 insertions(+) create mode 100644 drivers/iommu/sandbox_iommu.c create mode 100644 test/dm/iommu.c
Reviewed-by: Simon Glass sjg@chromium.org
You could add the CONFIG options to sandbox's Kconfig in arch/Kconfig

From: Simon Glass sjg@chromium.org Date: Mon, 11 Oct 2021 11:00:36 -0600
On Sun, 3 Oct 2021 at 12:31, Mark Kettenis kettenis@openbsd.org wrote:
Add a set of tests for the IOMMU uclass.
Signed-off-by: Mark Kettenis kettenis@openbsd.org
arch/sandbox/dts/test.dts | 6 ++++++ configs/sandbox64_defconfig | 1 + configs/sandbox_defconfig | 1 + configs/sandbox_flattree_defconfig | 1 + configs/sandbox_noinst_defconfig | 1 + configs/sandbox_spl_defconfig | 1 + drivers/iommu/Makefile | 2 ++ drivers/iommu/sandbox_iommu.c | 18 ++++++++++++++++++ test/dm/Makefile | 1 + test/dm/iommu.c | 28 ++++++++++++++++++++++++++++ 10 files changed, 60 insertions(+) create mode 100644 drivers/iommu/sandbox_iommu.c create mode 100644 test/dm/iommu.c
Reviewed-by: Simon Glass sjg@chromium.org
You could add the CONFIG options to sandbox's Kconfig in arch/Kconfig
The codebase is a bit inconsistent in that respect isn't it?

Hi Mark,
On Thu, 14 Oct 2021 at 13:51, Mark Kettenis mark.kettenis@xs4all.nl wrote:
From: Simon Glass sjg@chromium.org Date: Mon, 11 Oct 2021 11:00:36 -0600
On Sun, 3 Oct 2021 at 12:31, Mark Kettenis kettenis@openbsd.org wrote:
Add a set of tests for the IOMMU uclass.
Signed-off-by: Mark Kettenis kettenis@openbsd.org
arch/sandbox/dts/test.dts | 6 ++++++ configs/sandbox64_defconfig | 1 + configs/sandbox_defconfig | 1 + configs/sandbox_flattree_defconfig | 1 + configs/sandbox_noinst_defconfig | 1 + configs/sandbox_spl_defconfig | 1 + drivers/iommu/Makefile | 2 ++ drivers/iommu/sandbox_iommu.c | 18 ++++++++++++++++++ test/dm/Makefile | 1 + test/dm/iommu.c | 28 ++++++++++++++++++++++++++++ 10 files changed, 60 insertions(+) create mode 100644 drivers/iommu/sandbox_iommu.c create mode 100644 test/dm/iommu.c
Reviewed-by: Simon Glass sjg@chromium.org
You could add the CONFIG options to sandbox's Kconfig in arch/Kconfig
The codebase is a bit inconsistent in that respect isn't it?
Do you mean sometimes it is in defconfig and sometimes in Kconfig? Yes.
For the sandbox board, we try to enable everything For the other boards that use the sandbox arch, we have to enable what is needed to run tests, but not necessarily every feature
Regards, Simon

Add support for Apple's M1 SoC that is used in "Apple Silicon" Macs. This builds a basic U-Boot that can be used as a payload for the m1n1 boot loader being developed by the Asahi Linux project.
Signed-off-by: Mark Kettenis kettenis@openbsd.org --- arch/arm/Kconfig | 21 ++++ arch/arm/Makefile | 1 + arch/arm/mach-apple/Kconfig | 18 ++++ arch/arm/mach-apple/Makefile | 4 + arch/arm/mach-apple/board.c | 161 ++++++++++++++++++++++++++++ arch/arm/mach-apple/lowlevel_init.S | 17 +++ configs/apple_m1_defconfig | 14 +++ include/configs/apple.h | 38 +++++++ 8 files changed, 274 insertions(+) create mode 100644 arch/arm/mach-apple/Kconfig create mode 100644 arch/arm/mach-apple/Makefile create mode 100644 arch/arm/mach-apple/board.c create mode 100644 arch/arm/mach-apple/lowlevel_init.S create mode 100644 configs/apple_m1_defconfig create mode 100644 include/configs/apple.h
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index b5bd3284cd..4948dad4df 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -895,6 +895,25 @@ config ARCH_NEXELL select DM select GPIO_EXTRA_HEADER
+config ARCH_APPLE + bool "Apple SoCs" + select ARM64 + select BLK + select CMD_USB + select DM + select DM_KEYBOARD + select DM_SERIAL + select DM_USB + select DM_VIDEO + select LINUX_KERNEL_IMAGE_HEADER + select OF_CONTROL + select OF_BOARD + select POSITION_INDEPENDENT + select USB + imply CMD_DM + imply CMD_GPT + imply DISTRO_DEFAULTS + config ARCH_OWL bool "Actions Semi OWL SoCs" select DM @@ -1932,6 +1951,8 @@ config ISW_ENTRY_ADDR image headers. endif
+source "arch/arm/mach-apple/Kconfig" + source "arch/arm/mach-aspeed/Kconfig"
source "arch/arm/mach-at91/Kconfig" diff --git a/arch/arm/Makefile b/arch/arm/Makefile index c68e598a67..44178c204b 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -51,6 +51,7 @@ PLATFORM_CPPFLAGS += $(arch-y) $(tune-y)
# Machine directory name. This list is sorted alphanumerically # by CONFIG_* macro name. +machine-$(CONFIG_ARCH_APPLE) += apple machine-$(CONFIG_ARCH_ASPEED) += aspeed machine-$(CONFIG_ARCH_AT91) += at91 machine-$(CONFIG_ARCH_BCM283X) += bcm283x diff --git a/arch/arm/mach-apple/Kconfig b/arch/arm/mach-apple/Kconfig new file mode 100644 index 0000000000..66cab91b2a --- /dev/null +++ b/arch/arm/mach-apple/Kconfig @@ -0,0 +1,18 @@ +if ARCH_APPLE + +config SYS_TEXT_BASE + default 0x00000000 + +config SYS_CONFIG_NAME + default "apple" + +config SYS_SOC + default "m1" + +config SYS_MALLOC_LEN + default 0x4000000 + +config SYS_MALLOC_F_LEN + default 0x4000 + +endif diff --git a/arch/arm/mach-apple/Makefile b/arch/arm/mach-apple/Makefile new file mode 100644 index 0000000000..e74a8c9df1 --- /dev/null +++ b/arch/arm/mach-apple/Makefile @@ -0,0 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0+ + +obj-y += board.o +obj-y += lowlevel_init.o diff --git a/arch/arm/mach-apple/board.c b/arch/arm/mach-apple/board.c new file mode 100644 index 0000000000..188d31a1bd --- /dev/null +++ b/arch/arm/mach-apple/board.c @@ -0,0 +1,161 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * (C) Copyright 2021 Mark Kettenis kettenis@openbsd.org + */ + +#include <common.h> +#include <dm.h> +#include <efi_loader.h> + +#include <asm/armv8/mmu.h> +#include <asm/global_data.h> +#include <asm/io.h> +#include <asm/system.h> + +DECLARE_GLOBAL_DATA_PTR; + +static struct mm_region apple_mem_map[] = { + { + /* I/O */ + .virt = 0x200000000, + .phys = 0x200000000, + .size = 8UL * SZ_1G, + .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | + PTE_BLOCK_NON_SHARE | + PTE_BLOCK_PXN | PTE_BLOCK_UXN + }, { + /* I/O */ + .virt = 0x500000000, + .phys = 0x500000000, + .size = 2UL * SZ_1G, + .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | + PTE_BLOCK_NON_SHARE | + PTE_BLOCK_PXN | PTE_BLOCK_UXN + }, { + /* I/O */ + .virt = 0x680000000, + .phys = 0x680000000, + .size = SZ_512M, + .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | + PTE_BLOCK_NON_SHARE | + PTE_BLOCK_PXN | PTE_BLOCK_UXN + }, { + /* PCIE */ + .virt = 0x6a0000000, + .phys = 0x6a0000000, + .size = SZ_512M, + .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRE) | + PTE_BLOCK_INNER_SHARE | + PTE_BLOCK_PXN | PTE_BLOCK_UXN + }, { + /* PCIE */ + .virt = 0x6c0000000, + .phys = 0x6c0000000, + .size = SZ_1G, + .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRE) | + PTE_BLOCK_INNER_SHARE | + PTE_BLOCK_PXN | PTE_BLOCK_UXN + }, { + /* RAM */ + .virt = 0x800000000, + .phys = 0x800000000, + .size = 8UL * SZ_1G, + .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | + PTE_BLOCK_INNER_SHARE + }, { + /* Empty entry for framebuffer */ + 0, + }, { + /* List terminator */ + 0, + } +}; + +struct mm_region *mem_map = apple_mem_map; + +int board_init(void) +{ + return 0; +} + +int dram_init(void) +{ + ofnode node; + int index, ret; + fdt_addr_t base; + fdt_size_t size; + + ret = fdtdec_setup_mem_size_base(); + if (ret) + return ret; + + /* Update RAM mapping */ + index = ARRAY_SIZE(apple_mem_map) - 3; + apple_mem_map[index].virt = gd->ram_base; + apple_mem_map[index].phys = gd->ram_base; + apple_mem_map[index].size = gd->ram_size; + + node = ofnode_path("/chosen/framebuffer"); + if (!ofnode_valid(node)) + return 0; + + base = ofnode_get_addr_size(node, "reg", &size); + if (base == FDT_ADDR_T_NONE) + return 0; + + /* Add framebuffer mapping */ + index = ARRAY_SIZE(apple_mem_map) - 2; + apple_mem_map[index].virt = base; + apple_mem_map[index].phys = base; + apple_mem_map[index].size = size; + apple_mem_map[index].attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL_NC) | + PTE_BLOCK_INNER_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN; + + return 0; +} + +int dram_init_banksize(void) +{ + return fdtdec_setup_memory_banksize(); +} + +#define APPLE_WDT_BASE 0x23d2b0000ULL + +#define APPLE_WDT_SYS_CTL_ENABLE BIT(2) + +typedef struct apple_wdt { + u32 reserved0[3]; + u32 chip_ctl; + u32 sys_tmr; + u32 sys_cmp; + u32 reserved1; + u32 sys_ctl; +} apple_wdt_t; + +void reset_cpu(void) +{ + apple_wdt_t *wdt = (apple_wdt_t *)APPLE_WDT_BASE; + + writel(0, &wdt->sys_cmp); + writel(APPLE_WDT_SYS_CTL_ENABLE, &wdt->sys_ctl); + + while(1) + wfi(); +} + +extern long fw_dtb_pointer; + +void *board_fdt_blob_setup(void) +{ + /* Return DTB pointer passed by m1n1 */ + return (void *)fw_dtb_pointer; +} + +ulong board_get_usable_ram_top(ulong total_size) +{ + /* + * Top part of RAM is used by firmware for things like the + * framebuffer. This gives us plenty of room to play with. + */ + return 0x980000000; +} diff --git a/arch/arm/mach-apple/lowlevel_init.S b/arch/arm/mach-apple/lowlevel_init.S new file mode 100644 index 0000000000..e1c0d91cef --- /dev/null +++ b/arch/arm/mach-apple/lowlevel_init.S @@ -0,0 +1,17 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * (C) Copyright 2021 Mark Kettenis kettenis@openbsd.org + */ + +.align 8 +.global fw_dtb_pointer +fw_dtb_pointer: + .quad 0 + +.global save_boot_params +save_boot_params: + /* Stash DTB pointer passed by m1n1 */ + adr x1, fw_dtb_pointer + str x0, [x1] + + b save_boot_params_ret diff --git a/configs/apple_m1_defconfig b/configs/apple_m1_defconfig new file mode 100644 index 0000000000..a7ae15576b --- /dev/null +++ b/configs/apple_m1_defconfig @@ -0,0 +1,14 @@ +CONFIG_ARM=y +CONFIG_ARCH_APPLE=y +# CONFIG_DISPLAY_CPUINFO is not set +# CONFIG_MMC is not set +# CONFIG_NET is not set +CONFIG_VIDEO_SIMPLE=y +CONFIG_DISPLAY_BOARDINFO_LATE=y +CONFIG_USB_XHCI_HCD=y +CONFIG_USB_XHCI_DWC3=y +CONFIG_USB_KEYBOARD=y +CONFIG_USB_STORAGE=y +CONFIG_USE_PREBOOT=y +CONFIG_PREBOOT="usb start" +# CONFIG_GENERATE_SMBIOS_TABLE is not set diff --git a/include/configs/apple.h b/include/configs/apple.h new file mode 100644 index 0000000000..1c246af002 --- /dev/null +++ b/include/configs/apple.h @@ -0,0 +1,38 @@ +#ifndef __CONFIG_H +#define __CONFIG_H + +#include <linux/sizes.h> + +#define CONFIG_SYS_LOAD_ADDR 0x880000000 + +#define CONFIG_SYS_SDRAM_BASE 0x880000000 + +#define CONFIG_LNX_KRNL_IMG_TEXT_OFFSET_BASE CONFIG_SYS_TEXT_BASE + +/* Environment */ +#define ENV_DEVICE_SETTINGS \ + "stdin=serial,usbkbd\0" \ + "stdout=serial,vidconsole\0" \ + "stderr=serial,vidconsole\0" + +#define ENV_MEM_LAYOUT_SETTINGS \ + "fdt_addr_r=0x960100000\0" \ + "kernel_addr_r=0x960200000\0" + +#if CONFIG_IS_ENABLED(CMD_USB) + #define BOOT_TARGET_USB(func) func(USB, usb, 0) +#else + #define BOOT_TARGET_USB(func) +#endif + +#define BOOT_TARGET_DEVICES(func) \ + BOOT_TARGET_USB(func) + +#include <config_distro_bootcmd.h> + +#define CONFIG_EXTRA_ENV_SETTINGS \ + ENV_DEVICE_SETTINGS \ + ENV_MEM_LAYOUT_SETTINGS \ + BOOTENV + +#endif

On Sun, 3 Oct 2021 at 12:32, Mark Kettenis kettenis@openbsd.org wrote:
Add support for Apple's M1 SoC that is used in "Apple Silicon" Macs. This builds a basic U-Boot that can be used as a payload for the m1n1 boot loader being developed by the Asahi Linux project.
Signed-off-by: Mark Kettenis kettenis@openbsd.org
arch/arm/Kconfig | 21 ++++ arch/arm/Makefile | 1 + arch/arm/mach-apple/Kconfig | 18 ++++ arch/arm/mach-apple/Makefile | 4 + arch/arm/mach-apple/board.c | 161 ++++++++++++++++++++++++++++ arch/arm/mach-apple/lowlevel_init.S | 17 +++ configs/apple_m1_defconfig | 14 +++ include/configs/apple.h | 38 +++++++ 8 files changed, 274 insertions(+) create mode 100644 arch/arm/mach-apple/Kconfig create mode 100644 arch/arm/mach-apple/Makefile create mode 100644 arch/arm/mach-apple/board.c create mode 100644 arch/arm/mach-apple/lowlevel_init.S create mode 100644 configs/apple_m1_defconfig create mode 100644 include/configs/apple.h
Reviewed-by: Simon Glass sjg@chromium.org
As mentioned, please convert to a sysreset driver soon, before the release.

Apple M1 SoCs include an S5L UART which is a variant of the S5P UART. Add support for this variant and enable it by default on Apple SoCs.
Signed-off-by: Mark Kettenis kettenis@openbsd.org --- arch/arm/Kconfig | 1 + arch/arm/include/asm/arch-m1/uart.h | 41 +++++++++++ configs/apple_m1_defconfig | 4 ++ drivers/serial/Kconfig | 4 +- drivers/serial/serial_s5p.c | 104 ++++++++++++++++++++++------ 5 files changed, 130 insertions(+), 24 deletions(-) create mode 100644 arch/arm/include/asm/arch-m1/uart.h
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 4948dad4df..876d9c4044 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -899,6 +899,7 @@ config ARCH_APPLE bool "Apple SoCs" select ARM64 select BLK + select CLK select CMD_USB select DM select DM_KEYBOARD diff --git a/arch/arm/include/asm/arch-m1/uart.h b/arch/arm/include/asm/arch-m1/uart.h new file mode 100644 index 0000000000..d2a17a221e --- /dev/null +++ b/arch/arm/include/asm/arch-m1/uart.h @@ -0,0 +1,41 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * (C) Copyright 2009 Samsung Electronics + * Minkyu Kang mk7.kang@samsung.com + * Heungjun Kim riverful.kim@samsung.com + */ + +#ifndef __ASM_ARCH_UART_H_ +#define __ASM_ARCH_UART_H_ + +#ifndef __ASSEMBLY__ +/* baudrate rest value */ +union br_rest { + unsigned short slot; /* udivslot */ + unsigned char value; /* ufracval */ +}; + +struct s5p_uart { + unsigned int ulcon; + unsigned int ucon; + unsigned int ufcon; + unsigned int umcon; + unsigned int utrstat; + unsigned int uerstat; + unsigned int ufstat; + unsigned int umstat; + unsigned int utxh; + unsigned int urxh; + unsigned int ubrdiv; + union br_rest rest; + unsigned char res3[0x3fd0]; +}; + +static inline int s5p_uart_divslot(void) +{ + return 0; +} + +#endif /* __ASSEMBLY__ */ + +#endif diff --git a/configs/apple_m1_defconfig b/configs/apple_m1_defconfig index a7ae15576b..674b74b90b 100644 --- a/configs/apple_m1_defconfig +++ b/configs/apple_m1_defconfig @@ -12,3 +12,7 @@ CONFIG_USB_STORAGE=y CONFIG_USE_PREBOOT=y CONFIG_PREBOOT="usb start" # CONFIG_GENERATE_SMBIOS_TABLE is not set +CONFIG_DEBUG_UART=y +CONFIG_DEBUG_UART_ANNOUNCE=y +CONFIG_DEBUG_UART_BASE=0x235200000 +CONFIG_DEBUG_UART_CLOCK=240000 diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index 93348c0929..033d160579 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig @@ -272,7 +272,7 @@ config DEBUG_EFI_CONSOLE
config DEBUG_UART_S5P bool "Samsung S5P" - depends on ARCH_EXYNOS || ARCH_S5PC1XX + depends on ARCH_APPLE || ARCH_EXYNOS || ARCH_S5PC1XX help Select this to enable a debug UART using the serial_s5p driver. You will need to provide parameters to make this work. The driver will @@ -719,7 +719,7 @@ config ROCKCHIP_SERIAL
config S5P_SERIAL bool "Support for Samsung S5P UART" - depends on ARCH_EXYNOS || ARCH_S5PC1XX + depends on ARCH_APPLE || ARCH_EXYNOS || ARCH_S5PC1XX default y help Select this to enable Samsung S5P UART support. diff --git a/drivers/serial/serial_s5p.c b/drivers/serial/serial_s5p.c index 6d09952a5d..53a7b0bd1b 100644 --- a/drivers/serial/serial_s5p.c +++ b/drivers/serial/serial_s5p.c @@ -14,24 +14,45 @@ #include <asm/global_data.h> #include <linux/compiler.h> #include <asm/io.h> +#if !CONFIG_IS_ENABLED(ARCH_APPLE) #include <asm/arch/clk.h> +#endif #include <asm/arch/uart.h> #include <serial.h> #include <clk.h>
DECLARE_GLOBAL_DATA_PTR;
-#define RX_FIFO_COUNT_SHIFT 0 -#define RX_FIFO_COUNT_MASK (0xff << RX_FIFO_COUNT_SHIFT) -#define RX_FIFO_FULL (1 << 8) -#define TX_FIFO_COUNT_SHIFT 16 -#define TX_FIFO_COUNT_MASK (0xff << TX_FIFO_COUNT_SHIFT) -#define TX_FIFO_FULL (1 << 24) +enum { + PORT_S5P = 0, + PORT_S5L +}; + +#define S5L_RX_FIFO_COUNT_SHIFT 0 +#define S5L_RX_FIFO_COUNT_MASK (0xf << S5L_RX_FIFO_COUNT_SHIFT) +#define S5L_RX_FIFO_FULL (1 << 8) +#define S5L_TX_FIFO_COUNT_SHIFT 4 +#define S5L_TX_FIFO_COUNT_MASK (0xf << S5L_TX_FIFO_COUNT_SHIFT) +#define S5L_TX_FIFO_FULL (1 << 9) + +#define S5P_RX_FIFO_COUNT_SHIFT 0 +#define S5P_RX_FIFO_COUNT_MASK (0xff << S5P_RX_FIFO_COUNT_SHIFT) +#define S5P_RX_FIFO_FULL (1 << 8) +#define S5P_TX_FIFO_COUNT_SHIFT 16 +#define S5P_TX_FIFO_COUNT_MASK (0xff << S5P_TX_FIFO_COUNT_SHIFT) +#define S5P_TX_FIFO_FULL (1 << 24)
/* Information about a serial port */ struct s5p_serial_plat { struct s5p_uart *reg; /* address of registers in physical memory */ + u8 reg_width; /* register width */ u8 port_id; /* uart port number */ + u8 rx_fifo_count_shift; + u8 tx_fifo_count_shift; + u32 rx_fifo_count_mask; + u32 tx_fifo_count_mask; + u32 rx_fifo_full; + u32 tx_fifo_full; };
/* @@ -71,8 +92,8 @@ static void __maybe_unused s5p_serial_init(struct s5p_uart *uart) writel(0x245, &uart->ucon); }
-static void __maybe_unused s5p_serial_baud(struct s5p_uart *uart, uint uclk, - int baudrate) +static void __maybe_unused s5p_serial_baud(struct s5p_uart *uart, u8 reg_width, + uint uclk, int baudrate) { u32 val;
@@ -82,6 +103,8 @@ static void __maybe_unused s5p_serial_baud(struct s5p_uart *uart, uint uclk,
if (s5p_uart_divslot()) writew(udivslot[val % 16], &uart->rest.slot); + else if (reg_width == 4) + writel(val % 16, &uart->rest.value); else writeb(val % 16, &uart->rest.value); } @@ -93,7 +116,7 @@ int s5p_serial_setbrg(struct udevice *dev, int baudrate) struct s5p_uart *const uart = plat->reg; u32 uclk;
-#ifdef CONFIG_CLK_EXYNOS +#if CONFIG_IS_ENABLED(CLK_EXYNOS) || CONFIG_IS_ENABLED(ARCH_APPLE) struct clk clk; u32 ret;
@@ -105,7 +128,7 @@ int s5p_serial_setbrg(struct udevice *dev, int baudrate) uclk = get_uart_clk(plat->port_id); #endif
- s5p_serial_baud(uart, uclk, baudrate); + s5p_serial_baud(uart, plat->reg_width, uclk, baudrate);
return 0; } @@ -144,11 +167,14 @@ static int s5p_serial_getc(struct udevice *dev) struct s5p_serial_plat *plat = dev_get_plat(dev); struct s5p_uart *const uart = plat->reg;
- if (!(readl(&uart->ufstat) & RX_FIFO_COUNT_MASK)) + if (!(readl(&uart->ufstat) & plat->rx_fifo_count_mask)) return -EAGAIN;
serial_err_check(uart, 0); - return (int)(readb(&uart->urxh) & 0xff); + if (plat->reg_width == 4) + return (int)(readl(&uart->urxh) & 0xff); + else + return (int)(readb(&uart->urxh) & 0xff); }
static int s5p_serial_putc(struct udevice *dev, const char ch) @@ -156,10 +182,13 @@ static int s5p_serial_putc(struct udevice *dev, const char ch) struct s5p_serial_plat *plat = dev_get_plat(dev); struct s5p_uart *const uart = plat->reg;
- if (readl(&uart->ufstat) & TX_FIFO_FULL) + if (readl(&uart->ufstat) & plat->tx_fifo_full) return -EAGAIN;
- writeb(ch, &uart->utxh); + if (plat->reg_width == 4) + writel(ch, &uart->utxh); + else + writeb(ch, &uart->utxh); serial_err_check(uart, 1);
return 0; @@ -171,15 +200,19 @@ static int s5p_serial_pending(struct udevice *dev, bool input) struct s5p_uart *const uart = plat->reg; uint32_t ufstat = readl(&uart->ufstat);
- if (input) - return (ufstat & RX_FIFO_COUNT_MASK) >> RX_FIFO_COUNT_SHIFT; - else - return (ufstat & TX_FIFO_COUNT_MASK) >> TX_FIFO_COUNT_SHIFT; + if (input) { + return (ufstat & plat->rx_fifo_count_mask) >> + plat->rx_fifo_count_shift; + } else { + return (ufstat & plat->tx_fifo_count_mask) >> + plat->tx_fifo_count_shift; + } }
static int s5p_serial_of_to_plat(struct udevice *dev) { struct s5p_serial_plat *plat = dev_get_plat(dev); + const ulong port_type = dev_get_driver_data(dev); fdt_addr_t addr;
addr = dev_read_addr(dev); @@ -187,8 +220,26 @@ static int s5p_serial_of_to_plat(struct udevice *dev) return -EINVAL;
plat->reg = (struct s5p_uart *)addr; + plat->reg_width = dev_read_u32_default(dev, "reg-io-width", 1); plat->port_id = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev), "id", dev_seq(dev)); + + if (port_type == PORT_S5L) { + plat->rx_fifo_count_shift = S5L_RX_FIFO_COUNT_SHIFT; + plat->rx_fifo_count_mask = S5L_RX_FIFO_COUNT_MASK; + plat->rx_fifo_full = S5L_RX_FIFO_FULL; + plat->tx_fifo_count_shift = S5L_TX_FIFO_COUNT_SHIFT; + plat->tx_fifo_count_mask = S5L_TX_FIFO_COUNT_MASK; + plat->tx_fifo_full = S5L_TX_FIFO_FULL; + } else { + plat->rx_fifo_count_shift = S5P_RX_FIFO_COUNT_SHIFT; + plat->rx_fifo_count_mask = S5P_RX_FIFO_COUNT_MASK; + plat->rx_fifo_full = S5P_RX_FIFO_FULL; + plat->tx_fifo_count_shift = S5P_TX_FIFO_COUNT_SHIFT; + plat->tx_fifo_count_mask = S5P_TX_FIFO_COUNT_MASK; + plat->tx_fifo_full = S5P_TX_FIFO_FULL; + } + return 0; }
@@ -200,7 +251,8 @@ static const struct dm_serial_ops s5p_serial_ops = { };
static const struct udevice_id s5p_serial_ids[] = { - { .compatible = "samsung,exynos4210-uart" }, + { .compatible = "samsung,exynos4210-uart", .data = PORT_S5P }, + { .compatible = "apple,s5l-uart", .data = PORT_S5L }, { } };
@@ -224,16 +276,24 @@ static inline void _debug_uart_init(void) struct s5p_uart *uart = (struct s5p_uart *)CONFIG_DEBUG_UART_BASE;
s5p_serial_init(uart); - s5p_serial_baud(uart, CONFIG_DEBUG_UART_CLOCK, CONFIG_BAUDRATE); +#if CONFIG_IS_ENABLED(ARCH_APPLE) + s5p_serial_baud(uart, 4, CONFIG_DEBUG_UART_CLOCK, CONFIG_BAUDRATE); +#else + s5p_serial_baud(uart, 1, CONFIG_DEBUG_UART_CLOCK, CONFIG_BAUDRATE); +#endif }
static inline void _debug_uart_putc(int ch) { struct s5p_uart *uart = (struct s5p_uart *)CONFIG_DEBUG_UART_BASE;
- while (readl(&uart->ufstat) & TX_FIFO_FULL); - +#if CONFIG_IS_ENABLED(ARCH_APPLE) + while (readl(&uart->ufstat) & S5L_TX_FIFO_FULL); + writel(ch, &uart->utxh); +#else + while (readl(&uart->ufstat) & S5P_TX_FIFO_FULL); writeb(ch, &uart->utxh); +#endif }
DEBUG_UART_FUNCS

Hi Mark,
On Sun, 3 Oct 2021 at 12:33, Mark Kettenis kettenis@openbsd.org wrote:
Apple M1 SoCs include an S5L UART which is a variant of the S5P UART. Add support for this variant and enable it by default on Apple SoCs.
Signed-off-by: Mark Kettenis kettenis@openbsd.org
arch/arm/Kconfig | 1 + arch/arm/include/asm/arch-m1/uart.h | 41 +++++++++++ configs/apple_m1_defconfig | 4 ++ drivers/serial/Kconfig | 4 +- drivers/serial/serial_s5p.c | 104 ++++++++++++++++++++++------ 5 files changed, 130 insertions(+), 24 deletions(-) create mode 100644 arch/arm/include/asm/arch-m1/uart.h
Reviewed-by: Simon Glass sjg@chromium.org [..]
diff --git a/drivers/serial/serial_s5p.c b/drivers/serial/serial_s5p.c index 6d09952a5d..53a7b0bd1b 100644 --- a/drivers/serial/serial_s5p.c +++ b/drivers/serial/serial_s5p.c
[..]
@@ -93,7 +116,7 @@ int s5p_serial_setbrg(struct udevice *dev, int baudrate) struct s5p_uart *const uart = plat->reg; u32 uclk;
-#ifdef CONFIG_CLK_EXYNOS +#if CONFIG_IS_ENABLED(CLK_EXYNOS) || CONFIG_IS_ENABLED(ARCH_APPLE)
I really don't like making this any worse.
Does this work?
ret = clk_get_by_index(...) if (ret && ret != -ENOSYS) return ret
struct clk clk; u32 ret;
@@ -105,7 +128,7 @@ int s5p_serial_setbrg(struct udevice *dev, int baudrate) uclk = get_uart_clk(plat->port_id); #endif
s5p_serial_baud(uart, uclk, baudrate);
s5p_serial_baud(uart, plat->reg_width, uclk, baudrate); return 0;
}
[..]
Regards, Simon

From: Simon Glass sjg@chromium.org Date: Mon, 11 Oct 2021 11:00:39 -0600
Hi Mark,
On Sun, 3 Oct 2021 at 12:33, Mark Kettenis kettenis@openbsd.org wrote:
Apple M1 SoCs include an S5L UART which is a variant of the S5P UART. Add support for this variant and enable it by default on Apple SoCs.
Signed-off-by: Mark Kettenis kettenis@openbsd.org
arch/arm/Kconfig | 1 + arch/arm/include/asm/arch-m1/uart.h | 41 +++++++++++ configs/apple_m1_defconfig | 4 ++ drivers/serial/Kconfig | 4 +- drivers/serial/serial_s5p.c | 104 ++++++++++++++++++++++------ 5 files changed, 130 insertions(+), 24 deletions(-) create mode 100644 arch/arm/include/asm/arch-m1/uart.h
Reviewed-by: Simon Glass sjg@chromium.org [..]
diff --git a/drivers/serial/serial_s5p.c b/drivers/serial/serial_s5p.c index 6d09952a5d..53a7b0bd1b 100644 --- a/drivers/serial/serial_s5p.c +++ b/drivers/serial/serial_s5p.c
[..]
@@ -93,7 +116,7 @@ int s5p_serial_setbrg(struct udevice *dev, int baudrate) struct s5p_uart *const uart = plat->reg; u32 uclk;
-#ifdef CONFIG_CLK_EXYNOS +#if CONFIG_IS_ENABLED(CLK_EXYNOS) || CONFIG_IS_ENABLED(ARCH_APPLE)
I really don't like making this any worse.
Does this work?
ret = clk_get_by_index(...) if (ret && ret != -ENOSYS) return ret
The problem really is that I'm trying to avoid having to define get_uart_clock() for the new platform. So I need an #if of some sorts to avoid that code. I really think the current diff is the cleanest I can come up.
struct clk clk; u32 ret;
@@ -105,7 +128,7 @@ int s5p_serial_setbrg(struct udevice *dev, int baudrate) uclk = get_uart_clk(plat->port_id); #endif
s5p_serial_baud(uart, uclk, baudrate);
s5p_serial_baud(uart, plat->reg_width, uclk, baudrate); return 0;
}
[..]
Regards, Simon

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 --- 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 876d9c4044..91bf6a122a 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -906,6 +906,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 8cb377560e..51694c168c 100644 --- a/drivers/iommu/Kconfig +++ b/drivers/iommu/Kconfig @@ -10,4 +10,14 @@ config IOMMU help Enable driver model for IOMMU devices.
+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@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 +};

On Sun, 3 Oct 2021 at 12:34, Mark Kettenis kettenis@openbsd.org wrote:
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
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
Reviewed-by: Simon Glass sjg@chromium.org

Add preliminary device trees for the Apple M1 mini (2020) and Apple M1 Macbook Pro 13" (2020). Device tree bindings for the Apple M1 SoC are still being formalized and these device trees will be synchronized with the Linux kernel as needed.
These device trees are provided as a reference only as U-Boot uses the device tree passed by the m1n1 bootloader.
Signed-off-by: Mark Kettenis kettenis@openbsd.org --- arch/arm/dts/Makefile | 4 + arch/arm/dts/t8103-j274.dts | 135 +++++ arch/arm/dts/t8103-j293.dts | 97 +++ arch/arm/dts/t8103.dtsi | 560 ++++++++++++++++++ configs/apple_m1_defconfig | 1 + .../interrupt-controller/apple-aic.h | 15 + include/dt-bindings/pinctrl/apple.h | 13 + include/dt-bindings/spmi/spmi.h | 10 + 8 files changed, 835 insertions(+) create mode 100644 arch/arm/dts/t8103-j274.dts create mode 100644 arch/arm/dts/t8103-j293.dts create mode 100644 arch/arm/dts/t8103.dtsi create mode 100644 include/dt-bindings/interrupt-controller/apple-aic.h create mode 100644 include/dt-bindings/pinctrl/apple.h create mode 100644 include/dt-bindings/spmi/spmi.h
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index fc16a57e60..65152d3ddf 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -29,6 +29,10 @@ dtb-$(CONFIG_EXYNOS5) += exynos5250-arndale.dtb \ exynos5422-odroidxu3.dtb dtb-$(CONFIG_EXYNOS7420) += exynos7420-espresso7420.dtb
+dtb-$(CONFIG_ARCH_APPLE) += \ + t8103-j274.dtb \ + t8103-j293.dtb + dtb-$(CONFIG_ARCH_DAVINCI) += \ da850-evm.dtb \ da850-lcdk.dtb \ diff --git a/arch/arm/dts/t8103-j274.dts b/arch/arm/dts/t8103-j274.dts new file mode 100644 index 0000000000..aef1ae29b6 --- /dev/null +++ b/arch/arm/dts/t8103-j274.dts @@ -0,0 +1,135 @@ +// SPDX-License-Identifier: GPL-2.0+ OR MIT +/* + * Apple Mac mini (M1, 2020) + * + * target-type: J274 + * + * Copyright The Asahi Linux Contributors + */ + +/dts-v1/; + +#include "t8103.dtsi" + +/ { + compatible = "apple,j274", "apple,t8103", "apple,arm-platform"; + model = "Apple Mac mini (M1, 2020)"; + + aliases { + serial0 = &serial0; + ethernet0 = ð0; + wifi0 = &wifi0; + }; + + chosen { + #address-cells = <2>; + #size-cells = <2>; + ranges; + + stdout-path = "serial0"; + + framebuffer0: framebuffer@0 { + compatible = "apple,simple-framebuffer", "simple-framebuffer"; + reg = <0 0 0 0>; /* To be filled by loader */ + /* Format properties will be added by loader */ + status = "disabled"; + }; + }; + + memory@800000000 { + device_type = "memory"; + reg = <0x8 0 0x2 0>; /* To be filled by loader */ + }; +}; + +&serial0 { + status = "okay"; +}; + +&pcie0_dart_0 { + status = "okay"; +}; + +&pcie0_dart_1 { + status = "okay"; +}; + +&pcie0_dart_2 { + status = "okay"; +}; + +&pcie0 { + status = "okay"; + + pci0: pci@0,0 { + device_type = "pci"; + reg = <0x0 0x0 0x0 0x0 0x0>; + pwren-gpios = <&smc 13 0>; + reset-gpios = <&pinctrl_ap 152 0>; + max-link-speed = <2>; + + #address-cells = <3>; + #size-cells = <2>; + ranges; + }; + + pci1: pci@1,0 { + device_type = "pci"; + reg = <0x800 0x0 0x0 0x0 0x0>; + reset-gpios = <&pinctrl_ap 153 0>; + max-link-speed = <2>; + + #address-cells = <3>; + #size-cells = <2>; + ranges; + }; + + pci2: pci@2,0 { + device_type = "pci"; + reg = <0x1000 0x0 0x0 0x0 0x0>; + reset-gpios = <&pinctrl_ap 33 0>; + max-link-speed = <1>; + + #address-cells = <3>; + #size-cells = <2>; + ranges; + }; +}; + +&pci0 { + wifi0: network@0,0 { + reg = <0x10000 0x0 0x0 0x0 0x0>; + local-mac-address = [00 00 00 00 00 00]; + }; +}; + +&pci2 { + eth0: ethernet@0,0 { + reg = <0x30000 0x0 0x0 0x0 0x0>; + local-mac-address = [00 00 00 00 00 00]; + }; +}; + +&dwc3_0_dart_0 { + status = "okay"; +}; + +&dwc3_0_dart_1 { + status = "okay"; +}; + +&dwc3_0 { + status = "okay"; +}; + +&dwc3_1_dart_0 { + status = "okay"; +}; + +&dwc3_1_dart_1 { + status = "okay"; +}; + +&dwc3_1 { + status = "okay"; +}; diff --git a/arch/arm/dts/t8103-j293.dts b/arch/arm/dts/t8103-j293.dts new file mode 100644 index 0000000000..4a22596cf4 --- /dev/null +++ b/arch/arm/dts/t8103-j293.dts @@ -0,0 +1,97 @@ +// SPDX-License-Identifier: GPL-2.0+ OR MIT +/* + * Apple Macbook Pro (M1, 2020) + * + * target-type: J293 + * + * Copyright The Asahi Linux Contributors + */ + +/dts-v1/; + +#include "t8103.dtsi" + +/ { + compatible = "apple,j293", "apple,t8103", "apple,arm-platform"; + model = "Apple Macbook Pro (M1, 2020)"; + + aliases { + serial0 = &serial0; + wifi0 = &wifi0; + }; + + chosen { + #address-cells = <2>; + #size-cells = <2>; + ranges; + + stdout-path = "serial0"; + + framebuffer0: framebuffer@0 { + compatible = "apple,simple-framebuffer", "simple-framebuffer"; + reg = <0 0 0 0>; /* To be filled by loader */ + /* Format properties will be added by loader */ + status = "disabled"; + }; + }; + + memory@800000000 { + device_type = "memory"; + reg = <0x8 0 0x2 0>; /* To be filled by loader */ + }; +}; + +&serial0 { + status = "okay"; +}; + +&pcie0_dart_0 { + status = "okay"; +}; + +&pcie0 { + status = "okay"; + + pci0: pci@0,0 { + device_type = "pci"; + reg = <0x0 0x0 0x0 0x0 0x0>; + pwren-gpios = <&smc 13 0>; + reset-gpios = <&pinctrl_ap 152 0>; + max-link-speed = <2>; + + #address-cells = <3>; + #size-cells = <2>; + ranges; + }; +}; + +&pci0 { + wifi0: network@0,0 { + reg = <0x10000 0x0 0x0 0x0 0x0>; + local-mac-address = [00 00 00 00 00 00]; + }; +}; + +&dwc3_0_dart_0 { + status = "okay"; +}; + +&dwc3_0_dart_1 { + status = "okay"; +}; + +&dwc3_0 { + status = "okay"; +}; + +&dwc3_1_dart_0 { + status = "okay"; +}; + +&dwc3_1_dart_1 { + status = "okay"; +}; + +&dwc3_1 { + status = "okay"; +}; diff --git a/arch/arm/dts/t8103.dtsi b/arch/arm/dts/t8103.dtsi new file mode 100644 index 0000000000..7d9cb272f9 --- /dev/null +++ b/arch/arm/dts/t8103.dtsi @@ -0,0 +1,560 @@ +// SPDX-License-Identifier: GPL-2.0+ OR MIT +/* + * Apple T8103 "M1" SoC + * + * Other names: H13G, "Tonga" + * + * Copyright The Asahi Linux Contributors + */ + +#include <dt-bindings/gpio/gpio.h> +#include <dt-bindings/interrupt-controller/apple-aic.h> +#include <dt-bindings/interrupt-controller/irq.h> +#include <dt-bindings/pinctrl/apple.h> +#include <dt-bindings/spmi/spmi.h> + +/ { + compatible = "apple,t8103", "apple,arm-platform"; + + #address-cells = <2>; + #size-cells = <2>; + + cpus { + #address-cells = <2>; + #size-cells = <0>; + + cpu0: cpu@0 { + compatible = "apple,icestorm"; + device_type = "cpu"; + reg = <0x0 0x0>; + enable-method = "spin-table"; + cpu-release-addr = <0 0>; /* To be filled by loader */ + }; + + cpu1: cpu@1 { + compatible = "apple,icestorm"; + device_type = "cpu"; + reg = <0x0 0x1>; + enable-method = "spin-table"; + cpu-release-addr = <0 0>; /* To be filled by loader */ + }; + + cpu2: cpu@2 { + compatible = "apple,icestorm"; + device_type = "cpu"; + reg = <0x0 0x2>; + enable-method = "spin-table"; + cpu-release-addr = <0 0>; /* To be filled by loader */ + }; + + cpu3: cpu@3 { + compatible = "apple,icestorm"; + device_type = "cpu"; + reg = <0x0 0x3>; + enable-method = "spin-table"; + cpu-release-addr = <0 0>; /* To be filled by loader */ + }; + + cpu4: cpu@10100 { + compatible = "apple,firestorm"; + device_type = "cpu"; + reg = <0x0 0x10100>; + enable-method = "spin-table"; + cpu-release-addr = <0 0>; /* To be filled by loader */ + }; + + cpu5: cpu@10101 { + compatible = "apple,firestorm"; + device_type = "cpu"; + reg = <0x0 0x10101>; + enable-method = "spin-table"; + cpu-release-addr = <0 0>; /* To be filled by loader */ + }; + + cpu6: cpu@10102 { + compatible = "apple,firestorm"; + device_type = "cpu"; + reg = <0x0 0x10102>; + enable-method = "spin-table"; + cpu-release-addr = <0 0>; /* To be filled by loader */ + }; + + cpu7: cpu@10103 { + compatible = "apple,firestorm"; + device_type = "cpu"; + reg = <0x0 0x10103>; + enable-method = "spin-table"; + cpu-release-addr = <0 0>; /* To be filled by loader */ + }; + }; + + timer { + compatible = "arm,armv8-timer"; + interrupt-parent = <&aic>; + interrupt-names = "hyp-phys", "hyp-virt", "phys", "virt"; + interrupts = <AIC_FIQ AIC_TMR_HV_PHYS IRQ_TYPE_LEVEL_HIGH>, + <AIC_FIQ AIC_TMR_HV_VIRT IRQ_TYPE_LEVEL_HIGH>, + <AIC_FIQ AIC_TMR_GUEST_PHYS IRQ_TYPE_LEVEL_HIGH>, + <AIC_FIQ AIC_TMR_GUEST_VIRT IRQ_TYPE_LEVEL_HIGH>; + }; + + clkref: clock-ref { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <24000000>; + clock-output-names = "clkref"; + }; + + soc { + compatible = "simple-bus"; + #address-cells = <2>; + #size-cells = <2>; + + ranges; + dma-ranges; + dma-coherent; + nonposted-mmio; + + serial0: serial@235200000 { + compatible = "apple,s5l-uart"; + reg = <0x2 0x35200000 0x0 0x1000>; + reg-io-width = <4>; + interrupt-parent = <&aic>; + interrupts = <AIC_IRQ 605 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clkref>, <&clkref>, <&clkref>; + clock-names = "uart", "clk_uart_baud0", "clk_uart_baud1"; + power-domains = <&ps_uart0>; + status = "disabled"; + }; + + serial2: serial@235208000 { + compatible = "apple,s5l-uart"; + reg = <0x2 0x35208000 0x0 0x1000>; + reg-io-width = <4>; + interrupt-parent = <&aic>; + interrupts = <AIC_IRQ 607 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clkref>, <&clkref>, <&clkref>; + clock-names = "uart", "clk_uart_baud0", "clk_uart_baud1"; + power-domains = <&ps_uart2>; + status = "disabled"; + }; + + aic: interrupt-controller@23b100000 { + compatible = "apple,t8103-aic", "apple,aic"; + #interrupt-cells = <3>; + interrupt-controller; + reg = <0x2 0x3b100000 0x0 0x8000>; + }; + + pmgr: power-controller@23b700000 { + compatible = "apple,t8103-pmgr", "apple,pmgr", "syscon", "simple-mfd"; + #address-cells = <1>; + #size-cells = <0>; + + reg = <0x2 0x3b700000 0x0 0x14000>; + + ps_pcie_ref: power-controller@1a0 { + compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate"; + reg = <0x1a0>; + #power-domain-cells = <0>; + #reset-cells = <0>; + apple,domain-name = "pcie_ref"; + }; + + ps_imx: power-controller@1b8 { + compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate"; + reg = <0x1b8>; + #power-domain-cells = <0>; + #reset-cells = <0>; + apple,domain-name = "imx"; + apple,always-on; + }; + + ps_sio: power-controller@1c0 { + compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate"; + reg = <0x1c0>; + #power-domain-cells = <0>; + #reset-cells = <0>; + apple,domain-name = "sio"; + }; + + ps_uart_p: power-controller@220 { + compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate"; + reg = <0x220>; + #power-domain-cells = <0>; + #reset-cells = <0>; + power-domains = <&ps_sio>; + apple,domain-name = "uart_p"; + }; + + ps_uart0: power-controller@270 { + compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate"; + reg = <0x270>; + #power-domain-cells = <0>; + #reset-cells = <0>; + power-domains = <&ps_uart_p>; + apple,domain-name = "uart0"; + }; + + ps_uart1: power-controller@278 { + compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate"; + reg = <0x278>; + #power-domain-cells = <0>; + #reset-cells = <0>; + apple,domain-name = "uart1"; + power-domains = <&ps_uart_p>; + }; + + ps_uart2: power-controller@280 { + compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate"; + reg = <0x280>; + #power-domain-cells = <0>; + #reset-cells = <0>; + apple,domain-name = "uart2"; + power-domains = <&ps_uart_p>; + }; + + ps_uart3: power-controller@288 { + compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate"; + reg = <0x288>; + #power-domain-cells = <0>; + #reset-cells = <0>; + apple,domain-name = "uart3"; + power-domains = <&ps_uart_p>; + }; + + ps_apcie: power-controller@348 { + compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate"; + reg = <0x348>; + #power-domain-cells = <0>; + #reset-cells = <0>; + apple,domain-name = "apcie"; + power-domains = <&ps_imx>; + }; + + ps_apcie_gp: power-controller@3e8 { + compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate"; + reg = <0x3e8>; + #power-domain-cells = <0>; + #reset-cells = <0>; + apple,domain-name = "apcie_gp"; + power-domains = <&ps_apcie>; + }; + + ps_ans2: power-controller@3f0 { + compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate"; + reg = <0x3f0>; + #power-domain-cells = <0>; + #reset-cells = <0>; + apple,domain-name = "ans2"; + power-domains = <&ps_apcie_st>; + }; + + ps_apcie_st: power-controller@418 { + compatible = "apple,t8103-pmgr-pwrstate", "apple,pmgr-pwrstate"; + reg = <0x418>; + #power-domain-cells = <0>; + #reset-cells = <0>; + apple,domain-name = "apcie_st"; + power-domains = <&ps_apcie>; + }; + }; + + pinctrl_ap: pinctrl@23c100000 { + compatible = "apple,t8103-pinctrl", "apple,pinctrl"; + reg = <0x2 0x3c100000 0x0 0x100000>; + + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&pinctrl_ap 0 0 212>; + + interrupt-controller; + interrupt-parent = <&aic>; + interrupts = <AIC_IRQ 190 IRQ_TYPE_LEVEL_HIGH>, + <AIC_IRQ 191 IRQ_TYPE_LEVEL_HIGH>, + <AIC_IRQ 192 IRQ_TYPE_LEVEL_HIGH>, + <AIC_IRQ 193 IRQ_TYPE_LEVEL_HIGH>, + <AIC_IRQ 194 IRQ_TYPE_LEVEL_HIGH>, + <AIC_IRQ 195 IRQ_TYPE_LEVEL_HIGH>, + <AIC_IRQ 196 IRQ_TYPE_LEVEL_HIGH>; + + i2c0_pins: i2c0_pins { + pinmux = <APPLE_PINMUX(188, 1)>, + <APPLE_PINMUX(192, 1)>; + }; + + pcie_pins: pcie-pins { + pinmux = <APPLE_PINMUX(150, 1)>, + <APPLE_PINMUX(151, 1)>, + <APPLE_PINMUX(32, 1)>; + }; + }; + + pinctrl_aop: pinctrl@24a820000 { + compatible = "apple,t8103-pinctrl", "apple,pinctrl"; + reg = <0x2 0x4a820000 0x0 0x4000>; + + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&pinctrl_aop 0 0 42>; + + interrupt-controller; + interrupt-parent = <&aic>; + interrupts = <AIC_IRQ 268 IRQ_TYPE_LEVEL_HIGH>, + <AIC_IRQ 269 IRQ_TYPE_LEVEL_HIGH>, + <AIC_IRQ 270 IRQ_TYPE_LEVEL_HIGH>, + <AIC_IRQ 271 IRQ_TYPE_LEVEL_HIGH>, + <AIC_IRQ 272 IRQ_TYPE_LEVEL_HIGH>, + <AIC_IRQ 273 IRQ_TYPE_LEVEL_HIGH>, + <AIC_IRQ 274 IRQ_TYPE_LEVEL_HIGH>; + }; + + pinctrl_nub: pinctrl@23d1f0000 { + compatible = "apple,t8103-pinctrl", "apple,pinctrl"; + reg = <0x2 0x3d1f0000 0x0 0x4000>; + + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&pinctrl_nub 0 0 23>; + + interrupt-controller; + interrupt-parent = <&aic>; + interrupts = <AIC_IRQ 330 IRQ_TYPE_LEVEL_HIGH>, + <AIC_IRQ 331 IRQ_TYPE_LEVEL_HIGH>, + <AIC_IRQ 332 IRQ_TYPE_LEVEL_HIGH>, + <AIC_IRQ 333 IRQ_TYPE_LEVEL_HIGH>, + <AIC_IRQ 334 IRQ_TYPE_LEVEL_HIGH>, + <AIC_IRQ 335 IRQ_TYPE_LEVEL_HIGH>, + <AIC_IRQ 336 IRQ_TYPE_LEVEL_HIGH>; + }; + + pinctrl_smc: pinctrl@23e820000 { + compatible = "apple,t8103-pinctrl", "apple,pinctrl"; + reg = <0x2 0x3e820000 0x0 0x4000>; + + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&pinctrl_smc 0 0 16>; + + interrupt-controller; + interrupt-parent = <&aic>; + interrupts = <AIC_IRQ 391 IRQ_TYPE_LEVEL_HIGH>, + <AIC_IRQ 392 IRQ_TYPE_LEVEL_HIGH>, + <AIC_IRQ 393 IRQ_TYPE_LEVEL_HIGH>, + <AIC_IRQ 394 IRQ_TYPE_LEVEL_HIGH>, + <AIC_IRQ 395 IRQ_TYPE_LEVEL_HIGH>, + <AIC_IRQ 396 IRQ_TYPE_LEVEL_HIGH>, + <AIC_IRQ 397 IRQ_TYPE_LEVEL_HIGH>; + }; + + i2c0: i2c@20a110000 { + compatible = "apple,i2c-v0"; + reg = <0x2 0x35010000 0x0 0x4000>; + interrupt-parent = <&aic>; + interrupts = <AIC_IRQ 627 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clkref>; + pinctrl-0 = <&i2c0_pins>; + pinctrl-names = "default"; + #address-cells = <0x1>; + #size-cells = <0x0>; + + hpm0: hpm@38 { + compatible = "ti,tps6598x"; + reg = <0x38>; + }; + + hpm1: hpm@3f { + compatible = "ti,tps6598x"; + reg = <0x3f>; + }; + }; + + ans_mbox: mbox@277400000 { + compatible = "apple,iop-mailbox-m1"; + reg = <0x2 0x77400000 0x0 0x20000>; + interrupt-parent = <&aic>; + interrupts = <AIC_IRQ 583 IRQ_TYPE_LEVEL_HIGH>, + <AIC_IRQ 586 IRQ_TYPE_LEVEL_HIGH>; + power-domains = <&ps_ans2>; + #mbox-cells = <1>; + endpoints = <32>; + }; + + ans@27bcc0000 { + compatible = "apple,nvme-m1"; + reg = <0x2 0x7bcc0000 0x0 0x40000>, + <0x2 0x7bc50000 0x0 0x4000>; + interrupt-parent = <&aic>; + interrupts = <AIC_IRQ 590 IRQ_TYPE_LEVEL_HIGH>; + power-domains = <&ps_apcie_st>; + mboxes = <&ans_mbox 32>; + }; + + pcie0_dart_0: iommu@681008000 { + compatible = "apple,t8103-dart", "apple,dart-m1"; + reg = <0x6 0x81008000 0x0 0x4000>; + interrupt-parent = <&aic>; + interrupts = <AIC_IRQ 696 IRQ_TYPE_LEVEL_HIGH>; + #iommu-cells = <1>; + status = "disabled"; + }; + + pcie0_dart_1: iommu@682008000 { + compatible = "apple,t8103-dart", "apple,dart-m1"; + reg = <0x6 0x82008000 0x0 0x4000>; + interrupt-parent = <&aic>; + interrupts = <AIC_IRQ 699 IRQ_TYPE_LEVEL_HIGH>; + #iommu-cells = <1>; + status = "disabled"; + }; + + pcie0_dart_2: iommu@683008000 { + compatible = "apple,t8103-dart", "apple,dart-m1"; + reg = <0x6 0x83008000 0x0 0x4000>; + interrupt-parent = <&aic>; + interrupts = <AIC_IRQ 702 IRQ_TYPE_LEVEL_HIGH>; + #iommu-cells = <1>; + status = "disabled"; + }; + + smc_mbox: mbox@23e400000 { + compatible = "apple,iop-mailbox-m1"; + reg = <0x2 0x3e400000 0x0 0x20000>; + #mbox-cells = <1>; + endpoints = <32>; + }; + + smc: smc@23e050000 { + compatible = "apple,smc-m1"; + reg = <0x2 0x3e050000 0x0 0x4000>; + mboxes = <&smc_mbox 32>; + gpio-controller; + #gpio-cells = <2>; + gpio-13 = <0x00800000>; + }; + + pcie0: pcie@690000000 { + compatible = "apple,t8103-pcie", "apple,pcie"; + + reg = <0x6 0x90000000 0x0 0x1000000>, + <0x6 0x80000000 0x0 0x4000>, + <0x6 0x81000000 0x0 0x8000>, + <0x6 0x82000000 0x0 0x8000>, + <0x6 0x83000000 0x0 0x8000>; + reg-names = "config", "rc", "port0", "port1", "port2"; + + interrupt-parent = <&aic>; + interrupts = <AIC_IRQ 695 IRQ_TYPE_LEVEL_HIGH>, + <AIC_IRQ 698 IRQ_TYPE_LEVEL_HIGH>, + <AIC_IRQ 701 IRQ_TYPE_LEVEL_HIGH>; + + msi-controller; + msi-parent = <&pcie0>; + msi-ranges = <&aic AIC_IRQ 704 IRQ_TYPE_EDGE_RISING 32>; + + iommu-map = <0x100 &pcie0_dart_0 1 1>, + <0x200 &pcie0_dart_1 1 1>, + <0x300 &pcie0_dart_2 1 1>; + iommu-map-mask = <0xff00>; + + bus-range = <0 3>; + #address-cells = <3>; + #size-cells = <2>; + ranges = <0x43000000 0x6 0xa0000000 0x6 0xa0000000 + 0x0 0x20000000>, + <0x02000000 0x0 0xc0000000 0x6 0xc0000000 + 0x0 0x40000000>; + + power-domains = <&ps_apcie>, <&ps_apcie_gp>, <&ps_pcie_ref>; + pinctrl-0 = <&pcie_pins>; + pinctrl-names = "default"; + + device_type = "pci"; + status = "disabled"; + }; + + dwc3_0_dart_0: iommu@382f00000 { + compatible = "apple,t8103-dart"; + reg = <0x3 0x82f00000 0x0 0x4000>; + interrupt-parent = <&aic>; + interrupts = <AIC_IRQ 781 IRQ_TYPE_LEVEL_HIGH>; + #iommu-cells = <1>; + status = "disabled"; + }; + + dwc3_0_dart_1: iommu@382f80000 { + compatible = "apple,t8103-dart"; + reg = <0x3 0x82f80000 0x0 0x4000>; + interrupt-parent = <&aic>; + interrupts = <AIC_IRQ 781 IRQ_TYPE_LEVEL_HIGH>; + #iommu-cells = <1>; + status = "disabled"; + }; + + dwc3_0: usb@382280000{ + compatible = "snps,dwc3"; + reg = <0x3 0x82280000 0x0 0x100000>; + interrupt-parent = <&aic>; + interrupts = <AIC_IRQ 777 IRQ_TYPE_LEVEL_HIGH>; + dr_mode = "host"; + iommus = <&dwc3_0_dart_0 0>, <&dwc3_0_dart_1 1>; + status = "disabled"; + }; + + dwc3_1_dart_0: iommu@502f00000 { + compatible = "apple,t8103-dart"; + reg = <0x5 0x02f00000 0x0 0x4000>; + interrupt-parent = <&aic>; + interrupts = <AIC_IRQ 861 IRQ_TYPE_LEVEL_HIGH>; + #iommu-cells = <1>; + status = "disabled"; + }; + + dwc3_1_dart_1: iommu@502f80000 { + compatible = "apple,t8103-dart"; + reg = <0x5 0x02f80000 0x0 0x4000>; + interrupt-parent = <&aic>; + interrupts = <AIC_IRQ 861 IRQ_TYPE_LEVEL_HIGH>; + #iommu-cells = <1>; + status = "disabled"; + }; + + dwc3_1: usb@502280000{ + compatible = "snps,dwc3"; + reg = <0x5 0x02280000 0x0 0x100000>; + interrupt-parent = <&aic>; + interrupts = <AIC_IRQ 857 IRQ_TYPE_LEVEL_HIGH>; + dr_mode = "host"; + iommus = <&dwc3_1_dart_0 0>, <&dwc3_1_dart_1 1>; + status = "disabled"; + }; + + reboot@23d2b0000 { + compatible = "apple,reboot-v0"; + reg = <0x2 0x3d2b0000 0x0 0x4000>; + }; + + spi@23510c000 { + compatible = "apple,t8103-spi", "apple,spi"; + reg = <0x2 0x3510c000 0x0 0x4000>; + interrupt-parent = <&aic>; + interrupts = <AIC_IRQ 617 IRQ_TYPE_LEVEL_HIGH>; + cs-gpios = <&pinctrl_ap 49 GPIO_ACTIVE_HIGH>; + }; + + spmi@23d0d8000 { + compatible = "apple,t8103-spmi", "apple,spmi"; + reg = <0x2 0x3d0d9300 0x0 0x100>; + interrupt-parent = <&aic>; + interrupts = <AIC_IRQ 343 IRQ_TYPE_LEVEL_HIGH>; + + #address-cells = <2>; + #size-cells = <0>; + + pmu@f { + compatible = "apple,sera-pmu"; + reg = <0xf SPMI_USID>; + }; + }; + }; +}; diff --git a/configs/apple_m1_defconfig b/configs/apple_m1_defconfig index 674b74b90b..e7c347af74 100644 --- a/configs/apple_m1_defconfig +++ b/configs/apple_m1_defconfig @@ -1,5 +1,6 @@ CONFIG_ARM=y CONFIG_ARCH_APPLE=y +CONFIG_DEFAULT_DEVICE_TREE="t8103-j274" # CONFIG_DISPLAY_CPUINFO is not set # CONFIG_MMC is not set # CONFIG_NET is not set diff --git a/include/dt-bindings/interrupt-controller/apple-aic.h b/include/dt-bindings/interrupt-controller/apple-aic.h new file mode 100644 index 0000000000..9ac56a7e6d --- /dev/null +++ b/include/dt-bindings/interrupt-controller/apple-aic.h @@ -0,0 +1,15 @@ +/* SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause */ +#ifndef _DT_BINDINGS_INTERRUPT_CONTROLLER_APPLE_AIC_H +#define _DT_BINDINGS_INTERRUPT_CONTROLLER_APPLE_AIC_H + +#include <dt-bindings/interrupt-controller/irq.h> + +#define AIC_IRQ 0 +#define AIC_FIQ 1 + +#define AIC_TMR_HV_PHYS 0 +#define AIC_TMR_HV_VIRT 1 +#define AIC_TMR_GUEST_PHYS 2 +#define AIC_TMR_GUEST_VIRT 3 + +#endif diff --git a/include/dt-bindings/pinctrl/apple.h b/include/dt-bindings/pinctrl/apple.h new file mode 100644 index 0000000000..ea0a6f4665 --- /dev/null +++ b/include/dt-bindings/pinctrl/apple.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: GPL-2.0+ OR MIT */ +/* + * This header provides constants for Apple pinctrl bindings. + */ + +#ifndef _DT_BINDINGS_PINCTRL_APPLE_H +#define _DT_BINDINGS_PINCTRL_APPLE_H + +#define APPLE_PINMUX(pin, func) ((pin) | ((func) << 16)) +#define APPLE_PIN(pinmux) ((pinmux) & 0xffff) +#define APPLE_FUNC(pinmux) ((pinmux) >> 16) + +#endif /* _DT_BINDINGS_PINCTRL_APPLE_H */ diff --git a/include/dt-bindings/spmi/spmi.h b/include/dt-bindings/spmi/spmi.h new file mode 100644 index 0000000000..ad4a43481d --- /dev/null +++ b/include/dt-bindings/spmi/spmi.h @@ -0,0 +1,10 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* Copyright (c) 2013, The Linux Foundation. All rights reserved. + */ +#ifndef __DT_BINDINGS_SPMI_H +#define __DT_BINDINGS_SPMI_H + +#define SPMI_USID 0 +#define SPMI_GSID 1 + +#endif

On Sun, 3 Oct 2021 at 12:34, Mark Kettenis kettenis@openbsd.org wrote:
Add preliminary device trees for the Apple M1 mini (2020) and Apple M1 Macbook Pro 13" (2020). Device tree bindings for the Apple M1 SoC are still being formalized and these device trees will be synchronized with the Linux kernel as needed.
These device trees are provided as a reference only as U-Boot uses the device tree passed by the m1n1 bootloader.
Signed-off-by: Mark Kettenis kettenis@openbsd.org
arch/arm/dts/Makefile | 4 + arch/arm/dts/t8103-j274.dts | 135 +++++ arch/arm/dts/t8103-j293.dts | 97 +++ arch/arm/dts/t8103.dtsi | 560 ++++++++++++++++++ configs/apple_m1_defconfig | 1 + .../interrupt-controller/apple-aic.h | 15 + include/dt-bindings/pinctrl/apple.h | 13 + include/dt-bindings/spmi/spmi.h | 10 + 8 files changed, 835 insertions(+) create mode 100644 arch/arm/dts/t8103-j274.dts create mode 100644 arch/arm/dts/t8103-j293.dts create mode 100644 arch/arm/dts/t8103.dtsi create mode 100644 include/dt-bindings/interrupt-controller/apple-aic.h create mode 100644 include/dt-bindings/pinctrl/apple.h create mode 100644 include/dt-bindings/spmi/spmi.h
Reviewed-by: Simon Glass sjg@chromium.org

On Sun, Oct 3, 2021 at 1:35 PM Mark Kettenis kettenis@openbsd.org wrote:
Add preliminary device trees for the Apple M1 mini (2020) and Apple M1 Macbook Pro 13" (2020). Device tree bindings for the Apple M1 SoC are still being formalized and these device trees will be synchronized with the Linux kernel as needed.
So not synchronized currently? If it is sync'ed, you should specify which version you got.
These device trees are provided as a reference only as U-Boot uses the device tree passed by the m1n1 bootloader.
If reference only, why do they need to be checked in here? We're trying to get to fewer copies both of dtbs at runtime and dts files in source trees.
I mainly bring it up here because this is a platform with multiple OS targets, following the model that DT comes from the firmware, and should be free of schema validation warnings. In other words, it's a good candidate to define best practices.
Rob

Hi Rob,
On Mon, 11 Oct 2021 at 12:36, Rob Herring robh@kernel.org wrote:
On Sun, Oct 3, 2021 at 1:35 PM Mark Kettenis kettenis@openbsd.org wrote:
Add preliminary device trees for the Apple M1 mini (2020) and Apple M1 Macbook Pro 13" (2020). Device tree bindings for the Apple M1 SoC are still being formalized and these device trees will be synchronized with the Linux kernel as needed.
So not synchronized currently? If it is sync'ed, you should specify which version you got.
These device trees are provided as a reference only as U-Boot uses the device tree passed by the m1n1 bootloader.
If reference only, why do they need to be checked in here? We're trying to get to fewer copies both of dtbs at runtime and dts files in source trees.
I mainly bring it up here because this is a platform with multiple OS targets, following the model that DT comes from the firmware, and should be free of schema validation warnings. In other words, it's a good candidate to define best practices.
This is something I have brought in, as U-Boot DT maintainer, to provide some sort of reference in U-Boot as to what is actually built. It allows people to see the devices and also ensures that the build system does build a devicetree. The existing OF_PRIOR_STAGE is being removed and OF_BOARD is becoming a bool, with OF_SEPARATE the standard approach.
We have a few examples where this is not done (e.g. qemu-arm) but I am working on fixing that. It has led to discussions about whether U-Boot is entitled to having its own things in the DT, etc. etc. The whole area is in flux at present. If you want some background:
https://patchwork.ozlabs.org/project/uboot/patch/20210919215111.3830278-3-sj...
Regards, Simon

From: Rob Herring robh@kernel.org Date: Mon, 11 Oct 2021 13:36:29 -0500
Hi Rob,
On Sun, Oct 3, 2021 at 1:35 PM Mark Kettenis kettenis@openbsd.org wrote:
Add preliminary device trees for the Apple M1 mini (2020) and Apple M1 Macbook Pro 13" (2020). Device tree bindings for the Apple M1 SoC are still being formalized and these device trees will be synchronized with the Linux kernel as needed.
So not synchronized currently? If it is sync'ed, you should specify which version you got.
Not synched at the moment. It is based on what was in 5.13 or 5.14, but with lots of stuff added so specifying a version would be misleading. It should be mostly aligned with the bindings that are making their way into 5.15 or 5.16 though.
Hopefully now that the power domains are getting addressed we'll have something that can be synchronized soon. I was explicitly encouraged to start upstreaming the U-Boot code even though not all the DT bindings had been sorted out.
These device trees are provided as a reference only as U-Boot uses the device tree passed by the m1n1 bootloader.
If reference only, why do they need to be checked in here? We're trying to get to fewer copies both of dtbs at runtime and dts files in source trees.
The U-Boot maintainers insist there is a DT for each supported system in the U-Boot tree.
I mainly bring it up here because this is a platform with multiple OS targets, following the model that DT comes from the firmware, and should be free of schema validation warnings. In other words, it's a good candidate to define best practices.
You're preaching to the choir ;).
Must admit that it is somewhat convenient for me to have a somewhat complete DT for these devices at the moment. But in the long run I think it will just confuse people. That said, I plan to be aggressive in keeping the U-Boot tree synchronized with Linux.
Cheers,
Mark

On Mon, Oct 11, 2021 at 2:00 PM Mark Kettenis mark.kettenis@xs4all.nl wrote:
From: Rob Herring robh@kernel.org Date: Mon, 11 Oct 2021 13:36:29 -0500
Hi Rob,
On Sun, Oct 3, 2021 at 1:35 PM Mark Kettenis kettenis@openbsd.org wrote:
Add preliminary device trees for the Apple M1 mini (2020) and Apple M1 Macbook Pro 13" (2020). Device tree bindings for the Apple M1 SoC are still being formalized and these device trees will be synchronized with the Linux kernel as needed.
So not synchronized currently? If it is sync'ed, you should specify which version you got.
Not synched at the moment. It is based on what was in 5.13 or 5.14, but with lots of stuff added so specifying a version would be misleading. It should be mostly aligned with the bindings that are making their way into 5.15 or 5.16 though.
This and what's added or preliminary would be good to have in the commit msg.
Hopefully now that the power domains are getting addressed we'll have something that can be synchronized soon. I was explicitly encouraged to start upstreaming the U-Boot code even though not all the DT bindings had been sorted out.
In general, sounds like a recipe for getting out of sync and bindings never getting documented properly without any checks in place. The good news is checking that is at least possible now.
These device trees are provided as a reference only as U-Boot uses the device tree passed by the m1n1 bootloader.
If reference only, why do they need to be checked in here? We're trying to get to fewer copies both of dtbs at runtime and dts files in source trees.
The U-Boot maintainers insist there is a DT for each supported system in the U-Boot tree.
Ok, fair enough.
I mainly bring it up here because this is a platform with multiple OS targets, following the model that DT comes from the firmware, and should be free of schema validation warnings. In other words, it's a good candidate to define best practices.
You're preaching to the choir ;).
Good.
Must admit that it is somewhat convenient for me to have a somewhat complete DT for these devices at the moment. But in the long run I think it will just confuse people. That said, I plan to be aggressive in keeping the U-Boot tree synchronized with Linux.
What I'd like to see here is some sort of automatic synchronization. The idea I have here is just a list of boards to sync from the kernel tree to wherever. The requirement to get on the list would be passing schema validation and would be a declaration of stability (there's been numerous discussions over the years of how to declare a DT stable or unstable). It would perhaps also include passing validation on an older schema. I'm not sure how well that would catch compatibility issues, but that's the only idea I've come up with besides just testing of mixed versions. I'm happy to do the tooling to support that if we have a board/device to put in the list and u-boot folks agree to use it. I suppose even if just m1n1 used it to start with, I'd be willing to do the tooling.
Rob

Hi Rob,
On Mon, 11 Oct 2021 at 13:49, Rob Herring robh@kernel.org wrote:
On Mon, Oct 11, 2021 at 2:00 PM Mark Kettenis mark.kettenis@xs4all.nl wrote:
From: Rob Herring robh@kernel.org Date: Mon, 11 Oct 2021 13:36:29 -0500
Hi Rob,
On Sun, Oct 3, 2021 at 1:35 PM Mark Kettenis kettenis@openbsd.org wrote:
Add preliminary device trees for the Apple M1 mini (2020) and Apple M1 Macbook Pro 13" (2020). Device tree bindings for the Apple M1 SoC are still being formalized and these device trees will be synchronized with the Linux kernel as needed.
So not synchronized currently? If it is sync'ed, you should specify which version you got.
Not synched at the moment. It is based on what was in 5.13 or 5.14, but with lots of stuff added so specifying a version would be misleading. It should be mostly aligned with the bindings that are making their way into 5.15 or 5.16 though.
This and what's added or preliminary would be good to have in the commit msg.
Hopefully now that the power domains are getting addressed we'll have something that can be synchronized soon. I was explicitly encouraged to start upstreaming the U-Boot code even though not all the DT bindings had been sorted out.
In general, sounds like a recipe for getting out of sync and bindings never getting documented properly without any checks in place. The good news is checking that is at least possible now.
These device trees are provided as a reference only as U-Boot uses the device tree passed by the m1n1 bootloader.
If reference only, why do they need to be checked in here? We're trying to get to fewer copies both of dtbs at runtime and dts files in source trees.
The U-Boot maintainers insist there is a DT for each supported system in the U-Boot tree.
Ok, fair enough.
I mainly bring it up here because this is a platform with multiple OS targets, following the model that DT comes from the firmware, and should be free of schema validation warnings. In other words, it's a good candidate to define best practices.
You're preaching to the choir ;).
Good.
Must admit that it is somewhat convenient for me to have a somewhat complete DT for these devices at the moment. But in the long run I think it will just confuse people. That said, I plan to be aggressive in keeping the U-Boot tree synchronized with Linux.
What I'd like to see here is some sort of automatic synchronization. The idea I have here is just a list of boards to sync from the kernel tree to wherever. The requirement to get on the list would be passing schema validation and would be a declaration of stability (there's been numerous discussions over the years of how to declare a DT stable or unstable). It would perhaps also include passing validation on an older schema. I'm not sure how well that would catch compatibility issues, but that's the only idea I've come up with besides just testing of mixed versions. I'm happy to do the tooling to support that if we have a board/device to put in the list and u-boot folks agree to use it. I suppose even if just m1n1 used it to start with, I'd be willing to do the tooling.
That sounds great to me. Yes m1n1 is a good first target since it is new, but I'm pretty sure there are quite a few other SoCs that could move over right away.
Ideally we would add it to U-Boot CI too, so that pull requests warn or fail if something wrong is added. Of course it is probably a no-no to make U-Boot CI due to comparisons with another tree over which we have no control, but perhaps we can head in that direction.
+Tom Rini too as he has been looking at this.
Regards, Simon

On Mon, Oct 11, 2021 at 02:00:56PM -0600, Simon Glass wrote:
Hi Rob,
On Mon, 11 Oct 2021 at 13:49, Rob Herring robh@kernel.org wrote:
On Mon, Oct 11, 2021 at 2:00 PM Mark Kettenis mark.kettenis@xs4all.nl wrote:
From: Rob Herring robh@kernel.org Date: Mon, 11 Oct 2021 13:36:29 -0500
Hi Rob,
On Sun, Oct 3, 2021 at 1:35 PM Mark Kettenis kettenis@openbsd.org wrote:
Add preliminary device trees for the Apple M1 mini (2020) and Apple M1 Macbook Pro 13" (2020). Device tree bindings for the Apple M1 SoC are still being formalized and these device trees will be synchronized with the Linux kernel as needed.
So not synchronized currently? If it is sync'ed, you should specify which version you got.
Not synched at the moment. It is based on what was in 5.13 or 5.14, but with lots of stuff added so specifying a version would be misleading. It should be mostly aligned with the bindings that are making their way into 5.15 or 5.16 though.
This and what's added or preliminary would be good to have in the commit msg.
Hopefully now that the power domains are getting addressed we'll have something that can be synchronized soon. I was explicitly encouraged to start upstreaming the U-Boot code even though not all the DT bindings had been sorted out.
In general, sounds like a recipe for getting out of sync and bindings never getting documented properly without any checks in place. The good news is checking that is at least possible now.
These device trees are provided as a reference only as U-Boot uses the device tree passed by the m1n1 bootloader.
If reference only, why do they need to be checked in here? We're trying to get to fewer copies both of dtbs at runtime and dts files in source trees.
The U-Boot maintainers insist there is a DT for each supported system in the U-Boot tree.
Ok, fair enough.
I mainly bring it up here because this is a platform with multiple OS targets, following the model that DT comes from the firmware, and should be free of schema validation warnings. In other words, it's a good candidate to define best practices.
You're preaching to the choir ;).
Good.
Must admit that it is somewhat convenient for me to have a somewhat complete DT for these devices at the moment. But in the long run I think it will just confuse people. That said, I plan to be aggressive in keeping the U-Boot tree synchronized with Linux.
What I'd like to see here is some sort of automatic synchronization. The idea I have here is just a list of boards to sync from the kernel tree to wherever. The requirement to get on the list would be passing schema validation and would be a declaration of stability (there's been numerous discussions over the years of how to declare a DT stable or unstable). It would perhaps also include passing validation on an older schema. I'm not sure how well that would catch compatibility issues, but that's the only idea I've come up with besides just testing of mixed versions. I'm happy to do the tooling to support that if we have a board/device to put in the list and u-boot folks agree to use it. I suppose even if just m1n1 used it to start with, I'd be willing to do the tooling.
That sounds great to me. Yes m1n1 is a good first target since it is new, but I'm pretty sure there are quite a few other SoCs that could move over right away.
Ideally we would add it to U-Boot CI too, so that pull requests warn or fail if something wrong is added. Of course it is probably a no-no to make U-Boot CI due to comparisons with another tree over which we have no control, but perhaps we can head in that direction.
+Tom Rini too as he has been looking at this.
I guess the first priority is that so long as _everything_ is in sync, it doesn't super matter if we have an otherwise redundant copy of files in-tree.
And we need to get our DTS files back in sync with upstream, which is the case for some platforms, and not others. But once we get that sorted out, we need to do more regular resyncs, and hopefully once DTS files have settled down, because they all pass validation and for example incorrect names get fixed, it will be less of an issue to more automatically resync DTS files, that are fully validated at least.

From: Rob Herring robh@kernel.org Date: Mon, 11 Oct 2021 14:48:46 -0500
Hi Rob,
Trimming the CC list a bit and adding marcan.
On Mon, Oct 11, 2021 at 2:00 PM Mark Kettenis mark.kettenis@xs4all.nl wrote:
From: Rob Herring robh@kernel.org Date: Mon, 11 Oct 2021 13:36:29 -0500
Hi Rob,
On Sun, Oct 3, 2021 at 1:35 PM Mark Kettenis kettenis@openbsd.org wrote:
Add preliminary device trees for the Apple M1 mini (2020) and Apple M1 Macbook Pro 13" (2020). Device tree bindings for the Apple M1 SoC are still being formalized and these device trees will be synchronized with the Linux kernel as needed.
So not synchronized currently? If it is sync'ed, you should specify which version you got.
Not synched at the moment. It is based on what was in 5.13 or 5.14, but with lots of stuff added so specifying a version would be misleading. It should be mostly aligned with the bindings that are making their way into 5.15 or 5.16 though.
This and what's added or preliminary would be good to have in the commit msg.
Sure. I added that information to the commit message for v4.
Hopefully now that the power domains are getting addressed we'll have something that can be synchronized soon. I was explicitly encouraged to start upstreaming the U-Boot code even though not all the DT bindings had been sorted out.
In general, sounds like a recipe for getting out of sync and bindings never getting documented properly without any checks in place. The good news is checking that is at least possible now.
These device trees are provided as a reference only as U-Boot uses the device tree passed by the m1n1 bootloader.
If reference only, why do they need to be checked in here? We're trying to get to fewer copies both of dtbs at runtime and dts files in source trees.
The U-Boot maintainers insist there is a DT for each supported system in the U-Boot tree.
Ok, fair enough.
I mainly bring it up here because this is a platform with multiple OS targets, following the model that DT comes from the firmware, and should be free of schema validation warnings. In other words, it's a good candidate to define best practices.
You're preaching to the choir ;).
Good.
Must admit that it is somewhat convenient for me to have a somewhat complete DT for these devices at the moment. But in the long run I think it will just confuse people. That said, I plan to be aggressive in keeping the U-Boot tree synchronized with Linux.
What I'd like to see here is some sort of automatic synchronization. The idea I have here is just a list of boards to sync from the kernel tree to wherever. The requirement to get on the list would be passing schema validation and would be a declaration of stability (there's been numerous discussions over the years of how to declare a DT stable or unstable). It would perhaps also include passing validation on an older schema. I'm not sure how well that would catch compatibility issues, but that's the only idea I've come up with besides just testing of mixed versions. I'm happy to do the tooling to support that if we have a board/device to put in the list and u-boot folks agree to use it. I suppose even if just m1n1 used it to start with, I'd be willing to do the tooling.
Sounds interesting.
One of the things we would want to do a ship device trees for new models with m1n1 as soon as we get our hands on the hardware such that the they can be used with existing distro kernels as soon as possible. Under the assumption that the new hardware is compatible with the old of course. That means those new device trees should pass validation.
But as soon as the device tree for a model is available in the Linux tree, we probably want to be rather strict in synching it to m1n1.
Thanks,
Mark

Provide preliminary instructions on how to get U-Boot to run on Apple Silicon Macs.
Signed-off-by: Mark Kettenis kettenis@openbsd.org --- doc/board/apple/index.rst | 9 +++++++ doc/board/apple/m1.rst | 56 +++++++++++++++++++++++++++++++++++++++ doc/board/index.rst | 1 + 3 files changed, 66 insertions(+) create mode 100644 doc/board/apple/index.rst create mode 100644 doc/board/apple/m1.rst
diff --git a/doc/board/apple/index.rst b/doc/board/apple/index.rst new file mode 100644 index 0000000000..8446847818 --- /dev/null +++ b/doc/board/apple/index.rst @@ -0,0 +1,9 @@ +.. SPDX-License-Identifier: GPL-2.0+ + +Apple +===== + +.. toctree:: + :maxdepth: 2 + + m1 diff --git a/doc/board/apple/m1.rst b/doc/board/apple/m1.rst new file mode 100644 index 0000000000..2f2d940a4c --- /dev/null +++ b/doc/board/apple/m1.rst @@ -0,0 +1,56 @@ +.. SPDX-License-Identifier: GPL-2.0+ + +U-Boot for Apple Silicon Macs +============================= + +Allows Apple Silicon Macs to boot U-Boot via the m1n1 bootloader +developed by the Asahi Linux project. At this point the machines with +the following SoCs work: + + - Apple M1 SoC + +On these SoCs the following hardware is supported: + + - S5L serial port + - Framebuffer + - USB 3.1 Type-C ports + +Device trees are currently provided for the M1 Mac mini (2020, J274) +and M1 MacBook Pro 13" (2020, J293). The M1 MacBook Air (2020) is +expected to work with the J293 device tree. The M1 iMac (2021) may +work with the J274 device tree. + +Building U-Boot +--------------- + +.. code-block:: bash + + $ export CROSS_COMPILE=aarch64-none-elf- + $ make apple_m1_defconfig + $ make + +This will build ``u-boot-nodtb.bin`` as well as devices trees for some +of the supported machines. These device trees can be found in the +``arch/arm/dts`` subdirectory of your build. + +Image creation +-------------- + +In order to run U-Boot on an Apple Silicon Mac, U-Boot has to be used +as a payload for the m1n1 bootloader. Instructions for building m1n1 +can be found here: + + https://github.com/AsahiLinux/docs/wiki/SW%3Am1n1 + +.. code-block:: bash + + $ cat m1n1.macho t8103-j274.dtb u-boot-nodtb.bin > u-boot.macho + +Image installation +------------------ + +Instructions on how to install U-Boot on your Mac can be found at: + + https://github.com/AsahiLinux/docs/wiki/Developer-Quickstart + +Just replace ``m1n1.macho`` with ``u-boot.macho`` in the instructions. diff --git a/doc/board/index.rst b/doc/board/index.rst index 33087074fa..0add55b5d3 100644 --- a/doc/board/index.rst +++ b/doc/board/index.rst @@ -10,6 +10,7 @@ Board-specific doc advantech/index AndesTech/index amlogic/index + apple/index atmel/index congatec/index coreboot/index

On Sun, 3 Oct 2021 at 12:35, Mark Kettenis kettenis@openbsd.org wrote:
Provide preliminary instructions on how to get U-Boot to run on Apple Silicon Macs.
Signed-off-by: Mark Kettenis kettenis@openbsd.org
doc/board/apple/index.rst | 9 +++++++ doc/board/apple/m1.rst | 56 +++++++++++++++++++++++++++++++++++++++ doc/board/index.rst | 1 + 3 files changed, 66 insertions(+) create mode 100644 doc/board/apple/index.rst create mode 100644 doc/board/apple/m1.rst
Reviewed-by: Simon Glass sjg@chromium.org

Hi Mark,
On Sun, 3 Oct 2021 at 12:31, Mark Kettenis kettenis@openbsd.org wrote:
This series adds basic support for Apple's M1 SoC to U-Boot. This builds a basic U-Boot that can be used as a payload for the m1n1 boot loader being developed by the Asahi Linux project.
The goal here is to privide an UEFI interface on these machines that allows booting various open source OSes. This initial series provides support for the serial port, framebuffer and the USB 3.1 Type-C ports. It can boot a support OS (e.g. OpenBSD/arm64) from a USB disk.
This version attempts to address most comments. It doesn't add a proper WDT/sysreset driver yet since I prefer to do that once the device tree bindings for that have been ironed out.
Please do this soon. We can easily change a compatible string later if needed, but having strange code in there provides a bad example for others.
Regards, Simon
participants (5)
-
Mark Kettenis
-
Mark Kettenis
-
Rob Herring
-
Simon Glass
-
Tom Rini