diff options
author | Tom Rini <trini@konsulko.com> | 2020-06-04 20:50:39 +0300 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2020-06-04 20:50:39 +0300 |
commit | 07d90d8bd451b9595fb0369c51f90ee2dccd5d9f (patch) | |
tree | 97560956a7738893dd4cc972e3a1b463623033bb /board | |
parent | c27178ba3649f539c9f1890ea147f4c5415f63b5 (diff) | |
parent | 0a94007e829876c7ebd49daebfaa90eea25801b8 (diff) | |
download | u-boot-07d90d8bd451b9595fb0369c51f90ee2dccd5d9f.tar.xz |
Merge https://gitlab.denx.de/u-boot/custodians/u-boot-riscv
- Fixes 7e249bc13aaf: ("riscv: Move all SMP related SBI calls to
SBI_v01") Move sbi_probe_extension() out of CONFIG_SBI_V01.
- SiFive FU540 support SPL.
Diffstat (limited to 'board')
-rw-r--r-- | board/sifive/fu540/Kconfig | 18 | ||||
-rw-r--r-- | board/sifive/fu540/Makefile | 4 | ||||
-rw-r--r-- | board/sifive/fu540/fu540.c | 134 | ||||
-rw-r--r-- | board/sifive/fu540/spl.c | 74 |
4 files changed, 155 insertions, 75 deletions
diff --git a/board/sifive/fu540/Kconfig b/board/sifive/fu540/Kconfig index 75661f35f8..86193d7668 100644 --- a/board/sifive/fu540/Kconfig +++ b/board/sifive/fu540/Kconfig @@ -7,23 +7,35 @@ config SYS_VENDOR default "sifive" config SYS_CPU - default "generic" + default "fu540" config SYS_CONFIG_NAME default "sifive-fu540" config SYS_TEXT_BASE + default 0x80200000 if SPL default 0x80000000 if !RISCV_SMODE default 0x80200000 if RISCV_SMODE +config SPL_TEXT_BASE + default 0x08000000 + +config SPL_OPENSBI_LOAD_ADDR + default 0x80000000 + config BOARD_SPECIFIC_OPTIONS # dummy def_bool y - select GENERIC_RISCV + select SIFIVE_FU540 + select SUPPORT_SPL + select RAM + select SPL_RAM if SPL imply CMD_DHCP imply CMD_EXT2 imply CMD_EXT4 imply CMD_FAT imply CMD_FS_GENERIC + imply CMD_GPT + imply PARTITION_TYPE_GUID imply CMD_NET imply CMD_PING imply CMD_SF @@ -51,5 +63,7 @@ config BOARD_SPECIFIC_OPTIONS # dummy imply SIFIVE_GPIO imply CMD_GPIO imply SMP + imply MISC + imply SIFIVE_OTP endif diff --git a/board/sifive/fu540/Makefile b/board/sifive/fu540/Makefile index 6e1862c475..b05e2f5807 100644 --- a/board/sifive/fu540/Makefile +++ b/board/sifive/fu540/Makefile @@ -3,3 +3,7 @@ # Copyright (c) 2019 Western Digital Corporation or its affiliates. obj-y += fu540.o + +ifdef CONFIG_SPL_BUILD +obj-y += spl.o +endif diff --git a/board/sifive/fu540/fu540.c b/board/sifive/fu540/fu540.c index df57b6ecc2..fa705dea71 100644 --- a/board/sifive/fu540/fu540.c +++ b/board/sifive/fu540/fu540.c @@ -6,101 +6,69 @@ * Anup Patel <anup.patel@wdc.com> */ -#include <common.h> #include <dm.h> #include <env.h> #include <init.h> +#include <log.h> #include <linux/bug.h> #include <linux/delay.h> #include <linux/io.h> +#include <misc.h> +#include <spl.h> + +/* + * This define is a value used for error/unknown serial. + * If we really care about distinguishing errors and 0 is + * valid, we'll need a different one. + */ +#define ERROR_READING_SERIAL_NUMBER 0 #ifdef CONFIG_MISC_INIT_R -#define FU540_OTP_BASE_ADDR 0x10070000 - -struct fu540_otp_regs { - u32 pa; /* Address input */ - u32 paio; /* Program address input */ - u32 pas; /* Program redundancy cell selection input */ - u32 pce; /* OTP Macro enable input */ - u32 pclk; /* Clock input */ - u32 pdin; /* Write data input */ - u32 pdout; /* Read data output */ - u32 pdstb; /* Deep standby mode enable input (active low) */ - u32 pprog; /* Program mode enable input */ - u32 ptc; /* Test column enable input */ - u32 ptm; /* Test mode enable input */ - u32 ptm_rep;/* Repair function test mode enable input */ - u32 ptr; /* Test row enable input */ - u32 ptrim; /* Repair function enable input */ - u32 pwe; /* Write enable input (defines program cycle) */ -} __packed; - -#define BYTES_PER_FUSE 4 -#define NUM_FUSES 0x1000 - -static int fu540_otp_read(int offset, void *buf, int size) +#if CONFIG_IS_ENABLED(SIFIVE_OTP) +static u32 otp_read_serialnum(struct udevice *dev) { - struct fu540_otp_regs *regs = (void __iomem *)FU540_OTP_BASE_ADDR; - unsigned int i; - int fuseidx = offset / BYTES_PER_FUSE; - int fusecount = size / BYTES_PER_FUSE; - u32 fusebuf[fusecount]; - - /* check bounds */ - if (offset < 0 || size < 0) - return -EINVAL; - if (fuseidx >= NUM_FUSES) - return -EINVAL; - if ((fuseidx + fusecount) > NUM_FUSES) - return -EINVAL; + int ret; + u32 serial[2] = {0}; - /* init OTP */ - writel(0x01, ®s->pdstb); /* wake up from stand-by */ - writel(0x01, ®s->ptrim); /* enable repair function */ - writel(0x01, ®s->pce); /* enable input */ - - /* read all requested fuses */ - for (i = 0; i < fusecount; i++, fuseidx++) { - writel(fuseidx, ®s->pa); - - /* cycle clock to read */ - writel(0x01, ®s->pclk); - mdelay(1); - writel(0x00, ®s->pclk); - mdelay(1); - - /* read the value */ - fusebuf[i] = readl(®s->pdout); - } + for (int i = 0xfe * 4; i > 0; i -= 8) { + ret = misc_read(dev, i, serial, sizeof(serial)); - /* shut down */ - writel(0, ®s->pce); - writel(0, ®s->ptrim); - writel(0, ®s->pdstb); + if (ret != sizeof(serial)) { + printf("%s: error reading serial from OTP\n", __func__); + break; + } - /* copy out */ - memcpy(buf, fusebuf, size); + if (serial[0] == ~serial[1]) + return serial[0]; + } - return 0; + return ERROR_READING_SERIAL_NUMBER; } +#endif static u32 fu540_read_serialnum(void) { + u32 serial = ERROR_READING_SERIAL_NUMBER; + +#if CONFIG_IS_ENABLED(SIFIVE_OTP) + struct udevice *dev; int ret; - u32 serial[2] = {0}; - for (int i = 0xfe * 4; i > 0; i -= 8) { - ret = fu540_otp_read(i, serial, sizeof(serial)); - if (ret) { - printf("%s: error reading from OTP\n", __func__); - break; - } - if (serial[0] == ~serial[1]) - return serial[0]; + /* init OTP */ + ret = uclass_get_device_by_driver(UCLASS_MISC, + DM_GET_DRIVER(sifive_otp), &dev); + + if (ret) { + debug("%s: could not find otp device\n", __func__); + return serial; } - return 0; + /* read serial from OTP and set env var */ + serial = otp_read_serialnum(dev); +#endif + + return serial; } static void fu540_setup_macaddr(u32 serialnum) @@ -150,3 +118,23 @@ int board_init(void) return 0; } + +#ifdef CONFIG_SPL +u32 spl_boot_device(void) +{ +#ifdef CONFIG_SPL_MMC_SUPPORT + return BOOT_DEVICE_MMC1; +#else + puts("Unknown boot device\n"); + hang(); +#endif +} +#endif + +#ifdef CONFIG_SPL_LOAD_FIT +int board_fit_config_name_match(const char *name) +{ + /* boot using first FIT config */ + return 0; +} +#endif diff --git a/board/sifive/fu540/spl.c b/board/sifive/fu540/spl.c new file mode 100644 index 0000000000..55325cf99d --- /dev/null +++ b/board/sifive/fu540/spl.c @@ -0,0 +1,74 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (c) 2019 SiFive, Inc + * + * Authors: + * Pragnesh Patel <pragnesh.patel@sifive.com> + */ + +#include <init.h> +#include <spl.h> +#include <misc.h> +#include <log.h> +#include <linux/delay.h> +#include <asm/gpio.h> +#include <asm/arch/gpio.h> +#include <asm/arch/spl.h> + +#define GEM_PHY_RESET SIFIVE_GENERIC_GPIO_NR(0, 12) + +int init_clk_and_ddr(void) +{ + int ret; + + ret = soc_spl_init(); + if (ret) { + debug("FU540 SPL init failed: %d\n", ret); + return ret; + } + + /* + * GEMGXL init VSC8541 PHY reset sequence; + * leave pull-down active for 2ms + */ + udelay(2000); + ret = gpio_request(GEM_PHY_RESET, "gem_phy_reset"); + if (ret) { + debug("gem_phy_reset gpio request failed: %d\n", ret); + return ret; + } + + /* Set GPIO 12 (PHY NRESET) */ + ret = gpio_direction_output(GEM_PHY_RESET, 1); + if (ret) { + debug("gem_phy_reset gpio direction set failed: %d\n", ret); + return ret; + } + + udelay(1); + + /* Reset PHY again to enter unmanaged mode */ + gpio_set_value(GEM_PHY_RESET, 0); + udelay(1); + gpio_set_value(GEM_PHY_RESET, 1); + mdelay(15); + + return 0; +} + +void board_init_f(ulong dummy) +{ + int ret; + + ret = spl_early_init(); + if (ret) + panic("spl_early_init() failed: %d\n", ret); + + arch_cpu_init_dm(); + + preloader_console_init(); + + ret = init_clk_and_ddr(); + if (ret) + panic("init_clk_and_ddr() failed: %d\n", ret); +} |