diff options
author | Mark Kettenis <kettenis@openbsd.org> | 2021-10-23 16:58:03 +0200 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2021-10-31 08:46:44 -0400 |
commit | 003b657edcdc7ee96b7df277a16480129a5260a7 (patch) | |
tree | 38c454ce830b7eedd8bf65bc260d6cf6e863b2e7 /arch/arm | |
parent | fb5746243707d6b84dea02490a86868c3d7f534d (diff) | |
download | u-boot-003b657edcdc7ee96b7df277a16480129a5260a7.zip u-boot-003b657edcdc7ee96b7df277a16480129a5260a7.tar.gz u-boot-003b657edcdc7ee96b7df277a16480129a5260a7.tar.bz2 |
arm: apple: Add initial support for Apple's M1 SoC
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]
Diffstat (limited to 'arch/arm')
-rw-r--r-- | arch/arm/Kconfig | 21 | ||||
-rw-r--r-- | arch/arm/Makefile | 1 | ||||
-rw-r--r-- | arch/arm/mach-apple/Kconfig | 18 | ||||
-rw-r--r-- | arch/arm/mach-apple/Makefile | 4 | ||||
-rw-r--r-- | arch/arm/mach-apple/board.c | 162 | ||||
-rw-r--r-- | arch/arm/mach-apple/lowlevel_init.S | 17 |
6 files changed, 223 insertions, 0 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 86c1ebd..48188aa 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -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" diff --git a/arch/arm/Makefile b/arch/arm/Makefile index 6c9a00c..ad757e9 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -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 index 0000000..66cab91 --- /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 0000000..e74a8c9 --- /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 0000000..0bfbc47 --- /dev/null +++ b/arch/arm/mach-apple/board.c @@ -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 index 0000000..e1c0d91 --- /dev/null +++ b/arch/arm/mach-apple/lowlevel_init.S @@ -0,0 +1,17 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * (C) Copyright 2021 Mark Kettenis <kettenis@openbsd.org> + */ + +.align 8 +.global fw_dtb_pointer +fw_dtb_pointer: + .quad 0 + +.global save_boot_params +save_boot_params: + /* Stash DTB pointer passed by m1n1 */ + adr x1, fw_dtb_pointer + str x0, [x1] + + b save_boot_params_ret |