[PATCH 0/5] 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.
Mark Kettenis (5): arm: apple: Add initial support for Apple's M1 SoC serial: s5p: Add Apple M1 support misc: Add Apple DART driver arm: dts: apple: Add preliminary device trees doc: board: apple: Add Apple M1 documentation
arch/arm/Kconfig | 22 + arch/arm/Makefile | 1 + arch/arm/dts/t8103-j274.dts | 135 +++++ arch/arm/dts/t8103-j293.dts | 97 ++++ arch/arm/dts/t8103.dtsi | 506 ++++++++++++++++++ arch/arm/include/asm/arch-m1/clk.h | 11 + 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 | 163 ++++++ arch/arm/mach-apple/lowlevel_init.S | 16 + configs/apple_m1_defconfig | 14 + doc/board/apple/index.rst | 9 + doc/board/apple/m1.rst | 54 ++ doc/board/index.rst | 1 + drivers/misc/Kconfig | 7 + drivers/misc/Makefile | 1 + drivers/misc/apple_dart.c | 171 ++++++ drivers/serial/Kconfig | 2 +- drivers/serial/serial_s5p.c | 22 + include/configs/apple.h | 38 ++ .../interrupt-controller/apple-aic.h | 15 + include/dt-bindings/pinctrl/apple.h | 13 + include/dt-bindings/spmi/spmi.h | 10 + 24 files changed, 1370 insertions(+), 1 deletion(-) 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/clk.h 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/misc/apple_dart.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

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 | 22 ++++ arch/arm/Makefile | 1 + arch/arm/mach-apple/Kconfig | 18 ++++ arch/arm/mach-apple/Makefile | 4 + arch/arm/mach-apple/board.c | 158 ++++++++++++++++++++++++++++ arch/arm/mach-apple/lowlevel_init.S | 16 +++ configs/apple_m1_defconfig | 14 +++ include/configs/apple.h | 38 +++++++ 8 files changed, 271 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..7cdea1f615 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -895,6 +895,26 @@ config ARCH_NEXELL select DM select GPIO_EXTRA_HEADER
+config ARCH_APPLE + bool "Apple SoCs" + select ARM64 + select LINUX_KERNEL_IMAGE_HEADER + select POSITION_INDEPENDENT + select BLK + select DM + select DM_KEYBOARD + select DM_SERIAL + select DM_USB + select DM_VIDEO + select CMD_USB + select MISC + select OF_CONTROL + select OF_BOARD + select USB + imply CMD_DM + imply CMD_GPT + imply DISTRO_DEFAULTS + config ARCH_OWL bool "Actions Semi OWL SoCs" select DM @@ -1932,6 +1952,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..0c8b35292e --- /dev/null +++ b/arch/arm/mach-apple/board.c @@ -0,0 +1,158 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * (C) Copyright 2021 Mark Kettenis kettenis@openbsd.org + */ + +#include <common.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) +{ + int index, node, 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 = fdt_path_offset(gd->fdt_blob, "/chosen/framebuffer"); + if (node < 0) + return 0; + + base = fdtdec_get_addr_size(gd->fdt_blob, 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 (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..0f5313163e --- /dev/null +++ b/arch/arm/mach-apple/lowlevel_init.S @@ -0,0 +1,16 @@ +/* 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: + 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

