[U-Boot] [PATCH 14/38] spi: Add support for memory-mapped flash
Simon Glass
sjg at chromium.org
Mon Aug 26 15:59:19 UTC 2019
On x86 platforms the SPI flash can be mapped into memory so that the
contents can be read with normal memory accesses.
Add a new SPI flash method to find the location of the SPI flash in
memory. This differs from the existing device-tree "memory-map" mechanism
in that the location can be discovered at run-time.
Signed-off-by: Simon Glass <sjg at chromium.org>
---
drivers/mtd/spi/sandbox_direct.c | 11 +++++++++++
drivers/mtd/spi/sf-uclass.c | 11 +++++++++++
include/spi_flash.h | 27 +++++++++++++++++++++++++++
test/dm/sf.c | 9 +++++++++
4 files changed, 58 insertions(+)
diff --git a/drivers/mtd/spi/sandbox_direct.c b/drivers/mtd/spi/sandbox_direct.c
index 43d8907710..fb515edcb7 100644
--- a/drivers/mtd/spi/sandbox_direct.c
+++ b/drivers/mtd/spi/sandbox_direct.c
@@ -68,6 +68,16 @@ static int sandbox_direct_get_sw_write_prot(struct udevice *dev)
return priv->write_prot++ ? 1 : 0;
}
+static int sandbox_direct_get_mmap(struct udevice *dev, ulong *map_basep,
+ size_t *map_sizep, u32 *offsetp)
+{
+ *map_basep = 0x1000;
+ *map_sizep = 0x2000;
+ *offsetp = 0x100;
+
+ return 0;
+}
+
static int sandbox_direct_probe(struct udevice *dev)
{
struct sandbox_direct_priv *priv = dev_get_priv(dev);
@@ -82,6 +92,7 @@ static struct dm_spi_flash_ops sandbox_direct_ops = {
.write = sandbox_direct_write,
.erase = sandbox_direct_erase,
.get_sw_write_prot = sandbox_direct_get_sw_write_prot,
+ .get_mmap = sandbox_direct_get_mmap,
};
static const struct udevice_id sandbox_direct_ids[] = {
diff --git a/drivers/mtd/spi/sf-uclass.c b/drivers/mtd/spi/sf-uclass.c
index 719a2fd23a..127ec7e7aa 100644
--- a/drivers/mtd/spi/sf-uclass.c
+++ b/drivers/mtd/spi/sf-uclass.c
@@ -28,6 +28,17 @@ int spi_flash_erase_dm(struct udevice *dev, u32 offset, size_t len)
return log_ret(sf_get_ops(dev)->erase(dev, offset, len));
}
+int spi_flash_get_mmap(struct udevice *dev, ulong *map_basep, size_t *map_sizep,
+ u32 *offsetp)
+{
+ struct dm_spi_flash_ops *ops = sf_get_ops(dev);
+
+ if (!ops->get_mmap)
+ return -ENOSYS;
+
+ return ops->get_mmap(dev, map_basep, map_sizep, offsetp);
+}
+
int spl_flash_get_sw_write_prot(struct udevice *dev)
{
struct dm_spi_flash_ops *ops = sf_get_ops(dev);
diff --git a/include/spi_flash.h b/include/spi_flash.h
index 55b4721813..840189e22c 100644
--- a/include/spi_flash.h
+++ b/include/spi_flash.h
@@ -47,6 +47,19 @@ struct dm_spi_flash_ops {
* other -ve value on error
*/
int (*get_sw_write_prot)(struct udevice *dev);
+
+ /**
+ * get_mmap() - Get memory-mapped SPI
+ *
+ * @dev: SPI flash device
+ * @map_basep: Returns base memory address for mapped SPI
+ * @map_sizep: Returns size of mapped SPI
+ * @offsetp: Returns start offset of SPI flash where the map works
+ * correctly (offsets before this are not visible)
+ * @return 0 if OK, -EFAULT if memory mapping is not available
+ */
+ int (*get_mmap)(struct udevice *dev, ulong *map_basep,
+ size_t *map_sizep, u32 *offsetp);
};
/* Access the serial operations for a device */
@@ -88,6 +101,20 @@ int spi_flash_write_dm(struct udevice *dev, u32 offset, size_t len,
*/
int spi_flash_erase_dm(struct udevice *dev, u32 offset, size_t len);
+/**
+ * spi_flash_get_mmap() - Get memory-mapped SPI
+ *
+ * @dev: SPI flash device
+ * @map_basep: Returns base memory address for mapped SPI
+ * @map_sizep: Returns size of mapped SPI
+ * @offsetp: Returns start offset of SPI flash where the map works
+ * correctly (offsets before this are not visible)
+ * @return 0 if OK, -ENOSYS if no operation, -EFAULT if memory mapping is not
+ * available
+ */
+int spi_flash_get_mmap(struct udevice *dev, ulong *map_basep, size_t *map_sizep,
+ u32 *offsetp);
+
/**
* spl_flash_get_sw_write_prot() - Check state of software write-protect feature
*
diff --git a/test/dm/sf.c b/test/dm/sf.c
index 56277954c2..f8f9e71772 100644
--- a/test/dm/sf.c
+++ b/test/dm/sf.c
@@ -102,6 +102,9 @@ static int dm_test_spi_flash_direct(struct unit_test_state *uts)
{
struct udevice *dev;
char buf[BUF_SIZE];
+ size_t map_size;
+ ulong map_base;
+ u32 offset;
int i;
ut_assertok(uclass_get_device(UCLASS_SPI_FLASH, 1, &dev));
@@ -130,6 +133,12 @@ static int dm_test_spi_flash_direct(struct unit_test_state *uts)
ut_asserteq(0, spl_flash_get_sw_write_prot(dev));
ut_asserteq(1, spl_flash_get_sw_write_prot(dev));
+ /* Check mapping */
+ ut_assertok(spi_flash_get_mmap(dev, &map_base, &map_size, &offset));
+ ut_asserteq(0x1000, map_base);
+ ut_asserteq(0x2000, map_size);
+ ut_asserteq(0x100, offset);
+
return 0;
}
DM_TEST(dm_test_spi_flash_direct, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
--
2.23.0.187.g17f5b7556c-goog
More information about the U-Boot
mailing list