Skip to content

Commit 44a2f49

Browse files
committed
mtd: spinand: winbond: W35N octal DTR support
Extend the support for the W35N chip family by supporting the ODTR bus interface. The chip is capable to run in this mode, which brings a significant performance improvement. 1S-8S-8S: # flash_speed /dev/mtd0 -c1 -d eraseblock write speed is 7529 KiB/s eraseblock read speed is 15058 KiB/s 8D-8D-8D: # flash_speed /dev/mtd0 -c1 -d eraseblock write speed is 9481 KiB/s eraseblock read speed is 23272 KiB/s This is +55% read speed and +26% write speed with the same hardware. Tests have been conducted with a TI AM62A7 using the Cadence quad SPI controller. Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
1 parent 76b7dc7 commit 44a2f49

1 file changed

Lines changed: 18 additions & 2 deletions

File tree

drivers/mtd/nand/spi/winbond.c

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@
3636
*/
3737

3838
static SPINAND_OP_VARIANTS(read_cache_octal_variants,
39+
SPINAND_PAGE_READ_FROM_CACHE_8D_8D_8D_OP(0, 24, NULL, 0, 120 * HZ_PER_MHZ),
40+
SPINAND_PAGE_READ_FROM_CACHE_8D_8D_8D_OP(0, 16, NULL, 0, 86 * HZ_PER_MHZ),
3941
SPINAND_PAGE_READ_FROM_CACHE_1S_1D_8D_OP(0, 3, NULL, 0, 120 * HZ_PER_MHZ),
4042
SPINAND_PAGE_READ_FROM_CACHE_1S_1D_8D_OP(0, 2, NULL, 0, 105 * HZ_PER_MHZ),
4143
SPINAND_PAGE_READ_FROM_CACHE_1S_8S_8S_OP(0, 20, NULL, 0, 0),
@@ -48,11 +50,13 @@ static SPINAND_OP_VARIANTS(read_cache_octal_variants,
4850
SPINAND_PAGE_READ_FROM_CACHE_1S_1S_1S_OP(0, 1, NULL, 0, 0));
4951

5052
static SPINAND_OP_VARIANTS(write_cache_octal_variants,
53+
SPINAND_PROG_LOAD_8D_8D_8D_OP(true, 0, NULL, 0),
5154
SPINAND_PROG_LOAD_1S_8S_8S_OP(true, 0, NULL, 0),
5255
SPINAND_PROG_LOAD_1S_1S_8S_OP(0, NULL, 0),
5356
SPINAND_PROG_LOAD_1S_1S_1S_OP(true, 0, NULL, 0));
5457

5558
static SPINAND_OP_VARIANTS(update_cache_octal_variants,
59+
SPINAND_PROG_LOAD_8D_8D_8D_OP(false, 0, NULL, 0),
5660
SPINAND_PROG_LOAD_1S_8S_8S_OP(false, 0, NULL, 0),
5761
SPINAND_PROG_LOAD_1S_1S_1S_OP(false, 0, NULL, 0));
5862

@@ -93,13 +97,22 @@ static SPINAND_OP_VARIANTS(update_cache_variants,
9397
SPI_MEM_OP_NO_DUMMY, \
9498
SPI_MEM_OP_DATA_OUT(1, buf, 1))
9599

100+
#define SPINAND_WINBOND_WRITE_VCR_8D_8D_8D(reg, buf) \
101+
SPI_MEM_OP(SPI_MEM_DTR_OP_RPT_CMD(0x81, 8), \
102+
SPI_MEM_DTR_OP_ADDR(4, reg, 8), \
103+
SPI_MEM_OP_NO_DUMMY, \
104+
SPI_MEM_DTR_OP_DATA_OUT(2, buf, 8))
105+
96106
static SPINAND_OP_VARIANTS(winbond_w35_ops,
97-
SPINAND_WINBOND_WRITE_VCR_1S_1S_1S(0, NULL));
107+
SPINAND_WINBOND_WRITE_VCR_1S_1S_1S(0, NULL),
108+
SPINAND_WINBOND_WRITE_VCR_8D_8D_8D(0, NULL));
98109

99110
static struct spi_mem_op
100111
spinand_fill_winbond_write_vcr_op(struct spinand_device *spinand, u8 reg, void *valptr)
101112
{
102-
return (struct spi_mem_op)SPINAND_WINBOND_WRITE_VCR_1S_1S_1S(reg, valptr);
113+
return (spinand->bus_iface == SSDR) ?
114+
(struct spi_mem_op)SPINAND_WINBOND_WRITE_VCR_1S_1S_1S(reg, valptr) :
115+
(struct spi_mem_op)SPINAND_WINBOND_WRITE_VCR_8D_8D_8D(reg, valptr);
103116
}
104117

105118
#define SPINAND_WINBOND_SELECT_TARGET_1S_0_1S(buf) \
@@ -390,6 +403,9 @@ static int w35n0xjw_vcr_cfg(struct spinand_device *spinand,
390403
case SSDR:
391404
ref_op = spinand->ssdr_op_templates.read_cache;
392405
break;
406+
case ODTR:
407+
ref_op = spinand->odtr_op_templates.read_cache;
408+
break;
393409
default:
394410
return -EOPNOTSUPP;
395411
};

0 commit comments

Comments
 (0)