
On Tue, Dec 4, 2018 at 1:27 PM Vignesh R vigneshr@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 vigneshr@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