[U-Boot] [PATCH v3 014/108] spi: Add support for memory-mapped flash
Simon Glass
sjg at chromium.org
Mon Oct 21 03:31:47 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 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 v3:
- Move the get_mmap() method from the SPI_FLASH to the SPI uclass
Changes in v2: None
drivers/spi/sandbox_spi.c | 11 +++++++++++
drivers/spi/spi-uclass.c | 14 ++++++++++++++
include/spi.h | 27 +++++++++++++++++++++++++++
test/dm/sf.c | 9 +++++++++
4 files changed, 61 insertions(+)
diff --git a/drivers/spi/sandbox_spi.c b/drivers/spi/sandbox_spi.c
index 906401ec8ab..cefe2ed9a37 100644
--- a/drivers/spi/sandbox_spi.c
+++ b/drivers/spi/sandbox_spi.c
@@ -122,11 +122,22 @@ static int sandbox_cs_info(struct udevice *bus, uint cs,
return 0;
}
+static int sandbox_spi_get_mmap(struct udevice *dev, ulong *map_basep,
+ uint *map_sizep, uint *offsetp)
+{
+ *map_basep = 0x1000;
+ *map_sizep = 0x2000;
+ *offsetp = 0x100;
+
+ return 0;
+}
+
static const struct dm_spi_ops sandbox_spi_ops = {
.xfer = sandbox_spi_xfer,
.set_speed = sandbox_spi_set_speed,
.set_mode = sandbox_spi_set_mode,
.cs_info = sandbox_cs_info,
+ .get_mmap = sandbox_spi_get_mmap,
};
static const struct udevice_id sandbox_spi_ids[] = {
diff --git a/drivers/spi/spi-uclass.c b/drivers/spi/spi-uclass.c
index a4d1b65682d..9f5ff2a31d1 100644
--- a/drivers/spi/spi-uclass.c
+++ b/drivers/spi/spi-uclass.c
@@ -92,6 +92,20 @@ int dm_spi_xfer(struct udevice *dev, unsigned int bitlen,
return spi_get_ops(bus)->xfer(dev, bitlen, dout, din, flags);
}
+int dm_spi_get_mmap(struct udevice *dev, ulong *map_basep, uint *map_sizep,
+ uint *offsetp)
+{
+ struct udevice *bus = dev->parent;
+ struct dm_spi_ops *ops = spi_get_ops(bus);
+
+ if (bus->uclass->uc_drv->id != UCLASS_SPI)
+ return -EOPNOTSUPP;
+ if (!ops->get_mmap)
+ return -ENOSYS;
+
+ return ops->get_mmap(dev, map_basep, map_sizep, offsetp);
+}
+
int spi_claim_bus(struct spi_slave *slave)
{
return log_ret(dm_spi_claim_bus(slave->dev));
diff --git a/include/spi.h b/include/spi.h
index 5eec0c4775e..a12727e6361 100644
--- a/include/spi.h
+++ b/include/spi.h
@@ -462,6 +462,19 @@ struct dm_spi_ops {
* is invalid, other -ve value on error
*/
int (*cs_info)(struct udevice *bus, uint cs, struct spi_cs_info *info);
+
+ /**
+ * get_mmap() - Get memory-mapped SPI
+ *
+ * @dev: The SPI flash slave 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,
+ uint *map_sizep, uint *offsetp);
};
struct dm_spi_emul_ops {
@@ -650,6 +663,20 @@ void dm_spi_release_bus(struct udevice *dev);
int dm_spi_xfer(struct udevice *dev, unsigned int bitlen,
const void *dout, void *din, unsigned long flags);
+/**
+ * spi_get_mmap() - Get memory-mapped SPI
+ *
+ * @dev: SPI slave device to check
+ * @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 dm_spi_get_mmap(struct udevice *dev, ulong *map_basep, uint *map_sizep,
+ uint *offsetp);
+
/* Access the operations for a SPI device */
#define spi_get_ops(dev) ((struct dm_spi_ops *)(dev)->driver->ops)
#define spi_emul_get_ops(dev) ((struct dm_spi_emul_ops *)(dev)->driver->ops)
diff --git a/test/dm/sf.c b/test/dm/sf.c
index 3788d59052e..65aab4f2e9c 100644
--- a/test/dm/sf.c
+++ b/test/dm/sf.c
@@ -23,6 +23,9 @@ static int dm_test_spi_flash(struct unit_test_state *uts)
int full_size = 0x200000;
int size = 0x10000;
u8 *src, *dst;
+ uint map_size;
+ ulong map_base;
+ uint offset;
int i;
src = map_sysmem(0x20000, full_size);
@@ -54,6 +57,12 @@ static int dm_test_spi_flash(struct unit_test_state *uts)
sandbox_sf_set_block_protect(emul, 0);
ut_asserteq(0, spl_flash_get_sw_write_prot(dev));
+ /* Check mapping */
+ ut_assertok(dm_spi_get_mmap(dev, &map_base, &map_size, &offset));
+ ut_asserteq(0x1000, map_base);
+ ut_asserteq(0x2000, map_size);
+ ut_asserteq(0x100, offset);
+
/*
* Since we are about to destroy all devices, we must tell sandbox
* to forget the emulation device
--
2.23.0.866.gb869b98d4c-goog
More information about the U-Boot
mailing list