[U-Boot] [PATCH v2 14/38] spi: Add support for memory-mapped flash

Simon Glass sjg at chromium.org
Wed Sep 25 14:11:23 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>
---

Changes in v2: None

 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 43d8907710c..fb515edcb7c 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 719a2fd23ae..127ec7e7aa6 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 55b4721813a..840189e22c7 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 56277954c23..f8f9e717720 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.444.g18eeb5a265-goog



More information about the U-Boot mailing list