| /* SPDX-License-Identifier: GPL-2.0-only */ |
| /* This file is part of the coreboot project. */ |
| |
| #include <boot_device.h> |
| #include <symbols.h> |
| #include <cbfs.h> |
| #include <device/mmio.h> |
| #include <soc/addressmap.h> |
| #include <soc/spi.h> |
| #include <soc/clock.h> |
| #include <console/console.h> |
| #include <spi_sdcard.h> |
| |
| /* 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) |
| |
| static struct spi_sdcard card; |
| |
| /* At 0x20000000: A 256MiB long memory-mapped view of the flash at QSPI0 */ |
| static struct mem_region_device spi_mdev = |
| MEM_REGION_DEV_RO_INIT((void *)0x20000000, CONFIG_ROM_SIZE); |
| |
| static ssize_t unleashed_sd_readat(const struct region_device *rdev, void *dest, |
| size_t offset, size_t count) |
| { |
| spi_sdcard_read(&card, dest, offset, count); |
| return count; |
| } |
| |
| static const struct region_device_ops unleashed_sd_ops = { |
| .mmap = mmap_helper_rdev_mmap, |
| .munmap = mmap_helper_rdev_munmap, |
| .readat = unleashed_sd_readat, |
| }; |
| |
| |
| static struct mmap_helper_region_device sd_mdev = |
| MMAP_HELPER_REGION_INIT(&unleashed_sd_ops, 0, CONFIG_ROM_SIZE); |
| |
| const struct region_device *boot_device_ro(void) |
| { |
| uint32_t m = read32((uint32_t *)FU540_MSEL); |
| if (MSEL_SPI0x1(m) || MSEL_SPI0x4(m)) |
| return &spi_mdev.rdev; |
| if (MSEL_SPI2SD(m)) |
| return &sd_mdev.rdev; |
| die("Wrong configuration of MSEL\n"); |
| return NULL; |
| } |
| |
| const static struct fu540_spi_mmap_config spi_mmap_config = { |
| .cmd_en = 1, |
| .addr_len = 4, |
| .pad_cnt = 6, |
| .cmd_proto = FU540_SPI_PROTO_S, |
| .addr_proto = FU540_SPI_PROTO_Q, |
| .data_proto = FU540_SPI_PROTO_Q, |
| .cmd_code = 0xec, |
| .pad_code = 0 |
| }; |
| |
| void boot_device_init(void) |
| { |
| uint32_t m = read32((uint32_t *)FU540_MSEL); |
| if (MSEL_SPI0x1(m) || MSEL_SPI0x4(m)) { |
| struct spi_slave slave; |
| /* initialize spi controller */ |
| spi_setup_slave(0, 0, &slave); |
| /* map flash to memory space */ |
| fu540_spi_mmap(&slave, &spi_mmap_config); |
| return; |
| } |
| if (MSEL_SPI2SD(m)) { |
| spi_sdcard_init(&card, 2, 0); |
| mmap_helper_device_init(&sd_mdev, |
| _cbfs_cache, REGION_SIZE(cbfs_cache)); |
| return; |
| } |
| die("Wrong configuration of MSEL\n"); |
| } |