diff options
Diffstat (limited to 'arch/arm/boards/raspberry-pi/lowlevel.c')
-rw-r--r-- | arch/arm/boards/raspberry-pi/lowlevel.c | 159 |
1 files changed, 132 insertions, 27 deletions
diff --git a/arch/arm/boards/raspberry-pi/lowlevel.c b/arch/arm/boards/raspberry-pi/lowlevel.c index d58beb6052..b3727d930f 100644 --- a/arch/arm/boards/raspberry-pi/lowlevel.c +++ b/arch/arm/boards/raspberry-pi/lowlevel.c @@ -1,8 +1,14 @@ +// SPDX-License-Identifier: GPL-2.0-only + #include <asm/barebox-arm.h> #include <asm/cache.h> #include <common.h> #include <linux/sizes.h> -#include <mach/platform.h> +#include <asm/unaligned.h> +#include <mach/bcm283x/platform.h> +#include <debug_ll.h> +#include <mach/bcm283x/debug_ll.h> +#include <mach/bcm283x/mbox.h> #include <of.h> #include "lowlevel.h" @@ -31,52 +37,151 @@ static void copy_vc_fdt(void *dest, void *src, unsigned long max_size) memmove(dest, src, size); } -/* Must be inline since stack isn't setup yet. */ static inline void start_raspberry_pi(unsigned long memsize, void *fdt, void *vc_fdt) { - void *saved_vc_fdt; - unsigned long membase = BCM2835_SDRAM_BASE; + unsigned long endmem; - /* A pointer to the FDT created by VideoCore was passed to us in r2. We - * reserve some memory just above the region used for Basebox and copy - * this FDT there. We fetch it from there later in rpi_devices_init().*/ + /* + * A pointer to the FDT created by VideoCore was passed to us in x0/r2. We + * reserve some memory at the end of SDRAM copy this FDT there. We fetch it + * from there later in rpi_devices_init(). + */ memsize -= VIDEOCORE_FDT_SZ; + endmem = BCM2835_SDRAM_BASE + memsize; - arm_cpu_lowlevel_init(); - - /* Copied from barebox_arm_entry(). We need stack here early - * for normal function calls to work. */ - arm_setup_stack(arm_mem_stack_top(membase, membase + memsize)); + /* leave SZ_1K for the initial stack */ + copy_vc_fdt((void *)endmem, vc_fdt, VIDEOCORE_FDT_SZ - SZ_1K); fdt += get_runtime_offset(); - saved_vc_fdt = (void *)(membase + memsize); - copy_vc_fdt(saved_vc_fdt, vc_fdt, VIDEOCORE_FDT_SZ); + barebox_arm_entry(BCM2835_SDRAM_BASE, memsize, fdt); +} - barebox_arm_entry(membase, memsize, fdt); +#ifdef CONFIG_CPU_V8 +#define RPI_ENTRY_FUNCTION(name, memsize, fdt) \ + ENTRY_FUNCTION_WITHSTACK(name, BCM2835_SDRAM_BASE + (memsize), fdt, __x1, __x2) +#else +#define RPI_ENTRY_FUNCTION(name, memsize, fdt) \ + ENTRY_FUNCTION_WITHSTACK(name, BCM2835_SDRAM_BASE + (memsize), __r0, __r1, fdt) +#endif + +extern char __dtb_z_bcm2835_rpi_start[]; +extern char __dtb_z_bcm2836_rpi_2_start[]; +extern char __dtb_z_bcm2837_rpi_3_start[]; +extern char __dtb_z_bcm2837_rpi_cm3_start[]; +extern char __dtb_z_bcm2711_rpi_4_start[]; +extern char __dtb_z_bcm2711_rpi_400_start[]; +extern char __dtb_z_bcm2711_rpi_cm4_io_start[]; +extern char __dtb_z_bcm2711_rpi_cm4s_io_start[]; + +RPI_ENTRY_FUNCTION(start_raspberry_pi1, SZ_128M, fdt) +{ + arm_cpu_lowlevel_init(); + + start_raspberry_pi(SZ_128M, __dtb_z_bcm2835_rpi_start, (void *)fdt); } -extern char __dtb_bcm2835_rpi_start[]; -ENTRY_FUNCTION(start_raspberry_pi1, r0, r1, r2) +RPI_ENTRY_FUNCTION(start_raspberry_pi2, SZ_512M, fdt) { - start_raspberry_pi(SZ_128M, __dtb_bcm2835_rpi_start, (void *)r2); + arm_cpu_lowlevel_init(); + + start_raspberry_pi(SZ_512M, __dtb_z_bcm2836_rpi_2_start, (void *)fdt); } -extern char __dtb_bcm2836_rpi_2_start[]; -ENTRY_FUNCTION(start_raspberry_pi2, r0, r1, r2) +RPI_ENTRY_FUNCTION(start_raspberry_pi3, SZ_512M, fdt) { - start_raspberry_pi(SZ_512M, __dtb_bcm2836_rpi_2_start, (void *)r2); + arm_cpu_lowlevel_init(); + + start_raspberry_pi(SZ_512M, __dtb_z_bcm2837_rpi_3_start, (void *)fdt); } -extern char __dtb_bcm2837_rpi_3_start[]; -ENTRY_FUNCTION(start_raspberry_pi3, r0, r1, r2) +RPI_ENTRY_FUNCTION(start_raspberry_pi_cm3, SZ_512M, fdt) { - start_raspberry_pi(SZ_512M, __dtb_bcm2837_rpi_3_start, (void *)r2); + arm_cpu_lowlevel_init(); + + start_raspberry_pi(SZ_512M, __dtb_z_bcm2837_rpi_cm3_start, (void *)fdt); } -extern char __dtb_bcm2837_rpi_cm3_start[]; -ENTRY_FUNCTION(start_raspberry_pi_cm3, r0, r1, r2) +#define DT_IF_ENABLED(dt, cfg) \ + (IS_ENABLED(cfg) ? (dt) : NULL) + +static void *rpi_get_board_fdt(int rev) { - start_raspberry_pi(SZ_512M, __dtb_bcm2837_rpi_cm3_start, (void *)r2); + if (!(rev & 0x800000)) + return DT_IF_ENABLED(__dtb_z_bcm2835_rpi_start, CONFIG_MACH_RPI); + + switch (((rev >> 4) & 0xff)) { + case BCM2835_BOARD_REV_A: + case BCM2835_BOARD_REV_B: + case BCM2835_BOARD_REV_A_PLUS: + case BCM2835_BOARD_REV_B_PLUS: + case BCM2835_BOARD_REV_CM1: + case BCM2835_BOARD_REV_ZERO: + case BCM2835_BOARD_REV_ZERO_W: + return DT_IF_ENABLED(__dtb_z_bcm2835_rpi_start, CONFIG_MACH_RPI); + + case BCM2836_BOARD_REV_2_B: + return DT_IF_ENABLED(__dtb_z_bcm2836_rpi_2_start, CONFIG_MACH_RPI2); + + case BCM2837_BOARD_REV_3_B: + case BCM2837B0_BOARD_REV_3B_PLUS: + case BCM2837B0_BOARD_REV_3A_PLUS: + case BCM2837B0_BOARD_REV_ZERO_2: + return DT_IF_ENABLED(__dtb_z_bcm2837_rpi_3_start, CONFIG_MACH_RPI3); + + case BCM2837_BOARD_REV_CM3: + case BCM2837B0_BOARD_REV_CM3_PLUS: + return DT_IF_ENABLED(__dtb_z_bcm2837_rpi_cm3_start, CONFIG_MACH_RPI_CM3); + + case BCM2711_BOARD_REV_4_B: + return DT_IF_ENABLED(__dtb_z_bcm2711_rpi_4_start, CONFIG_MACH_RPI4); + case BCM2711_BOARD_REV_400: + return DT_IF_ENABLED(__dtb_z_bcm2711_rpi_400_start, CONFIG_MACH_RPI4); + case BCM2711_BOARD_REV_CM4: + return DT_IF_ENABLED(__dtb_z_bcm2711_rpi_cm4_io_start, CONFIG_MACH_RPI4); + case BCM2711_BOARD_REV_CM4_S: + return DT_IF_ENABLED(__dtb_z_bcm2711_rpi_cm4s_io_start, CONFIG_MACH_RPI4); + } + + return NULL; +} + +RPI_ENTRY_FUNCTION(start_raspberry_pi_generic, SZ_128M, vc_fdt) +{ + void *fdt = NULL; + ssize_t memsize; + int rev; + + arm_cpu_lowlevel_init(); + + debug_ll_init(); + + putc_ll('>'); + + relocate_to_current_adr(); + setup_c(); + + memsize = rpi_get_arm_mem(); + if (memsize < 0) { + pr_warn("mbox: failed to query ARM memory size. 128M assumed.\n"); + memsize = SZ_128M; + } + + rev = rpi_get_board_rev(); + if (rev >= 0) { + pr_debug("Detected revision %08x\n", rev); + fdt = rpi_get_board_fdt(rev); + } + + if (!fdt) { + fdt = (void *)vc_fdt; + + pr_warn("Unknown Rpi board with rev %08x.\n", rev); + + if (get_unaligned_be32(fdt) != 0xd00dfeed) + panic("No suitable built-in or videocore-supplied DT\n"); + } + + start_raspberry_pi(memsize, fdt, (void *)vc_fdt); } |