On Tue, Dec 4, 2018 at 1:27 PM Vignesh R <vigne...@ti.com> wrote: > > Switch spi_flash_* interfaces to call into new SPI NOR framework via MTD > layer. Fix up sf_dataflash to work in legacy way. And update sandbox to > use new interfaces/defintions > > Signed-off-by: Vignesh R <vigne...@ti.com> > --- > common/spl/Kconfig | 7 + > drivers/mtd/spi/Kconfig | 8 ++ > drivers/mtd/spi/Makefile | 4 +- > drivers/mtd/spi/sandbox.c | 36 +++--- > drivers/mtd/spi/sf_dataflash.c | 11 +- > drivers/mtd/spi/sf_internal.h | 228 +++++++-------------------------- > drivers/mtd/spi/sf_probe.c | 33 +++-- > drivers/mtd/spi/spi-nor.c | 59 +-------- > drivers/spi/stm32_qspi.c | 4 +- > include/spi_flash.h | 105 ++++----------- > 10 files changed, 130 insertions(+), 365 deletions(-) > > diff --git a/common/spl/Kconfig b/common/spl/Kconfig > index 0ddbffc7d1c6..2b6f315b1cf3 100644 > --- a/common/spl/Kconfig > +++ b/common/spl/Kconfig > @@ -727,6 +727,13 @@ config SPL_SPI_FLASH_SUPPORT > lines). This enables the drivers in drivers/mtd/spi as part of an > SPL build. This normally requires SPL_SPI_SUPPORT. > > +config SPL_SPI_FLASH_SFDP_SUPPORT > + bool "SFDP table parsing support for SPI NOR flashes" > + help > + Enable support for parsing and auto discovery of parameters for > + SPI NOR flashes using Serial Flash Discoverable Parameters (SFDP) > + tables as per JESD216 standard in SPL. > +
I know other options are like this, too, but I would prefer it if this option was disabled or hidden when SPL_SPI_FLASH_SUPPORT is disabled. Regards, Simon > config SPL_SPI_LOAD > bool "Support loading from SPI flash" > depends on SPL_SPI_FLASH_SUPPORT > diff --git a/drivers/mtd/spi/Kconfig b/drivers/mtd/spi/Kconfig > index 76d5a1d11527..d735884b48db 100644 > --- a/drivers/mtd/spi/Kconfig > +++ b/drivers/mtd/spi/Kconfig > @@ -27,6 +27,7 @@ config SPI_FLASH_SANDBOX > > config SPI_FLASH > bool "Legacy SPI Flash Interface support" > + select SPI_MEM > help > Enable the legacy SPI flash support. This will include basic > standard support for things like probing, read / write, and > @@ -34,6 +35,13 @@ config SPI_FLASH > > If unsure, say N > > +config SPI_FLASH_SFDP_SUPPORT > + bool "SFDP table parsing support for SPI NOR flashes" > + help > + Enable support for parsing and auto discovery of parameters for > + SPI NOR flashes using Serial Flash Discoverable Parameters (SFDP) > + tables as per JESD216 standard. > + > config SPI_FLASH_BAR > bool "SPI flash Bank/Extended address register support" > depends on SPI_FLASH > diff --git a/drivers/mtd/spi/Makefile b/drivers/mtd/spi/Makefile > index b4c7e1c98bd5..9cd6672e93ce 100644 > --- a/drivers/mtd/spi/Makefile > +++ b/drivers/mtd/spi/Makefile > @@ -9,7 +9,7 @@ ifdef CONFIG_SPL_BUILD > obj-$(CONFIG_SPL_SPI_BOOT) += fsl_espi_spl.o > endif > > -obj-$(CONFIG_SPI_FLASH) += sf_probe.o spi_flash.o spi_flash_ids.o sf.o > -obj-$(CONFIG_SPI_FLASH_DATAFLASH) += sf_dataflash.o > +obj-$(CONFIG_SPI_FLASH) += sf_probe.o spi-nor.o > +obj-$(CONFIG_SPI_FLASH_DATAFLASH) += sf_dataflash.o sf.o > obj-$(CONFIG_SPI_FLASH_MTD) += sf_mtd.o > obj-$(CONFIG_SPI_FLASH_SANDBOX) += sandbox.o > diff --git a/drivers/mtd/spi/sandbox.c b/drivers/mtd/spi/sandbox.c > index 7b9891cb981c..084c66e9840b 100644 > --- a/drivers/mtd/spi/sandbox.c > +++ b/drivers/mtd/spi/sandbox.c > @@ -92,7 +92,7 @@ struct sandbox_spi_flash { > /* The current flash status (see STAT_XXX defines above) */ > u16 status; > /* Data describing the flash we're emulating */ > - const struct spi_flash_info *data; > + const struct flash_info *data; > /* The file on disk to serv up data from */ > int fd; > }; > @@ -122,7 +122,7 @@ static int sandbox_sf_probe(struct udevice *dev) > /* spec = idcode:file */ > struct sandbox_spi_flash *sbsf = dev_get_priv(dev); > size_t len, idname_len; > - const struct spi_flash_info *data; > + const struct flash_info *data; > struct sandbox_spi_flash_plat_data *pdata = dev_get_platdata(dev); > struct sandbox_state *state = state_get_current(); > struct dm_spi_slave_platdata *slave_plat; > @@ -155,7 +155,7 @@ static int sandbox_sf_probe(struct udevice *dev) > idname_len = strlen(spec); > debug("%s: device='%s'\n", __func__, spec); > > - for (data = spi_flash_ids; data->name; data++) { > + for (data = spi_nor_ids; data->name; data++) { > len = strlen(data->name); > if (idname_len != len) > continue; > @@ -243,43 +243,43 @@ static int sandbox_sf_process_cmd(struct > sandbox_spi_flash *sbsf, const u8 *rx, > > sbsf->cmd = rx[0]; > switch (sbsf->cmd) { > - case CMD_READ_ID: > + case SPINOR_OP_RDID: > sbsf->state = SF_ID; > sbsf->cmd = SF_ID; > break; > - case CMD_READ_ARRAY_FAST: > + case SPINOR_OP_READ_FAST: > sbsf->pad_addr_bytes = 1; > - case CMD_READ_ARRAY_SLOW: > - case CMD_PAGE_PROGRAM: > + case SPINOR_OP_READ: > + case SPINOR_OP_PP: > sbsf->state = SF_ADDR; > break; > - case CMD_WRITE_DISABLE: > + case SPINOR_OP_WRDI: > debug(" write disabled\n"); > sbsf->status &= ~STAT_WEL; > break; > - case CMD_READ_STATUS: > + case SPINOR_OP_RDSR: > sbsf->state = SF_READ_STATUS; > break; > - case CMD_READ_STATUS1: > + case SPINOR_OP_RDSR2: > sbsf->state = SF_READ_STATUS1; > break; > - case CMD_WRITE_ENABLE: > + case SPINOR_OP_WREN: > debug(" write enabled\n"); > sbsf->status |= STAT_WEL; > break; > - case CMD_WRITE_STATUS: > + case SPINOR_OP_WRSR: > sbsf->state = SF_WRITE_STATUS; > break; > default: { > int flags = sbsf->data->flags; > > /* we only support erase here */ > - if (sbsf->cmd == CMD_ERASE_CHIP) { > + if (sbsf->cmd == SPINOR_OP_CHIP_ERASE) { > sbsf->erase_size = sbsf->data->sector_size * > sbsf->data->n_sectors; > - } else if (sbsf->cmd == CMD_ERASE_4K && (flags & SECT_4K)) { > + } else if (sbsf->cmd == SPINOR_OP_BE_4K && (flags & SECT_4K)) > { > sbsf->erase_size = 4 << 10; > - } else if (sbsf->cmd == CMD_ERASE_64K && !(flags & SECT_4K)) { > + } else if (sbsf->cmd == SPINOR_OP_SE && !(flags & SECT_4K)) { > sbsf->erase_size = 64 << 10; > } else { > debug(" cmd unknown: %#x\n", sbsf->cmd); > @@ -380,11 +380,11 @@ static int sandbox_sf_xfer(struct udevice *dev, > unsigned int bitlen, > return -EIO; > } > switch (sbsf->cmd) { > - case CMD_READ_ARRAY_FAST: > - case CMD_READ_ARRAY_SLOW: > + case SPINOR_OP_READ_FAST: > + case SPINOR_OP_READ: > sbsf->state = SF_READ; > break; > - case CMD_PAGE_PROGRAM: > + case SPINOR_OP_PP: > sbsf->state = SF_WRITE; > break; > default: > diff --git a/drivers/mtd/spi/sf_dataflash.c b/drivers/mtd/spi/sf_dataflash.c > index 4a60c1b2b43a..b6a2631747a9 100644 > --- a/drivers/mtd/spi/sf_dataflash.c > +++ b/drivers/mtd/spi/sf_dataflash.c > @@ -18,6 +18,7 @@ > > #include "sf_internal.h" > > +#define CMD_READ_ID 0x9f > /* reads can bypass the buffers */ > #define OP_READ_CONTINUOUS 0xE8 > #define OP_READ_PAGE 0xD2 > @@ -441,7 +442,7 @@ static int add_dataflash(struct udevice *dev, char *name, > int nr_pages, > return 0; > } > > -struct flash_info { > +struct data_flash_info { > char *name; > > /* > @@ -460,7 +461,7 @@ struct flash_info { > #define IS_POW2PS 0x0001 /* uses 2^N byte pages */ > }; > > -static struct flash_info dataflash_data[] = { > +static struct data_flash_info dataflash_data[] = { > /* > * NOTE: chips with SUP_POW2PS (rev D and up) need two entries, > * one with IS_POW2PS and the other without. The entry with the > @@ -501,12 +502,12 @@ static struct flash_info dataflash_data[] = { > { "at45db642d", 0x1f2800, 8192, 1024, 10, SUP_POW2PS | IS_POW2PS}, > }; > > -static struct flash_info *jedec_probe(struct spi_slave *spi) > +static struct data_flash_info *jedec_probe(struct spi_slave *spi) > { > int tmp; > uint8_t id[5]; > uint32_t jedec; > - struct flash_info *info; > + struct data_flash_info *info; > int status; > > /* > @@ -583,7 +584,7 @@ static int spi_dataflash_probe(struct udevice *dev) > { > struct spi_slave *spi = dev_get_parent_priv(dev); > struct spi_flash *spi_flash; > - struct flash_info *info; > + struct data_flash_info *info; > int status; > > spi_flash = dev_get_uclass_priv(dev); > diff --git a/drivers/mtd/spi/sf_internal.h b/drivers/mtd/spi/sf_internal.h > index 46a504441751..55619f5aea5c 100644 > --- a/drivers/mtd/spi/sf_internal.h > +++ b/drivers/mtd/spi/sf_internal.h > @@ -12,142 +12,66 @@ > #include <linux/types.h> > #include <linux/compiler.h> > > -/* Dual SPI flash memories - see SPI_COMM_DUAL_... */ > -enum spi_dual_flash { > - SF_SINGLE_FLASH = 0, > - SF_DUAL_STACKED_FLASH = BIT(0), > - SF_DUAL_PARALLEL_FLASH = BIT(1), > -}; > - > -enum spi_nor_option_flags { > - SNOR_F_SST_WR = BIT(0), > - SNOR_F_USE_FSR = BIT(1), > - SNOR_F_USE_UPAGE = BIT(3), > -}; > - > -#define SPI_FLASH_3B_ADDR_LEN 3 > -#define SPI_FLASH_CMD_LEN (1 + SPI_FLASH_3B_ADDR_LEN) > -#define SPI_FLASH_16MB_BOUN 0x1000000 > - > -/* CFI Manufacture ID's */ > -#define SPI_FLASH_CFI_MFR_SPANSION 0x01 > -#define SPI_FLASH_CFI_MFR_STMICRO 0x20 > -#define SPI_FLASH_CFI_MFR_MICRON 0x2C > -#define SPI_FLASH_CFI_MFR_MACRONIX 0xc2 > -#define SPI_FLASH_CFI_MFR_SST 0xbf > -#define SPI_FLASH_CFI_MFR_WINBOND 0xef > -#define SPI_FLASH_CFI_MFR_ATMEL 0x1f > - > -/* Erase commands */ > -#define CMD_ERASE_4K 0x20 > -#define CMD_ERASE_CHIP 0xc7 > -#define CMD_ERASE_64K 0xd8 > - > -/* Write commands */ > -#define CMD_WRITE_STATUS 0x01 > -#define CMD_PAGE_PROGRAM 0x02 > -#define CMD_WRITE_DISABLE 0x04 > -#define CMD_WRITE_ENABLE 0x06 > -#define CMD_QUAD_PAGE_PROGRAM 0x32 > - > -/* Read commands */ > -#define CMD_READ_ARRAY_SLOW 0x03 > -#define CMD_READ_ARRAY_FAST 0x0b > -#define CMD_READ_DUAL_OUTPUT_FAST 0x3b > -#define CMD_READ_DUAL_IO_FAST 0xbb > -#define CMD_READ_QUAD_OUTPUT_FAST 0x6b > -#define CMD_READ_QUAD_IO_FAST 0xeb > -#define CMD_READ_ID 0x9f > -#define CMD_READ_STATUS 0x05 > -#define CMD_READ_STATUS1 0x35 > -#define CMD_READ_CONFIG 0x35 > -#define CMD_FLAG_STATUS 0x70 > - > -/* Bank addr access commands */ > -#ifdef CONFIG_SPI_FLASH_BAR > -# define CMD_BANKADDR_BRWR 0x17 > -# define CMD_BANKADDR_BRRD 0x16 > -# define CMD_EXTNADDR_WREAR 0xC5 > -# define CMD_EXTNADDR_RDEAR 0xC8 > -#endif > +#define SPI_NOR_MAX_ID_LEN 6 > +#define SPI_NOR_MAX_ADDR_WIDTH 4 > > -/* Common status */ > -#define STATUS_WIP BIT(0) > -#define STATUS_QEB_WINSPAN BIT(1) > -#define STATUS_QEB_MXIC BIT(6) > -#define STATUS_PEC BIT(7) > -#define SR_BP0 BIT(2) /* Block protect 0 */ > -#define SR_BP1 BIT(3) /* Block protect 1 */ > -#define SR_BP2 BIT(4) /* Block protect 2 */ > - > -/* Flash timeout values */ > -#define SPI_FLASH_PROG_TIMEOUT (2 * CONFIG_SYS_HZ) > -#define SPI_FLASH_PAGE_ERASE_TIMEOUT (5 * CONFIG_SYS_HZ) > -#define SPI_FLASH_SECTOR_ERASE_TIMEOUT (10 * CONFIG_SYS_HZ) > - > -/* SST specific */ > -#ifdef CONFIG_SPI_FLASH_SST > -#define SST26_CMD_READ_BPR 0x72 > -#define SST26_CMD_WRITE_BPR 0x42 > - > -#define SST26_BPR_8K_NUM 4 > -#define SST26_MAX_BPR_REG_LEN (18 + 1) > -#define SST26_BOUND_REG_SIZE ((32 + SST26_BPR_8K_NUM * 8) * SZ_1K) > - > -enum lock_ctl { > - SST26_CTL_LOCK, > - SST26_CTL_UNLOCK, > - SST26_CTL_CHECK > -}; > - > -# define CMD_SST_BP 0x02 /* Byte Program */ > -# define CMD_SST_AAI_WP 0xAD /* Auto Address Incr Word > Program */ > - > -int sst_write_wp(struct spi_flash *flash, u32 offset, size_t len, > - const void *buf); > -int sst_write_bp(struct spi_flash *flash, u32 offset, size_t len, > - const void *buf); > -#endif > - > -#define JEDEC_MFR(info) ((info)->id[0]) > -#define JEDEC_ID(info) (((info)->id[1]) << 8 | ((info)->id[2])) > -#define JEDEC_EXT(info) (((info)->id[3]) << 8 | > ((info)->id[4])) > -#define SPI_FLASH_MAX_ID_LEN 6 > - > -struct spi_flash_info { > - /* Device name ([MANUFLETTER][DEVTYPE][DENSITY][EXTRAINFO]) */ > - const char *name; > +struct flash_info { > + char *name; > > /* > * This array stores the ID bytes. > * The first three bytes are the JEDIC ID. > * JEDEC ID zero means "no ID" (mostly older chips). > */ > - u8 id[SPI_FLASH_MAX_ID_LEN]; > + u8 id[SPI_NOR_MAX_ID_LEN]; > u8 id_len; > > - /* > - * The size listed here is what works with SPINOR_OP_SE, which isn't > + /* The size listed here is what works with SPINOR_OP_SE, which isn't > * necessarily called a "sector" by the vendor. > */ > - u32 sector_size; > - u32 n_sectors; > + unsigned int sector_size; > + u16 n_sectors; > > u16 page_size; > + u16 addr_width; > > u16 flags; > -#define SECT_4K BIT(0) /* CMD_ERASE_4K works > uniformly */ > -#define E_FSR BIT(1) /* use flag status register for */ > -#define SST_WR BIT(2) /* use SST byte/word programming */ > -#define WR_QPP BIT(3) /* use Quad Page Program */ > -#define RD_QUAD BIT(4) /* use Quad Read */ > -#define RD_DUAL BIT(5) /* use Dual Read */ > -#define RD_QUADIO BIT(6) /* use Quad IO Read */ > -#define RD_DUALIO BIT(7) /* use Dual IO Read */ > -#define RD_FULL (RD_QUAD | RD_DUAL | RD_QUADIO | > RD_DUALIO) > +#define SECT_4K BIT(0) /* SPINOR_OP_BE_4K works > uniformly */ > +#define SPI_NOR_NO_ERASE BIT(1) /* No erase command needed */ > +#define SST_WRITE BIT(2) /* use SST byte programming */ > +#define SPI_NOR_NO_FR BIT(3) /* Can't do fastread */ > +#define SECT_4K_PMC BIT(4) /* SPINOR_OP_BE_4K_PMC works > uniformly */ > +#define SPI_NOR_DUAL_READ BIT(5) /* Flash supports Dual Read */ > +#define SPI_NOR_QUAD_READ BIT(6) /* Flash supports Quad Read */ > +#define USE_FSR BIT(7) /* use flag status register */ > +#define SPI_NOR_HAS_LOCK BIT(8) /* Flash supports lock/unlock via SR > */ > +#define SPI_NOR_HAS_TB BIT(9) /* > + * Flash SR has Top/Bottom (TB) > protect > + * bit. Must be used with > + * SPI_NOR_HAS_LOCK. > + */ > +#define SPI_S3AN BIT(10) /* > + * Xilinx Spartan 3AN In-System Flash > + * (MFR cannot be used for probing > + * because it has the same value as > + * ATMEL flashes) > + */ > +#define SPI_NOR_4B_OPCODES BIT(11) /* > + * Use dedicated 4byte address op > codes > + * to support memory size above > 128Mib. > + */ > +#define NO_CHIP_ERASE BIT(12) /* Chip does not support chip erase */ > +#define SPI_NOR_SKIP_SFDP BIT(13) /* Skip parsing of SFDP tables */ > +#define USE_CLSR BIT(14) /* use CLSR command */ > +#ifndef __UBOOT__ > + int (*quad_enable)(struct spi_nor *nor); > +#endif > }; > > -extern const struct spi_flash_info spi_flash_ids[]; > +extern const struct flash_info spi_nor_ids[]; > + > +#define JEDEC_MFR(info) ((info)->id[0]) > +#define JEDEC_ID(info) (((info)->id[1]) << 8 | ((info)->id[2])) > > /* Send a single-byte command to the device and read the response */ > int spi_flash_cmd(struct spi_slave *spi, u8 cmd, void *response, size_t len); > @@ -167,78 +91,12 @@ int spi_flash_cmd_write(struct spi_slave *spi, const u8 > *cmd, size_t cmd_len, > const void *data, size_t data_len); > > > -/* Flash erase(sectors) operation, support all possible erase commands */ > -int spi_flash_cmd_erase_ops(struct spi_flash *flash, u32 offset, size_t len); > - > /* Get software write-protect value (BP bits) */ > int spi_flash_cmd_get_sw_write_prot(struct spi_flash *flash); > > -/* Lock stmicro spi flash region */ > -int stm_lock(struct spi_flash *flash, u32 ofs, size_t len); > - > -/* Unlock stmicro spi flash region */ > -int stm_unlock(struct spi_flash *flash, u32 ofs, size_t len); > - > -/* Check if a stmicro spi flash region is completely locked */ > -int stm_is_locked(struct spi_flash *flash, u32 ofs, size_t len); > - > -/* Enable writing on the SPI flash */ > -static inline int spi_flash_cmd_write_enable(struct spi_flash *flash) > -{ > - return spi_flash_cmd(flash->spi, CMD_WRITE_ENABLE, NULL, 0); > -} > - > -/* Disable writing on the SPI flash */ > -static inline int spi_flash_cmd_write_disable(struct spi_flash *flash) > -{ > - return spi_flash_cmd(flash->spi, CMD_WRITE_DISABLE, NULL, 0); > -} > - > -/* > - * Used for spi_flash write operation > - * - SPI claim > - * - spi_flash_cmd_write_enable > - * - spi_flash_cmd_write > - * - spi_flash_wait_till_ready > - * - SPI release > - */ > -int spi_flash_write_common(struct spi_flash *flash, const u8 *cmd, > - size_t cmd_len, const void *buf, size_t buf_len); > - > -/* > - * Flash write operation, support all possible write commands. > - * Write the requested data out breaking it up into multiple write > - * commands as needed per the write size. > - */ > -int spi_flash_cmd_write_ops(struct spi_flash *flash, u32 offset, > - size_t len, const void *buf); > - > -/* > - * Same as spi_flash_cmd_read() except it also claims/releases the SPI > - * bus. Used as common part of the ->read() operation. > - */ > -int spi_flash_read_common(struct spi_flash *flash, const u8 *cmd, > - size_t cmd_len, void *data, size_t data_len); > - > -/* Flash read operation, support all possible read commands */ > -int spi_flash_cmd_read_ops(struct spi_flash *flash, u32 offset, > - size_t len, void *data); > > #ifdef CONFIG_SPI_FLASH_MTD > int spi_flash_mtd_register(struct spi_flash *flash); > void spi_flash_mtd_unregister(void); > #endif > - > -/** > - * spi_flash_scan - scan the SPI FLASH > - * @flash: the spi flash structure > - * > - * The drivers can use this fuction to scan the SPI FLASH. > - * In the scanning, it will try to get all the necessary information to > - * fill the spi_flash{}. > - * > - * Return: 0 for success, others for failure. > - */ > -int spi_flash_scan(struct spi_flash *flash); > - > #endif /* _SF_INTERNAL_H_ */ > diff --git a/drivers/mtd/spi/sf_probe.c b/drivers/mtd/spi/sf_probe.c > index 5a2e932de8f8..c4c25a7e8403 100644 > --- a/drivers/mtd/spi/sf_probe.c > +++ b/drivers/mtd/spi/sf_probe.c > @@ -40,7 +40,7 @@ static int spi_flash_probe_slave(struct spi_flash *flash) > return ret; > } > > - ret = spi_flash_scan(flash); > + ret = spi_nor_scan(flash); > if (ret) > goto err_read_id; > > @@ -96,32 +96,38 @@ static int spi_flash_std_read(struct udevice *dev, u32 > offset, size_t len, > void *buf) > { > struct spi_flash *flash = dev_get_uclass_priv(dev); > + struct mtd_info *mtd = &flash->mtd; > + size_t retlen; > > - return log_ret(spi_flash_cmd_read_ops(flash, offset, len, buf)); > + return log_ret(mtd->_read(mtd, offset, len, &retlen, buf)); > } > > static int spi_flash_std_write(struct udevice *dev, u32 offset, size_t len, > const void *buf) > { > struct spi_flash *flash = dev_get_uclass_priv(dev); > + struct mtd_info *mtd = &flash->mtd; > + size_t retlen; > > -#if defined(CONFIG_SPI_FLASH_SST) > - if (flash->flags & SNOR_F_SST_WR) { > - if (flash->spi->mode & SPI_TX_BYTE) > - return sst_write_bp(flash, offset, len, buf); > - else > - return sst_write_wp(flash, offset, len, buf); > - } > -#endif > - > - return spi_flash_cmd_write_ops(flash, offset, len, buf); > + return mtd->_write(mtd, offset, len, &retlen, buf); > } > > static int spi_flash_std_erase(struct udevice *dev, u32 offset, size_t len) > { > struct spi_flash *flash = dev_get_uclass_priv(dev); > + struct mtd_info *mtd = &flash->mtd; > + struct erase_info instr; > + > + if (offset % mtd->erasesize || len % mtd->erasesize) { > + printf("SF: Erase offset/length not multiple of erase > size\n"); > + return -EINVAL; > + } > + > + memset(&instr, 0, sizeof(instr)); > + instr.addr = offset; > + instr.len = len; > > - return spi_flash_cmd_erase_ops(flash, offset, len); > + return mtd->_erase(mtd, &instr); > } > > static int spi_flash_std_get_sw_write_prot(struct udevice *dev) > @@ -153,6 +159,7 @@ static const struct dm_spi_flash_ops spi_flash_std_ops = { > > static const struct udevice_id spi_flash_std_ids[] = { > { .compatible = "spi-flash" }, > + { .compatible = "jedec,spi-nor" }, > { } > }; > > diff --git a/drivers/mtd/spi/spi-nor.c b/drivers/mtd/spi/spi-nor.c > index ff79601a8896..a192087882a1 100644 > --- a/drivers/mtd/spi/spi-nor.c > +++ b/drivers/mtd/spi/spi-nor.c > @@ -21,6 +21,8 @@ > #include <spi-mem.h> > #include <spi.h> > > +#include "sf_internal.h" > + > /* Define max times to check status register before we give up. */ > > /* > @@ -32,63 +34,6 @@ > > #define DEFAULT_READY_WAIT_JIFFIES (40UL * HZ) > > -#define SPI_NOR_MAX_ID_LEN 6 > -#define SPI_NOR_MAX_ADDR_WIDTH 4 > - > -struct flash_info { > - char *name; > - > - /* > - * This array stores the ID bytes. > - * The first three bytes are the JEDIC ID. > - * JEDEC ID zero means "no ID" (mostly older chips). > - */ > - u8 id[SPI_NOR_MAX_ID_LEN]; > - u8 id_len; > - > - /* The size listed here is what works with SPINOR_OP_SE, which isn't > - * necessarily called a "sector" by the vendor. > - */ > - unsigned int sector_size; > - u16 n_sectors; > - > - u16 page_size; > - u16 addr_width; > - > - u16 flags; > -#define SECT_4K BIT(0) /* SPINOR_OP_BE_4K works > uniformly */ > -#define SPI_NOR_NO_ERASE BIT(1) /* No erase command needed */ > -#define SST_WRITE BIT(2) /* use SST byte programming */ > -#define SPI_NOR_NO_FR BIT(3) /* Can't do fastread */ > -#define SECT_4K_PMC BIT(4) /* SPINOR_OP_BE_4K_PMC works > uniformly */ > -#define SPI_NOR_DUAL_READ BIT(5) /* Flash supports Dual Read */ > -#define SPI_NOR_QUAD_READ BIT(6) /* Flash supports Quad Read */ > -#define USE_FSR BIT(7) /* use flag status register */ > -#define SPI_NOR_HAS_LOCK BIT(8) /* Flash supports lock/unlock via SR > */ > -#define SPI_NOR_HAS_TB BIT(9) /* > - * Flash SR has Top/Bottom (TB) > protect > - * bit. Must be used with > - * SPI_NOR_HAS_LOCK. > - */ > -#define SPI_S3AN BIT(10) /* > - * Xilinx Spartan 3AN In-System Flash > - * (MFR cannot be used for probing > - * because it has the same value as > - * ATMEL flashes) > - */ > -#define SPI_NOR_4B_OPCODES BIT(11) /* > - * Use dedicated 4byte address op > codes > - * to support memory size above > 128Mib. > - */ > -#define NO_CHIP_ERASE BIT(12) /* Chip does not support chip erase */ > -#define SPI_NOR_SKIP_SFDP BIT(13) /* Skip parsing of SFDP tables */ > -#define USE_CLSR BIT(14) /* use CLSR command */ > - > - int (*quad_enable)(struct spi_nor *nor); > -}; > - > -#define JEDEC_MFR(info) ((info)->id[0]) > - > static int spi_nor_read_write_reg(struct spi_nor *nor, struct spi_mem_op > *op, void *buf) > { > diff --git a/drivers/spi/stm32_qspi.c b/drivers/spi/stm32_qspi.c > index 3b92254a5ce1..8b60d7c3b224 100644 > --- a/drivers/spi/stm32_qspi.c > +++ b/drivers/spi/stm32_qspi.c > @@ -271,9 +271,9 @@ static void _stm32_qspi_enable_mmap(struct > stm32_qspi_priv *priv, > { > unsigned int ccr_reg; > > - priv->command = flash->read_cmd | CMD_HAS_ADR | CMD_HAS_DATA > + priv->command = flash->read_opcode | CMD_HAS_ADR | CMD_HAS_DATA > | CMD_HAS_DUMMY; > - priv->dummycycles = flash->dummy_byte * 8; > + priv->dummycycles = flash->read_dummy; > > ccr_reg = _stm32_qspi_gen_ccr(priv, STM32_QSPI_CCR_MEM_MAP); > > diff --git a/include/spi_flash.h b/include/spi_flash.h > index e427e960d54f..7f691e8559cd 100644 > --- a/include/spi_flash.h > +++ b/include/spi_flash.h > @@ -11,6 +11,7 @@ > > #include <dm.h> /* Because we dereference struct udevice here */ > #include <linux/types.h> > +#include <linux/mtd/spi-nor.h> > > #ifndef CONFIG_SF_DEFAULT_SPEED > # define CONFIG_SF_DEFAULT_SPEED 1000000 > @@ -27,86 +28,6 @@ > > struct spi_slave; > > -/** > - * struct spi_flash - SPI flash structure > - * > - * @spi: SPI slave > - * @dev: SPI flash device > - * @name: Name of SPI flash > - * @dual_flash: Indicates dual flash memories - dual stacked, > parallel > - * @shift: Flash shift useful in dual parallel > - * @flags: Indication of spi flash flags > - * @size: Total flash size > - * @page_size: Write (page) size > - * @sector_size: Sector size > - * @erase_size: Erase size > - * @bank_read_cmd: Bank read cmd > - * @bank_write_cmd: Bank write cmd > - * @bank_curr: Current flash bank > - * @erase_cmd: Erase cmd 4K, 32K, 64K > - * @read_cmd: Read cmd - Array Fast, Extn read and quad read. > - * @write_cmd: Write cmd - page and quad program. > - * @dummy_byte: Dummy cycles for read operation. > - * @memory_map: Address of read-only SPI flash access > - * @flash_lock: lock a region of the SPI Flash > - * @flash_unlock: unlock a region of the SPI Flash > - * @flash_is_locked: check if a region of the SPI Flash is completely > locked > - * @read: Flash read ops: Read len bytes at offset into buf > - * Supported cmds: Fast Array Read > - * @write: Flash write ops: Write len bytes from buf into offset > - * Supported cmds: Page Program > - * @erase: Flash erase ops: Erase len bytes from offset > - * Supported cmds: Sector erase 4K, 32K, 64K > - * return 0 - Success, 1 - Failure > - */ > -struct spi_flash { > - struct spi_slave *spi; > -#ifdef CONFIG_DM_SPI_FLASH > - struct udevice *dev; > -#endif > - const char *name; > - u8 dual_flash; > - u8 shift; > - u16 flags; > - > - u32 size; > - u32 page_size; > - u32 sector_size; > - u32 erase_size; > -#ifdef CONFIG_SPI_FLASH_BAR > - u8 bank_read_cmd; > - u8 bank_write_cmd; > - u8 bank_curr; > -#endif > - u8 erase_cmd; > - u8 read_cmd; > - u8 write_cmd; > - u8 dummy_byte; > - > - void *memory_map; > - > - int (*flash_lock)(struct spi_flash *flash, u32 ofs, size_t len); > - int (*flash_unlock)(struct spi_flash *flash, u32 ofs, size_t len); > - int (*flash_is_locked)(struct spi_flash *flash, u32 ofs, size_t len); > -#ifndef CONFIG_DM_SPI_FLASH > - /* > - * These are not strictly needed for driver model, but keep them here > - * while the transition is in progress. > - * > - * Normally each driver would provide its own operations, but for > - * SPI flash most chips use the same algorithms. One approach is > - * to create a 'common' SPI flash device which knows how to talk > - * to most devices, and then allow other drivers to be used instead > - * if required, perhaps with a way of scanning through the list to > - * find the driver that matches the device. > - */ > - int (*read)(struct spi_flash *flash, u32 offset, size_t len, void > *buf); > - int (*write)(struct spi_flash *flash, u32 offset, size_t len, > - const void *buf); > - int (*erase)(struct spi_flash *flash, u32 offset, size_t len); > -#endif > -}; > - > struct dm_spi_flash_ops { > int (*read)(struct udevice *dev, u32 offset, size_t len, void *buf); > int (*write)(struct udevice *dev, u32 offset, size_t len, > @@ -225,19 +146,37 @@ void spi_flash_free(struct spi_flash *flash); > static inline int spi_flash_read(struct spi_flash *flash, u32 offset, > size_t len, void *buf) > { > - return flash->read(flash, offset, len, buf); > + struct mtd_info *mtd = &flash->mtd; > + size_t retlen; > + > + return mtd->_read(mtd, offset, len, &retlen, buf); > } > > static inline int spi_flash_write(struct spi_flash *flash, u32 offset, > size_t len, const void *buf) > { > - return flash->write(flash, offset, len, buf); > + struct mtd_info *mtd = &flash->mtd; > + size_t retlen; > + > + return mtd->_write(mtd, offset, len, &retlen, buf); > } > > static inline int spi_flash_erase(struct spi_flash *flash, u32 offset, > size_t len) > { > - return flash->erase(flash, offset, len); > + struct mtd_info *mtd = &flash->mtd; > + struct erase_info instr; > + > + if (offset % mtd->erasesize || len % mtd->erasesize) { > + printf("SF: Erase offset/length not multiple of erase > size\n"); > + return -EINVAL; > + } > + > + memset(&instr, 0, sizeof(instr)); > + instr.addr = offset; > + instr.len = len; > + > + return mtd->_erase(mtd, &instr); > } > #endif > > -- > 2.19.2 > _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de https://lists.denx.de/listinfo/u-boot