Hi Mark,
On Sat, Sep 18, 2021 at 9:55 PM 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 | 22 ++++ arch/arm/Makefile | 1 + arch/arm/mach-apple/Kconfig | 18 ++++ arch/arm/mach-apple/Makefile | 4 + arch/arm/mach-apple/board.c | 158 ++++++++++++++++++++++++++++ arch/arm/mach-apple/lowlevel_init.S | 16 +++ configs/apple_m1_defconfig | 14 +++ include/configs/apple.h | 38 +++++++ 8 files changed, 271 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..7cdea1f615 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -895,6 +895,26 @@ config ARCH_NEXELL select DM select GPIO_EXTRA_HEADER
+config ARCH_APPLE
bool "Apple SoCs"
select ARM64
select LINUX_KERNEL_IMAGE_HEADER
select POSITION_INDEPENDENT
select BLK
select DM
select DM_KEYBOARD
select DM_SERIAL
select DM_USB
select DM_VIDEO
select CMD_USB
select MISC
select OF_CONTROL
select OF_BOARD
select USB
imply CMD_DM
imply CMD_GPT
imply DISTRO_DEFAULTS
config ARCH_OWL bool "Actions Semi OWL SoCs" select DM @@ -1932,6 +1952,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..0c8b35292e --- /dev/null +++ b/arch/arm/mach-apple/board.c @@ -0,0 +1,158 @@ +// SPDX-License-Identifier: GPL-2.0+ +/*
- (C) Copyright 2021 Mark Kettenis kettenis@openbsd.org
- */
+#include <common.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) +{
int index, node, ret;
fdt_addr_t base;
fdt_size_t size;
ret = fdtdec_setup_mem_size_base();
if (ret)
return ret;
/* Update RAM mapping. */
nits: please remove the ending .
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 = fdt_path_offset(gd->fdt_blob, "/chosen/framebuffer");
if (node < 0)
return 0;
base = fdtdec_get_addr_size(gd->fdt_blob, node, "reg", &size);
if (base == FDT_ADDR_T_NONE)
return 0;
/* Add framebuffer mapping. */
ditto
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)
This looks like we should add a new sysreset driver for Apple Arm SoC.
+{
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 (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..0f5313163e --- /dev/null +++ b/arch/arm/mach-apple/lowlevel_init.S @@ -0,0 +1,16 @@ +/* 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
Is this filled in by m1n1?
+.global save_boot_params +save_boot_params:
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
Regards, Bin

Hi Mark,
On Sun, Sep 19, 2021 at 9:04 AM Bin Meng bmeng.cn@gmail.com wrote:
Hi Mark,
On Sat, Sep 18, 2021 at 9:55 PM 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 | 22 ++++ arch/arm/Makefile | 1 + arch/arm/mach-apple/Kconfig | 18 ++++ arch/arm/mach-apple/Makefile | 4 + arch/arm/mach-apple/board.c | 158 ++++++++++++++++++++++++++++ arch/arm/mach-apple/lowlevel_init.S | 16 +++ configs/apple_m1_defconfig | 14 +++ include/configs/apple.h | 38 +++++++ 8 files changed, 271 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..7cdea1f615 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -895,6 +895,26 @@ config ARCH_NEXELL select DM select GPIO_EXTRA_HEADER
+config ARCH_APPLE
bool "Apple SoCs"
select ARM64
select LINUX_KERNEL_IMAGE_HEADER
select POSITION_INDEPENDENT
select BLK
select DM
select DM_KEYBOARD
select DM_SERIAL
select DM_USB
select DM_VIDEO
select CMD_USB
select MISC
select OF_CONTROL
select OF_BOARD
select USB
imply CMD_DM
imply CMD_GPT
imply DISTRO_DEFAULTS
config ARCH_OWL bool "Actions Semi OWL SoCs" select DM @@ -1932,6 +1952,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..0c8b35292e --- /dev/null +++ b/arch/arm/mach-apple/board.c @@ -0,0 +1,158 @@ +// SPDX-License-Identifier: GPL-2.0+ +/*
- (C) Copyright 2021 Mark Kettenis kettenis@openbsd.org
- */
+#include <common.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) +{
int index, node, ret;
fdt_addr_t base;
fdt_size_t size;
ret = fdtdec_setup_mem_size_base();
if (ret)
return ret;
/* Update RAM mapping. */
nits: please remove the ending .
index = ARRAY_SIZE(apple_mem_map) - 3;
This is error prone. Someone else updating apple_mem_map may create an incorrect index for us.
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 = fdt_path_offset(gd->fdt_blob, "/chosen/framebuffer");
if (node < 0)
return 0;
base = fdtdec_get_addr_size(gd->fdt_blob, node, "reg", &size);
if (base == FDT_ADDR_T_NONE)
return 0;
/* Add framebuffer mapping. */
ditto
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)
This looks like we should add a new sysreset driver for Apple Arm SoC.
+{
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 (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..0f5313163e --- /dev/null +++ b/arch/arm/mach-apple/lowlevel_init.S @@ -0,0 +1,16 @@ +/* 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
Is this filled in by m1n1?
Sorry I misread, so this is passed by m1n1 and filled in by U-Boot. I think we should stop using CONFIG_OF_BOARD, and for such case we should use CONFIG_OF_PRIOR_STAGE.
+.global save_boot_params +save_boot_params:
adr x1, fw_dtb_pointer
str x0, [x1]
b save_boot_params_ret
Regards, Bin

From: Bin Meng bmeng.cn@gmail.com Date: Sun, 19 Sep 2021 09:17:07 +0800
Hi Mark,
On Sun, Sep 19, 2021 at 9:04 AM Bin Meng bmeng.cn@gmail.com wrote:
Hi Mark,
On Sat, Sep 18, 2021 at 9:55 PM 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 | 22 ++++ arch/arm/Makefile | 1 + arch/arm/mach-apple/Kconfig | 18 ++++ arch/arm/mach-apple/Makefile | 4 + arch/arm/mach-apple/board.c | 158 ++++++++++++++++++++++++++++ arch/arm/mach-apple/lowlevel_init.S | 16 +++ configs/apple_m1_defconfig | 14 +++ include/configs/apple.h | 38 +++++++ 8 files changed, 271 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..7cdea1f615 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -895,6 +895,26 @@ config ARCH_NEXELL select DM select GPIO_EXTRA_HEADER
+config ARCH_APPLE
bool "Apple SoCs"
select ARM64
select LINUX_KERNEL_IMAGE_HEADER
select POSITION_INDEPENDENT
select BLK
select DM
select DM_KEYBOARD
select DM_SERIAL
select DM_USB
select DM_VIDEO
select CMD_USB
select MISC
select OF_CONTROL
select OF_BOARD
select USB
imply CMD_DM
imply CMD_GPT
imply DISTRO_DEFAULTS
config ARCH_OWL bool "Actions Semi OWL SoCs" select DM @@ -1932,6 +1952,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..0c8b35292e --- /dev/null +++ b/arch/arm/mach-apple/board.c @@ -0,0 +1,158 @@ +// SPDX-License-Identifier: GPL-2.0+ +/*
- (C) Copyright 2021 Mark Kettenis kettenis@openbsd.org
- */
+#include <common.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) +{
int index, node, ret;
fdt_addr_t base;
fdt_size_t size;
ret = fdtdec_setup_mem_size_base();
if (ret)
return ret;
/* Update RAM mapping. */
nits: please remove the ending .
index = ARRAY_SIZE(apple_mem_map) - 3;
This is error prone. Someone else updating apple_mem_map may create an incorrect index for us.
I don't see a better way without introducing more complexity.
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 = fdt_path_offset(gd->fdt_blob, "/chosen/framebuffer");
if (node < 0)
return 0;
base = fdtdec_get_addr_size(gd->fdt_blob, node, "reg", &size);
if (base == FDT_ADDR_T_NONE)
return 0;
/* Add framebuffer mapping. */
ditto
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)
This looks like we should add a new sysreset driver for Apple Arm SoC.
+{
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 (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..0f5313163e --- /dev/null +++ b/arch/arm/mach-apple/lowlevel_init.S @@ -0,0 +1,16 @@ +/* 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
Is this filled in by m1n1?
Sorry I misread, so this is passed by m1n1 and filled in by U-Boot. I think we should stop using CONFIG_OF_BOARD, and for such case we should use CONFIG_OF_PRIOR_STAGE.
Yes, CONFIG_OF_PRIOR_STAGE would work as well. But Tom was talking about removing that option in favour of CONFIG_OF_BOARD the other day.
+.global save_boot_params +save_boot_params:
adr x1, fw_dtb_pointer
str x0, [x1]
b save_boot_params_ret
Regards, Bin

On Sun, Sep 19, 2021 at 10:33:25PM +0200, Mark Kettenis wrote:
From: Bin Meng bmeng.cn@gmail.com Date: Sun, 19 Sep 2021 09:17:07 +0800
Hi Mark,
On Sun, Sep 19, 2021 at 9:04 AM Bin Meng bmeng.cn@gmail.com wrote:
Hi Mark,
On Sat, Sep 18, 2021 at 9:55 PM 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 | 22 ++++ arch/arm/Makefile | 1 + arch/arm/mach-apple/Kconfig | 18 ++++ arch/arm/mach-apple/Makefile | 4 + arch/arm/mach-apple/board.c | 158 ++++++++++++++++++++++++++++ arch/arm/mach-apple/lowlevel_init.S | 16 +++ configs/apple_m1_defconfig | 14 +++ include/configs/apple.h | 38 +++++++ 8 files changed, 271 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..7cdea1f615 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -895,6 +895,26 @@ config ARCH_NEXELL select DM select GPIO_EXTRA_HEADER
+config ARCH_APPLE
bool "Apple SoCs"
select ARM64
select LINUX_KERNEL_IMAGE_HEADER
select POSITION_INDEPENDENT
select BLK
select DM
select DM_KEYBOARD
select DM_SERIAL
select DM_USB
select DM_VIDEO
select CMD_USB
select MISC
select OF_CONTROL
select OF_BOARD
select USB
imply CMD_DM
imply CMD_GPT
imply DISTRO_DEFAULTS
config ARCH_OWL bool "Actions Semi OWL SoCs" select DM @@ -1932,6 +1952,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..0c8b35292e --- /dev/null +++ b/arch/arm/mach-apple/board.c @@ -0,0 +1,158 @@ +// SPDX-License-Identifier: GPL-2.0+ +/*
- (C) Copyright 2021 Mark Kettenis kettenis@openbsd.org
- */
+#include <common.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) +{
int index, node, ret;
fdt_addr_t base;
fdt_size_t size;
ret = fdtdec_setup_mem_size_base();
if (ret)
return ret;
/* Update RAM mapping. */
nits: please remove the ending .
index = ARRAY_SIZE(apple_mem_map) - 3;
This is error prone. Someone else updating apple_mem_map may create an incorrect index for us.
I don't see a better way without introducing more complexity.
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 = fdt_path_offset(gd->fdt_blob, "/chosen/framebuffer");
if (node < 0)
return 0;
base = fdtdec_get_addr_size(gd->fdt_blob, node, "reg", &size);
if (base == FDT_ADDR_T_NONE)
return 0;
/* Add framebuffer mapping. */
ditto
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)
This looks like we should add a new sysreset driver for Apple Arm SoC.
+{
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 (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..0f5313163e --- /dev/null +++ b/arch/arm/mach-apple/lowlevel_init.S @@ -0,0 +1,16 @@ +/* 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
Is this filled in by m1n1?
Sorry I misread, so this is passed by m1n1 and filled in by U-Boot. I think we should stop using CONFIG_OF_BOARD, and for such case we should use CONFIG_OF_PRIOR_STAGE.
Yes, CONFIG_OF_PRIOR_STAGE would work as well. But Tom was talking about removing that option in favour of CONFIG_OF_BOARD the other day.
Yes. I was even looking for some feedback from you, Bin, on converting some boards from CONFIG_OF_PRIOR_STAGE to CONFIG_OF_BOARD. It seems like CONFIG_OF_PRIOR_STAGE is a subset of CONFIG_OF_BOARD, at the cost of possibly a few bytes.

On Tue, Sep 21, 2021 at 8:42 PM Tom Rini trini@konsulko.com wrote:
On Sun, Sep 19, 2021 at 10:33:25PM +0200, Mark Kettenis wrote:
From: Bin Meng bmeng.cn@gmail.com Date: Sun, 19 Sep 2021 09:17:07 +0800
Hi Mark,
On Sun, Sep 19, 2021 at 9:04 AM Bin Meng bmeng.cn@gmail.com wrote:
Hi Mark,
On Sat, Sep 18, 2021 at 9:55 PM 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 | 22 ++++ arch/arm/Makefile | 1 + arch/arm/mach-apple/Kconfig | 18 ++++ arch/arm/mach-apple/Makefile | 4 + arch/arm/mach-apple/board.c | 158 ++++++++++++++++++++++++++++ arch/arm/mach-apple/lowlevel_init.S | 16 +++ configs/apple_m1_defconfig | 14 +++ include/configs/apple.h | 38 +++++++ 8 files changed, 271 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..7cdea1f615 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -895,6 +895,26 @@ config ARCH_NEXELL select DM select GPIO_EXTRA_HEADER
+config ARCH_APPLE
bool "Apple SoCs"
select ARM64
select LINUX_KERNEL_IMAGE_HEADER
select POSITION_INDEPENDENT
select BLK
select DM
select DM_KEYBOARD
select DM_SERIAL
select DM_USB
select DM_VIDEO
select CMD_USB
select MISC
select OF_CONTROL
select OF_BOARD
select USB
imply CMD_DM
imply CMD_GPT
imply DISTRO_DEFAULTS
config ARCH_OWL bool "Actions Semi OWL SoCs" select DM @@ -1932,6 +1952,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..0c8b35292e --- /dev/null +++ b/arch/arm/mach-apple/board.c @@ -0,0 +1,158 @@ +// SPDX-License-Identifier: GPL-2.0+ +/*
- (C) Copyright 2021 Mark Kettenis kettenis@openbsd.org
- */
+#include <common.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) +{
int index, node, ret;
fdt_addr_t base;
fdt_size_t size;
ret = fdtdec_setup_mem_size_base();
if (ret)
return ret;
/* Update RAM mapping. */
nits: please remove the ending .
index = ARRAY_SIZE(apple_mem_map) - 3;
This is error prone. Someone else updating apple_mem_map may create an incorrect index for us.
I don't see a better way without introducing more complexity.
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 = fdt_path_offset(gd->fdt_blob, "/chosen/framebuffer");
if (node < 0)
return 0;
base = fdtdec_get_addr_size(gd->fdt_blob, node, "reg", &size);
if (base == FDT_ADDR_T_NONE)
return 0;
/* Add framebuffer mapping. */
ditto
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)
This looks like we should add a new sysreset driver for Apple Arm SoC.
+{
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 (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..0f5313163e --- /dev/null +++ b/arch/arm/mach-apple/lowlevel_init.S @@ -0,0 +1,16 @@ +/* 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
Is this filled in by m1n1?
Sorry I misread, so this is passed by m1n1 and filled in by U-Boot. I think we should stop using CONFIG_OF_BOARD, and for such case we should use CONFIG_OF_PRIOR_STAGE.
Yes, CONFIG_OF_PRIOR_STAGE would work as well. But Tom was talking about removing that option in favour of CONFIG_OF_BOARD the other day.
Yes. I was even looking for some feedback from you, Bin, on converting some boards from CONFIG_OF_PRIOR_STAGE to CONFIG_OF_BOARD. It seems like CONFIG_OF_PRIOR_STAGE is a subset of CONFIG_OF_BOARD, at the cost of possibly a few bytes.
Ah, I thought we wanted to do the other way around, by removing CONFIG_OF_BOARD, and convert that to CONFIG_OF_PRIORI_STAGE?
Regards, Bin

On Tue, Sep 21, 2021 at 11:53:10PM +0800, Bin Meng wrote:
On Tue, Sep 21, 2021 at 8:42 PM Tom Rini trini@konsulko.com wrote:
On Sun, Sep 19, 2021 at 10:33:25PM +0200, Mark Kettenis wrote:
From: Bin Meng bmeng.cn@gmail.com Date: Sun, 19 Sep 2021 09:17:07 +0800
Hi Mark,
On Sun, Sep 19, 2021 at 9:04 AM Bin Meng bmeng.cn@gmail.com wrote:
Hi Mark,
On Sat, Sep 18, 2021 at 9:55 PM 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 | 22 ++++ arch/arm/Makefile | 1 + arch/arm/mach-apple/Kconfig | 18 ++++ arch/arm/mach-apple/Makefile | 4 + arch/arm/mach-apple/board.c | 158 ++++++++++++++++++++++++++++ arch/arm/mach-apple/lowlevel_init.S | 16 +++ configs/apple_m1_defconfig | 14 +++ include/configs/apple.h | 38 +++++++ 8 files changed, 271 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..7cdea1f615 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -895,6 +895,26 @@ config ARCH_NEXELL select DM select GPIO_EXTRA_HEADER
+config ARCH_APPLE
bool "Apple SoCs"
select ARM64
select LINUX_KERNEL_IMAGE_HEADER
select POSITION_INDEPENDENT
select BLK
select DM
select DM_KEYBOARD
select DM_SERIAL
select DM_USB
select DM_VIDEO
select CMD_USB
select MISC
select OF_CONTROL
select OF_BOARD
select USB
imply CMD_DM
imply CMD_GPT
imply DISTRO_DEFAULTS
config ARCH_OWL bool "Actions Semi OWL SoCs" select DM @@ -1932,6 +1952,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..0c8b35292e --- /dev/null +++ b/arch/arm/mach-apple/board.c @@ -0,0 +1,158 @@ +// SPDX-License-Identifier: GPL-2.0+ +/*
- (C) Copyright 2021 Mark Kettenis kettenis@openbsd.org
- */
+#include <common.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) +{
int index, node, ret;
fdt_addr_t base;
fdt_size_t size;
ret = fdtdec_setup_mem_size_base();
if (ret)
return ret;
/* Update RAM mapping. */
nits: please remove the ending .
index = ARRAY_SIZE(apple_mem_map) - 3;
This is error prone. Someone else updating apple_mem_map may create an incorrect index for us.
I don't see a better way without introducing more complexity.
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 = fdt_path_offset(gd->fdt_blob, "/chosen/framebuffer");
if (node < 0)
return 0;
base = fdtdec_get_addr_size(gd->fdt_blob, node, "reg", &size);
if (base == FDT_ADDR_T_NONE)
return 0;
/* Add framebuffer mapping. */
ditto
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)
This looks like we should add a new sysreset driver for Apple Arm SoC.
+{
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 (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..0f5313163e --- /dev/null +++ b/arch/arm/mach-apple/lowlevel_init.S @@ -0,0 +1,16 @@ +/* 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
Is this filled in by m1n1?
Sorry I misread, so this is passed by m1n1 and filled in by U-Boot. I think we should stop using CONFIG_OF_BOARD, and for such case we should use CONFIG_OF_PRIOR_STAGE.
Yes, CONFIG_OF_PRIOR_STAGE would work as well. But Tom was talking about removing that option in favour of CONFIG_OF_BOARD the other day.
Yes. I was even looking for some feedback from you, Bin, on converting some boards from CONFIG_OF_PRIOR_STAGE to CONFIG_OF_BOARD. It seems like CONFIG_OF_PRIOR_STAGE is a subset of CONFIG_OF_BOARD, at the cost of possibly a few bytes.
Ah, I thought we wanted to do the other way around, by removing CONFIG_OF_BOARD, and convert that to CONFIG_OF_PRIORI_STAGE?
Maybe I had it backwards then? Whichever one can be implemented as a form of the other, and then we just keep one way of saying "we have the DT passed in to us".

From: Bin Meng bmeng.cn@gmail.com Date: Tue, 21 Sep 2021 23:53:10 +0800
On Tue, Sep 21, 2021 at 8:42 PM Tom Rini trini@konsulko.com wrote:
On Sun, Sep 19, 2021 at 10:33:25PM +0200, Mark Kettenis wrote:
From: Bin Meng bmeng.cn@gmail.com Date: Sun, 19 Sep 2021 09:17:07 +0800
Hi Mark,
On Sun, Sep 19, 2021 at 9:04 AM Bin Meng bmeng.cn@gmail.com wrote:
Hi Mark,
On Sat, Sep 18, 2021 at 9:55 PM 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 | 22 ++++ arch/arm/Makefile | 1 + arch/arm/mach-apple/Kconfig | 18 ++++ arch/arm/mach-apple/Makefile | 4 + arch/arm/mach-apple/board.c | 158 ++++++++++++++++++++++++++++ arch/arm/mach-apple/lowlevel_init.S | 16 +++ configs/apple_m1_defconfig | 14 +++ include/configs/apple.h | 38 +++++++ 8 files changed, 271 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..7cdea1f615 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -895,6 +895,26 @@ config ARCH_NEXELL select DM select GPIO_EXTRA_HEADER
+config ARCH_APPLE
bool "Apple SoCs"
select ARM64
select LINUX_KERNEL_IMAGE_HEADER
select POSITION_INDEPENDENT
select BLK
select DM
select DM_KEYBOARD
select DM_SERIAL
select DM_USB
select DM_VIDEO
select CMD_USB
select MISC
select OF_CONTROL
select OF_BOARD
select USB
imply CMD_DM
imply CMD_GPT
imply DISTRO_DEFAULTS
config ARCH_OWL bool "Actions Semi OWL SoCs" select DM @@ -1932,6 +1952,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..0c8b35292e --- /dev/null +++ b/arch/arm/mach-apple/board.c @@ -0,0 +1,158 @@ +// SPDX-License-Identifier: GPL-2.0+ +/*
- (C) Copyright 2021 Mark Kettenis kettenis@openbsd.org
- */
+#include <common.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) +{
int index, node, ret;
fdt_addr_t base;
fdt_size_t size;
ret = fdtdec_setup_mem_size_base();
if (ret)
return ret;
/* Update RAM mapping. */
nits: please remove the ending .
index = ARRAY_SIZE(apple_mem_map) - 3;
This is error prone. Someone else updating apple_mem_map may create an incorrect index for us.
I don't see a better way without introducing more complexity.
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 = fdt_path_offset(gd->fdt_blob, "/chosen/framebuffer");
if (node < 0)
return 0;
base = fdtdec_get_addr_size(gd->fdt_blob, node, "reg", &size);
if (base == FDT_ADDR_T_NONE)
return 0;
/* Add framebuffer mapping. */
ditto
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)
This looks like we should add a new sysreset driver for Apple Arm SoC.
+{
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 (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..0f5313163e --- /dev/null +++ b/arch/arm/mach-apple/lowlevel_init.S @@ -0,0 +1,16 @@ +/* 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
Is this filled in by m1n1?
Sorry I misread, so this is passed by m1n1 and filled in by U-Boot. I think we should stop using CONFIG_OF_BOARD, and for such case we should use CONFIG_OF_PRIOR_STAGE.
Yes, CONFIG_OF_PRIOR_STAGE would work as well. But Tom was talking about removing that option in favour of CONFIG_OF_BOARD the other day.
Yes. I was even looking for some feedback from you, Bin, on converting some boards from CONFIG_OF_PRIOR_STAGE to CONFIG_OF_BOARD. It seems like CONFIG_OF_PRIOR_STAGE is a subset of CONFIG_OF_BOARD, at the cost of possibly a few bytes.
Ah, I thought we wanted to do the other way around, by removing CONFIG_OF_BOARD, and convert that to CONFIG_OF_PRIORI_STAGE?
I must say that I see some logic in keeping both, where CONFIG_OF_BOARD indicates that the device tree is somehow stored on the board and U-Boot has to run some code to fetch it, and CONFIG_OF_PRIOR_STAGE is used when the device tree is provided by firmware that runs before U-Boot.
In that case I obviously should use CONFIG_OF_PRIOR_STAGE here.

Hi Mark,
On Tue, 21 Sept 2021 at 10:09, Mark Kettenis mark.kettenis@xs4all.nl wrote:
From: Bin Meng bmeng.cn@gmail.com Date: Tue, 21 Sep 2021 23:53:10 +0800
On Tue, Sep 21, 2021 at 8:42 PM Tom Rini trini@konsulko.com wrote:
On Sun, Sep 19, 2021 at 10:33:25PM +0200, Mark Kettenis wrote:
From: Bin Meng bmeng.cn@gmail.com Date: Sun, 19 Sep 2021 09:17:07 +0800
Hi Mark,
On Sun, Sep 19, 2021 at 9:04 AM Bin Meng bmeng.cn@gmail.com wrote:
Hi Mark,
On Sat, Sep 18, 2021 at 9:55 PM 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 | 22 ++++ > arch/arm/Makefile | 1 + > arch/arm/mach-apple/Kconfig | 18 ++++ > arch/arm/mach-apple/Makefile | 4 + > arch/arm/mach-apple/board.c | 158 ++++++++++++++++++++++++++++ > arch/arm/mach-apple/lowlevel_init.S | 16 +++ > configs/apple_m1_defconfig | 14 +++ > include/configs/apple.h | 38 +++++++ > 8 files changed, 271 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/mach-apple/lowlevel_init.S b/arch/arm/mach-apple/lowlevel_init.S > new file mode 100644 > index 0000000000..0f5313163e > --- /dev/null > +++ b/arch/arm/mach-apple/lowlevel_init.S > @@ -0,0 +1,16 @@ > +/* 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
Is this filled in by m1n1?
Sorry I misread, so this is passed by m1n1 and filled in by U-Boot. I think we should stop using CONFIG_OF_BOARD, and for such case we should use CONFIG_OF_PRIOR_STAGE.
Yes, CONFIG_OF_PRIOR_STAGE would work as well. But Tom was talking about removing that option in favour of CONFIG_OF_BOARD the other day.
Yes. I was even looking for some feedback from you, Bin, on converting some boards from CONFIG_OF_PRIOR_STAGE to CONFIG_OF_BOARD. It seems like CONFIG_OF_PRIOR_STAGE is a subset of CONFIG_OF_BOARD, at the cost of possibly a few bytes.
Ah, I thought we wanted to do the other way around, by removing CONFIG_OF_BOARD, and convert that to CONFIG_OF_PRIORI_STAGE?
I must say that I see some logic in keeping both, where CONFIG_OF_BOARD indicates that the device tree is somehow stored on the board and U-Boot has to run some code to fetch it, and CONFIG_OF_PRIOR_STAGE is used when the device tree is provided by firmware that runs before U-Boot.
In that case I obviously should use CONFIG_OF_PRIOR_STAGE here.
Well see Ilias' series where he proposed going with OF_BOARD!
Tested on: Macbook Air M1 Tested-by: Simon Glass sjg@chromium.org
Regards, Simon

From: Bin Meng bmeng.cn@gmail.com Date: Sun, 19 Sep 2021 09:04:56 +0800
Hi Bin,
Thanks for taking a look.
Hi Mark,
On Sat, Sep 18, 2021 at 9:55 PM 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 | 22 ++++ arch/arm/Makefile | 1 + arch/arm/mach-apple/Kconfig | 18 ++++ arch/arm/mach-apple/Makefile | 4 + arch/arm/mach-apple/board.c | 158 ++++++++++++++++++++++++++++ arch/arm/mach-apple/lowlevel_init.S | 16 +++ configs/apple_m1_defconfig | 14 +++ include/configs/apple.h | 38 +++++++ 8 files changed, 271 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..7cdea1f615 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -895,6 +895,26 @@ config ARCH_NEXELL select DM select GPIO_EXTRA_HEADER
+config ARCH_APPLE
bool "Apple SoCs"
select ARM64
select LINUX_KERNEL_IMAGE_HEADER
select POSITION_INDEPENDENT
select BLK
select DM
select DM_KEYBOARD
select DM_SERIAL
select DM_USB
select DM_VIDEO
select CMD_USB
select MISC
select OF_CONTROL
select OF_BOARD
select USB
imply CMD_DM
imply CMD_GPT
imply DISTRO_DEFAULTS
config ARCH_OWL bool "Actions Semi OWL SoCs" select DM @@ -1932,6 +1952,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..0c8b35292e --- /dev/null +++ b/arch/arm/mach-apple/board.c @@ -0,0 +1,158 @@ +// SPDX-License-Identifier: GPL-2.0+ +/*
- (C) Copyright 2021 Mark Kettenis kettenis@openbsd.org
- */
+#include <common.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) +{
int index, node, ret;
fdt_addr_t base;
fdt_size_t size;
ret = fdtdec_setup_mem_size_base();
if (ret)
return ret;
/* Update RAM mapping. */
nits: please remove the ending .
Really? The current codebase has both styles... But sure, I can make that change.
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 = fdt_path_offset(gd->fdt_blob, "/chosen/framebuffer");
if (node < 0)
return 0;
base = fdtdec_get_addr_size(gd->fdt_blob, node, "reg", &size);
if (base == FDT_ADDR_T_NONE)
return 0;
/* Add framebuffer mapping. */
ditto
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)
This looks like we should add a new sysreset driver for Apple Arm SoC.
Could be. This is actually a watchdog device that is used to reset the machine. So I suppose I should add a watchdog driver and use SYSRESET_WATCHDOG. Slight worry is that this relies on a lot more DM code. Does that mean the reset isn't available during early boot?
If it is acceptable, I would like to add the watchdog device in a future series, once the device tree bindings for the watchdog have been hammered out.
+{
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 (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..0f5313163e --- /dev/null +++ b/arch/arm/mach-apple/lowlevel_init.S @@ -0,0 +1,16 @@ +/* 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
Is this filled in by m1n1?
+.global save_boot_params +save_boot_params:
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
Regards, Bin

Hi Mark,
On Sat, 18 Sept 2021 at 07:55, 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 | 22 ++++ arch/arm/Makefile | 1 + arch/arm/mach-apple/Kconfig | 18 ++++ arch/arm/mach-apple/Makefile | 4 + arch/arm/mach-apple/board.c | 158 ++++++++++++++++++++++++++++ arch/arm/mach-apple/lowlevel_init.S | 16 +++ configs/apple_m1_defconfig | 14 +++ include/configs/apple.h | 38 +++++++ 8 files changed, 271 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..7cdea1f615 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -895,6 +895,26 @@ config ARCH_NEXELL select DM select GPIO_EXTRA_HEADER
+config ARCH_APPLE
bool "Apple SoCs"
select ARM64
select LINUX_KERNEL_IMAGE_HEADER
select POSITION_INDEPENDENT
select BLK
select DM
select DM_KEYBOARD
select DM_SERIAL
select DM_USB
select DM_VIDEO
select CMD_USB
select MISC
select OF_CONTROL
select OF_BOARD
select USB
imply CMD_DM
imply CMD_GPT
imply DISTRO_DEFAULTS
Suggest sorting these
config ARCH_OWL bool "Actions Semi OWL SoCs" select DM @@ -1932,6 +1952,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..0c8b35292e --- /dev/null +++ b/arch/arm/mach-apple/board.c @@ -0,0 +1,158 @@ +// SPDX-License-Identifier: GPL-2.0+ +/*
- (C) Copyright 2021 Mark Kettenis kettenis@openbsd.org
- */
+#include <common.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) +{
int index, node, ret;
fdt_addr_t base;
fdt_size_t size;
ret = fdtdec_setup_mem_size_base();
if (ret)
return ret;
/* Update RAM mapping. */
Do you want the period at the end of that?
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 = fdt_path_offset(gd->fdt_blob, "/chosen/framebuffer");
Can you use the ofnode interface here and below?
if (node < 0)
return 0;
base = fdtdec_get_addr_size(gd->fdt_blob, 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
should be in DT I think, with a driver
+#define APPLE_WDT_SYS_CTL_ENABLE BIT(2)
+typedef struct apple_wdt {
Needs comments
u32 reserved0[3];
u32 chip_ctl;
u32 sys_tmr;
u32 sys_cmp;
u32 reserved1;
u32 sys_ctl;
+} apple_wdt_t;
+void reset_cpu(void)
You should add a sysreset driver, as Bin says.
+{
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;
comment
+void *board_fdt_blob_setup(void) +{
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..0f5313163e --- /dev/null +++ b/arch/arm/mach-apple/lowlevel_init.S @@ -0,0 +1,16 @@ +/* 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:
adr x1, fw_dtb_pointer
could use a comment as to where this is set up. Previous-stage firmware, I suppose?
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
2.33.0
Regards, Simon

From: Simon Glass sjg@chromium.org Date: Sun, 19 Sep 2021 21:15:57 -0600
Hi Mark,
On Sat, 18 Sept 2021 at 07:55, 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 | 22 ++++ arch/arm/Makefile | 1 + arch/arm/mach-apple/Kconfig | 18 ++++ arch/arm/mach-apple/Makefile | 4 + arch/arm/mach-apple/board.c | 158 ++++++++++++++++++++++++++++ arch/arm/mach-apple/lowlevel_init.S | 16 +++ configs/apple_m1_defconfig | 14 +++ include/configs/apple.h | 38 +++++++ 8 files changed, 271 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..7cdea1f615 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -895,6 +895,26 @@ config ARCH_NEXELL select DM select GPIO_EXTRA_HEADER
+config ARCH_APPLE
bool "Apple SoCs"
select ARM64
select LINUX_KERNEL_IMAGE_HEADER
select POSITION_INDEPENDENT
select BLK
select DM
select DM_KEYBOARD
select DM_SERIAL
select DM_USB
select DM_VIDEO
select CMD_USB
select MISC
select OF_CONTROL
select OF_BOARD
select USB
imply CMD_DM
imply CMD_GPT
imply DISTRO_DEFAULTS
Suggest sorting these
As in sort all the selects alphabetically and sort all the implies alphabetically seperately?
Does my use of impy here even make sense?
This whole Kconfig stuff is a bit alien to me and I must say that it isn't obvious what "best-practice" is in this area...
config ARCH_OWL bool "Actions Semi OWL SoCs" select DM @@ -1932,6 +1952,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..0c8b35292e --- /dev/null +++ b/arch/arm/mach-apple/board.c @@ -0,0 +1,158 @@ +// SPDX-License-Identifier: GPL-2.0+ +/*
- (C) Copyright 2021 Mark Kettenis kettenis@openbsd.org
- */
+#include <common.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) +{
int index, node, ret;
fdt_addr_t base;
fdt_size_t size;
ret = fdtdec_setup_mem_size_base();
if (ret)
return ret;
/* Update RAM mapping. */
Do you want the period at the end of that?
Given that Bin brought up the same thing, I gather that not having a full stop at the end of single-line comments is preferred?
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 = fdt_path_offset(gd->fdt_blob, "/chosen/framebuffer");
Can you use the ofnode interface here and below?
I can try...
if (node < 0)
return 0;
base = fdtdec_get_addr_size(gd->fdt_blob, 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
should be in DT I think, with a driver
+#define APPLE_WDT_SYS_CTL_ENABLE BIT(2)
+typedef struct apple_wdt {
Needs comments
u32 reserved0[3];
u32 chip_ctl;
u32 sys_tmr;
u32 sys_cmp;
u32 reserved1;
u32 sys_ctl;
+} apple_wdt_t;
+void reset_cpu(void)
You should add a sysreset driver, as Bin says.
+{
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;
comment
+void *board_fdt_blob_setup(void) +{
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..0f5313163e --- /dev/null +++ b/arch/arm/mach-apple/lowlevel_init.S @@ -0,0 +1,16 @@ +/* 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:
adr x1, fw_dtb_pointer
could use a comment as to where this is set up. Previous-stage firmware, I suppose?
Yes. I'm basically making U-Boot look like a Linux kernel, and m1n1 passes the DT in x1 just like the Linux kernel expects.
I suspect using CONFIG_OF_PRIOR_STAGE would make it more obvious what is happening here. But (a) I didn't know that existed and (b) we discussed removing that option in the near future.
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
2.33.0
Regards, Simon

Hi Mark,
On Mon, 20 Sept 2021 at 02:49, Mark Kettenis mark.kettenis@xs4all.nl wrote:
From: Simon Glass sjg@chromium.org Date: Sun, 19 Sep 2021 21:15:57 -0600
Hi Mark,
On Sat, 18 Sept 2021 at 07:55, 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 | 22 ++++ arch/arm/Makefile | 1 + arch/arm/mach-apple/Kconfig | 18 ++++ arch/arm/mach-apple/Makefile | 4 + arch/arm/mach-apple/board.c | 158 ++++++++++++++++++++++++++++ arch/arm/mach-apple/lowlevel_init.S | 16 +++ configs/apple_m1_defconfig | 14 +++ include/configs/apple.h | 38 +++++++ 8 files changed, 271 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..7cdea1f615 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -895,6 +895,26 @@ config ARCH_NEXELL select DM select GPIO_EXTRA_HEADER
+config ARCH_APPLE
bool "Apple SoCs"
select ARM64
select LINUX_KERNEL_IMAGE_HEADER
select POSITION_INDEPENDENT
select BLK
select DM
select DM_KEYBOARD
select DM_SERIAL
select DM_USB
select DM_VIDEO
select CMD_USB
select MISC
select OF_CONTROL
select OF_BOARD
select USB
imply CMD_DM
imply CMD_GPT
imply DISTRO_DEFAULTS
Suggest sorting these
As in sort all the selects alphabetically and sort all the implies alphabetically seperately?
I suppose so.
Does my use of impy here even make sense?
It allows people to disable it, whereas select does not. It looks OK to me.
This whole Kconfig stuff is a bit alien to me and I must say that it isn't obvious what "best-practice" is in this area...
We try to avoid select so only use it if it really cannot build/run without that feature. From what I can tell you have done that.
I know this is a different project, but there are some ideas here:
https://docs.zephyrproject.org/1.14.0/guides/kconfig/index.html
[..]
+int dram_init(void) +{
int index, node, ret;
fdt_addr_t base;
fdt_size_t size;
ret = fdtdec_setup_mem_size_base();
if (ret)
return ret;
/* Update RAM mapping. */
Do you want the period at the end of that?
Given that Bin brought up the same thing, I gather that not having a full stop at the end of single-line comments is preferred?
Yes, the periods just clutter things and people start adding them only when it is a valid sentence, etc. Best to just leave them out.
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 = fdt_path_offset(gd->fdt_blob, "/chosen/framebuffer");
Can you use the ofnode interface here and below?
I can try...
Something like:
ofnode node;
node = ofnode_path("/chosen/framebuffer");
then use ofnode_get_addr_size()
if (node < 0)
return 0;
base = fdtdec_get_addr_size(gd->fdt_blob, 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;
+}
[..]
diff --git a/arch/arm/mach-apple/lowlevel_init.S b/arch/arm/mach-apple/lowlevel_init.S new file mode 100644 index 0000000000..0f5313163e --- /dev/null +++ b/arch/arm/mach-apple/lowlevel_init.S @@ -0,0 +1,16 @@ +/* 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:
adr x1, fw_dtb_pointer
could use a comment as to where this is set up. Previous-stage firmware, I suppose?
Yes. I'm basically making U-Boot look like a Linux kernel, and m1n1 passes the DT in x1 just like the Linux kernel expects.
I suspect using CONFIG_OF_PRIOR_STAGE would make it more obvious what is happening here. But (a) I didn't know that existed and (b) we discussed removing that option in the near future.
That sounds right to me, but a comment would help.
Regards, Simon

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/include/asm/arch-m1/clk.h | 11 ++++++++ arch/arm/include/asm/arch-m1/uart.h | 41 +++++++++++++++++++++++++++++ arch/arm/mach-apple/board.c | 5 ++++ drivers/serial/Kconfig | 2 +- drivers/serial/serial_s5p.c | 22 ++++++++++++++++ 5 files changed, 80 insertions(+), 1 deletion(-) create mode 100644 arch/arm/include/asm/arch-m1/clk.h create mode 100644 arch/arm/include/asm/arch-m1/uart.h
diff --git a/arch/arm/include/asm/arch-m1/clk.h b/arch/arm/include/asm/arch-m1/clk.h new file mode 100644 index 0000000000..f4326d0c0f --- /dev/null +++ b/arch/arm/include/asm/arch-m1/clk.h @@ -0,0 +1,11 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2021 Mark Kettenis kettenis@openbsd.org + */ + +#ifndef __ASM_ARM_ARCH_CLK_H_ +#define __ASM_ARM_ARCH_CLK_H_ + +unsigned long get_uart_clk(int dev_index); + +#endif 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/arch/arm/mach-apple/board.c b/arch/arm/mach-apple/board.c index 0c8b35292e..8bc5c2f69e 100644 --- a/arch/arm/mach-apple/board.c +++ b/arch/arm/mach-apple/board.c @@ -156,3 +156,8 @@ ulong board_get_usable_ram_top(ulong total_size) */ return 0x980000000; } + +unsigned long get_uart_clk(int dev_index) +{ + return 24000000; +} diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index 93348c0929..c3ac773929 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig @@ -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..eb770d9b62 100644 --- a/drivers/serial/serial_s5p.c +++ b/drivers/serial/serial_s5p.c @@ -21,12 +21,21 @@
DECLARE_GLOBAL_DATA_PTR;
+#ifdef CONFIG_ARCH_APPLE +#define RX_FIFO_COUNT_SHIFT 0 +#define RX_FIFO_COUNT_MASK (0xf << RX_FIFO_COUNT_SHIFT) +#define RX_FIFO_FULL (1 << 8) +#define TX_FIFO_COUNT_SHIFT 4 +#define TX_FIFO_COUNT_MASK (0xf << TX_FIFO_COUNT_SHIFT) +#define TX_FIFO_FULL (1 << 9) +#else #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) +#endif
/* Information about a serial port */ struct s5p_serial_plat { @@ -83,7 +92,11 @@ 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 +#ifdef CONFIG_ARCH_APPLE + writel(val % 16, &uart->rest.value); +#else writeb(val % 16, &uart->rest.value); +#endif }
#ifndef CONFIG_SPL_BUILD @@ -148,7 +161,11 @@ static int s5p_serial_getc(struct udevice *dev) return -EAGAIN;
serial_err_check(uart, 0); +#ifdef CONFIG_ARCH_APPLE + return (int)(readl(&uart->urxh) & 0xff); +#else return (int)(readb(&uart->urxh) & 0xff); +#endif }
static int s5p_serial_putc(struct udevice *dev, const char ch) @@ -159,7 +176,11 @@ static int s5p_serial_putc(struct udevice *dev, const char ch) if (readl(&uart->ufstat) & TX_FIFO_FULL) return -EAGAIN;
+#ifdef CONFIG_ARCH_APPLE + writel(ch, &uart->utxh); +#else writeb(ch, &uart->utxh); +#endif serial_err_check(uart, 1);
return 0; @@ -201,6 +222,7 @@ static const struct dm_serial_ops s5p_serial_ops = {
static const struct udevice_id s5p_serial_ids[] = { { .compatible = "samsung,exynos4210-uart" }, + { .compatible = "apple,s5l-uart" }, { } };

Hi Mark,
On Sat, Sep 18, 2021 at 9:55 PM 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/include/asm/arch-m1/clk.h | 11 ++++++++ arch/arm/include/asm/arch-m1/uart.h | 41 +++++++++++++++++++++++++++++ arch/arm/mach-apple/board.c | 5 ++++ drivers/serial/Kconfig | 2 +- drivers/serial/serial_s5p.c | 22 ++++++++++++++++ 5 files changed, 80 insertions(+), 1 deletion(-) create mode 100644 arch/arm/include/asm/arch-m1/clk.h create mode 100644 arch/arm/include/asm/arch-m1/uart.h
diff --git a/arch/arm/include/asm/arch-m1/clk.h b/arch/arm/include/asm/arch-m1/clk.h new file mode 100644 index 0000000000..f4326d0c0f --- /dev/null +++ b/arch/arm/include/asm/arch-m1/clk.h @@ -0,0 +1,11 @@ +// SPDX-License-Identifier: GPL-2.0+ +/*
- Copyright (C) 2021 Mark Kettenis kettenis@openbsd.org
- */
+#ifndef __ASM_ARM_ARCH_CLK_H_ +#define __ASM_ARM_ARCH_CLK_H_
+unsigned long get_uart_clk(int dev_index);
+#endif 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];
+};
This does not look correct. This should be declared in the s5p UART driver header instead of SoC's
+static inline int s5p_uart_divslot(void) +{
return 0;
+}
+#endif /* __ASSEMBLY__ */
+#endif diff --git a/arch/arm/mach-apple/board.c b/arch/arm/mach-apple/board.c index 0c8b35292e..8bc5c2f69e 100644 --- a/arch/arm/mach-apple/board.c +++ b/arch/arm/mach-apple/board.c @@ -156,3 +156,8 @@ ulong board_get_usable_ram_top(ulong total_size) */ return 0x980000000; }
+unsigned long get_uart_clk(int dev_index) +{
return 24000000;
+} diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index 93348c0929..c3ac773929 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig @@ -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..eb770d9b62 100644 --- a/drivers/serial/serial_s5p.c +++ b/drivers/serial/serial_s5p.c @@ -21,12 +21,21 @@
DECLARE_GLOBAL_DATA_PTR;
+#ifdef CONFIG_ARCH_APPLE +#define RX_FIFO_COUNT_SHIFT 0 +#define RX_FIFO_COUNT_MASK (0xf << RX_FIFO_COUNT_SHIFT) +#define RX_FIFO_FULL (1 << 8) +#define TX_FIFO_COUNT_SHIFT 4 +#define TX_FIFO_COUNT_MASK (0xf << TX_FIFO_COUNT_SHIFT) +#define TX_FIFO_FULL (1 << 9)
So different bit positions for RX/TX FIFIO register but still it is s5p compatible, strange ...
+#else #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) +#endif
/* Information about a serial port */ struct s5p_serial_plat { @@ -83,7 +92,11 @@ 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 +#ifdef CONFIG_ARCH_APPLE
writel(val % 16, &uart->rest.value);
This looks like we should add a property in DT like "reg-width" to control such behavior?
+#else writeb(val % 16, &uart->rest.value); +#endif }
#ifndef CONFIG_SPL_BUILD @@ -148,7 +161,11 @@ static int s5p_serial_getc(struct udevice *dev) return -EAGAIN;
serial_err_check(uart, 0);
+#ifdef CONFIG_ARCH_APPLE
return (int)(readl(&uart->urxh) & 0xff);
+#else return (int)(readb(&uart->urxh) & 0xff); +#endif }
static int s5p_serial_putc(struct udevice *dev, const char ch) @@ -159,7 +176,11 @@ static int s5p_serial_putc(struct udevice *dev, const char ch) if (readl(&uart->ufstat) & TX_FIFO_FULL) return -EAGAIN;
+#ifdef CONFIG_ARCH_APPLE
writel(ch, &uart->utxh);
+#else writeb(ch, &uart->utxh); +#endif serial_err_check(uart, 1);
return 0;
@@ -201,6 +222,7 @@ static const struct dm_serial_ops s5p_serial_ops = {
static const struct udevice_id s5p_serial_ids[] = { { .compatible = "samsung,exynos4210-uart" },
{ .compatible = "apple,s5l-uart" }, { }
};
Regards, Bin

From: Bin Meng bmeng.cn@gmail.com Date: Sun, 19 Sep 2021 09:11:06 +0800
Hi Mark,
On Sat, Sep 18, 2021 at 9:55 PM 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/include/asm/arch-m1/clk.h | 11 ++++++++ arch/arm/include/asm/arch-m1/uart.h | 41 +++++++++++++++++++++++++++++ arch/arm/mach-apple/board.c | 5 ++++ drivers/serial/Kconfig | 2 +- drivers/serial/serial_s5p.c | 22 ++++++++++++++++ 5 files changed, 80 insertions(+), 1 deletion(-) create mode 100644 arch/arm/include/asm/arch-m1/clk.h create mode 100644 arch/arm/include/asm/arch-m1/uart.h
diff --git a/arch/arm/include/asm/arch-m1/clk.h b/arch/arm/include/asm/arch-m1/clk.h new file mode 100644 index 0000000000..f4326d0c0f --- /dev/null +++ b/arch/arm/include/asm/arch-m1/clk.h @@ -0,0 +1,11 @@ +// SPDX-License-Identifier: GPL-2.0+ +/*
- Copyright (C) 2021 Mark Kettenis kettenis@openbsd.org
- */
+#ifndef __ASM_ARM_ARCH_CLK_H_ +#define __ASM_ARM_ARCH_CLK_H_
+unsigned long get_uart_clk(int dev_index);
+#endif 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];
+};
This does not look correct. This should be declared in the s5p UART driver header instead of SoC's
Well, this is the status quo for this driver. There are several variations of the hardware with slightly different register layouts and the header file trick is how that is handled.
+static inline int s5p_uart_divslot(void) +{
return 0;
+}
+#endif /* __ASSEMBLY__ */
+#endif diff --git a/arch/arm/mach-apple/board.c b/arch/arm/mach-apple/board.c index 0c8b35292e..8bc5c2f69e 100644 --- a/arch/arm/mach-apple/board.c +++ b/arch/arm/mach-apple/board.c @@ -156,3 +156,8 @@ ulong board_get_usable_ram_top(ulong total_size) */ return 0x980000000; }
+unsigned long get_uart_clk(int dev_index) +{
return 24000000;
+} diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index 93348c0929..c3ac773929 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig @@ -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..eb770d9b62 100644 --- a/drivers/serial/serial_s5p.c +++ b/drivers/serial/serial_s5p.c @@ -21,12 +21,21 @@
DECLARE_GLOBAL_DATA_PTR;
+#ifdef CONFIG_ARCH_APPLE +#define RX_FIFO_COUNT_SHIFT 0 +#define RX_FIFO_COUNT_MASK (0xf << RX_FIFO_COUNT_SHIFT) +#define RX_FIFO_FULL (1 << 8) +#define TX_FIFO_COUNT_SHIFT 4 +#define TX_FIFO_COUNT_MASK (0xf << TX_FIFO_COUNT_SHIFT) +#define TX_FIFO_FULL (1 << 9)
So different bit positions for RX/TX FIFIO register but still it is s5p compatible, strange ...
Yeah, the Apple hardware is based on an older variant of the s5p that had a smaller FIFO. The size of the FIFO was increased somewhere along the way and the bits were moved...
+#else #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) +#endif
/* Information about a serial port */ struct s5p_serial_plat { @@ -83,7 +92,11 @@ 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 +#ifdef CONFIG_ARCH_APPLE
writel(val % 16, &uart->rest.value);
This looks like we should add a property in DT like "reg-width" to control such behavior?
There actually is such a property in the binding called "reg-io-width". So I suppose I should use that.
+#else writeb(val % 16, &uart->rest.value); +#endif }
#ifndef CONFIG_SPL_BUILD @@ -148,7 +161,11 @@ static int s5p_serial_getc(struct udevice *dev) return -EAGAIN;
serial_err_check(uart, 0);
+#ifdef CONFIG_ARCH_APPLE
return (int)(readl(&uart->urxh) & 0xff);
+#else return (int)(readb(&uart->urxh) & 0xff); +#endif }
static int s5p_serial_putc(struct udevice *dev, const char ch) @@ -159,7 +176,11 @@ static int s5p_serial_putc(struct udevice *dev, const char ch) if (readl(&uart->ufstat) & TX_FIFO_FULL) return -EAGAIN;
+#ifdef CONFIG_ARCH_APPLE
writel(ch, &uart->utxh);
+#else writeb(ch, &uart->utxh); +#endif serial_err_check(uart, 1);
return 0;
@@ -201,6 +222,7 @@ static const struct dm_serial_ops s5p_serial_ops = {
static const struct udevice_id s5p_serial_ids[] = { { .compatible = "samsung,exynos4210-uart" },
{ .compatible = "apple,s5l-uart" }, { }
};
Regards, Bin

Hi Mark,
On Sat, 18 Sept 2021 at 07:55, 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/include/asm/arch-m1/clk.h | 11 ++++++++ arch/arm/include/asm/arch-m1/uart.h | 41 +++++++++++++++++++++++++++++ arch/arm/mach-apple/board.c | 5 ++++ drivers/serial/Kconfig | 2 +- drivers/serial/serial_s5p.c | 22 ++++++++++++++++ 5 files changed, 80 insertions(+), 1 deletion(-) create mode 100644 arch/arm/include/asm/arch-m1/clk.h create mode 100644 arch/arm/include/asm/arch-m1/uart.h
diff --git a/arch/arm/include/asm/arch-m1/clk.h b/arch/arm/include/asm/arch-m1/clk.h new file mode 100644 index 0000000000..f4326d0c0f --- /dev/null +++ b/arch/arm/include/asm/arch-m1/clk.h @@ -0,0 +1,11 @@ +// SPDX-License-Identifier: GPL-2.0+ +/*
- Copyright (C) 2021 Mark Kettenis kettenis@openbsd.org
- */
+#ifndef __ASM_ARM_ARCH_CLK_H_ +#define __ASM_ARM_ARCH_CLK_H_
+unsigned long get_uart_clk(int dev_index);
comment? But this should be in a clock driver, unless you are trying to get a debug UART up ASAP with minimal code?
+#endif 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/arch/arm/mach-apple/board.c b/arch/arm/mach-apple/board.c index 0c8b35292e..8bc5c2f69e 100644 --- a/arch/arm/mach-apple/board.c +++ b/arch/arm/mach-apple/board.c @@ -156,3 +156,8 @@ ulong board_get_usable_ram_top(ulong total_size) */ return 0x980000000; }
+unsigned long get_uart_clk(int dev_index) +{
return 24000000;
Should add to devicetree for the driver
+} diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index 93348c0929..c3ac773929 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig @@ -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..eb770d9b62 100644 --- a/drivers/serial/serial_s5p.c +++ b/drivers/serial/serial_s5p.c @@ -21,12 +21,21 @@
DECLARE_GLOBAL_DATA_PTR;
+#ifdef CONFIG_ARCH_APPLE
This should use the compatible string to decide which variant it is, then the checks happen at runtime. We should never have arch-specific #ifdefs in drivers.
+#define RX_FIFO_COUNT_SHIFT 0 +#define RX_FIFO_COUNT_MASK (0xf << RX_FIFO_COUNT_SHIFT) +#define RX_FIFO_FULL (1 << 8) +#define TX_FIFO_COUNT_SHIFT 4 +#define TX_FIFO_COUNT_MASK (0xf << TX_FIFO_COUNT_SHIFT) +#define TX_FIFO_FULL (1 << 9) +#else #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) +#endif
/* Information about a serial port */ struct s5p_serial_plat { @@ -83,7 +92,11 @@ 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 +#ifdef CONFIG_ARCH_APPLE
writel(val % 16, &uart->rest.value);
+#else writeb(val % 16, &uart->rest.value); +#endif }
#ifndef CONFIG_SPL_BUILD @@ -148,7 +161,11 @@ static int s5p_serial_getc(struct udevice *dev) return -EAGAIN;
serial_err_check(uart, 0);
+#ifdef CONFIG_ARCH_APPLE
return (int)(readl(&uart->urxh) & 0xff);
+#else return (int)(readb(&uart->urxh) & 0xff); +#endif }
static int s5p_serial_putc(struct udevice *dev, const char ch) @@ -159,7 +176,11 @@ static int s5p_serial_putc(struct udevice *dev, const char ch) if (readl(&uart->ufstat) & TX_FIFO_FULL) return -EAGAIN;
+#ifdef CONFIG_ARCH_APPLE
writel(ch, &uart->utxh);
+#else writeb(ch, &uart->utxh); +#endif serial_err_check(uart, 1);
return 0;
@@ -201,6 +222,7 @@ static const struct dm_serial_ops s5p_serial_ops = {
static const struct udevice_id s5p_serial_ids[] = { { .compatible = "samsung,exynos4210-uart" },
{ .compatible = "apple,s5l-uart" }, { }
};
-- 2.33.0
Can you add debug UART support? Or does this already work?
Regards, Simon

On Sun, 19 Sept 2021 at 21:15, Simon Glass sjg@chromium.org wrote:
Hi Mark,
On Sat, 18 Sept 2021 at 07:55, 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/include/asm/arch-m1/clk.h | 11 ++++++++ arch/arm/include/asm/arch-m1/uart.h | 41 +++++++++++++++++++++++++++++ arch/arm/mach-apple/board.c | 5 ++++ drivers/serial/Kconfig | 2 +- drivers/serial/serial_s5p.c | 22 ++++++++++++++++ 5 files changed, 80 insertions(+), 1 deletion(-) create mode 100644 arch/arm/include/asm/arch-m1/clk.h create mode 100644 arch/arm/include/asm/arch-m1/uart.h
Tested on: Macbook Air M1 Tested-by: Simon Glass sjg@chromium.org

From: Simon Glass sjg@chromium.org Date: Sun, 19 Sep 2021 21:15:59 -0600
Hi Mark,
On Sat, 18 Sept 2021 at 07:55, 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/include/asm/arch-m1/clk.h | 11 ++++++++ arch/arm/include/asm/arch-m1/uart.h | 41 +++++++++++++++++++++++++++++ arch/arm/mach-apple/board.c | 5 ++++ drivers/serial/Kconfig | 2 +- drivers/serial/serial_s5p.c | 22 ++++++++++++++++ 5 files changed, 80 insertions(+), 1 deletion(-) create mode 100644 arch/arm/include/asm/arch-m1/clk.h create mode 100644 arch/arm/include/asm/arch-m1/uart.h
diff --git a/arch/arm/include/asm/arch-m1/clk.h b/arch/arm/include/asm/arch-m1/clk.h new file mode 100644 index 0000000000..f4326d0c0f --- /dev/null +++ b/arch/arm/include/asm/arch-m1/clk.h @@ -0,0 +1,11 @@ +// SPDX-License-Identifier: GPL-2.0+ +/*
- Copyright (C) 2021 Mark Kettenis kettenis@openbsd.org
- */
+#ifndef __ASM_ARM_ARCH_CLK_H_ +#define __ASM_ARM_ARCH_CLK_H_
+unsigned long get_uart_clk(int dev_index);
comment? But this should be in a clock driver, unless you are trying to get a debug UART up ASAP with minimal code?
+#endif 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/arch/arm/mach-apple/board.c b/arch/arm/mach-apple/board.c index 0c8b35292e..8bc5c2f69e 100644 --- a/arch/arm/mach-apple/board.c +++ b/arch/arm/mach-apple/board.c @@ -156,3 +156,8 @@ ulong board_get_usable_ram_top(ulong total_size) */ return 0x980000000; }
+unsigned long get_uart_clk(int dev_index) +{
return 24000000;
Should add to devicetree for the driver
+} diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index 93348c0929..c3ac773929 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig @@ -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..eb770d9b62 100644 --- a/drivers/serial/serial_s5p.c +++ b/drivers/serial/serial_s5p.c @@ -21,12 +21,21 @@
DECLARE_GLOBAL_DATA_PTR;
+#ifdef CONFIG_ARCH_APPLE
This should use the compatible string to decide which variant it is, then the checks happen at runtime. We should never have arch-specific #ifdefs in drivers.
+#define RX_FIFO_COUNT_SHIFT 0 +#define RX_FIFO_COUNT_MASK (0xf << RX_FIFO_COUNT_SHIFT) +#define RX_FIFO_FULL (1 << 8) +#define TX_FIFO_COUNT_SHIFT 4 +#define TX_FIFO_COUNT_MASK (0xf << TX_FIFO_COUNT_SHIFT) +#define TX_FIFO_FULL (1 << 9) +#else #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) +#endif
/* Information about a serial port */ struct s5p_serial_plat { @@ -83,7 +92,11 @@ 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 +#ifdef CONFIG_ARCH_APPLE
writel(val % 16, &uart->rest.value);
+#else writeb(val % 16, &uart->rest.value); +#endif }
#ifndef CONFIG_SPL_BUILD @@ -148,7 +161,11 @@ static int s5p_serial_getc(struct udevice *dev) return -EAGAIN;
serial_err_check(uart, 0);
+#ifdef CONFIG_ARCH_APPLE
return (int)(readl(&uart->urxh) & 0xff);
+#else return (int)(readb(&uart->urxh) & 0xff); +#endif }
static int s5p_serial_putc(struct udevice *dev, const char ch) @@ -159,7 +176,11 @@ static int s5p_serial_putc(struct udevice *dev, const char ch) if (readl(&uart->ufstat) & TX_FIFO_FULL) return -EAGAIN;
+#ifdef CONFIG_ARCH_APPLE
writel(ch, &uart->utxh);
+#else writeb(ch, &uart->utxh); +#endif serial_err_check(uart, 1);
return 0;
@@ -201,6 +222,7 @@ static const struct dm_serial_ops s5p_serial_ops = {
static const struct udevice_id s5p_serial_ids[] = { { .compatible = "samsung,exynos4210-uart" },
{ .compatible = "apple,s5l-uart" }, { }
};
-- 2.33.0
Can you add debug UART support? Or does this already work?
I don't think it does work. But yes, I want to add it since it will help a lot with debugging. That makes fixing some of the issues raised by you and bing more problematic since the debug UART support code:
- Needs to use 32-bit access on Apple M1, and using the "reg-io-width" property there isn't possible.
- Relies on the FIFO control bits which are in a different position on the Apple M1.
So I am starting to wonder whether it makes sense to simply copy serial_s5p.c to serial_s5l.c and modify that one to do the right thing on the apple SoC.
Alternatively I could introduce Kconfig stuff to switch between S5L and S5P support.

Hi Mark,
On Sat, 2 Oct 2021 at 16:16, Mark Kettenis mark.kettenis@xs4all.nl wrote:
From: Simon Glass sjg@chromium.org Date: Sun, 19 Sep 2021 21:15:59 -0600
Hi Mark,
On Sat, 18 Sept 2021 at 07:55, 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/include/asm/arch-m1/clk.h | 11 ++++++++ arch/arm/include/asm/arch-m1/uart.h | 41 +++++++++++++++++++++++++++++ arch/arm/mach-apple/board.c | 5 ++++ drivers/serial/Kconfig | 2 +- drivers/serial/serial_s5p.c | 22 ++++++++++++++++ 5 files changed, 80 insertions(+), 1 deletion(-) create mode 100644 arch/arm/include/asm/arch-m1/clk.h create mode 100644 arch/arm/include/asm/arch-m1/uart.h
diff --git a/arch/arm/include/asm/arch-m1/clk.h b/arch/arm/include/asm/arch-m1/clk.h new file mode 100644 index 0000000000..f4326d0c0f --- /dev/null +++ b/arch/arm/include/asm/arch-m1/clk.h @@ -0,0 +1,11 @@ +// SPDX-License-Identifier: GPL-2.0+ +/*
- Copyright (C) 2021 Mark Kettenis kettenis@openbsd.org
- */
+#ifndef __ASM_ARM_ARCH_CLK_H_ +#define __ASM_ARM_ARCH_CLK_H_
+unsigned long get_uart_clk(int dev_index);
comment? But this should be in a clock driver, unless you are trying to get a debug UART up ASAP with minimal code?
+#endif 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/arch/arm/mach-apple/board.c b/arch/arm/mach-apple/board.c index 0c8b35292e..8bc5c2f69e 100644 --- a/arch/arm/mach-apple/board.c +++ b/arch/arm/mach-apple/board.c @@ -156,3 +156,8 @@ ulong board_get_usable_ram_top(ulong total_size) */ return 0x980000000; }
+unsigned long get_uart_clk(int dev_index) +{
return 24000000;
Should add to devicetree for the driver
+} diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index 93348c0929..c3ac773929 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig @@ -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..eb770d9b62 100644 --- a/drivers/serial/serial_s5p.c +++ b/drivers/serial/serial_s5p.c @@ -21,12 +21,21 @@
DECLARE_GLOBAL_DATA_PTR;
+#ifdef CONFIG_ARCH_APPLE
This should use the compatible string to decide which variant it is, then the checks happen at runtime. We should never have arch-specific #ifdefs in drivers.
+#define RX_FIFO_COUNT_SHIFT 0 +#define RX_FIFO_COUNT_MASK (0xf << RX_FIFO_COUNT_SHIFT) +#define RX_FIFO_FULL (1 << 8) +#define TX_FIFO_COUNT_SHIFT 4 +#define TX_FIFO_COUNT_MASK (0xf << TX_FIFO_COUNT_SHIFT) +#define TX_FIFO_FULL (1 << 9) +#else #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) +#endif
/* Information about a serial port */ struct s5p_serial_plat { @@ -83,7 +92,11 @@ 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 +#ifdef CONFIG_ARCH_APPLE
writel(val % 16, &uart->rest.value);
+#else writeb(val % 16, &uart->rest.value); +#endif }
#ifndef CONFIG_SPL_BUILD @@ -148,7 +161,11 @@ static int s5p_serial_getc(struct udevice *dev) return -EAGAIN;
serial_err_check(uart, 0);
+#ifdef CONFIG_ARCH_APPLE
return (int)(readl(&uart->urxh) & 0xff);
+#else return (int)(readb(&uart->urxh) & 0xff); +#endif }
static int s5p_serial_putc(struct udevice *dev, const char ch) @@ -159,7 +176,11 @@ static int s5p_serial_putc(struct udevice *dev, const char ch) if (readl(&uart->ufstat) & TX_FIFO_FULL) return -EAGAIN;
+#ifdef CONFIG_ARCH_APPLE
writel(ch, &uart->utxh);
+#else writeb(ch, &uart->utxh); +#endif serial_err_check(uart, 1);
return 0;
@@ -201,6 +222,7 @@ static const struct dm_serial_ops s5p_serial_ops = {
static const struct udevice_id s5p_serial_ids[] = { { .compatible = "samsung,exynos4210-uart" },
{ .compatible = "apple,s5l-uart" }, { }
};
-- 2.33.0
Can you add debug UART support? Or does this already work?
I don't think it does work. But yes, I want to add it since it will help a lot with debugging. That makes fixing some of the issues raised by you and bing more problematic since the debug UART support code:
Needs to use 32-bit access on Apple M1, and using the "reg-io-width" property there isn't possible.
Relies on the FIFO control bits which are in a different position on the Apple M1.
So I am starting to wonder whether it makes sense to simply copy serial_s5p.c to serial_s5l.c and modify that one to do the right thing on the apple SoC.
Alternatively I could introduce Kconfig stuff to switch between S5L and S5P support.
Well, firstly you can use a compatible string as mentioned above which solves the normal case. You just need a flag in plat which indicates that it should use word access for some registers. The ns16550 shows how to call dev_get_driver_data(). You will need to add members to s5p_serial_plat to select the tx/tx FIFO values since these need tobe variables now.
BTW s5p_serial_baud() should have a param to indicate which access method to use.
For the debug UART I suggest just putting an IS_ENABLED(CONFIG_ARCH_APPLE) in there. You could add a Kconfig for the Apple UART (even though it uses the same file) which might be a little nicer, but it is only the debug UART, after all...
Finally, this driver is not perfect as it has CLK_EXYNOS only for some boards. Ideally all boards would move to use the clock driver.
Regards, Simon

The DART is an IOMMU that is used on Apple's M1 SoC. This driver supports the DART in bypass mode as well as in a mode where it creates a 1:1 mapping of a subset of RAM as not all DARTs support bypass mode. The USB3 ports integrated on the SoC use a DART that supports bypass mode. The 1:1 mapping will be used in the future to support other devices such as the PCIe host bridge of the M1 SoC.
Signed-off-by: Mark Kettenis kettenis@openbsd.org --- drivers/misc/Kconfig | 7 ++ drivers/misc/Makefile | 1 + drivers/misc/apple_dart.c | 171 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 179 insertions(+) create mode 100644 drivers/misc/apple_dart.c
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index 997b713221..d70b060e74 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -38,6 +38,13 @@ config ALTERA_SYSID Select this to enable a sysid for Altera devices. Please find details on the "Embedded Peripherals IP User Guide" of Altera.
+config APPLE_DART + bool "Apple DART support" + depends on MISC && ARCH_APPLE + default y + help + Enable support for the DART on Apple SoCs. + config ATSHA204A bool "Support for Atmel ATSHA204A module" depends on MISC diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile index b64cd2a4de..f666cd392d 100644 --- a/drivers/misc/Makefile +++ b/drivers/misc/Makefile @@ -29,6 +29,7 @@ endif endif obj-$(CONFIG_ALI152X) += ali512x.o obj-$(CONFIG_ALTERA_SYSID) += altera_sysid.o +obj-$(CONFIG_APPLE_DART) += apple_dart.o obj-$(CONFIG_ATSHA204A) += atsha204a-i2c.o obj-$(CONFIG_CBMEM_CONSOLE) += cbmem_console.o obj-$(CONFIG_DS4510) += ds4510.o diff --git a/drivers/misc/apple_dart.c b/drivers/misc/apple_dart.c new file mode 100644 index 0000000000..f619a624d0 --- /dev/null +++ b/drivers/misc/apple_dart.c @@ -0,0 +1,171 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2021 Mark Kettenis kettenis@openbsd.org + */ + +#include <common.h> +#include <clk.h> +#include <cpu_func.h> +#include <dm.h> +#include <mapmem.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 + +struct apple_dart_priv { + struct clk_bulk clks; + void *base; +}; + +dma_addr_t apple_dart_bus_start; +phys_addr_t apple_dart_phys_start; +phys_size_t apple_dart_size = SZ_512M; + +static void apple_dart_flush_tlb(struct apple_dart_priv *priv) +{ + u32 status; + + writel(0xffffffff, priv->base + DART_TLB_OP_SIDMASK); + writel(DART_TLB_OP_FLUSH, priv->base + DART_TLB_OP); + + for (;;) { + status = readl(priv->base + DART_TLB_OP); + if ((status & DART_TLB_OP_OPMASK) == 0) + break; + if ((status & DART_TLB_OP_BUSY) == 0) + break; + } +} + +static int apple_dart_clk_init(struct udevice *dev, + struct apple_dart_priv *priv) +{ + int ret; + + ret = clk_get_bulk(dev, &priv->clks); + if (ret == -ENOSYS || ret == -ENOENT) + return 0; + if (ret) + return ret; + + ret = clk_enable_bulk(&priv->clks); + if (ret) { + clk_release_bulk(&priv->clks); + return ret; + } + + return 0; +} + +static int apple_dart_bind(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 int apple_dart_probe(struct udevice *dev) +{ + struct apple_dart_priv *priv = dev_get_priv(dev); + phys_addr_t phys; + u64 *l1, *l2; + int sid, i, j; + int ret; + + apple_dart_phys_start = gd->ram_top - apple_dart_size; + + priv->base = dev_read_addr_ptr(dev); + if (!priv->base) + return -EINVAL; + + ret = apple_dart_clk_init(dev, priv); + if (ret) + return ret; + + l1 = memalign(SZ_64K, SZ_64K); + memset(l1, 0, SZ_64K); + + i = 0; + phys = apple_dart_phys_start; + while (phys < apple_dart_phys_start + apple_dart_size) { + l2 = memalign(SZ_16K, SZ_16K); + memset(l2, 0, SZ_16K); + + for (j = 0; j < 2048; j++) { + l2[j] = phys | 0x3; + phys += SZ_16K; + } + flush_dcache_range((unsigned long)l2, + (unsigned long)l2 + SZ_16K); + + l1[i++] = (phys_addr_t)l2 | 0x8 | 0x3; + } + + flush_dcache_range((unsigned long)l1, (unsigned long)l1 + SZ_64K); + + for (sid = 0; sid < 16; sid++) { + for (i = 0; i < 4; i++) + writel(0, priv->base + DART_TTBR(sid, i)); + } + + apple_dart_flush_tlb(priv); + + for (sid = 0; sid < 16; sid++) { + phys = (phys_addr_t)l1; + for (i = 0; i < 4; i++) { + writel((phys >> DART_TTBR_SHIFT) | DART_TTBR_VALID, + priv->base + DART_TTBR(sid, i)); + phys += SZ_16K; + } + } + + apple_dart_flush_tlb(priv); + + for (sid = 0; sid < 16; sid++) + writel(DART_TCR_TRANSLATE_ENABLE, priv->base + DART_TCR(sid)); + + 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_MISC, + .of_match = apple_dart_ids, + .priv_auto = sizeof(struct apple_dart_priv), + .bind = apple_dart_bind, + .probe = apple_dart_probe +};

Hi Mark,
On Sat, 18 Sept 2021 at 07:55, Mark Kettenis kettenis@openbsd.org wrote:
The DART is an IOMMU that is used on Apple's M1 SoC. This driver supports the DART in bypass mode as well as in a mode where it creates a 1:1 mapping of a subset of RAM as not all DARTs support bypass mode. The USB3 ports integrated on the SoC use a DART that supports bypass mode. The 1:1 mapping will be used in the future to support other devices such as the PCIe host bridge of the M1 SoC.
Signed-off-by: Mark Kettenis kettenis@openbsd.org
drivers/misc/Kconfig | 7 ++ drivers/misc/Makefile | 1 + drivers/misc/apple_dart.c | 171 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 179 insertions(+) create mode 100644 drivers/misc/apple_dart.c
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index 997b713221..d70b060e74 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -38,6 +38,13 @@ config ALTERA_SYSID Select this to enable a sysid for Altera devices. Please find details on the "Embedded Peripherals IP User Guide" of Altera.
+config APPLE_DART
bool "Apple DART support"
depends on MISC && ARCH_APPLE
default y
help
Enable support for the DART on Apple SoCs.
Should have at least 3 lines. E.g. what does DART stand for, what does it do and what does the driver support?
config ATSHA204A bool "Support for Atmel ATSHA204A module" depends on MISC diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile index b64cd2a4de..f666cd392d 100644 --- a/drivers/misc/Makefile +++ b/drivers/misc/Makefile @@ -29,6 +29,7 @@ endif endif obj-$(CONFIG_ALI152X) += ali512x.o obj-$(CONFIG_ALTERA_SYSID) += altera_sysid.o +obj-$(CONFIG_APPLE_DART) += apple_dart.o obj-$(CONFIG_ATSHA204A) += atsha204a-i2c.o obj-$(CONFIG_CBMEM_CONSOLE) += cbmem_console.o obj-$(CONFIG_DS4510) += ds4510.o diff --git a/drivers/misc/apple_dart.c b/drivers/misc/apple_dart.c new file mode 100644 index 0000000000..f619a624d0 --- /dev/null +++ b/drivers/misc/apple_dart.c @@ -0,0 +1,171 @@ +// SPDX-License-Identifier: GPL-2.0+ +/*
- Copyright (C) 2021 Mark Kettenis kettenis@openbsd.org
- */
+#include <common.h> +#include <clk.h> +#include <cpu_func.h> +#include <dm.h> +#include <mapmem.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
+struct apple_dart_priv {
How about s/apple_dart/dart/ ?
It makes the code easier to read.
struct clk_bulk clks;
void *base;
+};
+dma_addr_t apple_dart_bus_start; +phys_addr_t apple_dart_phys_start; +phys_size_t apple_dart_size = SZ_512M;
Try to avoid variables in drivers. Can these go in a priv struct?
+static void apple_dart_flush_tlb(struct apple_dart_priv *priv)
comments on these functions
+{
u32 status;
writel(0xffffffff, priv->base + DART_TLB_OP_SIDMASK);
writel(DART_TLB_OP_FLUSH, priv->base + DART_TLB_OP);
for (;;) {
status = readl(priv->base + DART_TLB_OP);
if ((status & DART_TLB_OP_OPMASK) == 0)
break;
if ((status & DART_TLB_OP_BUSY) == 0)
break;
}
+}
+static int apple_dart_clk_init(struct udevice *dev,
struct apple_dart_priv *priv)
+{
int ret;
ret = clk_get_bulk(dev, &priv->clks);
if (ret == -ENOSYS || ret == -ENOENT)
Does -ENOSYS not indicate an error? If it doesn't, I think a comment would help here.
return 0;
if (ret)
return ret;
ret = clk_enable_bulk(&priv->clks);
if (ret) {
clk_release_bulk(&priv->clks);
return ret;
}
return 0;
+}
+static int apple_dart_bind(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));
}
}
Not allowed hardware access in bind(). Can this more to probe() ?
return 0;
+}
+static int apple_dart_probe(struct udevice *dev) +{
struct apple_dart_priv *priv = dev_get_priv(dev);
phys_addr_t phys;
u64 *l1, *l2;
int sid, i, j;
int ret;
apple_dart_phys_start = gd->ram_top - apple_dart_size;
priv->base = dev_read_addr_ptr(dev);
if (!priv->base)
return -EINVAL;
ret = apple_dart_clk_init(dev, priv);
if (ret)
return ret;
l1 = memalign(SZ_64K, SZ_64K);
memset(l1, 0, SZ_64K);
i = 0;
phys = apple_dart_phys_start;
while (phys < apple_dart_phys_start + apple_dart_size) {
l2 = memalign(SZ_16K, SZ_16K);
check for error
memset(l2, 0, SZ_16K);
for (j = 0; j < 2048; j++) {
l2[j] = phys | 0x3;
phys += SZ_16K;
}
flush_dcache_range((unsigned long)l2,
(unsigned long)l2 + SZ_16K);
l1[i++] = (phys_addr_t)l2 | 0x8 | 0x3;
Do you need the cast? What are the magic numbers here? Can you use an enum/#define ?
}
flush_dcache_range((unsigned long)l1, (unsigned long)l1 + SZ_64K);
for (sid = 0; sid < 16; sid++) {
comment,...what is this doing?
for (i = 0; i < 4; i++)
writel(0, priv->base + DART_TTBR(sid, i));
}
apple_dart_flush_tlb(priv);
for (sid = 0; sid < 16; sid++) {
phys = (phys_addr_t)l1;
for (i = 0; i < 4; i++) {
writel((phys >> DART_TTBR_SHIFT) | DART_TTBR_VALID,
priv->base + DART_TTBR(sid, i));
phys += SZ_16K;
}
}
apple_dart_flush_tlb(priv);
for (sid = 0; sid < 16; sid++)
writel(DART_TCR_TRANSLATE_ENABLE, priv->base + DART_TCR(sid));
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_MISC,
.of_match = apple_dart_ids,
.priv_auto = sizeof(struct apple_dart_priv),
.bind = apple_dart_bind,
.probe = apple_dart_probe
+};
2.33.0
Regards, Simon

From: Simon Glass sjg@chromium.org Date: Sun, 19 Sep 2021 21:16:00 -0600
Hi Mark,
On Sat, 18 Sept 2021 at 07:55, Mark Kettenis kettenis@openbsd.org wrote:
The DART is an IOMMU that is used on Apple's M1 SoC. This driver supports the DART in bypass mode as well as in a mode where it creates a 1:1 mapping of a subset of RAM as not all DARTs support bypass mode. The USB3 ports integrated on the SoC use a DART that supports bypass mode. The 1:1 mapping will be used in the future to support other devices such as the PCIe host bridge of the M1 SoC.
Signed-off-by: Mark Kettenis kettenis@openbsd.org
drivers/misc/Kconfig | 7 ++ drivers/misc/Makefile | 1 + drivers/misc/apple_dart.c | 171 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 179 insertions(+) create mode 100644 drivers/misc/apple_dart.c
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index 997b713221..d70b060e74 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -38,6 +38,13 @@ config ALTERA_SYSID Select this to enable a sysid for Altera devices. Please find details on the "Embedded Peripherals IP User Guide" of Altera.
+config APPLE_DART
bool "Apple DART support"
depends on MISC && ARCH_APPLE
default y
help
Enable support for the DART on Apple SoCs.
Should have at least 3 lines. E.g. what does DART stand for, what does it do and what does the driver support?
Sure. The DART is what we usually call an IOMMU.
config ATSHA204A bool "Support for Atmel ATSHA204A module" depends on MISC diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile index b64cd2a4de..f666cd392d 100644 --- a/drivers/misc/Makefile +++ b/drivers/misc/Makefile @@ -29,6 +29,7 @@ endif endif obj-$(CONFIG_ALI152X) += ali512x.o obj-$(CONFIG_ALTERA_SYSID) += altera_sysid.o +obj-$(CONFIG_APPLE_DART) += apple_dart.o obj-$(CONFIG_ATSHA204A) += atsha204a-i2c.o obj-$(CONFIG_CBMEM_CONSOLE) += cbmem_console.o obj-$(CONFIG_DS4510) += ds4510.o diff --git a/drivers/misc/apple_dart.c b/drivers/misc/apple_dart.c new file mode 100644 index 0000000000..f619a624d0 --- /dev/null +++ b/drivers/misc/apple_dart.c @@ -0,0 +1,171 @@ +// SPDX-License-Identifier: GPL-2.0+ +/*
- Copyright (C) 2021 Mark Kettenis kettenis@openbsd.org
- */
+#include <common.h> +#include <clk.h> +#include <cpu_func.h> +#include <dm.h> +#include <mapmem.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
+struct apple_dart_priv {
How about s/apple_dart/dart/ ?
It makes the code easier to read.
I think using apple_dart_ consistently as a prefix makes more sense.
struct clk_bulk clks;
void *base;
+};
+dma_addr_t apple_dart_bus_start; +phys_addr_t apple_dart_phys_start; +phys_size_t apple_dart_size = SZ_512M;
Try to avoid variables in drivers. Can these go in a priv struct?
Not really since the intent is that these variables specify a global "window" that is mapped 1:1 into all the DARTs.
+static void apple_dart_flush_tlb(struct apple_dart_priv *priv)
comments on these functions
+{
u32 status;
writel(0xffffffff, priv->base + DART_TLB_OP_SIDMASK);
writel(DART_TLB_OP_FLUSH, priv->base + DART_TLB_OP);
for (;;) {
status = readl(priv->base + DART_TLB_OP);
if ((status & DART_TLB_OP_OPMASK) == 0)
break;
if ((status & DART_TLB_OP_BUSY) == 0)
break;
}
+}
+static int apple_dart_clk_init(struct udevice *dev,
struct apple_dart_priv *priv)
+{
int ret;
ret = clk_get_bulk(dev, &priv->clks);
if (ret == -ENOSYS || ret == -ENOENT)
Does -ENOSYS not indicate an error? If it doesn't, I think a comment would help here.
So we just learned that what we previously considered to be clocks are really better modelled as power domains. So this code will go away.
return 0;
if (ret)
return ret;
ret = clk_enable_bulk(&priv->clks);
if (ret) {
clk_release_bulk(&priv->clks);
return ret;
}
return 0;
+}
+static int apple_dart_bind(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));
}
}
Not allowed hardware access in bind(). Can this more to probe() ?
Well, I need to make sure that this happens before other drivers get probed (in particular the xhci-dwc3 driver). Is there a better mechanism to achieve that?
return 0;
+}
+static int apple_dart_probe(struct udevice *dev) +{
struct apple_dart_priv *priv = dev_get_priv(dev);
phys_addr_t phys;
u64 *l1, *l2;
int sid, i, j;
int ret;
apple_dart_phys_start = gd->ram_top - apple_dart_size;
priv->base = dev_read_addr_ptr(dev);
if (!priv->base)
return -EINVAL;
ret = apple_dart_clk_init(dev, priv);
if (ret)
return ret;
l1 = memalign(SZ_64K, SZ_64K);
memset(l1, 0, SZ_64K);
i = 0;
phys = apple_dart_phys_start;
while (phys < apple_dart_phys_start + apple_dart_size) {
l2 = memalign(SZ_16K, SZ_16K);
check for error
memset(l2, 0, SZ_16K);
for (j = 0; j < 2048; j++) {
l2[j] = phys | 0x3;
phys += SZ_16K;
}
flush_dcache_range((unsigned long)l2,
(unsigned long)l2 + SZ_16K);
l1[i++] = (phys_addr_t)l2 | 0x8 | 0x3;
Do you need the cast? What are the magic numbers here? Can you use an enum/#define ?
Not sure if we know the exact meaning of those bits yet. But there is a Linux driver now, so maybe I need to look at it again.
}
flush_dcache_range((unsigned long)l1, (unsigned long)l1 + SZ_64K);
for (sid = 0; sid < 16; sid++) {
comment,...what is this doing?
for (i = 0; i < 4; i++)
writel(0, priv->base + DART_TTBR(sid, i));
}
apple_dart_flush_tlb(priv);
for (sid = 0; sid < 16; sid++) {
phys = (phys_addr_t)l1;
for (i = 0; i < 4; i++) {
writel((phys >> DART_TTBR_SHIFT) | DART_TTBR_VALID,
priv->base + DART_TTBR(sid, i));
phys += SZ_16K;
}
}
apple_dart_flush_tlb(priv);
for (sid = 0; sid < 16; sid++)
writel(DART_TCR_TRANSLATE_ENABLE, priv->base + DART_TCR(sid));
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_MISC,
.of_match = apple_dart_ids,
.priv_auto = sizeof(struct apple_dart_priv),
.bind = apple_dart_bind,
.probe = apple_dart_probe
+};
2.33.0
Regards, Simon

Hi Mark,
On Mon, 20 Sept 2021 at 02:33, Mark Kettenis mark.kettenis@xs4all.nl wrote:
From: Simon Glass sjg@chromium.org Date: Sun, 19 Sep 2021 21:16:00 -0600
Hi Mark,
On Sat, 18 Sept 2021 at 07:55, Mark Kettenis kettenis@openbsd.org wrote:
The DART is an IOMMU that is used on Apple's M1 SoC. This driver supports the DART in bypass mode as well as in a mode where it creates a 1:1 mapping of a subset of RAM as not all DARTs support bypass mode. The USB3 ports integrated on the SoC use a DART that supports bypass mode. The 1:1 mapping will be used in the future to support other devices such as the PCIe host bridge of the M1 SoC.
Signed-off-by: Mark Kettenis kettenis@openbsd.org
drivers/misc/Kconfig | 7 ++ drivers/misc/Makefile | 1 + drivers/misc/apple_dart.c | 171 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 179 insertions(+) create mode 100644 drivers/misc/apple_dart.c
[..]
+struct apple_dart_priv {
How about s/apple_dart/dart/ ?
It makes the code easier to read.
I think using apple_dart_ consistently as a prefix makes more sense.
OK I don't mind too much. I just prefer shorter code and sometimes people use globally unique things in drivers when it really doesn't help anything.
struct clk_bulk clks;
void *base;
+};
+dma_addr_t apple_dart_bus_start; +phys_addr_t apple_dart_phys_start; +phys_size_t apple_dart_size = SZ_512M;
Try to avoid variables in drivers. Can these go in a priv struct?
Not really since the intent is that these variables specify a global "window" that is mapped 1:1 into all the DARTs.
So there are multiple DART devices? In that can you could store this info in a priv struct attached to the uclass.
[..]
+static int apple_dart_bind(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));
}
}
Not allowed hardware access in bind(). Can this more to probe() ?
Well, I need to make sure that this happens before other drivers get probed (in particular the xhci-dwc3 driver). Is there a better mechanism to achieve that?
If those drivers have something in the DT indicating that they need this, then you can add a uclass_get_device_by_phandle() in those drivers.
If not, then you can probe all the DART devices with uclass_probe_all().
Having said that, I see you are using UCLASS_MISC. I suspect this should have its own UCLASS_IOMMU.
[..]
memset(l2, 0, SZ_16K);
for (j = 0; j < 2048; j++) {
l2[j] = phys | 0x3;
phys += SZ_16K;
}
flush_dcache_range((unsigned long)l2,
(unsigned long)l2 + SZ_16K);
l1[i++] = (phys_addr_t)l2 | 0x8 | 0x3;
Do you need the cast? What are the magic numbers here? Can you use an enum/#define ?
Not sure if we know the exact meaning of those bits yet. But there is a Linux driver now, so maybe I need to look at it again.
Oh well, a comment that we don't know is fine, too. People can fix it later if it becomes known.
[..]
Regards, Simon

On Mon, 20 Sept 2021 at 19:11, Simon Glass sjg@chromium.org wrote:
Hi Mark,
On Mon, 20 Sept 2021 at 02:33, Mark Kettenis mark.kettenis@xs4all.nl wrote:
From: Simon Glass sjg@chromium.org Date: Sun, 19 Sep 2021 21:16:00 -0600
Hi Mark,
On Sat, 18 Sept 2021 at 07:55, Mark Kettenis kettenis@openbsd.org wrote:
The DART is an IOMMU that is used on Apple's M1 SoC. This driver supports the DART in bypass mode as well as in a mode where it creates a 1:1 mapping of a subset of RAM as not all DARTs support bypass mode. The USB3 ports integrated on the SoC use a DART that supports bypass mode. The 1:1 mapping will be used in the future to support other devices such as the PCIe host bridge of the M1 SoC.
Signed-off-by: Mark Kettenis kettenis@openbsd.org
drivers/misc/Kconfig | 7 ++ drivers/misc/Makefile | 1 + drivers/misc/apple_dart.c | 171 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 179 insertions(+) create mode 100644 drivers/misc/apple_dart.c
Tested on: Macbook Air M1 Tested-by: Simon Glass sjg@chromium.org

From: Simon Glass sjg@chromium.org Date: Mon, 20 Sep 2021 19:11:25 -0600
Hi Simon,
[..]
+static int apple_dart_bind(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));
}
}
Not allowed hardware access in bind(). Can this more to probe() ?
Well, I need to make sure that this happens before other drivers get probed (in particular the xhci-dwc3 driver). Is there a better mechanism to achieve that?
If those drivers have something in the DT indicating that they need this, then you can add a uclass_get_device_by_phandle() in those drivers.
Yes, there is an "iommus" property that points at the IOMMU. This is a standard property and I think it would make sense to have the core device probing code handle it in a way similar to how "power-domains" is handled. That way we don't have to add IOMMU hooks into each and every driver.
If not, then you can probe all the DART devices with uclass_probe_all().
Having said that, I see you are using UCLASS_MISC. I suspect this should have its own UCLASS_IOMMU.
So here is a proof-of-concept diff to add UCLASS_IOMMU. This deliberately does not yet introduce driver ops yet; coming up with something sensible there needs a bit more thought. For USB support all I need is for the probe function to put the IOMMU in bypass mode, so that is what's implemented here.
Does this look reasonable? I'll split this up eventually into a commit that adds UCLASS_IOMMU and a commit that adds the apple_dart driver.
commit 606979a32d8e0d19ee45df97ad6855c24e27e5ad Author: Mark Kettenis kettenis@openbsd.org Date: Sun Sep 26 22:35:30 2021 +0200
iommu: Proof of concept
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..d0638140af --- /dev/null +++ b/drivers/iommu/Kconfig @@ -0,0 +1,20 @@ +# +# 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. + +config APPLE_DART + bool "Apple DART support" + depends on IOMMU && ARCH_APPLE + default y + help + Enable support for the DART on Apple SoCs. + +endmenu diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile new file mode 100644 index 0000000000..8a50e3aba8 --- /dev/null +++ b/drivers/iommu/Makefile @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: GPL-2.0+ + +obj-$(CONFIG_IOMMU) += iommu-uclass.o + +obj-$(CONFIG_APPLE_DART) += apple_dart.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 +}; 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) */

Hi Mark,
On Sun, 26 Sept 2021 at 14:53, Mark Kettenis mark.kettenis@xs4all.nl wrote:
From: Simon Glass sjg@chromium.org Date: Mon, 20 Sep 2021 19:11:25 -0600
Hi Simon,
[..]
+static int apple_dart_bind(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));
}
}
Not allowed hardware access in bind(). Can this more to probe() ?
Well, I need to make sure that this happens before other drivers get probed (in particular the xhci-dwc3 driver). Is there a better mechanism to achieve that?
If those drivers have something in the DT indicating that they need this, then you can add a uclass_get_device_by_phandle() in those drivers.
Yes, there is an "iommus" property that points at the IOMMU. This is a standard property and I think it would make sense to have the core device probing code handle it in a way similar to how "power-domains" is handled. That way we don't have to add IOMMU hooks into each and every driver.
OK.
If not, then you can probe all the DART devices with uclass_probe_all().
Having said that, I see you are using UCLASS_MISC. I suspect this should have its own UCLASS_IOMMU.
So here is a proof-of-concept diff to add UCLASS_IOMMU. This deliberately does not yet introduce driver ops yet; coming up with something sensible there needs a bit more thought. For USB support all I need is for the probe function to put the IOMMU in bypass mode, so that is what's implemented here.
Does this look reasonable? I'll split this up eventually into a commit that adds UCLASS_IOMMU and a commit that adds the apple_dart driver.
Yes from a quick look. Remember for the IOMMU uclass to add a sandbox test, even though for now it will only probe the driver since there are no ops.
Also you don't need the #if in iommu-uclass.c as the linked will garbage-collect it.
Regards, Simon

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/t8103-j274.dts | 135 +++++ arch/arm/dts/t8103-j293.dts | 97 ++++ arch/arm/dts/t8103.dtsi | 506 ++++++++++++++++++ .../interrupt-controller/apple-aic.h | 15 + include/dt-bindings/pinctrl/apple.h | 13 + include/dt-bindings/spmi/spmi.h | 10 + 6 files changed, 776 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/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..6074fc9080 --- /dev/null +++ b/arch/arm/dts/t8103.dtsi @@ -0,0 +1,506 @@ +// 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>; + }; + + clk24: clock-24m { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <24000000>; + clock-output-names = "clk24"; + }; + + soc { + compatible = "simple-bus"; + #address-cells = <2>; + #size-cells = <2>; + + ranges; + dma-ranges; + dma-coherent; + nonposted-mmio; + + aic: interrupt-controller@23b100000 { + compatible = "apple,t8103-aic", "apple,aic"; + #interrupt-cells = <3>; + interrupt-controller; + reg = <0x2 0x3b100000 0x0 0x8000>; + }; + + 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>; + /* + * TODO: figure out the clocking properly, there may + * be a third selectable clock. + */ + clocks = <&clk24>, <&clk24>; + clock-names = "uart", "clk_uart_baud0"; + status = "disabled"; + }; + + gpio_clk: clock@23b700130 { + compatible = "apple,pmgr-clk-gate"; + reg = <0x2 0x3b700130 0x0 0x8>; + #clock-cells = <0>; + }; + + pinctrl_ap: pinctrl@23c100000 { + compatible = "apple,t8103-pinctrl", "apple,pinctrl"; + reg = <0x2 0x3c100000 0x0 0x100000>; + clocks = <&gpio_clk>; + + 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>; + }; + + sio_busif_clk: clock@23b7001c0 { + compatible = "apple,pmgr-clk-gate"; + reg = <0x2 0x3b7001c0 0x0 0x8>; + #clock-cells = <0>; + clocks = <&clk24>; + }; + + sio_clk: clock@23b7001c8 { + compatible = "apple,pmgr-clk-gate"; + reg = <0x2 0x3b7001c8 0x0 0x8>; + #clock-cells = <0>; + clocks = <&sio_busif_clk>; + }; + + i2c0_clk: clock@23b7001f0 { + compatible = "apple,pmgr-clk-gate"; + reg = <0x2 0x3b7001f0 0x0 0x8>; + #clock-cells = <0>; + clocks = <&sio_clk>; + }; + + i2c0: i2c@20a110000 { + compatible = "apple,i2c-v0"; + reg = <0x2 0x35010000 0x0 0x4000>; + interrupt-parent = <&aic>; + interrupts = <AIC_IRQ 627 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&i2c0_clk>; + 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>; + }; + }; + + imx_clk: clock@23b7001b8 { + compatible = "apple,pmgr-clk-gate"; + reg = <0x2 0x3b7001b8 0x0 0x8>; + #clock-cells = <0>; + }; + + pcie_aux_clk: clock@23b700348 { + compatible = "apple,pmgr-clk-gate"; + reg = <0x2 0x3b700348 0x0 0x8>; + #clock-cells = <0>; + clocks = <&imx_clk>; + }; + + pcie_core_clk: clock@23b7003e8 { + compatible = "apple,pmgr-clk-gate"; + reg = <0x2 0x3b7003e8 0x0 0x8>; + #clock-cells = <0>; + clocks = <&pcie_aux_clk>; + }; + + pcie_ref_clk: clock@23b7001a0 { + compatible = "apple,pmgr-clk-gate"; + reg = <0x2 0x3b7001a0 0x0 0x8>; + #clock-cells = <0>; + }; + + ans_clk: clock@23b7003f0 { + compatible = "apple,pmgr-clk-gate"; + reg = <0x2 0x3b7003f0 0x0 0x8>; + #clock-cells = <0>; + clocks = <&pcie_aux_clk>; + }; + + ans_st_clk: clock@23b700418 { + compatible = "apple,pmgr-clk-gate"; + reg = <0x2 0x3b700418 0x0 0x8>; + #clock-cells = <0>; + clocks = <&ans_clk>; + }; + + 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>; + clocks = <&ans_st_clk>; + #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>; + clocks = <&ans_st_clk>; + 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>; + + clocks = <&pcie_core_clk>, <&pcie_aux_clk>, + <&pcie_ref_clk>; + 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/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 Sat, 18 Sept 2021 at 07:56, 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/t8103-j274.dts | 135 +++++ arch/arm/dts/t8103-j293.dts | 97 ++++ arch/arm/dts/t8103.dtsi | 506 ++++++++++++++++++ .../interrupt-controller/apple-aic.h | 15 + include/dt-bindings/pinctrl/apple.h | 13 + include/dt-bindings/spmi/spmi.h | 10 + 6 files changed, 776 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, 19 Sept 2021 at 21:16, Simon Glass sjg@chromium.org wrote:
On Sat, 18 Sept 2021 at 07:56, 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/t8103-j274.dts | 135 +++++ arch/arm/dts/t8103-j293.dts | 97 ++++ arch/arm/dts/t8103.dtsi | 506 ++++++++++++++++++ .../interrupt-controller/apple-aic.h | 15 + include/dt-bindings/pinctrl/apple.h | 13 + include/dt-bindings/spmi/spmi.h | 10 + 6 files changed, 776 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
Tested on: Macbook Air M1 Tested-by: Simon Glass sjg@chromium.org

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 Sat, Sep 18, 2021 at 9:56 PM 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: Bin Meng bmeng.cn@gmail.com

On Sat, 18 Sept 2021 at 07:56, 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

On Sun, 19 Sept 2021 at 21:16, Simon Glass sjg@chromium.org wrote:
On Sat, 18 Sept 2021 at 07:56, 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
Tested on: Macbook Air M1 Tested-by: Simon Glass sjg@chromium.org

On Sat, Sep 18, 2021 at 4:56 PM 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
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:
+.. 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:
+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
-- 2.33.0
Reviewed-by: Igor Opaniuk igor.opaniuk@gmail.com

Hi Mark,
On Sat, 18 Sept 2021 at 07:54, 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
provide
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.
Mark Kettenis (5): arm: apple: Add initial support for Apple's M1 SoC serial: s5p: Add Apple M1 support misc: Add Apple DART driver arm: dts: apple: Add preliminary device trees doc: board: apple: Add Apple M1 documentation
arch/arm/Kconfig | 22 + arch/arm/Makefile | 1 + arch/arm/dts/t8103-j274.dts | 135 +++++ arch/arm/dts/t8103-j293.dts | 97 ++++ arch/arm/dts/t8103.dtsi | 506 ++++++++++++++++++ arch/arm/include/asm/arch-m1/clk.h | 11 + 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 | 163 ++++++ arch/arm/mach-apple/lowlevel_init.S | 16 + configs/apple_m1_defconfig | 14 + doc/board/apple/index.rst | 9 + doc/board/apple/m1.rst | 54 ++ doc/board/index.rst | 1 + drivers/misc/Kconfig | 7 + drivers/misc/Makefile | 1 + drivers/misc/apple_dart.c | 171 ++++++ drivers/serial/Kconfig | 2 +- drivers/serial/serial_s5p.c | 22 + include/configs/apple.h | 38 ++ .../interrupt-controller/apple-aic.h | 15 + include/dt-bindings/pinctrl/apple.h | 13 + include/dt-bindings/spmi/spmi.h | 10 + 24 files changed, 1370 insertions(+), 1 deletion(-) 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/clk.h 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/misc/apple_dart.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
-- 2.33.0
I gave this a whirl on a Macbook Air A2337 and needed the patch below to build the devicetree files. Sorry the formatting is broken.
Also when booting I get this:
... Preparing to boot kernel at 0x808200000 with fdt at 0x8082e8000 Valid payload found Preparing to run next stage at 0x808200000... MMU: shutting down... MMU: shutdown successful, clearing caches
Then the display clears and it hangs. If I try the J274 devicetree it just reboots at that point.
What should I expect? I was hoping for console output as I don't have serial connected. I don't have a suitable serial cable, and the USB gadget mode did not result in a ttyACM0 device appearing.
Regards, Simon
Subject: [PATCH] Fix up devicetree
Get these building.
Signed-off-by: Simon Glass sjg@chromium.org ---
arch/arm/dts/Makefile | 2 ++ configs/apple_m1_defconfig | 11 +++++------ 2 files changed, 7 insertions(+), 6 deletions(-)
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index fc16a57e60b..0c40947cc33 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -1130,6 +1130,8 @@ dtb-$(CONFIG_TARGET_IMX8MM_CL_IOT_GATE) += imx8mm-cl-iot-gate.dtb
dtb-$(CONFIG_TARGET_EA_LPC3250DEVKITV2) += lpc3250-ea3250.dtb
+dtb-$(CONFIG_ARCH_APPLE) += t8103-j274.dtb t8103-j293.dtb + targets += $(dtb-y)
# Add any required device tree compiler flags here diff --git a/configs/apple_m1_defconfig b/configs/apple_m1_defconfig index a7ae15576bf..7712a0bac52 100644 --- a/configs/apple_m1_defconfig +++ b/configs/apple_m1_defconfig @@ -1,14 +1,13 @@ CONFIG_ARM=y CONFIG_ARCH_APPLE=y +CONFIG_DEFAULT_DEVICE_TREE="t8103-j293" +CONFIG_USE_PREBOOT=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_NET is not set +# CONFIG_MMC is not set 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_VIDEO_SIMPLE=y # CONFIG_GENERATE_SMBIOS_TABLE is not set

From: Simon Glass sjg@chromium.org Date: Fri, 24 Sep 2021 19:20:32 -0600
Hi Mark,
On Sat, 18 Sept 2021 at 07:54, 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
provide
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.
Mark Kettenis (5): arm: apple: Add initial support for Apple's M1 SoC serial: s5p: Add Apple M1 support misc: Add Apple DART driver arm: dts: apple: Add preliminary device trees doc: board: apple: Add Apple M1 documentation
arch/arm/Kconfig | 22 + arch/arm/Makefile | 1 + arch/arm/dts/t8103-j274.dts | 135 +++++ arch/arm/dts/t8103-j293.dts | 97 ++++ arch/arm/dts/t8103.dtsi | 506 ++++++++++++++++++ arch/arm/include/asm/arch-m1/clk.h | 11 + 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 | 163 ++++++ arch/arm/mach-apple/lowlevel_init.S | 16 + configs/apple_m1_defconfig | 14 + doc/board/apple/index.rst | 9 + doc/board/apple/m1.rst | 54 ++ doc/board/index.rst | 1 + drivers/misc/Kconfig | 7 + drivers/misc/Makefile | 1 + drivers/misc/apple_dart.c | 171 ++++++ drivers/serial/Kconfig | 2 +- drivers/serial/serial_s5p.c | 22 + include/configs/apple.h | 38 ++ .../interrupt-controller/apple-aic.h | 15 + include/dt-bindings/pinctrl/apple.h | 13 + include/dt-bindings/spmi/spmi.h | 10 + 24 files changed, 1370 insertions(+), 1 deletion(-) 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/clk.h 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/misc/apple_dart.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
-- 2.33.0
I gave this a whirl on a Macbook Air A2337 and needed the patch below to build the devicetree files. Sorry the formatting is broken.
Also when booting I get this:
... Preparing to boot kernel at 0x808200000 with fdt at 0x8082e8000 Valid payload found Preparing to run next stage at 0x808200000... MMU: shutting down... MMU: shutdown successful, clearing caches
Then the display clears and it hangs. If I try the J274 devicetree it just reboots at that point.
What should I expect? I was hoping for console output as I don't have serial connected. I don't have a suitable serial cable, and the USB gadget mode did not result in a ttyACM0 device appearing.
For framebuffer support you also need the "30bpp framebuffer support" series I posted earlier:
https://patchwork.ozlabs.org/project/uboot/list/?series=262617
With that your should get the usual U-Boot output on the screen. I've not tested the Air, but it should work there.
I'll probably post a v2 of that series this weekend as I fixed the EFI GOP support with the help of Heinrich. But that shouldn't matter for U-Boot itself.
Regarding the device tree, I was afraid that setting CONFIG_DEFAULT_DEVICE_TREE would make the distroboot commands try to load a device tree from disk before loading the EFI bootloader, but it looks I was mistaken there. It still is a little bit pointless to build the device tree and a u-boot.bin that includes it, but if that makes you happier, I'll add it to the series.
Cheers,
Mark
Subject: [PATCH] Fix up devicetree
Get these building.
Signed-off-by: Simon Glass sjg@chromium.org
arch/arm/dts/Makefile | 2 ++ configs/apple_m1_defconfig | 11 +++++------ 2 files changed, 7 insertions(+), 6 deletions(-)
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index fc16a57e60b..0c40947cc33 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -1130,6 +1130,8 @@ dtb-$(CONFIG_TARGET_IMX8MM_CL_IOT_GATE) += imx8mm-cl-iot-gate.dtb
dtb-$(CONFIG_TARGET_EA_LPC3250DEVKITV2) += lpc3250-ea3250.dtb
+dtb-$(CONFIG_ARCH_APPLE) += t8103-j274.dtb t8103-j293.dtb
targets += $(dtb-y)
# Add any required device tree compiler flags here diff --git a/configs/apple_m1_defconfig b/configs/apple_m1_defconfig index a7ae15576bf..7712a0bac52 100644 --- a/configs/apple_m1_defconfig +++ b/configs/apple_m1_defconfig @@ -1,14 +1,13 @@ CONFIG_ARM=y CONFIG_ARCH_APPLE=y +CONFIG_DEFAULT_DEVICE_TREE="t8103-j293" +CONFIG_USE_PREBOOT=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_NET is not set +# CONFIG_MMC is not set 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_VIDEO_SIMPLE=y
# CONFIG_GENERATE_SMBIOS_TABLE is not set
2.25.1

Hi Mark,
On Sat, 25 Sept 2021 at 02:11, Mark Kettenis mark.kettenis@xs4all.nl wrote:
From: Simon Glass sjg@chromium.org Date: Fri, 24 Sep 2021 19:20:32 -0600
Hi Mark,
On Sat, 18 Sept 2021 at 07:54, 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
provide
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.
Mark Kettenis (5): arm: apple: Add initial support for Apple's M1 SoC serial: s5p: Add Apple M1 support misc: Add Apple DART driver arm: dts: apple: Add preliminary device trees doc: board: apple: Add Apple M1 documentation
arch/arm/Kconfig | 22 + arch/arm/Makefile | 1 + arch/arm/dts/t8103-j274.dts | 135 +++++ arch/arm/dts/t8103-j293.dts | 97 ++++ arch/arm/dts/t8103.dtsi | 506 ++++++++++++++++++ arch/arm/include/asm/arch-m1/clk.h | 11 + 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 | 163 ++++++ arch/arm/mach-apple/lowlevel_init.S | 16 + configs/apple_m1_defconfig | 14 + doc/board/apple/index.rst | 9 + doc/board/apple/m1.rst | 54 ++ doc/board/index.rst | 1 + drivers/misc/Kconfig | 7 + drivers/misc/Makefile | 1 + drivers/misc/apple_dart.c | 171 ++++++ drivers/serial/Kconfig | 2 +- drivers/serial/serial_s5p.c | 22 + include/configs/apple.h | 38 ++ .../interrupt-controller/apple-aic.h | 15 + include/dt-bindings/pinctrl/apple.h | 13 + include/dt-bindings/spmi/spmi.h | 10 + 24 files changed, 1370 insertions(+), 1 deletion(-) 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/clk.h 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/misc/apple_dart.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
-- 2.33.0
I gave this a whirl on a Macbook Air A2337 and needed the patch below to build the devicetree files. Sorry the formatting is broken.
Also when booting I get this:
... Preparing to boot kernel at 0x808200000 with fdt at 0x8082e8000 Valid payload found Preparing to run next stage at 0x808200000... MMU: shutting down... MMU: shutdown successful, clearing caches
Then the display clears and it hangs. If I try the J274 devicetree it just reboots at that point.
What should I expect? I was hoping for console output as I don't have serial connected. I don't have a suitable serial cable, and the USB gadget mode did not result in a ttyACM0 device appearing.
For framebuffer support you also need the "30bpp framebuffer support" series I posted earlier:
https://patchwork.ozlabs.org/project/uboot/list/?series=262617
With that your should get the usual U-Boot output on the screen. I've not tested the Air, but it should work there.
Ah OK, yes that fixes it, thanks!
So how do I get the keyboard to work in U-Boot? Or are you using serial somehow?
Also it takes for ever to put a test version on the device...how are you doing that for development?
I'll probably post a v2 of that series this weekend as I fixed the EFI GOP support with the help of Heinrich. But that shouldn't matter for U-Boot itself.
OK
Regarding the device tree, I was afraid that setting CONFIG_DEFAULT_DEVICE_TREE would make the distroboot commands try to load a device tree from disk before loading the EFI bootloader, but it looks I was mistaken there. It still is a little bit pointless to build the device tree and a u-boot.bin that includes it, but if that makes you happier, I'll add it to the series.
Well I get a build error without it, so yes please. It's just a default.
Regards, Simon
Cheers,
Mark
Subject: [PATCH] Fix up devicetree
Get these building.
Signed-off-by: Simon Glass sjg@chromium.org
arch/arm/dts/Makefile | 2 ++ configs/apple_m1_defconfig | 11 +++++------ 2 files changed, 7 insertions(+), 6 deletions(-)
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index fc16a57e60b..0c40947cc33 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -1130,6 +1130,8 @@ dtb-$(CONFIG_TARGET_IMX8MM_CL_IOT_GATE) += imx8mm-cl-iot-gate.dtb
dtb-$(CONFIG_TARGET_EA_LPC3250DEVKITV2) += lpc3250-ea3250.dtb
+dtb-$(CONFIG_ARCH_APPLE) += t8103-j274.dtb t8103-j293.dtb
targets += $(dtb-y)
# Add any required device tree compiler flags here diff --git a/configs/apple_m1_defconfig b/configs/apple_m1_defconfig index a7ae15576bf..7712a0bac52 100644 --- a/configs/apple_m1_defconfig +++ b/configs/apple_m1_defconfig @@ -1,14 +1,13 @@ CONFIG_ARM=y CONFIG_ARCH_APPLE=y +CONFIG_DEFAULT_DEVICE_TREE="t8103-j293" +CONFIG_USE_PREBOOT=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_NET is not set +# CONFIG_MMC is not set 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_VIDEO_SIMPLE=y
# CONFIG_GENERATE_SMBIOS_TABLE is not set
2.25.1

From: Simon Glass sjg@chromium.org Date: Sat, 25 Sep 2021 07:27:41 -0600
Hi Mark,
On Sat, 25 Sept 2021 at 02:11, Mark Kettenis mark.kettenis@xs4all.nl wrote:
From: Simon Glass sjg@chromium.org Date: Fri, 24 Sep 2021 19:20:32 -0600
Hi Mark,
On Sat, 18 Sept 2021 at 07:54, 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
provide
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.
Mark Kettenis (5): arm: apple: Add initial support for Apple's M1 SoC serial: s5p: Add Apple M1 support misc: Add Apple DART driver arm: dts: apple: Add preliminary device trees doc: board: apple: Add Apple M1 documentation
arch/arm/Kconfig | 22 + arch/arm/Makefile | 1 + arch/arm/dts/t8103-j274.dts | 135 +++++ arch/arm/dts/t8103-j293.dts | 97 ++++ arch/arm/dts/t8103.dtsi | 506 ++++++++++++++++++ arch/arm/include/asm/arch-m1/clk.h | 11 + 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 | 163 ++++++ arch/arm/mach-apple/lowlevel_init.S | 16 + configs/apple_m1_defconfig | 14 + doc/board/apple/index.rst | 9 + doc/board/apple/m1.rst | 54 ++ doc/board/index.rst | 1 + drivers/misc/Kconfig | 7 + drivers/misc/Makefile | 1 + drivers/misc/apple_dart.c | 171 ++++++ drivers/serial/Kconfig | 2 +- drivers/serial/serial_s5p.c | 22 + include/configs/apple.h | 38 ++ .../interrupt-controller/apple-aic.h | 15 + include/dt-bindings/pinctrl/apple.h | 13 + include/dt-bindings/spmi/spmi.h | 10 + 24 files changed, 1370 insertions(+), 1 deletion(-) 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/clk.h 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/misc/apple_dart.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
-- 2.33.0
I gave this a whirl on a Macbook Air A2337 and needed the patch below to build the devicetree files. Sorry the formatting is broken.
Also when booting I get this:
... Preparing to boot kernel at 0x808200000 with fdt at 0x8082e8000 Valid payload found Preparing to run next stage at 0x808200000... MMU: shutting down... MMU: shutdown successful, clearing caches
Then the display clears and it hangs. If I try the J274 devicetree it just reboots at that point.
What should I expect? I was hoping for console output as I don't have serial connected. I don't have a suitable serial cable, and the USB gadget mode did not result in a ttyACM0 device appearing.
For framebuffer support you also need the "30bpp framebuffer support" series I posted earlier:
https://patchwork.ozlabs.org/project/uboot/list/?series=262617
With that your should get the usual U-Boot output on the screen. I've not tested the Air, but it should work there.
Ah OK, yes that fixes it, thanks!
So how do I get the keyboard to work in U-Boot? Or are you using serial somehow?
The laptop keyboard doesn't work yet, so I'm using a USB keyboard when I'm not using a serial console. You need the xhci-dwc3 diff I sent earlier for that:
https://patchwork.ozlabs.org/project/uboot/patch/20210916140009.59009-1-kett...
Also it takes for ever to put a test version on the device...how are you doing that for development?
If you install m1n1.macho without a payload, you can then use the python scripts that come with m1n1 to upload kernels over serial. There is a USB gadget implementation in m1n1, so you don't need a real serial connection. Just connect a Linux machine to the M1 Mac using a USB cable and a USB serial device should show up on the Linux machine once m1n1 is running on the Mac. Set the M1N1DEVICE environment variable to the right device name and run:
$ python3 linux.py --compression=none u-boot-nodtb.bin t8103-j274.dtb
I'll probably post a v2 of that series this weekend as I fixed the EFI GOP support with the help of Heinrich. But that shouldn't matter for U-Boot itself.
OK
Regarding the device tree, I was afraid that setting CONFIG_DEFAULT_DEVICE_TREE would make the distroboot commands try to load a device tree from disk before loading the EFI bootloader, but it looks I was mistaken there. It still is a little bit pointless to build the device tree and a u-boot.bin that includes it, but if that makes you happier, I'll add it to the series.
Well I get a build error without it, so yes please. It's just a default.
Regards, Simon
Cheers,
Mark
Subject: [PATCH] Fix up devicetree
Get these building.
Signed-off-by: Simon Glass sjg@chromium.org
arch/arm/dts/Makefile | 2 ++ configs/apple_m1_defconfig | 11 +++++------ 2 files changed, 7 insertions(+), 6 deletions(-)
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index fc16a57e60b..0c40947cc33 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -1130,6 +1130,8 @@ dtb-$(CONFIG_TARGET_IMX8MM_CL_IOT_GATE) += imx8mm-cl-iot-gate.dtb
dtb-$(CONFIG_TARGET_EA_LPC3250DEVKITV2) += lpc3250-ea3250.dtb
+dtb-$(CONFIG_ARCH_APPLE) += t8103-j274.dtb t8103-j293.dtb
targets += $(dtb-y)
# Add any required device tree compiler flags here diff --git a/configs/apple_m1_defconfig b/configs/apple_m1_defconfig index a7ae15576bf..7712a0bac52 100644 --- a/configs/apple_m1_defconfig +++ b/configs/apple_m1_defconfig @@ -1,14 +1,13 @@ CONFIG_ARM=y CONFIG_ARCH_APPLE=y +CONFIG_DEFAULT_DEVICE_TREE="t8103-j293" +CONFIG_USE_PREBOOT=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_NET is not set +# CONFIG_MMC is not set 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_VIDEO_SIMPLE=y
# CONFIG_GENERATE_SMBIOS_TABLE is not set
2.25.1

Hi Mark,
On Sat, 25 Sept 2021 at 07:52, Mark Kettenis mark.kettenis@xs4all.nl wrote:
From: Simon Glass sjg@chromium.org Date: Sat, 25 Sep 2021 07:27:41 -0600
Hi Mark,
On Sat, 25 Sept 2021 at 02:11, Mark Kettenis mark.kettenis@xs4all.nl wrote:
From: Simon Glass sjg@chromium.org Date: Fri, 24 Sep 2021 19:20:32 -0600
Hi Mark,
On Sat, 18 Sept 2021 at 07:54, 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
provide
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.
Mark Kettenis (5): arm: apple: Add initial support for Apple's M1 SoC serial: s5p: Add Apple M1 support misc: Add Apple DART driver arm: dts: apple: Add preliminary device trees doc: board: apple: Add Apple M1 documentation
arch/arm/Kconfig | 22 + arch/arm/Makefile | 1 + arch/arm/dts/t8103-j274.dts | 135 +++++ arch/arm/dts/t8103-j293.dts | 97 ++++ arch/arm/dts/t8103.dtsi | 506 ++++++++++++++++++ arch/arm/include/asm/arch-m1/clk.h | 11 + 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 | 163 ++++++ arch/arm/mach-apple/lowlevel_init.S | 16 + configs/apple_m1_defconfig | 14 + doc/board/apple/index.rst | 9 + doc/board/apple/m1.rst | 54 ++ doc/board/index.rst | 1 + drivers/misc/Kconfig | 7 + drivers/misc/Makefile | 1 + drivers/misc/apple_dart.c | 171 ++++++ drivers/serial/Kconfig | 2 +- drivers/serial/serial_s5p.c | 22 + include/configs/apple.h | 38 ++ .../interrupt-controller/apple-aic.h | 15 + include/dt-bindings/pinctrl/apple.h | 13 + include/dt-bindings/spmi/spmi.h | 10 + 24 files changed, 1370 insertions(+), 1 deletion(-) 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/clk.h 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/misc/apple_dart.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
-- 2.33.0
I gave this a whirl on a Macbook Air A2337 and needed the patch below to build the devicetree files. Sorry the formatting is broken.
Also when booting I get this:
... Preparing to boot kernel at 0x808200000 with fdt at 0x8082e8000 Valid payload found Preparing to run next stage at 0x808200000... MMU: shutting down... MMU: shutdown successful, clearing caches
Then the display clears and it hangs. If I try the J274 devicetree it just reboots at that point.
What should I expect? I was hoping for console output as I don't have serial connected. I don't have a suitable serial cable, and the USB gadget mode did not result in a ttyACM0 device appearing.
For framebuffer support you also need the "30bpp framebuffer support" series I posted earlier:
https://patchwork.ozlabs.org/project/uboot/list/?series=262617
With that your should get the usual U-Boot output on the screen. I've not tested the Air, but it should work there.
Ah OK, yes that fixes it, thanks!
So how do I get the keyboard to work in U-Boot? Or are you using serial somehow?
The laptop keyboard doesn't work yet, so I'm using a USB keyboard when I'm not using a serial console. You need the xhci-dwc3 diff I sent earlier for that:
https://patchwork.ozlabs.org/project/uboot/patch/20210916140009.59009-1-kett...
Actually that seems to be applied in mainline now. Yes USB keyboard works.
It looks like the keyboard needs SPI and there is some sort of linux keyboard driver, but perhaps not for M1.
Also it takes for ever to put a test version on the device...how are you doing that for development?
If you install m1n1.macho without a payload, you can then use the python scripts that come with m1n1 to upload kernels over serial. There is a USB gadget implementation in m1n1, so you don't need a real serial connection. Just connect a Linux machine to the M1 Mac using a USB cable and a USB serial device should show up on the Linux machine once m1n1 is running on the Mac. Set the M1N1DEVICE environment variable to the right device name and run:
$ python3 linux.py --compression=none u-boot-nodtb.bin t8103-j274.dtb
OK I see. I did try the USB serial thing but was missing the fact that U-Boot seems to kill it. So this works fine, thank you will await your next series. Any way to get U-Boot serial console going in the same way?
[..]
Regards, Simon

From: Simon Glass sjg@chromium.org Date: Sat, 25 Sep 2021 08:42:30 -0600
Hi Mark,
On Sat, 25 Sept 2021 at 07:52, Mark Kettenis mark.kettenis@xs4all.nl wrote:
From: Simon Glass sjg@chromium.org Date: Sat, 25 Sep 2021 07:27:41 -0600
Hi Mark,
On Sat, 25 Sept 2021 at 02:11, Mark Kettenis mark.kettenis@xs4all.nl wrote:
From: Simon Glass sjg@chromium.org Date: Fri, 24 Sep 2021 19:20:32 -0600
Hi Mark,
On Sat, 18 Sept 2021 at 07:54, 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
provide
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.
Mark Kettenis (5): arm: apple: Add initial support for Apple's M1 SoC serial: s5p: Add Apple M1 support misc: Add Apple DART driver arm: dts: apple: Add preliminary device trees doc: board: apple: Add Apple M1 documentation
arch/arm/Kconfig | 22 + arch/arm/Makefile | 1 + arch/arm/dts/t8103-j274.dts | 135 +++++ arch/arm/dts/t8103-j293.dts | 97 ++++ arch/arm/dts/t8103.dtsi | 506 ++++++++++++++++++ arch/arm/include/asm/arch-m1/clk.h | 11 + 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 | 163 ++++++ arch/arm/mach-apple/lowlevel_init.S | 16 + configs/apple_m1_defconfig | 14 + doc/board/apple/index.rst | 9 + doc/board/apple/m1.rst | 54 ++ doc/board/index.rst | 1 + drivers/misc/Kconfig | 7 + drivers/misc/Makefile | 1 + drivers/misc/apple_dart.c | 171 ++++++ drivers/serial/Kconfig | 2 +- drivers/serial/serial_s5p.c | 22 + include/configs/apple.h | 38 ++ .../interrupt-controller/apple-aic.h | 15 + include/dt-bindings/pinctrl/apple.h | 13 + include/dt-bindings/spmi/spmi.h | 10 + 24 files changed, 1370 insertions(+), 1 deletion(-) 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/clk.h 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/misc/apple_dart.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
-- 2.33.0
I gave this a whirl on a Macbook Air A2337 and needed the patch below to build the devicetree files. Sorry the formatting is broken.
Also when booting I get this:
... Preparing to boot kernel at 0x808200000 with fdt at 0x8082e8000 Valid payload found Preparing to run next stage at 0x808200000... MMU: shutting down... MMU: shutdown successful, clearing caches
Then the display clears and it hangs. If I try the J274 devicetree it just reboots at that point.
What should I expect? I was hoping for console output as I don't have serial connected. I don't have a suitable serial cable, and the USB gadget mode did not result in a ttyACM0 device appearing.
For framebuffer support you also need the "30bpp framebuffer support" series I posted earlier:
https://patchwork.ozlabs.org/project/uboot/list/?series=262617
With that your should get the usual U-Boot output on the screen. I've not tested the Air, but it should work there.
Ah OK, yes that fixes it, thanks!
So how do I get the keyboard to work in U-Boot? Or are you using serial somehow?
The laptop keyboard doesn't work yet, so I'm using a USB keyboard when I'm not using a serial console. You need the xhci-dwc3 diff I sent earlier for that:
https://patchwork.ozlabs.org/project/uboot/patch/20210916140009.59009-1-kett...
Actually that seems to be applied in mainline now. Yes USB keyboard works.
It looks like the keyboard needs SPI and there is some sort of linux keyboard driver, but perhaps not for M1.
Yes. It is certaily doable in u-boot, but not a priority. I plan to revisit this once I have a driver going in OpenBSD and a better understanding of how the hardware works.
Also it takes for ever to put a test version on the device...how are you doing that for development?
If you install m1n1.macho without a payload, you can then use the python scripts that come with m1n1 to upload kernels over serial. There is a USB gadget implementation in m1n1, so you don't need a real serial connection. Just connect a Linux machine to the M1 Mac using a USB cable and a USB serial device should show up on the Linux machine once m1n1 is running on the Mac. Set the M1N1DEVICE environment variable to the right device name and run:
$ python3 linux.py --compression=none u-boot-nodtb.bin t8103-j274.dtb
OK I see. I did try the USB serial thing but was missing the fact that U-Boot seems to kill it. So this works fine, thank you will await your next series. Any way to get U-Boot serial console going in the same way?
Probably, but the existing USB gadget code in u-boot doesn't seem to implement USB serial so it would be a significant amount of work. And it would only work after you bring the USB controller up, so it wouldn't be very useful for debugging purposes.
There is a real serial port, and if you have another M1 Mac it should be fairly easy to access it:
https://github.com/AsahiLinux/docs/wiki/Developer-Quickstart#using-an-m1-mac...
Otherwise you need to build some special hardware.

Hi Mark,
On Sat, 25 Sept 2021 at 10:46, Mark Kettenis mark.kettenis@xs4all.nl wrote:
From: Simon Glass sjg@chromium.org Date: Sat, 25 Sep 2021 08:42:30 -0600
Hi Mark,
On Sat, 25 Sept 2021 at 07:52, Mark Kettenis mark.kettenis@xs4all.nl wrote:
From: Simon Glass sjg@chromium.org Date: Sat, 25 Sep 2021 07:27:41 -0600
Hi Mark,
On Sat, 25 Sept 2021 at 02:11, Mark Kettenis mark.kettenis@xs4all.nl wrote:
From: Simon Glass sjg@chromium.org Date: Fri, 24 Sep 2021 19:20:32 -0600
Hi Mark,
On Sat, 18 Sept 2021 at 07:54, 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
provide
> 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. > > Mark Kettenis (5): > arm: apple: Add initial support for Apple's M1 SoC > serial: s5p: Add Apple M1 support > misc: Add Apple DART driver > arm: dts: apple: Add preliminary device trees > doc: board: apple: Add Apple M1 documentation > > arch/arm/Kconfig | 22 + > arch/arm/Makefile | 1 + > arch/arm/dts/t8103-j274.dts | 135 +++++ > arch/arm/dts/t8103-j293.dts | 97 ++++ > arch/arm/dts/t8103.dtsi | 506 ++++++++++++++++++ > arch/arm/include/asm/arch-m1/clk.h | 11 + > 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 | 163 ++++++ > arch/arm/mach-apple/lowlevel_init.S | 16 + > configs/apple_m1_defconfig | 14 + > doc/board/apple/index.rst | 9 + > doc/board/apple/m1.rst | 54 ++ > doc/board/index.rst | 1 + > drivers/misc/Kconfig | 7 + > drivers/misc/Makefile | 1 + > drivers/misc/apple_dart.c | 171 ++++++ > drivers/serial/Kconfig | 2 +- > drivers/serial/serial_s5p.c | 22 + > include/configs/apple.h | 38 ++ > .../interrupt-controller/apple-aic.h | 15 + > include/dt-bindings/pinctrl/apple.h | 13 + > include/dt-bindings/spmi/spmi.h | 10 + > 24 files changed, 1370 insertions(+), 1 deletion(-) > 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/clk.h > 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/misc/apple_dart.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 > > -- > 2.33.0 >
I gave this a whirl on a Macbook Air A2337 and needed the patch below to build the devicetree files. Sorry the formatting is broken.
Also when booting I get this:
... Preparing to boot kernel at 0x808200000 with fdt at 0x8082e8000 Valid payload found Preparing to run next stage at 0x808200000... MMU: shutting down... MMU: shutdown successful, clearing caches
Then the display clears and it hangs. If I try the J274 devicetree it just reboots at that point.
What should I expect? I was hoping for console output as I don't have serial connected. I don't have a suitable serial cable, and the USB gadget mode did not result in a ttyACM0 device appearing.
For framebuffer support you also need the "30bpp framebuffer support" series I posted earlier:
https://patchwork.ozlabs.org/project/uboot/list/?series=262617
With that your should get the usual U-Boot output on the screen. I've not tested the Air, but it should work there.
Ah OK, yes that fixes it, thanks!
So how do I get the keyboard to work in U-Boot? Or are you using serial somehow?
The laptop keyboard doesn't work yet, so I'm using a USB keyboard when I'm not using a serial console. You need the xhci-dwc3 diff I sent earlier for that:
https://patchwork.ozlabs.org/project/uboot/patch/20210916140009.59009-1-kett...
Actually that seems to be applied in mainline now. Yes USB keyboard works.
It looks like the keyboard needs SPI and there is some sort of linux keyboard driver, but perhaps not for M1.
Yes. It is certaily doable in u-boot, but not a priority. I plan to revisit this once I have a driver going in OpenBSD and a better understanding of how the hardware works.
Makes sense.
Also it takes for ever to put a test version on the device...how are you doing that for development?
If you install m1n1.macho without a payload, you can then use the python scripts that come with m1n1 to upload kernels over serial. There is a USB gadget implementation in m1n1, so you don't need a real serial connection. Just connect a Linux machine to the M1 Mac using a USB cable and a USB serial device should show up on the Linux machine once m1n1 is running on the Mac. Set the M1N1DEVICE environment variable to the right device name and run:
$ python3 linux.py --compression=none u-boot-nodtb.bin t8103-j274.dtb
OK I see. I did try the USB serial thing but was missing the fact that U-Boot seems to kill it. So this works fine, thank you will await your next series. Any way to get U-Boot serial console going in the same way?
Probably, but the existing USB gadget code in u-boot doesn't seem to implement USB serial so it would be a significant amount of work. And it would only work after you bring the USB controller up, so it wouldn't be very useful for debugging purposes.
Yse, usbtty.c is very old and doesn't even use driver model, so would need a refresh.
There is a real serial port, and if you have another M1 Mac it should be fairly easy to access it:
https://github.com/AsahiLinux/docs/wiki/Developer-Quickstart#using-an-m1-mac...
Otherwise you need to build some special hardware.
Yes I saw that but I only have one. Will see if I can steal/find another.
Regards, Simon

Hi Mark,
On Sun, 26 Sept 2021 at 09:53, Simon Glass sjg@chromium.org wrote:
Hi Mark,
On Sat, 25 Sept 2021 at 10:46, Mark Kettenis mark.kettenis@xs4all.nl wrote:
From: Simon Glass sjg@chromium.org Date: Sat, 25 Sep 2021 08:42:30 -0600
Hi Mark,
On Sat, 25 Sept 2021 at 07:52, Mark Kettenis mark.kettenis@xs4all.nl wrote:
From: Simon Glass sjg@chromium.org Date: Sat, 25 Sep 2021 07:27:41 -0600
Hi Mark,
On Sat, 25 Sept 2021 at 02:11, Mark Kettenis mark.kettenis@xs4all.nl wrote:
> From: Simon Glass sjg@chromium.org > Date: Fri, 24 Sep 2021 19:20:32 -0600 > > Hi Mark, > > On Sat, 18 Sept 2021 at 07:54, 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 > > provide > > > 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. > > > > Mark Kettenis (5): > > arm: apple: Add initial support for Apple's M1 SoC > > serial: s5p: Add Apple M1 support > > misc: Add Apple DART driver > > arm: dts: apple: Add preliminary device trees > > doc: board: apple: Add Apple M1 documentation > > > > arch/arm/Kconfig | 22 + > > arch/arm/Makefile | 1 + > > arch/arm/dts/t8103-j274.dts | 135 +++++ > > arch/arm/dts/t8103-j293.dts | 97 ++++ > > arch/arm/dts/t8103.dtsi | 506 ++++++++++++++++++ > > arch/arm/include/asm/arch-m1/clk.h | 11 + > > 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 | 163 ++++++ > > arch/arm/mach-apple/lowlevel_init.S | 16 + > > configs/apple_m1_defconfig | 14 + > > doc/board/apple/index.rst | 9 + > > doc/board/apple/m1.rst | 54 ++ > > doc/board/index.rst | 1 + > > drivers/misc/Kconfig | 7 + > > drivers/misc/Makefile | 1 + > > drivers/misc/apple_dart.c | 171 ++++++ > > drivers/serial/Kconfig | 2 +- > > drivers/serial/serial_s5p.c | 22 + > > include/configs/apple.h | 38 ++ > > .../interrupt-controller/apple-aic.h | 15 + > > include/dt-bindings/pinctrl/apple.h | 13 + > > include/dt-bindings/spmi/spmi.h | 10 + > > 24 files changed, 1370 insertions(+), 1 deletion(-) > > 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/clk.h > > 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/misc/apple_dart.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 > > > > -- > > 2.33.0 > > > > I gave this a whirl on a Macbook Air A2337 and needed the patch below > to build the devicetree files. Sorry the formatting is broken. > > Also when booting I get this: > > ... > Preparing to boot kernel at 0x808200000 with fdt at 0x8082e8000 > Valid payload found > Preparing to run next stage at 0x808200000... > MMU: shutting down... > MMU: shutdown successful, clearing caches > > > Then the display clears and it hangs. If I try the J274 devicetree it > just reboots at that point. > > What should I expect? I was hoping for console output as I don't have > serial connected. I don't have a suitable serial cable, and the USB > gadget mode did not result in a ttyACM0 device appearing.
For framebuffer support you also need the "30bpp framebuffer support" series I posted earlier:
https://patchwork.ozlabs.org/project/uboot/list/?series=262617
With that your should get the usual U-Boot output on the screen. I've not tested the Air, but it should work there.
Ah OK, yes that fixes it, thanks!
So how do I get the keyboard to work in U-Boot? Or are you using serial somehow?
The laptop keyboard doesn't work yet, so I'm using a USB keyboard when I'm not using a serial console. You need the xhci-dwc3 diff I sent earlier for that:
https://patchwork.ozlabs.org/project/uboot/patch/20210916140009.59009-1-kett...
Actually that seems to be applied in mainline now. Yes USB keyboard works.
It looks like the keyboard needs SPI and there is some sort of linux keyboard driver, but perhaps not for M1.
Yes. It is certaily doable in u-boot, but not a priority. I plan to revisit this once I have a driver going in OpenBSD and a better understanding of how the hardware works.
Makes sense.
Also it takes for ever to put a test version on the device...how are you doing that for development?
If you install m1n1.macho without a payload, you can then use the python scripts that come with m1n1 to upload kernels over serial. There is a USB gadget implementation in m1n1, so you don't need a real serial connection. Just connect a Linux machine to the M1 Mac using a USB cable and a USB serial device should show up on the Linux machine once m1n1 is running on the Mac. Set the M1N1DEVICE environment variable to the right device name and run:
$ python3 linux.py --compression=none u-boot-nodtb.bin t8103-j274.dtb
OK I see. I did try the USB serial thing but was missing the fact that U-Boot seems to kill it. So this works fine, thank you will await your next series. Any way to get U-Boot serial console going in the same way?
Probably, but the existing USB gadget code in u-boot doesn't seem to implement USB serial so it would be a significant amount of work. And it would only work after you bring the USB controller up, so it wouldn't be very useful for debugging purposes.
Yse, usbtty.c is very old and doesn't even use driver model, so would need a refresh.
There is a real serial port, and if you have another M1 Mac it should be fairly easy to access it:
https://github.com/AsahiLinux/docs/wiki/Developer-Quickstart#using-an-m1-mac...
Otherwise you need to build some special hardware.
Yes I saw that but I only have one. Will see if I can steal/find another.
OK got a mini as a DUT. It works so far as running macvdmtool on the Air and I can see the /dev/cu.debug-console device, but don't see any serial output when I reboot the DUT. The display works fine, although the USB keyboard only works on the USB-C ports of the mini, not the USB-A ones.
Do you use 'screen /dev/cu.debug-console' or something else? I have a cable with SS on it: This is what I see on the air.
sudo ./macvdmtool reboot serial Mac type: J313AP Looking for HPM devices... Found: IOService:/AppleARMPE/arm-io@10F00000/AppleT810xIO/i2c0@35010000/AppleS5L8940XI2CController/hpmBusManager@6B/AppleHPMBusController/hpm0/AppleHPMARM Connection: Sink Status: APP Unlocking... OK Entering DBMa mode... Status: DBMa Rebooting target into normal mode... OK Waiting for connection........ Connected Putting target into serial mode... OK Putting local end into serial mode... OK Exiting DBMa mode... OK sglass@Simons-MacBook-Air macvdmtool
So it seems to be connected but I am not seeing serial output from m1n1 or U-Boot.
Regards, Simon

From: Simon Glass sjg@chromium.org Date: Mon, 27 Sep 2021 21:46:56 -0600
Hi Mark,
On Sun, 26 Sept 2021 at 09:53, Simon Glass sjg@chromium.org wrote:
Hi Mark,
On Sat, 25 Sept 2021 at 10:46, Mark Kettenis mark.kettenis@xs4all.nl wrote:
From: Simon Glass sjg@chromium.org Date: Sat, 25 Sep 2021 08:42:30 -0600
Hi Mark,
On Sat, 25 Sept 2021 at 07:52, Mark Kettenis mark.kettenis@xs4all.nl wrote:
From: Simon Glass sjg@chromium.org Date: Sat, 25 Sep 2021 07:27:41 -0600
Hi Mark,
On Sat, 25 Sept 2021 at 02:11, Mark Kettenis mark.kettenis@xs4all.nl wrote: > > > From: Simon Glass sjg@chromium.org > > Date: Fri, 24 Sep 2021 19:20:32 -0600 > > > > Hi Mark, > > > > On Sat, 18 Sept 2021 at 07:54, 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 > > > > provide > > > > > 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. > > > > > > Mark Kettenis (5): > > > arm: apple: Add initial support for Apple's M1 SoC > > > serial: s5p: Add Apple M1 support > > > misc: Add Apple DART driver > > > arm: dts: apple: Add preliminary device trees > > > doc: board: apple: Add Apple M1 documentation > > > > > > arch/arm/Kconfig | 22 + > > > arch/arm/Makefile | 1 + > > > arch/arm/dts/t8103-j274.dts | 135 +++++ > > > arch/arm/dts/t8103-j293.dts | 97 ++++ > > > arch/arm/dts/t8103.dtsi | 506 ++++++++++++++++++ > > > arch/arm/include/asm/arch-m1/clk.h | 11 + > > > 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 | 163 ++++++ > > > arch/arm/mach-apple/lowlevel_init.S | 16 + > > > configs/apple_m1_defconfig | 14 + > > > doc/board/apple/index.rst | 9 + > > > doc/board/apple/m1.rst | 54 ++ > > > doc/board/index.rst | 1 + > > > drivers/misc/Kconfig | 7 + > > > drivers/misc/Makefile | 1 + > > > drivers/misc/apple_dart.c | 171 ++++++ > > > drivers/serial/Kconfig | 2 +- > > > drivers/serial/serial_s5p.c | 22 + > > > include/configs/apple.h | 38 ++ > > > .../interrupt-controller/apple-aic.h | 15 + > > > include/dt-bindings/pinctrl/apple.h | 13 + > > > include/dt-bindings/spmi/spmi.h | 10 + > > > 24 files changed, 1370 insertions(+), 1 deletion(-) > > > 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/clk.h > > > 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/misc/apple_dart.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 > > > > > > -- > > > 2.33.0 > > > > > > > I gave this a whirl on a Macbook Air A2337 and needed the patch below > > to build the devicetree files. Sorry the formatting is broken. > > > > Also when booting I get this: > > > > ... > > Preparing to boot kernel at 0x808200000 with fdt at 0x8082e8000 > > Valid payload found > > Preparing to run next stage at 0x808200000... > > MMU: shutting down... > > MMU: shutdown successful, clearing caches > > > > > > Then the display clears and it hangs. If I try the J274 devicetree it > > just reboots at that point. > > > > What should I expect? I was hoping for console output as I don't have > > serial connected. I don't have a suitable serial cable, and the USB > > gadget mode did not result in a ttyACM0 device appearing. > > For framebuffer support you also need the "30bpp framebuffer support" > series I posted earlier: > > https://patchwork.ozlabs.org/project/uboot/list/?series=262617 > > With that your should get the usual U-Boot output on the screen. I've > not tested the Air, but it should work there.
Ah OK, yes that fixes it, thanks!
So how do I get the keyboard to work in U-Boot? Or are you using serial somehow?
The laptop keyboard doesn't work yet, so I'm using a USB keyboard when I'm not using a serial console. You need the xhci-dwc3 diff I sent earlier for that:
https://patchwork.ozlabs.org/project/uboot/patch/20210916140009.59009-1-kett...
Actually that seems to be applied in mainline now. Yes USB keyboard works.
It looks like the keyboard needs SPI and there is some sort of linux keyboard driver, but perhaps not for M1.
Yes. It is certaily doable in u-boot, but not a priority. I plan to revisit this once I have a driver going in OpenBSD and a better understanding of how the hardware works.
Makes sense.
Also it takes for ever to put a test version on the device...how are you doing that for development?
If you install m1n1.macho without a payload, you can then use the python scripts that come with m1n1 to upload kernels over serial. There is a USB gadget implementation in m1n1, so you don't need a real serial connection. Just connect a Linux machine to the M1 Mac using a USB cable and a USB serial device should show up on the Linux machine once m1n1 is running on the Mac. Set the M1N1DEVICE environment variable to the right device name and run:
$ python3 linux.py --compression=none u-boot-nodtb.bin t8103-j274.dtb
OK I see. I did try the USB serial thing but was missing the fact that U-Boot seems to kill it. So this works fine, thank you will await your next series. Any way to get U-Boot serial console going in the same way?
Probably, but the existing USB gadget code in u-boot doesn't seem to implement USB serial so it would be a significant amount of work. And it would only work after you bring the USB controller up, so it wouldn't be very useful for debugging purposes.
Yse, usbtty.c is very old and doesn't even use driver model, so would need a refresh.
There is a real serial port, and if you have another M1 Mac it should be fairly easy to access it:
https://github.com/AsahiLinux/docs/wiki/Developer-Quickstart#using-an-m1-mac...
Otherwise you need to build some special hardware.
Yes I saw that but I only have one. Will see if I can steal/find another.
OK got a mini as a DUT. It works so far as running macvdmtool on the Air and I can see the /dev/cu.debug-console device, but don't see any serial output when I reboot the DUT. The display works fine, although the USB keyboard only works on the USB-C ports of the mini, not the USB-A ones.
Do you use 'screen /dev/cu.debug-console' or something else? I have a cable with SS on it: This is what I see on the air.
sudo ./macvdmtool reboot serial Mac type: J313AP Looking for HPM devices... Found: IOService:/AppleARMPE/arm-io@10F00000/AppleT810xIO/i2c0@35010000/AppleS5L8940XI2CController/hpmBusManager@6B/AppleHPMBusController/hpm0/AppleHPMARM Connection: Sink Status: APP Unlocking... OK Entering DBMa mode... Status: DBMa Rebooting target into normal mode... OK Waiting for connection........ Connected Putting target into serial mode... OK Putting local end into serial mode... OK Exiting DBMa mode... OK sglass@Simons-MacBook-Air macvdmtool
So it seems to be connected but I am not seeing serial output from m1n1 or U-Boot.
Maybe ask on #asahi; apparently not all type-C to type-C cables have all the necessary wires. But when we briefly tried this during the last OpenBSD hackathon, I couldn't get it to work either.

Hi Mark,
On Tue, 28 Sept 2021 at 01:36, Mark Kettenis mark.kettenis@xs4all.nl wrote:
From: Simon Glass sjg@chromium.org Date: Mon, 27 Sep 2021 21:46:56 -0600
Hi Mark,
On Sun, 26 Sept 2021 at 09:53, Simon Glass sjg@chromium.org wrote:
Hi Mark,
On Sat, 25 Sept 2021 at 10:46, Mark Kettenis mark.kettenis@xs4all.nl wrote:
From: Simon Glass sjg@chromium.org Date: Sat, 25 Sep 2021 08:42:30 -0600
Hi Mark,
On Sat, 25 Sept 2021 at 07:52, Mark Kettenis mark.kettenis@xs4all.nl wrote:
> From: Simon Glass sjg@chromium.org > Date: Sat, 25 Sep 2021 07:27:41 -0600 > > Hi Mark, > > On Sat, 25 Sept 2021 at 02:11, Mark Kettenis mark.kettenis@xs4all.nl wrote: > > > > > From: Simon Glass sjg@chromium.org > > > Date: Fri, 24 Sep 2021 19:20:32 -0600 > > > > > > Hi Mark, > > > > > > On Sat, 18 Sept 2021 at 07:54, 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 > > > > > > provide > > > > > > > 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. > > > > > > > > Mark Kettenis (5): > > > > arm: apple: Add initial support for Apple's M1 SoC > > > > serial: s5p: Add Apple M1 support > > > > misc: Add Apple DART driver > > > > arm: dts: apple: Add preliminary device trees > > > > doc: board: apple: Add Apple M1 documentation > > > > > > > > arch/arm/Kconfig | 22 + > > > > arch/arm/Makefile | 1 + > > > > arch/arm/dts/t8103-j274.dts | 135 +++++ > > > > arch/arm/dts/t8103-j293.dts | 97 ++++ > > > > arch/arm/dts/t8103.dtsi | 506 ++++++++++++++++++ > > > > arch/arm/include/asm/arch-m1/clk.h | 11 + > > > > 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 | 163 ++++++ > > > > arch/arm/mach-apple/lowlevel_init.S | 16 + > > > > configs/apple_m1_defconfig | 14 + > > > > doc/board/apple/index.rst | 9 + > > > > doc/board/apple/m1.rst | 54 ++ > > > > doc/board/index.rst | 1 + > > > > drivers/misc/Kconfig | 7 + > > > > drivers/misc/Makefile | 1 + > > > > drivers/misc/apple_dart.c | 171 ++++++ > > > > drivers/serial/Kconfig | 2 +- > > > > drivers/serial/serial_s5p.c | 22 + > > > > include/configs/apple.h | 38 ++ > > > > .../interrupt-controller/apple-aic.h | 15 + > > > > include/dt-bindings/pinctrl/apple.h | 13 + > > > > include/dt-bindings/spmi/spmi.h | 10 + > > > > 24 files changed, 1370 insertions(+), 1 deletion(-) > > > > 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/clk.h > > > > 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/misc/apple_dart.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 > > > > > > > > -- > > > > 2.33.0 > > > > > > > > > > I gave this a whirl on a Macbook Air A2337 and needed the patch below > > > to build the devicetree files. Sorry the formatting is broken. > > > > > > Also when booting I get this: > > > > > > ... > > > Preparing to boot kernel at 0x808200000 with fdt at 0x8082e8000 > > > Valid payload found > > > Preparing to run next stage at 0x808200000... > > > MMU: shutting down... > > > MMU: shutdown successful, clearing caches > > > > > > > > > Then the display clears and it hangs. If I try the J274 devicetree it > > > just reboots at that point. > > > > > > What should I expect? I was hoping for console output as I don't have > > > serial connected. I don't have a suitable serial cable, and the USB > > > gadget mode did not result in a ttyACM0 device appearing. > > > > For framebuffer support you also need the "30bpp framebuffer support" > > series I posted earlier: > > > > https://patchwork.ozlabs.org/project/uboot/list/?series=262617 > > > > With that your should get the usual U-Boot output on the screen. I've > > not tested the Air, but it should work there. > > Ah OK, yes that fixes it, thanks! > > So how do I get the keyboard to work in U-Boot? Or are you using > serial somehow?
The laptop keyboard doesn't work yet, so I'm using a USB keyboard when I'm not using a serial console. You need the xhci-dwc3 diff I sent earlier for that:
https://patchwork.ozlabs.org/project/uboot/patch/20210916140009.59009-1-kett...
Actually that seems to be applied in mainline now. Yes USB keyboard works.
It looks like the keyboard needs SPI and there is some sort of linux keyboard driver, but perhaps not for M1.
Yes. It is certaily doable in u-boot, but not a priority. I plan to revisit this once I have a driver going in OpenBSD and a better understanding of how the hardware works.
Makes sense.
> Also it takes for ever to put a test version on the device...how are > you doing that for development?
If you install m1n1.macho without a payload, you can then use the python scripts that come with m1n1 to upload kernels over serial. There is a USB gadget implementation in m1n1, so you don't need a real serial connection. Just connect a Linux machine to the M1 Mac using a USB cable and a USB serial device should show up on the Linux machine once m1n1 is running on the Mac. Set the M1N1DEVICE environment variable to the right device name and run:
$ python3 linux.py --compression=none u-boot-nodtb.bin t8103-j274.dtb
OK I see. I did try the USB serial thing but was missing the fact that U-Boot seems to kill it. So this works fine, thank you will await your next series. Any way to get U-Boot serial console going in the same way?
Probably, but the existing USB gadget code in u-boot doesn't seem to implement USB serial so it would be a significant amount of work. And it would only work after you bring the USB controller up, so it wouldn't be very useful for debugging purposes.
Yse, usbtty.c is very old and doesn't even use driver model, so would need a refresh.
There is a real serial port, and if you have another M1 Mac it should be fairly easy to access it:
https://github.com/AsahiLinux/docs/wiki/Developer-Quickstart#using-an-m1-mac...
Otherwise you need to build some special hardware.
Yes I saw that but I only have one. Will see if I can steal/find another.
OK got a mini as a DUT. It works so far as running macvdmtool on the Air and I can see the /dev/cu.debug-console device, but don't see any serial output when I reboot the DUT. The display works fine, although the USB keyboard only works on the USB-C ports of the mini, not the USB-A ones.
Do you use 'screen /dev/cu.debug-console' or something else? I have a cable with SS on it: This is what I see on the air.
sudo ./macvdmtool reboot serial Mac type: J313AP Looking for HPM devices... Found: IOService:/AppleARMPE/arm-io@10F00000/AppleT810xIO/i2c0@35010000/AppleS5L8940XI2CController/hpmBusManager@6B/AppleHPMBusController/hpm0/AppleHPMARM Connection: Sink Status: APP Unlocking... OK Entering DBMa mode... Status: DBMa Rebooting target into normal mode... OK Waiting for connection........ Connected Putting target into serial mode... OK Putting local
end into serial mode... OK
Exiting DBMa mode... OK sglass@Simons-MacBook-Air macvdmtool
So it seems to be connected but I am not seeing serial output from m1n1 or U-Boot.
Maybe ask on #asahi; apparently not all type-C to type-C cables have all the necessary wires. But when we briefly tried this during the last OpenBSD hackathon, I couldn't get it to work either.
Thanks for the tip. I asked on irc and found I was not setting the baud rate, and screen doesn't seem to work. But this works:
sudo picocom -q --omap crlf --imap lfcrlf -b 115200 /dev/tty.debug-console
Regards, Simon
participants (6)
-
Bin Meng
-
Igor Opaniuk
-
Mark Kettenis
-
Mark Kettenis
-
Simon Glass
-
Tom Rini