Message ID | 1363018093-28979-11-git-send-email-sjg@chromium.org |
---|---|
State | Accepted, archived |
Delegated to: | Tom Rini |
Headers | show |
Hi Simon, On Mon, Mar 11, 2013 at 9:38 PM, Simon Glass <sjg@chromium.org> wrote: > Enable device tree control of SPI flash, and use this to implement > memory-mapped SPI flash, which is supported on Intel chips. > > Signed-off-by: Simon Glass <sjg@chromium.org> > --- > Changes in v2: None > > drivers/mtd/spi/spi_flash.c | 46 ++++++++++++++++++++++++++++++++++++++++++++- > include/fdtdec.h | 1 + > include/spi_flash.h | 1 + > lib/fdtdec.c | 1 + > 4 files changed, 48 insertions(+), 1 deletion(-) > > diff --git a/drivers/mtd/spi/spi_flash.c b/drivers/mtd/spi/spi_flash.c > index b82011d..111185a 100644 > --- a/drivers/mtd/spi/spi_flash.c > +++ b/drivers/mtd/spi/spi_flash.c > @@ -8,6 +8,7 @@ > */ > > #include <common.h> > +#include <fdtdec.h> > #include <malloc.h> > #include <spi.h> > #include <spi_flash.h> > @@ -15,6 +16,8 @@ > > #include "spi_flash_internal.h" > > +DECLARE_GLOBAL_DATA_PTR; > + > static void spi_flash_addr(u32 addr, u8 *cmd) > { > /* cmd[0] is actual command */ > @@ -146,6 +149,10 @@ int spi_flash_cmd_read_fast(struct spi_flash *flash, u32 offset, > { > u8 cmd[5]; > > + /* Handle memory-mapped SPI */ > + if (flash->memory_map) > + memcpy(data, flash->memory_map + offset, len); > + What is this change implies, does this means for memory mapped flashes, read can do directly through memcpy() and no need for spi_flash_read_common(). I am thinking what exactly this req' is for as you read the flash->memory_map + offset onto data and again your reading FAST_READ on data using spi_flash_read_common(). Can you please explain. Thanks, Jagan. > cmd[0] = CMD_READ_ARRAY_FAST; > spi_flash_addr(offset, cmd); > cmd[4] = 0x00; > @@ -275,6 +282,34 @@ int spi_flash_cmd_write_status(struct spi_flash *flash, u8 sr) > return 0; > } > > +#ifdef CONFIG_OF_CONTROL > +int spi_flash_decode_fdt(const void *blob, struct spi_flash *flash) > +{ > + fdt_addr_t addr; > + fdt_size_t size; > + int node; > + > + /* If there is no node, do nothing */ > + node = fdtdec_next_compatible(blob, 0, COMPAT_GENERIC_SPI_FLASH); > + if (node < 0) > + return 0; > + > + addr = fdtdec_get_addr_size(blob, node, "memory-map", &size); > + if (addr == FDT_ADDR_T_NONE) { > + debug("%s: Cannot decode address\n", __func__); > + return 0; > + } > + > + if (flash->size != size) { > + debug("%s: Memory map must cover entire device\n", __func__); > + return -1; > + } > + flash->memory_map = (void *)addr; > + > + return 0; > +} > +#endif /* CONFIG_OF_CONTROL */ > + > /* > * The following table holds all device probe functions > * > @@ -391,9 +426,18 @@ struct spi_flash *spi_flash_probe(unsigned int bus, unsigned int cs, > goto err_manufacturer_probe; > } > > +#ifdef CONFIG_OF_CONTROL > + if (spi_flash_decode_fdt(gd->fdt_blob, flash)) { > + debug("SF: FDT decode error\n"); > + goto err_manufacturer_probe; > + } > +#endif > printf("SF: Detected %s with page size ", flash->name); > print_size(flash->sector_size, ", total "); > - print_size(flash->size, "\n"); > + print_size(flash->size, ""); > + if (flash->memory_map) > + printf(", mapped at %p", flash->memory_map); > + puts("\n"); > > spi_release_bus(spi); > > diff --git a/include/fdtdec.h b/include/fdtdec.h > index d86dbe2..a46e51c 100644 > --- a/include/fdtdec.h > +++ b/include/fdtdec.h > @@ -83,6 +83,7 @@ enum fdt_compat_id { > COMPAT_SAMSUNG_EXYNOS_EHCI, /* Exynos EHCI controller */ > COMPAT_SAMSUNG_EXYNOS_USB_PHY, /* Exynos phy controller for usb2.0 */ > COMPAT_MAXIM_MAX77686_PMIC, /* MAX77686 PMIC */ > + COMPAT_GENERIC_SPI_FLASH, /* Generic SPI Flash chip */ > > COMPAT_COUNT, > }; > diff --git a/include/spi_flash.h b/include/spi_flash.h > index 030d49c..3b6a44e 100644 > --- a/include/spi_flash.h > +++ b/include/spi_flash.h > @@ -39,6 +39,7 @@ struct spi_flash { > /* Erase (sector) size */ > u32 sector_size; > > + void *memory_map; /* Address of read-only SPI flash access */ > int (*read)(struct spi_flash *flash, u32 offset, > size_t len, void *buf); > int (*write)(struct spi_flash *flash, u32 offset, > diff --git a/lib/fdtdec.c b/lib/fdtdec.c > index e99a4b9..2145354 100644 > --- a/lib/fdtdec.c > +++ b/lib/fdtdec.c > @@ -56,6 +56,7 @@ static const char * const compat_names[COMPAT_COUNT] = { > COMPAT(SAMSUNG_EXYNOS_EHCI, "samsung,exynos-ehci"), > COMPAT(SAMSUNG_EXYNOS_USB_PHY, "samsung,exynos-usb-phy"), > COMPAT(MAXIM_MAX77686_PMIC, "maxim,max77686_pmic"), > + COMPAT(GENERIC_SPI_FLASH, "spi-flash"), > }; > > const char *fdtdec_get_compatible(enum fdt_compat_id id) > -- > 1.8.1.3 > > _______________________________________________ > U-Boot mailing list > U-Boot@lists.denx.de > http://lists.denx.de/mailman/listinfo/u-boot
Hi Jagan, On Tue, Apr 23, 2013 at 1:49 PM, Jagan Teki <jagannadh.teki@gmail.com> wrote: > Hi Simon, > > On Mon, Mar 11, 2013 at 9:38 PM, Simon Glass <sjg@chromium.org> wrote: >> Enable device tree control of SPI flash, and use this to implement >> memory-mapped SPI flash, which is supported on Intel chips. >> >> Signed-off-by: Simon Glass <sjg@chromium.org> >> --- >> Changes in v2: None >> >> drivers/mtd/spi/spi_flash.c | 46 ++++++++++++++++++++++++++++++++++++++++++++- >> include/fdtdec.h | 1 + >> include/spi_flash.h | 1 + >> lib/fdtdec.c | 1 + >> 4 files changed, 48 insertions(+), 1 deletion(-) >> >> diff --git a/drivers/mtd/spi/spi_flash.c b/drivers/mtd/spi/spi_flash.c >> index b82011d..111185a 100644 >> --- a/drivers/mtd/spi/spi_flash.c >> +++ b/drivers/mtd/spi/spi_flash.c >> @@ -8,6 +8,7 @@ >> */ >> >> #include <common.h> >> +#include <fdtdec.h> >> #include <malloc.h> >> #include <spi.h> >> #include <spi_flash.h> >> @@ -15,6 +16,8 @@ >> >> #include "spi_flash_internal.h" >> >> +DECLARE_GLOBAL_DATA_PTR; >> + >> static void spi_flash_addr(u32 addr, u8 *cmd) >> { >> /* cmd[0] is actual command */ >> @@ -146,6 +149,10 @@ int spi_flash_cmd_read_fast(struct spi_flash *flash, u32 offset, >> { >> u8 cmd[5]; >> >> + /* Handle memory-mapped SPI */ >> + if (flash->memory_map) >> + memcpy(data, flash->memory_map + offset, len); >> + > > What is this change implies, does this means for memory mapped > flashes, read can do directly through memcpy() > and no need for spi_flash_read_common(). > > I am thinking what exactly this req' is for as you read the > flash->memory_map + offset onto data and again your reading > FAST_READ on data using spi_flash_read_common(). > > Can you please explain. Yes you are right, this should exit at this point - at present it is reading twice. I will prepare a patch. Regards, Simon > > Thanks, > Jagan. > >> cmd[0] = CMD_READ_ARRAY_FAST; >> spi_flash_addr(offset, cmd); >> cmd[4] = 0x00; >> @@ -275,6 +282,34 @@ int spi_flash_cmd_write_status(struct spi_flash *flash, u8 sr) >> return 0; >> } >> >> +#ifdef CONFIG_OF_CONTROL >> +int spi_flash_decode_fdt(const void *blob, struct spi_flash *flash) >> +{ >> + fdt_addr_t addr; >> + fdt_size_t size; >> + int node; >> + >> + /* If there is no node, do nothing */ >> + node = fdtdec_next_compatible(blob, 0, COMPAT_GENERIC_SPI_FLASH); >> + if (node < 0) >> + return 0; >> + >> + addr = fdtdec_get_addr_size(blob, node, "memory-map", &size); >> + if (addr == FDT_ADDR_T_NONE) { >> + debug("%s: Cannot decode address\n", __func__); >> + return 0; >> + } >> + >> + if (flash->size != size) { >> + debug("%s: Memory map must cover entire device\n", __func__); >> + return -1; >> + } >> + flash->memory_map = (void *)addr; >> + >> + return 0; >> +} >> +#endif /* CONFIG_OF_CONTROL */ >> + >> /* >> * The following table holds all device probe functions >> * >> @@ -391,9 +426,18 @@ struct spi_flash *spi_flash_probe(unsigned int bus, unsigned int cs, >> goto err_manufacturer_probe; >> } >> >> +#ifdef CONFIG_OF_CONTROL >> + if (spi_flash_decode_fdt(gd->fdt_blob, flash)) { >> + debug("SF: FDT decode error\n"); >> + goto err_manufacturer_probe; >> + } >> +#endif >> printf("SF: Detected %s with page size ", flash->name); >> print_size(flash->sector_size, ", total "); >> - print_size(flash->size, "\n"); >> + print_size(flash->size, ""); >> + if (flash->memory_map) >> + printf(", mapped at %p", flash->memory_map); >> + puts("\n"); >> >> spi_release_bus(spi); >> >> diff --git a/include/fdtdec.h b/include/fdtdec.h >> index d86dbe2..a46e51c 100644 >> --- a/include/fdtdec.h >> +++ b/include/fdtdec.h >> @@ -83,6 +83,7 @@ enum fdt_compat_id { >> COMPAT_SAMSUNG_EXYNOS_EHCI, /* Exynos EHCI controller */ >> COMPAT_SAMSUNG_EXYNOS_USB_PHY, /* Exynos phy controller for usb2.0 */ >> COMPAT_MAXIM_MAX77686_PMIC, /* MAX77686 PMIC */ >> + COMPAT_GENERIC_SPI_FLASH, /* Generic SPI Flash chip */ >> >> COMPAT_COUNT, >> }; >> diff --git a/include/spi_flash.h b/include/spi_flash.h >> index 030d49c..3b6a44e 100644 >> --- a/include/spi_flash.h >> +++ b/include/spi_flash.h >> @@ -39,6 +39,7 @@ struct spi_flash { >> /* Erase (sector) size */ >> u32 sector_size; >> >> + void *memory_map; /* Address of read-only SPI flash access */ >> int (*read)(struct spi_flash *flash, u32 offset, >> size_t len, void *buf); >> int (*write)(struct spi_flash *flash, u32 offset, >> diff --git a/lib/fdtdec.c b/lib/fdtdec.c >> index e99a4b9..2145354 100644 >> --- a/lib/fdtdec.c >> +++ b/lib/fdtdec.c >> @@ -56,6 +56,7 @@ static const char * const compat_names[COMPAT_COUNT] = { >> COMPAT(SAMSUNG_EXYNOS_EHCI, "samsung,exynos-ehci"), >> COMPAT(SAMSUNG_EXYNOS_USB_PHY, "samsung,exynos-usb-phy"), >> COMPAT(MAXIM_MAX77686_PMIC, "maxim,max77686_pmic"), >> + COMPAT(GENERIC_SPI_FLASH, "spi-flash"), >> }; >> >> const char *fdtdec_get_compatible(enum fdt_compat_id id) >> -- >> 1.8.1.3 >> >> _______________________________________________ >> U-Boot mailing list >> U-Boot@lists.denx.de >> http://lists.denx.de/mailman/listinfo/u-boot
diff --git a/drivers/mtd/spi/spi_flash.c b/drivers/mtd/spi/spi_flash.c index b82011d..111185a 100644 --- a/drivers/mtd/spi/spi_flash.c +++ b/drivers/mtd/spi/spi_flash.c @@ -8,6 +8,7 @@ */ #include <common.h> +#include <fdtdec.h> #include <malloc.h> #include <spi.h> #include <spi_flash.h> @@ -15,6 +16,8 @@ #include "spi_flash_internal.h" +DECLARE_GLOBAL_DATA_PTR; + static void spi_flash_addr(u32 addr, u8 *cmd) { /* cmd[0] is actual command */ @@ -146,6 +149,10 @@ int spi_flash_cmd_read_fast(struct spi_flash *flash, u32 offset, { u8 cmd[5]; + /* Handle memory-mapped SPI */ + if (flash->memory_map) + memcpy(data, flash->memory_map + offset, len); + cmd[0] = CMD_READ_ARRAY_FAST; spi_flash_addr(offset, cmd); cmd[4] = 0x00; @@ -275,6 +282,34 @@ int spi_flash_cmd_write_status(struct spi_flash *flash, u8 sr) return 0; } +#ifdef CONFIG_OF_CONTROL +int spi_flash_decode_fdt(const void *blob, struct spi_flash *flash) +{ + fdt_addr_t addr; + fdt_size_t size; + int node; + + /* If there is no node, do nothing */ + node = fdtdec_next_compatible(blob, 0, COMPAT_GENERIC_SPI_FLASH); + if (node < 0) + return 0; + + addr = fdtdec_get_addr_size(blob, node, "memory-map", &size); + if (addr == FDT_ADDR_T_NONE) { + debug("%s: Cannot decode address\n", __func__); + return 0; + } + + if (flash->size != size) { + debug("%s: Memory map must cover entire device\n", __func__); + return -1; + } + flash->memory_map = (void *)addr; + + return 0; +} +#endif /* CONFIG_OF_CONTROL */ + /* * The following table holds all device probe functions * @@ -391,9 +426,18 @@ struct spi_flash *spi_flash_probe(unsigned int bus, unsigned int cs, goto err_manufacturer_probe; } +#ifdef CONFIG_OF_CONTROL + if (spi_flash_decode_fdt(gd->fdt_blob, flash)) { + debug("SF: FDT decode error\n"); + goto err_manufacturer_probe; + } +#endif printf("SF: Detected %s with page size ", flash->name); print_size(flash->sector_size, ", total "); - print_size(flash->size, "\n"); + print_size(flash->size, ""); + if (flash->memory_map) + printf(", mapped at %p", flash->memory_map); + puts("\n"); spi_release_bus(spi); diff --git a/include/fdtdec.h b/include/fdtdec.h index d86dbe2..a46e51c 100644 --- a/include/fdtdec.h +++ b/include/fdtdec.h @@ -83,6 +83,7 @@ enum fdt_compat_id { COMPAT_SAMSUNG_EXYNOS_EHCI, /* Exynos EHCI controller */ COMPAT_SAMSUNG_EXYNOS_USB_PHY, /* Exynos phy controller for usb2.0 */ COMPAT_MAXIM_MAX77686_PMIC, /* MAX77686 PMIC */ + COMPAT_GENERIC_SPI_FLASH, /* Generic SPI Flash chip */ COMPAT_COUNT, }; diff --git a/include/spi_flash.h b/include/spi_flash.h index 030d49c..3b6a44e 100644 --- a/include/spi_flash.h +++ b/include/spi_flash.h @@ -39,6 +39,7 @@ struct spi_flash { /* Erase (sector) size */ u32 sector_size; + void *memory_map; /* Address of read-only SPI flash access */ int (*read)(struct spi_flash *flash, u32 offset, size_t len, void *buf); int (*write)(struct spi_flash *flash, u32 offset, diff --git a/lib/fdtdec.c b/lib/fdtdec.c index e99a4b9..2145354 100644 --- a/lib/fdtdec.c +++ b/lib/fdtdec.c @@ -56,6 +56,7 @@ static const char * const compat_names[COMPAT_COUNT] = { COMPAT(SAMSUNG_EXYNOS_EHCI, "samsung,exynos-ehci"), COMPAT(SAMSUNG_EXYNOS_USB_PHY, "samsung,exynos-usb-phy"), COMPAT(MAXIM_MAX77686_PMIC, "maxim,max77686_pmic"), + COMPAT(GENERIC_SPI_FLASH, "spi-flash"), }; const char *fdtdec_get_compatible(enum fdt_compat_id id)
Enable device tree control of SPI flash, and use this to implement memory-mapped SPI flash, which is supported on Intel chips. Signed-off-by: Simon Glass <sjg@chromium.org> --- Changes in v2: None drivers/mtd/spi/spi_flash.c | 46 ++++++++++++++++++++++++++++++++++++++++++++- include/fdtdec.h | 1 + include/spi_flash.h | 1 + lib/fdtdec.c | 1 + 4 files changed, 48 insertions(+), 1 deletion(-)