On 05/12/18 12:34 PM, Simon Goldschmidt wrote: > 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. >
I agree, will fix that in next revision. Regards Vignesh > 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 >> -- Regards Vignesh _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de https://lists.denx.de/listinfo/u-boot