diff options
author | Kristian Amlie <kristian.amlie@northern.tech> | 2021-09-07 08:37:51 +0200 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2021-09-24 14:30:46 -0400 |
commit | 15e30106ce624ade62ba87c2defe7ea67c88f1b5 (patch) | |
tree | 040296743e7065f07d6892d1df4e564640a32039 /board/armltd | |
parent | 6493fa4c3da3299ecf5fcbdb10de967162f12856 (diff) | |
download | u-boot-15e30106ce624ade62ba87c2defe7ea67c88f1b5.tar.gz u-boot-15e30106ce624ade62ba87c2defe7ea67c88f1b5.tar.bz2 u-boot-15e30106ce624ade62ba87c2defe7ea67c88f1b5.zip |
ARM: vexpress_ca9x4: Reintroduce board in order to use with QEMU.
vexpress_ca9x4 is seemingly the only board except for qemu_arm which
is able to run U-Boot correctly, using the `-M vexpress-a9` option to
QEMU. Building for qemu_arm and running qemu-system-arm with the `-M
virt` argument has a number of downsides, most importantly that it
only supports virtio storage drivers. This significantly reduces its
usefulness in testing memory card and Flash solutions, especially when
the tested images are from a third party source.
So therefore we reintroduce the vexpress_ca9x4 board in this commit,
with the explicit goal of using it with QEMU.
A number of differences to note from the original:
* Since the board was apparently unmaintained, I have now set myself
as the maintainer.
* The board has been converted to use the driver model, which was the
reason it was removed in the first place.
* The vexpress_ca15_tc2 and vexpress_ca5x2 boards, which were removed
in the same commit, are not necessary for the QEMU use case, and
have been omitted.
* An `mmc0` alias was introduced in the dts file. The mmc is not
detected correctly without this, now that it's based on the device
tree instead of the board's init function.
* A couple of other nodes were removed because they were problematic
when trying to run the UEFI bootmgr. Once again, the primary use
case here is QEMU, and these nodes are not needed for that to work.
* Unnecessary board init code has been removed, thanks to driver model
and device tree.
* `CONFIG_OF_EMBED` has been enabled. I know this goes against
recommended practice, but there doesn't seem to be any other way to
pass the dtb to U-Boot in the QEMU scenario. Using the -dtb argument
does not work, I suppose because U-Boot doesn't use the same
mechanics as the kernel when it's booting.
* Load addresses have been changed to fit QEMU use case.
People wanting to get a more detailed, yet somewhat isolated, diff
between this and the original, can run this command:
git diff c6c26a05b89f25a06e7562f8c2071b60fd0c9eac~1 -- \
$( git diff-tree --diff-filter=A -r --name-only HEAD~1 HEAD)
(Make sure to either check out this commit first, or replace HEAD with
the commit ID of this commit)
Signed-off-by: Kristian Amlie <kristian.amlie@northern.tech>
Diffstat (limited to 'board/armltd')
-rw-r--r-- | board/armltd/vexpress/Kconfig | 12 | ||||
-rw-r--r-- | board/armltd/vexpress/MAINTAINERS | 6 | ||||
-rw-r--r-- | board/armltd/vexpress/Makefile | 6 | ||||
-rw-r--r-- | board/armltd/vexpress/vexpress_common.c | 167 |
4 files changed, 191 insertions, 0 deletions
diff --git a/board/armltd/vexpress/Kconfig b/board/armltd/vexpress/Kconfig new file mode 100644 index 0000000000..1b0dcf9669 --- /dev/null +++ b/board/armltd/vexpress/Kconfig @@ -0,0 +1,12 @@ +if TARGET_VEXPRESS_CA9X4 + +config SYS_BOARD + default "vexpress" + +config SYS_VENDOR + default "armltd" + +config SYS_CONFIG_NAME + default "vexpress_ca9x4" + +endif diff --git a/board/armltd/vexpress/MAINTAINERS b/board/armltd/vexpress/MAINTAINERS new file mode 100644 index 0000000000..2b3e4916a5 --- /dev/null +++ b/board/armltd/vexpress/MAINTAINERS @@ -0,0 +1,6 @@ +VERSATILE EXPRESS BOARDS +M: Kristian Amlie <kristian.amlie@northern.tech> +S: Maintained +F: board/armltd/vexpress/ +F: include/configs/vexpress_ca9x4.h +F: configs/vexpress_ca9x4_defconfig diff --git a/board/armltd/vexpress/Makefile b/board/armltd/vexpress/Makefile new file mode 100644 index 0000000000..84804f5ce7 --- /dev/null +++ b/board/armltd/vexpress/Makefile @@ -0,0 +1,6 @@ +# SPDX-License-Identifier: GPL-2.0+ +# +# (C) Copyright 2000-2004 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. + +obj-y := vexpress_common.o diff --git a/board/armltd/vexpress/vexpress_common.c b/board/armltd/vexpress/vexpress_common.c new file mode 100644 index 0000000000..1c83019265 --- /dev/null +++ b/board/armltd/vexpress/vexpress_common.c @@ -0,0 +1,167 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH <www.elinos.com> + * Marius Groeger <mgroeger@sysgo.de> + * + * (C) Copyright 2002 + * David Mueller, ELSOFT AG, <d.mueller@elsoft.ch> + * + * (C) Copyright 2003 + * Texas Instruments, <www.ti.com> + * Kshitij Gupta <Kshitij@ti.com> + * + * (C) Copyright 2004 + * ARM Ltd. + * Philippe Robin, <philippe.robin@arm.com> + */ +#include <common.h> +#include <bootstage.h> +#include <cpu_func.h> +#include <init.h> +#include <malloc.h> +#include <errno.h> +#include <net.h> +#include <netdev.h> +#include <asm/global_data.h> +#include <asm/io.h> +#include <asm/mach-types.h> +#include <asm/arch/systimer.h> +#include <asm/arch/sysctrl.h> +#include <asm/arch/wdt.h> + +static struct systimer *systimer_base = (struct systimer *)V2M_TIMER01; +static struct sysctrl *sysctrl_base = (struct sysctrl *)SCTL_BASE; + +static void flash__init(void); +static void vexpress_timer_init(void); +DECLARE_GLOBAL_DATA_PTR; + +#if defined(CONFIG_SHOW_BOOT_PROGRESS) +void show_boot_progress(int progress) +{ + printf("Boot reached stage %d\n", progress); +} +#endif + +static inline void delay(ulong loops) +{ + __asm__ volatile ("1:\n" + "subs %0, %1, #1\n" + "bne 1b" : "=r" (loops) : "0" (loops)); +} + +int board_init(void) +{ + gd->bd->bi_boot_params = LINUX_BOOT_PARAM_ADDR; + gd->bd->bi_arch_number = MACH_TYPE_VEXPRESS; + + icache_enable(); + flash__init(); + vexpress_timer_init(); + + return 0; +} + +static void flash__init(void) +{ + /* Setup the sytem control register to allow writing to flash */ + writel(readl(&sysctrl_base->scflashctrl) | VEXPRESS_FLASHPROG_FLVPPEN, + &sysctrl_base->scflashctrl); +} + +int dram_init(void) +{ + gd->ram_size = + get_ram_size((long *)CONFIG_SYS_SDRAM_BASE, PHYS_SDRAM_1_SIZE); + return 0; +} + +int dram_init_banksize(void) +{ + gd->bd->bi_dram[0].start = PHYS_SDRAM_1; + gd->bd->bi_dram[0].size = + get_ram_size((long *)PHYS_SDRAM_1, PHYS_SDRAM_1_SIZE); + gd->bd->bi_dram[1].start = PHYS_SDRAM_2; + gd->bd->bi_dram[1].size = + get_ram_size((long *)PHYS_SDRAM_2, PHYS_SDRAM_2_SIZE); + + return 0; +} + +/* + * Start timer: + * Setup a 32 bit timer, running at 1KHz + * Versatile Express Motherboard provides 1 MHz timer + */ +static void vexpress_timer_init(void) +{ + /* + * Set clock frequency in system controller: + * VEXPRESS_REFCLK is 32KHz + * VEXPRESS_TIMCLK is 1MHz + */ + writel(SP810_TIMER0_ENSEL | SP810_TIMER1_ENSEL | + SP810_TIMER2_ENSEL | SP810_TIMER3_ENSEL | + readl(&sysctrl_base->scctrl), &sysctrl_base->scctrl); + + /* + * Set Timer0 to be: + * Enabled, free running, no interrupt, 32-bit, wrapping + */ + writel(SYSTIMER_RELOAD, &systimer_base->timer0load); + writel(SYSTIMER_RELOAD, &systimer_base->timer0value); + writel(SYSTIMER_EN | SYSTIMER_32BIT | + readl(&systimer_base->timer0control), + &systimer_base->timer0control); +} + +int v2m_cfg_write(u32 devfn, u32 data) +{ + /* Configuration interface broken? */ + u32 val; + + devfn |= SYS_CFG_START | SYS_CFG_WRITE; + + val = readl(V2M_SYS_CFGSTAT); + writel(val & ~SYS_CFG_COMPLETE, V2M_SYS_CFGSTAT); + + writel(data, V2M_SYS_CFGDATA); + writel(devfn, V2M_SYS_CFGCTRL); + + do { + val = readl(V2M_SYS_CFGSTAT); + } while (val == 0); + + return !!(val & SYS_CFG_ERR); +} + +/* Use the ARM Watchdog System to cause reset */ +void reset_cpu(void) +{ + if (v2m_cfg_write(SYS_CFG_REBOOT | SYS_CFG_SITE_MB, 0)) + printf("Unable to reboot\n"); +} + +void lowlevel_init(void) +{ +} + +ulong get_board_rev(void){ + return readl((u32 *)SYS_ID); +} + +#ifdef CONFIG_ARMV7_NONSEC +/* Setting the address at which secondary cores start from. + * Versatile Express uses one address for all cores, so ignore corenr + */ +void smp_set_core_boot_addr(unsigned long addr, int corenr) +{ + /* The SYSFLAGS register on VExpress needs to be cleared first + * by writing to the next address, since any writes to the address + * at offset 0 will only be ORed in + */ + writel(~0, CONFIG_SYSFLAGS_ADDR + 4); + writel(addr, CONFIG_SYSFLAGS_ADDR); +} +#endif |