lib/smbios: Improve Type9
[coreboot2.git] / src / drivers / spi / cbfs_spi.c
blob15a18b72e4e9c41a232c78eddd6503895377c32e
1 /* SPDX-License-Identifier: GPL-2.0-only */
3 /*
4 * This file provides a common CBFS wrapper for SPI storage. SPI driver
5 * context is expanded with the buffer descriptor used to store data read from
6 * SPI.
7 */
9 #include <boot_device.h>
10 #include <cbfs.h>
11 #include <console/console.h>
12 #include <spi_flash.h>
13 #include <symbols.h>
14 #include <stdint.h>
15 #include <timer.h>
17 static struct spi_flash spi_flash_info;
18 static bool spi_flash_init_done;
21 * SPI speed logging for big transfers available with BIOS_DEBUG. The format is:
23 * read SPI 0x62854 0x7db7: 10416 us, 3089 KB/s, 24.712 Mbps
25 * The important number is the last one. It should roughly match your SPI
26 * clock. If it doesn't, your driver might need a little tuning.
28 static ssize_t spi_readat(const struct region_device *rd, void *b,
29 size_t offset, size_t size)
31 struct stopwatch sw;
32 bool show = size >= 4 * KiB && console_log_level(BIOS_DEBUG);
34 if (show)
35 stopwatch_init(&sw);
36 if (spi_flash_read(&spi_flash_info, offset, size, b))
37 return -1;
38 if (show) {
39 long usecs;
41 usecs = stopwatch_duration_usecs(&sw);
42 u64 speed; /* KiB/s */
43 int bps; /* Bits per second */
45 speed = size * (u64)1000 / usecs;
46 bps = speed * 8;
48 printk(BIOS_DEBUG, "read SPI %#zx %#zx: %ld us, %lld KB/s, %d.%03d Mbps\n",
49 offset, size, usecs, speed, bps / 1000, bps % 1000);
51 return size;
54 static ssize_t spi_writeat(const struct region_device *rd, const void *b,
55 size_t offset, size_t size)
57 if (spi_flash_write(&spi_flash_info, offset, size, b))
58 return -1;
59 return size;
62 static ssize_t spi_eraseat(const struct region_device *rd,
63 size_t offset, size_t size)
65 if (spi_flash_erase(&spi_flash_info, offset, size))
66 return -1;
67 return size;
70 /* Provide all operations on the same device. */
71 static const struct region_device_ops spi_ops = {
72 .mmap = mmap_helper_rdev_mmap,
73 .munmap = mmap_helper_rdev_munmap,
74 .readat = spi_readat,
75 .writeat = spi_writeat,
76 .eraseat = spi_eraseat,
79 static struct mmap_helper_region_device mdev =
80 MMAP_HELPER_DEV_INIT(&spi_ops, 0, CONFIG_ROM_SIZE, &cbfs_cache);
82 void boot_device_init(void)
84 int bus = CONFIG_BOOT_DEVICE_SPI_FLASH_BUS;
85 int cs = 0;
87 if (spi_flash_init_done == true)
88 return;
90 if (spi_flash_probe(bus, cs, &spi_flash_info))
91 return;
93 spi_flash_init_done = true;
96 /* Return the CBFS boot device. */
97 const struct region_device *boot_device_ro(void)
99 if (spi_flash_init_done != true)
100 return NULL;
102 return &mdev.rdev;
105 /* The read-only and read-write implementations are symmetric. */
106 const struct region_device *boot_device_rw(void)
108 return boot_device_ro();
111 const struct spi_flash *boot_device_spi_flash(void)
113 boot_device_init();
115 if (spi_flash_init_done != true)
116 return NULL;
118 return &spi_flash_info;