]> git.dujemihanovic.xyz Git - u-boot.git/commitdiff
arm: apple: Add initial support for Apple's M1 SoC
authorMark Kettenis <kettenis@openbsd.org>
Sat, 23 Oct 2021 14:58:03 +0000 (16:58 +0200)
committerTom Rini <trini@konsulko.com>
Sun, 31 Oct 2021 12:46:44 +0000 (08:46 -0400)
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>
Reviewed-by: Simon Glass <sjg@chromium.org>
[trini: Add MAINTAINERS entry]

MAINTAINERS
arch/arm/Kconfig
arch/arm/Makefile
arch/arm/mach-apple/Kconfig [new file with mode: 0644]
arch/arm/mach-apple/Makefile [new file with mode: 0644]
arch/arm/mach-apple/board.c [new file with mode: 0644]
arch/arm/mach-apple/lowlevel_init.S [new file with mode: 0644]
configs/apple_m1_defconfig [new file with mode: 0644]
include/configs/apple.h [new file with mode: 0644]

index 5069f18806529f170ef498f162a689ca7577561a..4ed72aecee01caf8e55944b9f4e9eefaf66de9b2 100644 (file)
@@ -108,6 +108,15 @@ L: uboot-snps-arc@synopsys.com
 F:     doc/device-tree-bindings/mmc/snps,dw-mmc.txt
 F:     drivers/mmc/snps_dw_mmc.c
 
+APPLE M1 SOC SUPPORT
+M:     Mark Kettenis <kettenis@openbsd.org>
+S:     Maintained
+F:     arch/arm/include/asm/arch-m1/
+F:     arch/arm/mach-apple/
+F:     configs/apple_m1_defconfig
+F:     drivers/iommu/apple_dart.c
+F:     include/configs/apple.h
+
 ARM
 M:     Tom Rini <trini@konsulko.com>
 S:     Maintained
index 86c1ebde05ccbcc32479ade89ceb68b5c6969c91..48188aad018c635c401af539e406902ac46ff4a9 100644 (file)
@@ -920,6 +920,25 @@ config ARCH_NEXELL
        select DM
        select GPIO_EXTRA_HEADER
 
+config ARCH_APPLE
+       bool "Apple SoCs"
+       select ARM64
+       select BLK
+       select CMD_USB
+       select DM
+       select DM_KEYBOARD
+       select DM_SERIAL
+       select DM_USB
+       select DM_VIDEO
+       select LINUX_KERNEL_IMAGE_HEADER
+       select OF_CONTROL
+       select OF_BOARD
+       select POSITION_INDEPENDENT
+       select USB
+       imply CMD_DM
+       imply CMD_GPT
+       imply DISTRO_DEFAULTS
+
 config ARCH_OWL
        bool "Actions Semi OWL SoCs"
        select DM
