spi: Add support for memory-mapped flash
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@chromium.org> Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
This commit is contained in:
parent
e1500a6ce2
commit
c53b318e1b
@ -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[] = {
|
||||
|
@ -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));
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user