diff --git a/MAINTAINERS b/MAINTAINERS index 5069f18806..4ed72aecee 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -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 +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 S: Maintained diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 86c1ebde05..48188aad01 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 6c9a00c5a4..ad757e982e 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 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..0bfbc473ec --- /dev/null +++ b/arch/arm/mach-apple/board.c @@ -0,0 +1,162 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * (C) Copyright 2021 Mark Kettenis + */ + +#include +#include +#include + +#include +#include +#include +#include + +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 0000000000..e1c0d91cef --- /dev/null +++ b/arch/arm/mach-apple/lowlevel_init.S @@ -0,0 +1,17 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * (C) Copyright 2021 Mark Kettenis + */ + +.align 8 +.global fw_dtb_pointer +fw_dtb_pointer: + .quad 0 + +.global save_boot_params +save_boot_params: + /* Stash DTB pointer passed by m1n1 */ + adr x1, fw_dtb_pointer + str x0, [x1] + + b save_boot_params_ret diff --git a/configs/apple_m1_defconfig b/configs/apple_m1_defconfig new file mode 100644 index 0000000000..6072e7524c --- /dev/null +++ b/configs/apple_m1_defconfig @@ -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 index 0000000000..b1f6043174 --- /dev/null +++ b/include/configs/apple.h @@ -0,0 +1,36 @@ +#ifndef __CONFIG_H +#define __CONFIG_H + +#include + +#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 + +#define CONFIG_EXTRA_ENV_SETTINGS \ + ENV_DEVICE_SETTINGS \ + ENV_MEM_LAYOUT_SETTINGS \ + BOOTENV + +#endif