@@ -2016,6 +2035,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"
index 6c9a00c5a481e01e80765ce9897966c655e029c5..ad757e982e37a3179a0adf13b3ac57c3bbffbfe7 100644 (file)
@@ -55,6 +55,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 (file)
index 0000000..66cab91
--- /dev/null
@@ -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 (file)
index 0000000..e74a8c9
--- /dev/null
@@ -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 (file)
index 0000000..0bfbc47
--- /dev/null
@@ -0,0 +1,162 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2021 Mark Kettenis <kettenis@openbsd.org>
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <efi_loader.h>
+
+#include <asm/armv8/mmu.h>
+#include <asm/global_data.h>
+#include <asm/io.h>
+#include <asm/system.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static struct mm_region apple_mem_map[] = {
+       {
+               /* I/O */
+               .virt = 0x200000000,
+               .phys = 0x200000000,
+               .size = 8UL * SZ_1G,
+               .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+                        PTE_BLOCK_NON_SHARE |
+                        PTE_BLOCK_PXN | PTE_BLOCK_UXN
+       }, {
+               /* I/O */
+               .virt = 0x500000000,
+               .phys = 0x500000000,
+               .size = 2UL * SZ_1G,
+               .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+                        PTE_BLOCK_NON_SHARE |
+                        PTE_BLOCK_PXN | PTE_BLOCK_UXN
+       }, {
+               /* I/O */
+               .virt = 0x680000000,
+               .phys = 0x680000000,
+               .size = SZ_512M,
+               .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+                        PTE_BLOCK_NON_SHARE |
+                        PTE_BLOCK_PXN | PTE_BLOCK_UXN
+       }, {
+               /* PCIE */
+               .virt = 0x6a0000000,
+               .phys = 0x6a0000000,
+               .size = SZ_512M,
+               .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRE) |
+                        PTE_BLOCK_INNER_SHARE |
+                        PTE_BLOCK_PXN | PTE_BLOCK_UXN
+       }, {
+               /* PCIE */
+               .virt = 0x6c0000000,
+               .phys = 0x6c0000000,
+               .size = SZ_1G,
+               .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRE) |
+                        PTE_BLOCK_INNER_SHARE |
+                        PTE_BLOCK_PXN | PTE_BLOCK_UXN
+       }, {
+               /* RAM */
+               .virt = 0x800000000,
+               .phys = 0x800000000,
+               .size = 8UL * SZ_1G,
+               .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
+                        PTE_BLOCK_INNER_SHARE
+       }, {
+               /* Empty entry for framebuffer */
+               0,
+       }, {
+               /* List terminator */
+               0,
+       }
+};
+
+struct mm_region *mem_map = apple_mem_map;
+
+int board_init(void)
+{
+       return 0;
+}
+
+int dram_init(void)
+{
+       ofnode node;
+       int index, ret;
+       fdt_addr_t base;
+       fdt_size_t size;
+
+       ret = fdtdec_setup_mem_size_base();
+       if (ret)
+               return ret;
+
+       /* Update RAM mapping */
+       index = ARRAY_SIZE(apple_mem_map) - 3;
+       apple_mem_map[index].virt = gd->ram_base;
+       apple_mem_map[index].phys = gd->ram_base;
+       apple_mem_map[index].size = gd->ram_size;
+
+       node = ofnode_path("/chosen/framebuffer");
+       if (!ofnode_valid(node))
+               return 0;
+
+       base = ofnode_get_addr_size(node, "reg", &size);
+       if (base == FDT_ADDR_T_NONE)
+               return 0;
+
+       /* Add framebuffer mapping */
+       index = ARRAY_SIZE(apple_mem_map) - 2;
+       apple_mem_map[index].virt = base;
+       apple_mem_map[index].phys = base;
+       apple_mem_map[index].size = size;
+       apple_mem_map[index].attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL_NC) |
+               PTE_BLOCK_INNER_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN;
+
+       return 0;
+}
+
+int dram_init_banksize(void)
+{
+       return fdtdec_setup_memory_banksize();
+}
+
+#define APPLE_WDT_BASE         0x23d2b0000ULL
+
+#define APPLE_WDT_SYS_CTL_ENABLE       BIT(2)
+
+typedef struct apple_wdt {
+       u32     reserved0[3];
+       u32     chip_ctl;
+       u32     sys_tmr;
+       u32     sys_cmp;
+       u32     reserved1;
+       u32     sys_ctl;
+} apple_wdt_t;
+
+void reset_cpu(void)
+{
+       apple_wdt_t *wdt = (apple_wdt_t *)APPLE_WDT_BASE;
+
+       writel(0, &wdt->sys_cmp);
+       writel(APPLE_WDT_SYS_CTL_ENABLE, &wdt->sys_ctl);
+
+       while(1)
+               wfi();
+}
+
+extern long fw_dtb_pointer;
+
+void *board_fdt_blob_setup(int *err)
+{
+       /* Return DTB pointer passed by m1n1 */
+       *err = 0;
+       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 (file)
index 0000000..e1c0d91
--- /dev/null
@@ -0,0 +1,17 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * (C) Copyright 2021 Mark Kettenis <kettenis@openbsd.org>
+ */
+
+.align 8
+.global fw_dtb_pointer
+fw_dtb_pointer:
+       .quad   0
+
+.global save_boot_params
+save_boot_params:
+       /* Stash DTB pointer passed by m1n1 */
+       adr     x1, fw_dtb_pointer
+       str     x0, [x1]
+
+       b       save_boot_params_ret
diff --git a/configs/apple_m1_defconfig b/configs/apple_m1_defconfig
new file mode 100644 (file)
index 0000000..6072e75
--- /dev/null
@@ -0,0 +1,15 @@
+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_SYS_LOAD_ADDR=0x880000000
+# CONFIG_GENERATE_SMBIOS_TABLE is not set
diff --git a/include/configs/apple.h b/include/configs/apple.h
new file mode 100644 (file)
index 0000000..b1f6043
--- /dev/null
@@ -0,0 +1,36 @@
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+#include <linux/sizes.h>
+
+#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