From c53b318e1bad2e0d5c2b846fadfc79ec77bfc5f7 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 20 Oct 2019 21:31:47 -0600 Subject: 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 Reviewed-by: Bin Meng --- drivers/spi/sandbox_spi.c | 11 +++++++++++ drivers/spi/spi-uclass.c | 14 ++++++++++++++ 2 files changed, 25 insertions(+) (limited to 'drivers') diff --git a/drivers/spi/sandbox_spi.c b/drivers/spi/sandbox_spi.c index 16473ec7a0b..6b610ff8231 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 947516073ea..665611f7e23 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)); -- cgit v1.2.3 From 096c71e34bac7551aa228bbcb9e1c867ad9e5d07 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 20 Oct 2019 21:31:54 -0600 Subject: x86: timer: Set up the timer in timer_early_get_count() This function can be called before the timer is set up. Make sure that the init function is called so that it works correctly. This is needed so that bootstage can work correctly in TPL. Signed-off-by: Simon Glass Reviewed-by: Bin Meng --- drivers/timer/tsc_timer.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/timer/tsc_timer.c b/drivers/timer/tsc_timer.c index 919caba8a14..f19d2237e4f 100644 --- a/drivers/timer/tsc_timer.c +++ b/drivers/timer/tsc_timer.c @@ -461,6 +461,8 @@ unsigned long notrace timer_early_get_rate(void) u64 notrace timer_early_get_count(void) { + tsc_timer_ensure_setup(true); + return rdtsc() - gd->arch.tsc_base; } -- cgit v1.2.3 From a478a26cd00bbe14d51952b9ae3620415fbdf2b2 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 20 Oct 2019 21:37:47 -0600 Subject: x86: timer: Use a separate flag for whether timer is inited At present the value of the timer base is used to determine whether the timer has been set up or not. It is true that the timer is essentially never exactly 0 when it is read. However 'time 0' may indicate the time that the machine was reset so it is useful to be able to denote that. Update the code to use a separate flag instead. Signed-off-by: Simon Glass Tested-by: Aiden Park Reviewed-by: Aiden Park Reviewed-by: Bin Meng --- arch/x86/include/asm/global_data.h | 1 + drivers/timer/tsc_timer.c | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/arch/x86/include/asm/global_data.h b/arch/x86/include/asm/global_data.h index 17a4d344913..7f3ada06f61 100644 --- a/arch/x86/include/asm/global_data.h +++ b/arch/x86/include/asm/global_data.h @@ -76,6 +76,7 @@ struct arch_global_data { uint8_t x86_mask; uint32_t x86_device; uint64_t tsc_base; /* Initial value returned by rdtsc() */ + bool tsc_inited; /* true if tsc is ready for use */ unsigned long clock_rate; /* Clock rate of timer in Hz */ void *new_fdt; /* Relocated FDT */ uint32_t bist; /* Built-in self test value */ diff --git a/drivers/timer/tsc_timer.c b/drivers/timer/tsc_timer.c index f19d2237e4f..637c8ff25a5 100644 --- a/drivers/timer/tsc_timer.c +++ b/drivers/timer/tsc_timer.c @@ -394,7 +394,7 @@ static int tsc_timer_get_count(struct udevice *dev, u64 *count) static void tsc_timer_ensure_setup(bool early) { - if (gd->arch.tsc_base) + if (gd->arch.tsc_inited) return; gd->arch.tsc_base = rdtsc(); @@ -425,6 +425,7 @@ static void tsc_timer_ensure_setup(bool early) done: gd->arch.clock_rate = fast_calibrate * 1000000; } + gd->arch.tsc_inited = true; } static int tsc_timer_probe(struct udevice *dev) -- cgit v1.2.3