Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit dbbafb74 authored by Geert Uytterhoeven's avatar Geert Uytterhoeven Committed by Brian Norris
Browse files

mtd: m25p80: Add dual read support



Add support for Dual SPI read transfers, which is supported by some
Spansion SPI FLASHes.

Signed-off-by: default avatarGeert Uytterhoeven <geert+renesas@linux-m68k.org>
Acked-by: default avatarMarek Vasut <marex@denx.de>
Signed-off-by: default avatarBrian Norris <computersforpeace@gmail.com>
parent fa389e22
Loading
Loading
Loading
Loading
+19 −4
Original line number Diff line number Diff line
@@ -41,7 +41,8 @@
#define	OPCODE_WRSR		0x01	/* Write status register 1 byte */
#define	OPCODE_NORM_READ	0x03	/* Read data bytes (low frequency) */
#define	OPCODE_FAST_READ	0x0b	/* Read data bytes (high frequency) */
#define	OPCODE_QUAD_READ        0x6b    /* Read data bytes */
#define	OPCODE_DUAL_READ        0x3b    /* Read data bytes (Dual SPI) */
#define	OPCODE_QUAD_READ        0x6b    /* Read data bytes (Quad SPI) */
#define	OPCODE_PP		0x02	/* Page program (up to 256 bytes) */
#define	OPCODE_BE_4K		0x20	/* Erase 4KiB block */
#define	OPCODE_BE_4K_PMC	0xd7	/* Erase 4KiB block on PMC chips */
@@ -54,7 +55,8 @@
/* 4-byte address opcodes - used on Spansion and some Macronix flashes. */
#define	OPCODE_NORM_READ_4B	0x13	/* Read data bytes (low frequency) */
#define	OPCODE_FAST_READ_4B	0x0c	/* Read data bytes (high frequency) */
#define	OPCODE_QUAD_READ_4B	0x6c    /* Read data bytes */
#define	OPCODE_DUAL_READ_4B	0x3c    /* Read data bytes (Dual SPI) */
#define	OPCODE_QUAD_READ_4B	0x6c    /* Read data bytes (Quad SPI) */
#define	OPCODE_PP_4B		0x12	/* Page program (up to 256 bytes) */
#define	OPCODE_SE_4B		0xdc	/* Sector erase (usually 64KiB) */

@@ -95,6 +97,7 @@
enum read_type {
	M25P80_NORMAL = 0,
	M25P80_FAST,
	M25P80_DUAL,
	M25P80_QUAD,
};

@@ -479,6 +482,7 @@ static inline int m25p80_dummy_cycles_read(struct m25p *flash)
{
	switch (flash->flash_read) {
	case M25P80_FAST:
	case M25P80_DUAL:
	case M25P80_QUAD:
		return 1;
	case M25P80_NORMAL:
@@ -492,6 +496,8 @@ static inline int m25p80_dummy_cycles_read(struct m25p *flash)
static inline unsigned int m25p80_rx_nbits(const struct m25p *flash)
{
	switch (flash->flash_read) {
	case M25P80_DUAL:
		return 2;
	case M25P80_QUAD:
		return 4;
	default:
@@ -855,7 +861,8 @@ struct flash_info {
#define	SST_WRITE	0x04		/* use SST byte programming */
#define	M25P_NO_FR	0x08		/* Can't do fastread */
#define	SECT_4K_PMC	0x10		/* OPCODE_BE_4K_PMC works uniformly */
#define	M25P80_QUAD_READ	0x20    /* Flash supports Quad Read */
#define	M25P80_DUAL_READ	0x20    /* Flash supports Dual Read */
#define	M25P80_QUAD_READ	0x40    /* Flash supports Quad Read */
};

#define INFO(_jedec_id, _ext_id, _sector_size, _n_sectors, _flags)	\
@@ -1226,7 +1233,7 @@ static int m25p_probe(struct spi_device *spi)
	if (info->flags & M25P_NO_FR)
		flash->flash_read = M25P80_NORMAL;

	/* Quad-read mode takes precedence over fast/normal */
	/* Quad/Dual-read mode takes precedence over fast/normal */
	if (spi->mode & SPI_RX_QUAD && info->flags & M25P80_QUAD_READ) {
		ret = set_quad_mode(flash, info->jedec_id);
		if (ret) {
@@ -1234,6 +1241,8 @@ static int m25p_probe(struct spi_device *spi)
			return ret;
		}
		flash->flash_read = M25P80_QUAD;
	} else if (spi->mode & SPI_RX_DUAL && info->flags & M25P80_DUAL_READ) {
		flash->flash_read = M25P80_DUAL;
	}

	/* Default commands */
@@ -1241,6 +1250,9 @@ static int m25p_probe(struct spi_device *spi)
	case M25P80_QUAD:
		flash->read_opcode = OPCODE_QUAD_READ;
		break;
	case M25P80_DUAL:
		flash->read_opcode = OPCODE_DUAL_READ;
		break;
	case M25P80_FAST:
		flash->read_opcode = OPCODE_FAST_READ;
		break;
@@ -1265,6 +1277,9 @@ static int m25p_probe(struct spi_device *spi)
			case M25P80_QUAD:
				flash->read_opcode = OPCODE_QUAD_READ_4B;
				break;
			case M25P80_DUAL:
				flash->read_opcode = OPCODE_DUAL_READ_4B;
				break;
			case M25P80_FAST:
				flash->read_opcode = OPCODE_FAST_READ_4B;
				break;