Angel Pons | 274a037 | 2020-04-03 01:23:27 +0200 | [diff] [blame] | 1 | /* SPDX-License-Identifier: GPL-2.0-only */ |
Jonathan Neuschäfer | 55b4645 | 2018-04-19 16:23:54 +0200 | [diff] [blame] | 2 | |
| 3 | #include <boot_device.h> |
Julius Werner | 9b1f3cc | 2020-12-30 17:30:12 -0800 | [diff] [blame] | 4 | #include <cbfs.h> |
Xiang Wang | d577726 | 2019-08-27 16:04:54 +0800 | [diff] [blame] | 5 | #include <symbols.h> |
Julius Werner | 55009af | 2019-12-02 22:03:27 -0800 | [diff] [blame] | 6 | #include <device/mmio.h> |
Xiang Wang | d577726 | 2019-08-27 16:04:54 +0800 | [diff] [blame] | 7 | #include <soc/addressmap.h> |
Xiang Wang | f4e1583 | 2019-05-29 15:39:48 +0800 | [diff] [blame] | 8 | #include <soc/spi.h> |
Xiang Wang | d577726 | 2019-08-27 16:04:54 +0800 | [diff] [blame] | 9 | #include <soc/clock.h> |
| 10 | #include <console/console.h> |
| 11 | #include <spi_sdcard.h> |
| 12 | |
| 13 | /* follow is the FSBL boot device defined by ZSBL of sifive |
| 14 | * FSBL replaced by bootblock of coreboot |
| 15 | * MSEL_SPInx1 -> test if boot from memory-mapped on SPIn |
| 16 | * MSEL_SPInx4 -> test if boot from memory-mapped on QPIn |
| 17 | * MSEL_SPInSD -> test if boot from sdcard mount on SPIn */ |
| 18 | #define MSEL_SPI0x1(m) (((m) == 5) || ((m) == 14)) |
| 19 | #define MSEL_SPI0x4(m) (((m) == 6) || ((m) == 10) || ((m) == 15)) |
| 20 | #define MSEL_SPI1x1(m) ((m) == 12) |
| 21 | #define MSEL_SPI1x4(m) (((m) == 7) || ((m) == 13)) |
| 22 | #define MSEL_SPI1SD(m) ((m) == 8) |
| 23 | #define MSEL_SPI2x1(m) ((m) == 9) |
| 24 | #define MSEL_SPI2SD(m) ((m) == 11) |
| 25 | |
| 26 | static struct spi_sdcard card; |
Jonathan Neuschäfer | 55b4645 | 2018-04-19 16:23:54 +0200 | [diff] [blame] | 27 | |
| 28 | /* At 0x20000000: A 256MiB long memory-mapped view of the flash at QSPI0 */ |
Xiang Wang | d577726 | 2019-08-27 16:04:54 +0800 | [diff] [blame] | 29 | static struct mem_region_device spi_mdev = |
Jonathan Neuschäfer | 55b4645 | 2018-04-19 16:23:54 +0200 | [diff] [blame] | 30 | MEM_REGION_DEV_RO_INIT((void *)0x20000000, CONFIG_ROM_SIZE); |
| 31 | |
Xiang Wang | d577726 | 2019-08-27 16:04:54 +0800 | [diff] [blame] | 32 | static ssize_t unleashed_sd_readat(const struct region_device *rdev, void *dest, |
| 33 | size_t offset, size_t count) |
| 34 | { |
| 35 | spi_sdcard_read(&card, dest, offset, count); |
| 36 | return count; |
| 37 | } |
| 38 | |
| 39 | static const struct region_device_ops unleashed_sd_ops = { |
| 40 | .mmap = mmap_helper_rdev_mmap, |
| 41 | .munmap = mmap_helper_rdev_munmap, |
| 42 | .readat = unleashed_sd_readat, |
| 43 | }; |
| 44 | |
Xiang Wang | d577726 | 2019-08-27 16:04:54 +0800 | [diff] [blame] | 45 | static struct mmap_helper_region_device sd_mdev = |
Julius Werner | 9b1f3cc | 2020-12-30 17:30:12 -0800 | [diff] [blame] | 46 | MMAP_HELPER_DEV_INIT(&unleashed_sd_ops, 0, CONFIG_ROM_SIZE, &cbfs_cache); |
Xiang Wang | d577726 | 2019-08-27 16:04:54 +0800 | [diff] [blame] | 47 | |
Jonathan Neuschäfer | 55b4645 | 2018-04-19 16:23:54 +0200 | [diff] [blame] | 48 | const struct region_device *boot_device_ro(void) |
| 49 | { |
Xiang Wang | d577726 | 2019-08-27 16:04:54 +0800 | [diff] [blame] | 50 | uint32_t m = read32((uint32_t *)FU540_MSEL); |
| 51 | if (MSEL_SPI0x1(m) || MSEL_SPI0x4(m)) |
| 52 | return &spi_mdev.rdev; |
| 53 | if (MSEL_SPI2SD(m)) |
| 54 | return &sd_mdev.rdev; |
| 55 | die("Wrong configuration of MSEL\n"); |
| 56 | return NULL; |
Jonathan Neuschäfer | 55b4645 | 2018-04-19 16:23:54 +0200 | [diff] [blame] | 57 | } |
Xiang Wang | f4e1583 | 2019-05-29 15:39:48 +0800 | [diff] [blame] | 58 | |
| 59 | const static struct fu540_spi_mmap_config spi_mmap_config = { |
| 60 | .cmd_en = 1, |
| 61 | .addr_len = 4, |
| 62 | .pad_cnt = 6, |
| 63 | .cmd_proto = FU540_SPI_PROTO_S, |
| 64 | .addr_proto = FU540_SPI_PROTO_Q, |
| 65 | .data_proto = FU540_SPI_PROTO_Q, |
| 66 | .cmd_code = 0xec, |
| 67 | .pad_code = 0 |
| 68 | }; |
| 69 | |
| 70 | void boot_device_init(void) |
| 71 | { |
Xiang Wang | d577726 | 2019-08-27 16:04:54 +0800 | [diff] [blame] | 72 | uint32_t m = read32((uint32_t *)FU540_MSEL); |
| 73 | if (MSEL_SPI0x1(m) || MSEL_SPI0x4(m)) { |
| 74 | struct spi_slave slave; |
| 75 | /* initialize spi controller */ |
| 76 | spi_setup_slave(0, 0, &slave); |
| 77 | /* map flash to memory space */ |
| 78 | fu540_spi_mmap(&slave, &spi_mmap_config); |
| 79 | return; |
| 80 | } |
| 81 | if (MSEL_SPI2SD(m)) { |
| 82 | spi_sdcard_init(&card, 2, 0); |
Xiang Wang | d577726 | 2019-08-27 16:04:54 +0800 | [diff] [blame] | 83 | return; |
| 84 | } |
| 85 | die("Wrong configuration of MSEL\n"); |
Xiang Wang | f4e1583 | 2019-05-29 15:39:48 +0800 | [diff] [blame] | 86 | } |