From mboxrd@z Thu Jan 1 00:00:00 1970 From: Simon Glass Date: Wed, 25 Sep 2019 08:11:23 -0600 Subject: [U-Boot] [PATCH v2 14/38] spi: Add support for memory-mapped flash In-Reply-To: <20190925141147.191166-1-sjg@chromium.org> References: <20190925141147.191166-1-sjg@chromium.org> Message-ID: <20190925141147.191166-15-sjg@chromium.org> List-Id: MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit To: u-boot@lists.denx.de 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 --- 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