Maximilian Brune has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/79954?usp=email )
Change subject: mb/sifive: Add Hifive Unmatched mainboard ......................................................................
mb/sifive: Add Hifive Unmatched mainboard
Signed-off-by: Maximilian Brune maximilian.brune@9elements.com Change-Id: Ife0afdce89d5a1a1b936c30c8027f1bc191b8c53 --- A src/mainboard/sifive/hifive-unmatched/Kconfig A src/mainboard/sifive/hifive-unmatched/Kconfig.name A src/mainboard/sifive/hifive-unmatched/board_info.txt A src/mainboard/sifive/hifive-unmatched/cbfs_spi.c A src/mainboard/sifive/hifive-unmatched/default.fmd A src/mainboard/sifive/hifive-unmatched/devicetree.cb A src/mainboard/sifive/hifive-unmatched/fixup_fdt.c A src/mainboard/sifive/hifive-unmatched/fu740-c000.dtsi A src/mainboard/sifive/hifive-unmatched/hifive-unmatched-a00-mod.dts A src/mainboard/sifive/hifive-unmatched/hifive-unmatched-a00.dts A src/mainboard/sifive/hifive-unmatched/mainboard.c A src/mainboard/sifive/hifive-unmatched/romstage.c 12 files changed, 1,234 insertions(+), 0 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/54/79954/1
diff --git a/src/mainboard/sifive/hifive-unmatched/Kconfig b/src/mainboard/sifive/hifive-unmatched/Kconfig new file mode 100644 index 0000000..5e2a064f --- /dev/null +++ b/src/mainboard/sifive/hifive-unmatched/Kconfig @@ -0,0 +1,27 @@ +# SPDX-License-Identifier: GPL-2.0-only + +if BOARD_SIFIVE_HIFIVE_UNMATCHED + +config BOARD_SPECIFIC_OPTIONS + def_bool y + select SOC_SIFIVE_FU740 + select BOARD_ROMSIZE_KB_32768 + select MISSING_BOARD_RESET + select FLATTENED_DEVICE_TREE + select SPI_FLASH + select SPI_FLASH_ISSI + select SPI_SDCARD + +config HEAP_SIZE + default 0x10000 #TODO + +config MAINBOARD_DIR + default "sifive/hifive-unmatched" + +config MAINBOARD_PART_NUMBER + default "HiFive Unmatched" + +config FMDFILE + default "src/mainboard/$(CONFIG_MAINBOARD_DIR)/default.fmd" + +endif diff --git a/src/mainboard/sifive/hifive-unmatched/Kconfig.name b/src/mainboard/sifive/hifive-unmatched/Kconfig.name new file mode 100644 index 0000000..bbba82c --- /dev/null +++ b/src/mainboard/sifive/hifive-unmatched/Kconfig.name @@ -0,0 +1,2 @@ +config BOARD_SIFIVE_HIFIVE_UNMATCHED + bool "HiFive Unmatched" diff --git a/src/mainboard/sifive/hifive-unmatched/board_info.txt b/src/mainboard/sifive/hifive-unmatched/board_info.txt new file mode 100644 index 0000000..e48ba27 --- /dev/null +++ b/src/mainboard/sifive/hifive-unmatched/board_info.txt @@ -0,0 +1,6 @@ +Category: eval +ROM package: SOIC-16 +ROM protocol: SPI +ROM socketed: n +Flashrom support: n +Board URL: https://www.crowdsupply.com/sifive/hifive-unmatched diff --git a/src/mainboard/sifive/hifive-unmatched/cbfs_spi.c b/src/mainboard/sifive/hifive-unmatched/cbfs_spi.c new file mode 100644 index 0000000..122fa80 --- /dev/null +++ b/src/mainboard/sifive/hifive-unmatched/cbfs_spi.c @@ -0,0 +1,171 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +/* + * This file is basically drivers/spi/cbfs_spi.cb but the boot device is not known at build time + */ + +#include <boot_device.h> +#include <cbfs.h> +#include <console/console.h> +#include <device/mmio.h> +#include <lib.h> +#include <soc/addressmap.h> +#include <soc/clock.h> +#include <soc/spi.h> +#include <spi_flash.h> +#include <spi_sdcard.h> +#include <stdint.h> +#include <symbols.h> +#include <timer.h> + +// There are two different means of accessing the SPI flash. +// They are controled by the fctrl register. +// 1. memory mapped access +// 2. FIFO based access + +/* follow is the FSBL boot device defined by ZSBL of sifive + * FSBL replaced by bootblock of coreboot + * MSEL_SPInx1 -> test if boot from memory-mapped on SPIn + * MSEL_SPInx4 -> test if boot from memory-mapped on QPIn + * MSEL_SPInSD -> test if boot from sdcard mount on SPIn */ +#define MSEL_SPI0x1(m) (((m) == 5) || ((m) == 14)) +#define MSEL_SPI0x4(m) (((m) == 6) || ((m) == 10) || ((m) == 15)) +#define MSEL_SPI1x1(m) ((m) == 12) +#define MSEL_SPI1x4(m) (((m) == 7) || ((m) == 13)) +#define MSEL_SPI1SD(m) ((m) == 8) +#define MSEL_SPI2x1(m) ((m) == 9) +#define MSEL_SPI2SD(m) ((m) == 11) + +#define MSEL_ACCESS_METHOD_MMAP(m) ((m == 5) || (m == 6) || (m == 7) || (m == 10) || (m == 13)) + +// probably something for devicetree +struct fu740_spi_config fu740_spi_configs[] = { + { 0 }, + { + .freq = 10*1000*1000, + }, + { 0 }, +}; + +static struct spi_sdcard spi2_sdcard; //TODO initialize SPI2 +//static struct spi_flash spi0_flash; +//static struct spi_flash spi1_flash; +static struct spi_flash spi_flash; +static bool spi_flash_init_done; + +static ssize_t sd_readat(const struct region_device *rdev, void *dest, + size_t offset, size_t count) +{ + spi_sdcard_read(&spi2_sdcard, dest, offset, count); + return count; +} + +static ssize_t spi_readat(const struct region_device *rd, void *b, size_t offset, size_t size) +{ + if (spi_flash_read(&spi_flash, offset, size, b)) + return -1; + return size; +} + +static ssize_t spi_writeat(const struct region_device *rd, const void *b, + size_t offset, size_t size) +{ + if (spi_flash_write(&spi_flash, offset, size, b)) + return -1; + return size; +} + +static ssize_t spi_eraseat(const struct region_device *rd, size_t offset, size_t size) +{ + if (spi_flash_erase(&spi_flash, offset, size)) + return -1; + return size; +} + +static const struct region_device_ops sd_ops = { + .mmap = mmap_helper_rdev_mmap, + .munmap = mmap_helper_rdev_munmap, + .readat = sd_readat, +}; + +static const struct region_device_ops spi_ops = { + .mmap = mmap_helper_rdev_mmap, + .munmap = mmap_helper_rdev_munmap, + .readat = spi_readat, + .writeat = spi_writeat, + .eraseat = spi_eraseat, +}; + +//TODO using postram cache means that all spi transistions are transfered to actual memory. Native memory mapping obviously doesnt have that problem. That can however only happen if memory has been initialized before accessing the boot device. So no CBFS access before boot. +//static struct mem_pool mem_cbfs_cache = +// MEM_POOL_INIT(_postram_cbfs_cache, REGION_SIZE(postram_cbfs_cache), CONFIG_CBFS_CACHE_ALIGN); +//static struct mmap_helper_region_device spi_mdev = +// MMAP_HELPER_DEV_INIT(&spi_ops, 0, CONFIG_ROM_SIZE, &mem_cbfs_cache); + +static struct mmap_helper_region_device spi_mdev = + MMAP_HELPER_DEV_INIT(&spi_ops, 0, CONFIG_ROM_SIZE, &cbfs_cache); + +static struct mmap_helper_region_device sd_mdev = + MMAP_HELPER_DEV_INIT(&sd_ops, 0, CONFIG_ROM_SIZE, &cbfs_cache); + +void boot_device_init(void) +{ + printk(BIOS_DEBUG, "%s 0\n", __func__); + if (spi_flash_init_done == true) + return; + + uint32_t m = read32((uint32_t *)FU740_MSEL); + // Pass the information of the flash read operation to the spi controller + //.pad_cnt = 6, + if (MSEL_SPI0x4(m) || MSEL_SPI1x4(m)) { + //config.ffmt_config.data_proto = FU740_SPI_PROTO_Q; + //config.ffmt_config.cmd_code = 0x6B; // Quad output read + //.cmd_code = 0xec, + } + if (MSEL_SPI1x1(m)) { + printk(BIOS_DEBUG, "%s 1\n", __func__); + fu740_spi_configs[1].ffmt_config.data_proto = FU740_SPI_PROTO_S; + fu740_spi_configs[1].ffmt_config.cmd_code = 0x03; // Normal read + //TODO SPI1x1 is always using programmed IO (FIFO)? (memory map did not work...) + if (spi_flash_probe(1, 0, &spi_flash)) { + printk(BIOS_EMERG, "failed to init SPI flash\n"); + return; + } + // initialize soc spi controller + //if (fu740_spi_setup(&spi1_flash.spi) == -1) { + // printk(BIOS_EMERG, "failed to configure mmap for SPI flash\n"); + //} + //hexdump((void*)0x10041000, 0x100); + //hexdump((void*)0x30000000, 0x100); + printk(BIOS_DEBUG, "%s 2\n", __func__); + } else if (MSEL_SPI2SD(m)) { + spi_sdcard_init(&spi2_sdcard, 2, 0); + } else { + die("Wrong configuration of MSEL\n"); + } + + spi_flash_init_done = true; +} + +/* Return the CBFS boot device. */ +const struct region_device *boot_device_ro(void) +{ + if (spi_flash_init_done != true) + return NULL; + + uint32_t m = read32((uint32_t *)FU740_MSEL); + + if (MSEL_SPI2SD(m) || MSEL_SPI1SD(m)) + return &sd_mdev.rdev; + return &spi_mdev.rdev; +} + +//const struct spi_flash *boot_device_spi_flash(void) +//{ +// boot_device_init(); +// +// if (spi_flash_init_done != true) +// return NULL; +// +// return &spi_flash; +//} diff --git a/src/mainboard/sifive/hifive-unmatched/default.fmd b/src/mainboard/sifive/hifive-unmatched/default.fmd new file mode 100644 index 0000000..322776d --- /dev/null +++ b/src/mainboard/sifive/hifive-unmatched/default.fmd @@ -0,0 +1,7 @@ +FLASH@0 32M { + BIOS@0 32M { + BOOTBLOCK@0 128K + FMAP 512 + COREBOOT(CBFS) + } +} diff --git a/src/mainboard/sifive/hifive-unmatched/devicetree.cb b/src/mainboard/sifive/hifive-unmatched/devicetree.cb new file mode 100644 index 0000000..3d52b54 --- /dev/null +++ b/src/mainboard/sifive/hifive-unmatched/devicetree.cb @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: GPL-2.0-only + +chip soc/sifive/fu740 + device cpu_cluster 0 on end +end diff --git a/src/mainboard/sifive/hifive-unmatched/fixup_fdt.c b/src/mainboard/sifive/hifive-unmatched/fixup_fdt.c new file mode 100644 index 0000000..ed24ee3 --- /dev/null +++ b/src/mainboard/sifive/hifive-unmatched/fixup_fdt.c @@ -0,0 +1,106 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <stdint.h> +#include <stdlib.h> +#include <string.h> +#include <console/console.h> +#include <soc/otp.h> +#include <soc/sdram.h> +#include <cbfs.h> +#include <device_tree.h> +#include <bootstate.h> +#include <mcall.h> + +static void do_fixup_mac(struct device_tree_node *node) +{ + uint32_t serial = otp_read_serial(); + static unsigned char mac[6] = { 0x70, 0xb3, 0xd5, 0x92, 0xf0, 0x00 }; + if (serial != ~0) { + mac[5] |= (serial >> 0) & 0xff; + mac[4] |= (serial >> 8) & 0xff; + mac[3] |= (serial >> 16) & 0xff; + } + dt_add_bin_prop(node, "local-mac-address", mac, 6); +} + +static void fixup_mac(struct device_tree_node *parent) +{ + struct device_tree_property *prop; + const char *name = "local-mac-address"; + + list_for_each(prop, parent->properties, list_node) { + if (!strcmp(name, prop->prop.name)) + do_fixup_mac(parent); + } + + struct device_tree_node *child; + list_for_each(child, parent->children, list_node) { + fixup_mac(child); + } +} + +static void do_fixup_memory(struct device_tree_node *node) +{ + u64 addrs[1], sizes[1]; + addrs[0] = 0x80000000; + sizes[0] = sdram_size(); + dt_add_reg_prop(node, addrs, sizes, 1, 2, 2); +} + +static void fixup_memory(struct device_tree_node *parent) +{ + struct device_tree_property *prop; + const char *name = "device_type"; + const char *value = "memory"; + + list_for_each(prop, parent->properties, list_node) { + if (!strcmp(name, prop->prop.name)) { + if (!strcmp(value, (char *)prop->prop.data)) + do_fixup_memory(parent); + } + } + + struct device_tree_node *child; + list_for_each(child, parent->children, list_node) { + fixup_memory(child); + } +} + +static void fixup_fdt(void *unused) +{ + printk(BIOS_DEBUG, "fix up FDT\n"); + + void *fdt_rom; + struct device_tree *tree; + + /* load flat dt from cbfs */ + fdt_rom = cbfs_map("fallback/DTB", NULL); + + if (fdt_rom == NULL) { + printk(BIOS_ERR, "Unable to load fallback/DTB from CBFS\n"); + return; + } + + /* Expand DT into a tree */ + tree = fdt_unflatten(fdt_rom); + + /* fixup tree */ + fixup_mac(tree->root); + fixup_memory(tree->root); + + /* convert the tree to a flat dt */ + void *dt = malloc(dt_flat_size(tree)); + + if (dt == NULL) { + printk(BIOS_ERR, "Unable to allocate memory for flat device tree\n"); + return; + } + + dt_flatten(tree, dt); + + /* update HLS */ + for (int i = 0; i < CONFIG_MAX_CPUS; i++) + OTHER_HLS(i)->fdt = dt; +} + +BOOT_STATE_INIT_ENTRY(BS_WRITE_TABLES, BS_ON_EXIT, fixup_fdt, NULL); diff --git a/src/mainboard/sifive/hifive-unmatched/fu740-c000.dtsi b/src/mainboard/sifive/hifive-unmatched/fu740-c000.dtsi new file mode 100644 index 0000000..823240c --- /dev/null +++ b/src/mainboard/sifive/hifive-unmatched/fu740-c000.dtsi @@ -0,0 +1,363 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +/dts-v1/; + +/ { + #address-cells = <2>; + #size-cells = <2>; + compatible = "sifive,fu740-c000", "sifive,fu740"; + + aliases { + serial0 = &uart0; + serial1 = &uart1; + ethernet0 = ð0; + }; + + chosen { + }; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + cpu0: cpu@0 { + compatible = "sifive,bullet0", "riscv"; + device_type = "cpu"; + i-cache-block-size = <64>; + i-cache-sets = <128>; + i-cache-size = <16384>; + next-level-cache = <&ccache>; + reg = <0x0>; + riscv,isa = "rv64imac"; + // the S7 core does not support Supervisor mode and has no FPU + status = "disabled"; + cpu0_intc: interrupt-controller { + #interrupt-cells = <1>; + compatible = "riscv,cpu-intc"; + interrupt-controller; + }; + }; + cpu1: cpu@1 { + compatible = "sifive,bullet0", "riscv"; + d-cache-block-size = <64>; + d-cache-sets = <64>; + d-cache-size = <32768>; + d-tlb-sets = <1>; + d-tlb-size = <40>; + device_type = "cpu"; + i-cache-block-size = <64>; + i-cache-sets = <128>; + i-cache-size = <32768>; + i-tlb-sets = <1>; + i-tlb-size = <40>; + mmu-type = "riscv,sv39"; + next-level-cache = <&ccache>; + reg = <0x1>; + riscv,isa = "rv64imafdc"; + tlb-split; + cpu1_intc: interrupt-controller { + #interrupt-cells = <1>; + compatible = "riscv,cpu-intc"; + interrupt-controller; + }; + }; + cpu2: cpu@2 { + compatible = "sifive,bullet0", "riscv"; + d-cache-block-size = <64>; + d-cache-sets = <64>; + d-cache-size = <32768>; + d-tlb-sets = <1>; + d-tlb-size = <40>; + device_type = "cpu"; + i-cache-block-size = <64>; + i-cache-sets = <128>; + i-cache-size = <32768>; + i-tlb-sets = <1>; + i-tlb-size = <40>; + mmu-type = "riscv,sv39"; + next-level-cache = <&ccache>; + reg = <0x2>; + riscv,isa = "rv64imafdc"; + tlb-split; + cpu2_intc: interrupt-controller { + #interrupt-cells = <1>; + compatible = "riscv,cpu-intc"; + interrupt-controller; + }; + }; + cpu3: cpu@3 { + compatible = "sifive,bullet0", "riscv"; + d-cache-block-size = <64>; + d-cache-sets = <64>; + d-cache-size = <32768>; + d-tlb-sets = <1>; + d-tlb-size = <40>; + device_type = "cpu"; + i-cache-block-size = <64>; + i-cache-sets = <128>; + i-cache-size = <32768>; + i-tlb-sets = <1>; + i-tlb-size = <40>; + mmu-type = "riscv,sv39"; + next-level-cache = <&ccache>; + reg = <0x3>; + riscv,isa = "rv64imafdc"; + tlb-split; + cpu3_intc: interrupt-controller { + #interrupt-cells = <1>; + compatible = "riscv,cpu-intc"; + interrupt-controller; + }; + }; + cpu4: cpu@4 { + compatible = "sifive,bullet0", "riscv"; + d-cache-block-size = <64>; + d-cache-sets = <64>; + d-cache-size = <32768>; + d-tlb-sets = <1>; + d-tlb-size = <40>; + device_type = "cpu"; + i-cache-block-size = <64>; + i-cache-sets = <128>; + i-cache-size = <32768>; + i-tlb-sets = <1>; + i-tlb-size = <40>; + mmu-type = "riscv,sv39"; + next-level-cache = <&ccache>; + reg = <0x4>; + riscv,isa = "rv64imafdc"; + tlb-split; + cpu4_intc: interrupt-controller { + #interrupt-cells = <1>; + compatible = "riscv,cpu-intc"; + interrupt-controller; + }; + }; + + cpu-map { + cluster0 { + core0 { + cpu = <&cpu0>; + }; + + core1 { + cpu = <&cpu1>; + }; + + core2 { + cpu = <&cpu2>; + }; + + core3 { + cpu = <&cpu3>; + }; + + core4 { + cpu = <&cpu4>; + }; + }; + }; + }; + soc { + #address-cells = <2>; + #size-cells = <2>; + compatible = "simple-bus"; + ranges; + // clint is mainly used by openSBI and not the OS, since interrupts-extended currently only + // contains machine mode interrupts which the OS will ignore if not running in machine mode + clint: clint@2000000 { + compatible = "riscv,clint0"; + //TODO Add RISCV_M_SOFT_IRQ and RISCV_M_TIME_IRQ macros for better readability + interrupts-extended = <&cpu0_intc 3 &cpu0_intc 7 + &cpu1_intc 3 &cpu1_intc 7 + &cpu2_intc 3 &cpu2_intc 7 + &cpu3_intc 3 &cpu3_intc 7 + &cpu4_intc 3 &cpu4_intc 7>; + reg = <0x0 0x2000000 0x0 0x10000>; + }; + plic0: interrupt-controller@c000000 { + #interrupt-cells = <1>; + #address-cells = <0>; + compatible = "sifive,fu540-c000-plic", "sifive,plic-1.0.0"; + reg = <0x0 0xc000000 0x0 0x4000000>; + riscv,ndev = <69>; + interrupt-controller; + interrupts-extended = + <&cpu0_intc 0xffffffff>, + <&cpu1_intc 0xffffffff>, <&cpu1_intc 9>, + <&cpu2_intc 0xffffffff>, <&cpu2_intc 9>, + <&cpu3_intc 0xffffffff>, <&cpu3_intc 9>, + <&cpu4_intc 0xffffffff>, <&cpu4_intc 9>; + }; + prci: clock-controller@10000000 { + compatible = "sifive,fu740-c000-prci"; + reg = <0x0 0x10000000 0x0 0x1000>; + clocks = <&hfclk>, <&rtcclk>; + #clock-cells = <1>; + #reset-cells = <1>; + }; + uart0: serial@10010000 { + compatible = "sifive,fu740-c000-uart", "sifive,uart0"; + reg = <0x0 0x10010000 0x0 0x1000>; + interrupt-parent = <&plic0>; + interrupts = <39>; + clocks = <&prci 7>; + status = "disabled"; + }; + uart1: serial@10011000 { + compatible = "sifive,fu740-c000-uart", "sifive,uart0"; + reg = <0x0 0x10011000 0x0 0x1000>; + interrupt-parent = <&plic0>; + interrupts = <40>; + clocks = <&prci 7>; + status = "disabled"; + }; + i2c0: i2c@10030000 { + compatible = "sifive,fu740-c000-i2c", "sifive,i2c0"; + reg = <0x0 0x10030000 0x0 0x1000>; + interrupt-parent = <&plic0>; + interrupts = <52>; + clocks = <&prci 7>; + reg-shift = <2>; + reg-io-width = <1>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + i2c1: i2c@10031000 { + compatible = "sifive,fu740-c000-i2c", "sifive,i2c0"; + reg = <0x0 0x10031000 0x0 0x1000>; + interrupt-parent = <&plic0>; + interrupts = <53>; + clocks = <&prci 7>; + reg-shift = <2>; + reg-io-width = <1>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + qspi0: spi@10040000 { + compatible = "sifive,fu740-c000-spi", "sifive,spi0"; + reg = <0x0 0x10040000 0x0 0x1000>, + <0x0 0x20000000 0x0 0x10000000>; + interrupt-parent = <&plic0>; + interrupts = <41>; + clocks = <&prci 7>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + qspi1: spi@10041000 { + compatible = "sifive,fu740-c000-spi", "sifive,spi0"; + reg = <0x0 0x10041000 0x0 0x1000>, + <0x0 0x30000000 0x0 0x10000000>; + interrupt-parent = <&plic0>; + interrupts = <42>; + clocks = <&prci 7>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + spi0: spi@10050000 { + compatible = "sifive,fu740-c000-spi", "sifive,spi0"; + reg = <0x0 0x10050000 0x0 0x1000>; + interrupt-parent = <&plic0>; + interrupts = <43>; + clocks = <&prci 7>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + eth0: ethernet@10090000 { + compatible = "sifive,fu540-c000-gem"; + interrupt-parent = <&plic0>; + interrupts = <55>; + reg = <0x0 0x10090000 0x0 0x2000>, + <0x0 0x100a0000 0x0 0x1000>; + local-mac-address = [00 00 00 00 00 00]; + clock-names = "pclk", "hclk"; + clocks = <&prci 2>, + <&prci 2>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + phandle = <0x13>; //TODO remove + }; + pwm0: pwm@10020000 { + compatible = "sifive,fu740-c000-pwm", "sifive,pwm0"; + reg = <0x0 0x10020000 0x0 0x1000>; + interrupt-parent = <&plic0>; + interrupts = <44>, <45>, <46>, <47>; + clocks = <&prci 7>; + #pwm-cells = <3>; + status = "disabled"; + }; + pwm1: pwm@10021000 { + compatible = "sifive,fu740-c000-pwm", "sifive,pwm0"; + reg = <0x0 0x10021000 0x0 0x1000>; + interrupt-parent = <&plic0>; + interrupts = <48>, <49>, <50>, <51>; + clocks = <&prci 7>; + #pwm-cells = <3>; + status = "disabled"; + }; + ccache: cache-controller@2010000 { + compatible = "sifive,fu740-c000-ccache", "cache"; + cache-block-size = <64>; + cache-level = <2>; + cache-sets = <2048>; + cache-size = <2097152>; + cache-unified; + interrupt-parent = <&plic0>; + interrupts = <19>, <21>, <22>, <20>; + reg = <0x0 0x2010000 0x0 0x1000>; + }; + gpio: gpio@10060000 { + compatible = "sifive,fu740-c000-gpio", "sifive,gpio0"; + interrupt-parent = <&plic0>; + interrupts = <23>, <24>, <25>, <26>, <27>, <28>, <29>, + <30>, <31>, <32>, <33>, <34>, <35>, <36>, + <37>, <38>; + reg = <0x0 0x10060000 0x0 0x1000>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + clocks = <&prci 7>; + status = "disabled"; + }; + pcie@e00000000 { + compatible = "sifive,fu740-pcie"; + #address-cells = <3>; + #size-cells = <2>; + #interrupt-cells = <1>; + reg = <0xe 0x00000000 0x0 0x80000000>, + <0xd 0xf0000000 0x0 0x10000000>, + <0x0 0x100d0000 0x0 0x1000>; + reg-names = "dbi", "config", "mgmt"; + device_type = "pci"; + dma-coherent; + bus-range = <0x0 0xff>; + //TODO + //ranges = <0x81000000 0x0 0x60080000 0x0 0x60080000 0x0 0x10000>, /* I/O */ + // <0x82000000 0x0 0x60090000 0x0 0x60090000 0x0 0xff70000>, /* mem */ + // <0x82000000 0x0 0x70000000 0x0 0x70000000 0x0 0x1000000>, /* mem */ + // <0xc3000000 0x20 0x00000000 0x20 0x00000000 0x20 0x00000000>; /* mem prefetchable */ + ranges = <0x81000000 0x00 0x60080000 0x00 0x60080000 0x00 0x10000 0x82000000 0x00 0x60090000 0x00 0x60090000 0x00 0xff70000 0x82000000 0x00 0x70000000 0x00 0x70000000 0x00 0x10000000 0xc3000000 0x20 0x00 0x20 0x00 0x20 0x00>; + num-lanes = <0x8>; + interrupts = <56>, <57>, <58>, <59>, <60>, <61>, <62>, <63>, <64>; + interrupt-names = "msi", "inta", "intb", "intc", "intd"; + interrupt-parent = <&plic0>; + interrupt-map-mask = <0x0 0x0 0x0 0x7>; + interrupt-map = <0x0 0x0 0x0 0x1 &plic0 57>, + <0x0 0x0 0x0 0x2 &plic0 58>, + <0x0 0x0 0x0 0x3 &plic0 59>, + <0x0 0x0 0x0 0x4 &plic0 60>; + clock-names = "pcie_aux"; + clocks = <&prci 8>; + pwren-gpios = <&gpio 5 0>; + reset-gpios = <&gpio 8 0>; + resets = <&prci 4>; + status = "okay"; + }; + }; +}; diff --git a/src/mainboard/sifive/hifive-unmatched/hifive-unmatched-a00-mod.dts b/src/mainboard/sifive/hifive-unmatched/hifive-unmatched-a00-mod.dts new file mode 100644 index 0000000..715ec1b --- /dev/null +++ b/src/mainboard/sifive/hifive-unmatched/hifive-unmatched-a00-mod.dts @@ -0,0 +1,232 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +/include/ "fu740-c000.dtsi" + +/ { + model = "SiFive HiFive Unmatched A00"; + compatible = "sifive,hifive-unmatched-a00", "sifive,fu740-c000", "sifive,fu740"; + + cpus { + //TODO replace with CLOCK_FREQUENCY macro that is used in both code and here to have a single source of truth + timebase-frequency = <1000000>; + }; + + memory@80000000 { + device_type = "memory"; + reg = <0x0 0x80000000 0x4 0x00000000>; + }; + + hfclk: hfclk { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <26000000>; + clock-output-names = "hfclk"; + }; + + rtcclk: rtcclk { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <1000000>; + clock-output-names = "rtcclk"; + }; +}; + +&uart0 { + status = "okay"; +}; + +&uart1 { + status = "okay"; +}; + +&i2c0 { + status = "okay"; + + temperature-sensor@4c { + compatible = "ti,tmp451"; + reg = <0x4c>; + vcc-supply = <&vdd_bpro>; + interrupt-parent = <&gpio>; + interrupts = <6 8>; + }; + + eeprom@54 { + compatible = "microchip,24c02", "atmel,24c02"; + reg = <0x54>; + label = "board-id"; + vcc-supply = <0x10>; + pagesize = <16>; + read-only; + size = <256>; + }; + + pmic@58 { + compatible = "dlg,da9063"; + reg = <0x58>; + interrupt-parent = <&gpio>; + interrupts = <1 8>; + interrupt-controller; + + onkey { + compatible = "dlg,da9063-onkey"; + }; + + rtc { + compatible = "dlg,da9063-rtc"; + }; + + watchdog { + compatible = "dlg,da9063-watchdog"; + }; + + regulators { + vdd_bcore: bcores-merged { + regulator-min-microvolt = <1050000>; + regulator-max-microvolt = <1050000>; + regulator-min-microamp = <4800000>; + regulator-max-microamp = <4800000>; + regulator-always-on; + }; + + vdd_bpro: bpro { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-min-microamp = <2400000>; + regulator-max-microamp = <2400000>; + regulator-always-on; + }; + + vdd_bperi: bperi { + regulator-min-microvolt = <1060000>; + regulator-max-microvolt = <1060000>; + regulator-min-microamp = <1500000>; + regulator-max-microamp = <1500000>; + regulator-always-on; + }; + + vdd_bmem_bio: bmem-bio-merged { + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-min-microamp = <3000000>; + regulator-max-microamp = <3000000>; + regulator-always-on; + }; + + vdd_ldo1: ldo1 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + }; + + vdd_ldo2: ldo2 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + }; + + vdd_ldo3: ldo3 { + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + + vdd_ldo4: ldo4 { + regulator-min-microvolt = <2500000>; + regulator-max-microvolt = <2500000>; + regulator-always-on; + }; + + vdd_ldo5: ldo5 { + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + + vdd_ldo6: ldo6 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + }; + + vdd_ldo7: ldo7 { + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + + vdd_ldo8: ldo8 { + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + + vdd_ld09: ldo9 { + regulator-min-microvolt = <1050000>; + regulator-max-microvolt = <1050000>; + regulator-always-on; + }; + + vdd_ldo10: ldo10 { + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1000000>; + regulator-always-on; + }; + + vdd_ldo11: ldo11 { + regulator-min-microvolt = <2500000>; + regulator-max-microvolt = <2500000>; + regulator-always-on; + }; + }; + }; + +}; + +&qspi0 { + status = "okay"; + flash@0 { + compatible = "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <50000000>; + m25p,fast-read; + spi-tx-bus-width = <4>; + spi-rx-bus-width = <4>; + }; +}; + +&spi0 { + status = "okay"; + mmc@0 { + compatible = "mmc-spi-slot"; + reg = <0>; + spi-max-frequency = <20000000>; + voltage-ranges = <3300 3300>; + disable-wp; + gpios = <0x11 0x0f 0x01>; + }; +}; + +ð0 { + status = "okay"; + phy-mode = "gmii"; + phy-handle = <&phy0>; + phy0: ethernet-phy@0 { + reg = <0>; + }; +}; + +&pwm0 { + status = "okay"; +}; + +&pwm1 { + status = "okay"; +}; + +&gpio { + status = "okay"; + gpio-line-names = "J29.1", "PMICNTB", "PMICSHDN", "J8.1", "J8.3", + "PCIe_PWREN", "THERM", "UBRDG_RSTN", "PCIe_PERSTN", + "ULPI_RSTN", "J8.2", "UHUB_RSTN", "GEMGXL_RST", "J8.4", + "EN_VDD_SD", "SD_CD"; +}; diff --git a/src/mainboard/sifive/hifive-unmatched/hifive-unmatched-a00.dts b/src/mainboard/sifive/hifive-unmatched/hifive-unmatched-a00.dts new file mode 100644 index 0000000..82b5830 --- /dev/null +++ b/src/mainboard/sifive/hifive-unmatched/hifive-unmatched-a00.dts @@ -0,0 +1,230 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +/include/ "fu740-c000.dtsi" + +/ { + model = "SiFive HiFive Unmatched A00"; + compatible = "sifive,hifive-unmatched-a00", "sifive,fu740-c000", "sifive,fu740"; + + cpus { + //TODO replace with CLOCK_FREQUENCY macro that is used in both code and here to have a single source of truth + timebase-frequency = <1000000>; + }; + + memory@80000000 { + device_type = "memory"; + reg = <0x0 0x80000000 0x4 0x00000000>; + }; + + hfclk: hfclk { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <26000000>; + clock-output-names = "hfclk"; + }; + + rtcclk: rtcclk { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <1000000>; + clock-output-names = "rtcclk"; + }; +}; + +&uart0 { + status = "okay"; +}; + +&uart1 { + status = "okay"; +}; + +&i2c0 { + status = "okay"; + + temperature-sensor@4c { + compatible = "ti,tmp451"; + reg = <0x4c>; + vcc-supply = <&vdd_bpro>; + interrupt-parent = <&gpio>; + interrupts = <6 3>; + }; + + eeprom@54 { + compatible = "microchip,24c02", "atmel,24c02"; + reg = <0x54>; + label = "board-id"; + pagesize = <16>; + read-only; + size = <256>; + }; + + pmic@58 { + compatible = "dlg,da9063"; + reg = <0x58>; + interrupt-parent = <&gpio>; + interrupts = <1 3>; + interrupt-controller; + + onkey { + compatible = "dlg,da9063-onkey"; + }; + + rtc { + compatible = "dlg,da9063-rtc"; + }; + + watchdog { + compatible = "dlg,da9063-watchdog"; + }; + + regulators { + vdd_bcore: bcores-merged { + regulator-min-microvolt = <1050000>; + regulator-max-microvolt = <1050000>; + regulator-min-microamp = <4800000>; + regulator-max-microamp = <4800000>; + regulator-always-on; + }; + + vdd_bpro: bpro { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-min-microamp = <2400000>; + regulator-max-microamp = <2400000>; + regulator-always-on; + }; + + vdd_bperi: bperi { + regulator-min-microvolt = <1060000>; + regulator-max-microvolt = <1060000>; + regulator-min-microamp = <1500000>; + regulator-max-microamp = <1500000>; + regulator-always-on; + }; + + vdd_bmem_bio: bmem-bio-merged { + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-min-microamp = <3000000>; + regulator-max-microamp = <3000000>; + regulator-always-on; + }; + + vdd_ldo1: ldo1 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + }; + + vdd_ldo2: ldo2 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + }; + + vdd_ldo3: ldo3 { + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + + vdd_ldo4: ldo4 { + regulator-min-microvolt = <2500000>; + regulator-max-microvolt = <2500000>; + regulator-always-on; + }; + + vdd_ldo5: ldo5 { + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + + vdd_ldo6: ldo6 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + }; + + vdd_ldo7: ldo7 { + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + + vdd_ldo8: ldo8 { + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + + vdd_ld09: ldo9 { + regulator-min-microvolt = <1050000>; + regulator-max-microvolt = <1050000>; + regulator-always-on; + }; + + vdd_ldo10: ldo10 { + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1000000>; + regulator-always-on; + }; + + vdd_ldo11: ldo11 { + regulator-min-microvolt = <2500000>; + regulator-max-microvolt = <2500000>; + regulator-always-on; + }; + }; + }; + +}; + +&qspi0 { + status = "okay"; + flash@0 { + compatible = "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <50000000>; + m25p,fast-read; + spi-tx-bus-width = <4>; + spi-rx-bus-width = <4>; + }; +}; + +&spi0 { + status = "okay"; + mmc@0 { + compatible = "mmc-spi-slot"; + reg = <0>; + spi-max-frequency = <20000000>; + voltage-ranges = <3300 3300>; + disable-wp; + }; +}; + +ð0 { + status = "okay"; + phy-mode = "gmii"; + phy-handle = <&phy0>; + phy0: ethernet-phy@0 { + reg = <0>; + }; +}; + +&pwm0 { + status = "okay"; +}; + +&pwm1 { + status = "okay"; +}; + +&gpio { + status = "okay"; + gpio-line-names = "J29.1", "PMICNTB", "PMICSHDN", "J8.1", "J8.3", + "PCIe_PWREN", "THERM", "UBRDG_RSTN", "PCIe_PERSTN", + "ULPI_RSTN", "J8.2", "UHUB_RSTN", "GEMGXL_RST", "J8.4", + "EN_VDD_SD", "SD_CD"; +}; diff --git a/src/mainboard/sifive/hifive-unmatched/mainboard.c b/src/mainboard/sifive/hifive-unmatched/mainboard.c new file mode 100644 index 0000000..2b4c659 --- /dev/null +++ b/src/mainboard/sifive/hifive-unmatched/mainboard.c @@ -0,0 +1,11 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <device/device.h> + +static void mainboard_enable(struct device *dev) +{ +} + +struct chip_operations mainboard_ops = { + .enable_dev = mainboard_enable, +}; diff --git a/src/mainboard/sifive/hifive-unmatched/romstage.c b/src/mainboard/sifive/hifive-unmatched/romstage.c new file mode 100644 index 0000000..edab59f --- /dev/null +++ b/src/mainboard/sifive/hifive-unmatched/romstage.c @@ -0,0 +1,74 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <boot/tables.h> // write_tables() +#include <cbmem.h> +#include <console/console.h> +#include <console/streams.h> +#include <console/uart.h> +#include <hardwaremain.h> +#include <program_loading.h> +#include <soc/clock.h> +#include <soc/sdram.h> +#include <symbols.h> // _dram symbol +#include <mcall.h> // HLS() +#include <lib.h> // hexdump +#include <device_tree.h> // fdt_unflatten +#include <cbfs.h> // cbfs_map +#include <arch/encoding.h> // write_csr +#include <soc/gpio.h> // gpio_init +#include <delay.h> +#include <romstage_common.h> +#include <soc/addressmap.h> + +void __noreturn romstage_main(void) +{ + //TODO see if it makes any difference and check doc +#define CSR_U74_FEATURE_DISABLE 0x7c1 + write_csr(0x7c1, 0); + + console_init(); + + clock_init(); + //delay(2); //TODO see if that works or if we need to put it below uart_init? Maybe uart_init is just taking too long? + + if (CONFIG(CONSOLE_SERIAL)) + uart_init(get_uart_for_console()); + + printk(BIOS_SPEW, "%s: after uart_init\n", __func__); + //delay(2); //TODO see if that works or if we need to put it below uart_init? Maybe uart_init is just taking too long? + + if (get_log_level() == BIOS_SPEW) { + // print FDT supplied by ROM code + // /TODO in order to unflatten the fdt from zsbl I need malloc. But malloc currently is tied to the heap which in turn is tied to actual dram. For testing use cbfs_cache as backend for malloc to circuimvent this (works suprisingly flawless). //TODO maybe just add romstage to ENV_HAS_HEAP + //printk(BIOS_SPEW, "fdt: %p\n", HLS()->fdt); + //struct device_tree *tree = fdt_unflatten(HLS()->fdt); + //dt_print_node(tree->root); + } + +#define DDR_SIZE (16UL * 1024UL * 1024UL * 1024UL) + //TODO test if the common version works + //sdram_init((u32 *)FU740_DDRCTRL, (u64 *)FU740_PHYSICAL_FILTER, FU740_DRAM, DDR_SIZE); + sdram_init(); + + cbmem_initialize_empty(); + + // need to setup devices because bootmem will get the memory ranges by enemurating the devices + + // Schedule the static boot state entries. + //boot_state_schedule_static_entries(); + + //bs_walk_state_machine(); + + //die("Boot state machine failure.\n"); + + //// write_tables will set up bootmem which is needed for payload_load() to figure out where it is allowed to place the payload + //write_tables(); + + //bootmem_dump_ranges(); + //printk(BIOS_DEBUG, "%s: 1", __func__); + //payload_load(); + //bootmem_dump_ranges(); + //printk(BIOS_DEBUG, "%s: 2", __func__); + //payload_run(); + run_ramstage(); +}