1111#include <linux/kernel.h>
1212#include <linux/mtd/spinand.h>
1313#include <linux/units.h>
14+ #include <linux/delay.h>
1415
1516#define SPINAND_MFR_WINBOND 0xEF
1617
2122#define W25N0XJW_SR4 0xD0
2223#define W25N0XJW_SR4_HS BIT(2)
2324
25+ #define W35N01JW_VCR_IO_MODE 0x00
26+ #define W35N01JW_VCR_IO_MODE_SINGLE_SDR 0xFF
27+ #define W35N01JW_VCR_IO_MODE_OCTAL_SDR 0xDF
28+ #define W35N01JW_VCR_IO_MODE_OCTAL_DDR_DS 0xE7
29+ #define W35N01JW_VCR_IO_MODE_OCTAL_DDR 0xC7
30+ #define W35N01JW_VCR_DUMMY_CLOCK_REG 0x01
31+
2432/*
2533 * "X2" in the core is equivalent to "dual output" in the datasheets,
2634 * "X4" in the core is equivalent to "quad output" in the datasheets.
2735 */
2836
2937static SPINAND_OP_VARIANTS (read_cache_octal_variants ,
38+ SPINAND_PAGE_READ_FROM_CACHE_1S_1D_8D_OP (0 , 3 , NULL, 0 , 120 * HZ_PER_MHZ ),
3039 SPINAND_PAGE_READ_FROM_CACHE_1S_1D_8D_OP (0 , 2 , NULL, 0 , 105 * HZ_PER_MHZ ),
40+ SPINAND_PAGE_READ_FROM_CACHE_1S_8S_8S_OP (0 , 20 , NULL , 0 , 0 ),
3141 SPINAND_PAGE_READ_FROM_CACHE_1S_8S_8S_OP (0 , 16 , NULL, 0 , 162 * HZ_PER_MHZ ),
42+ SPINAND_PAGE_READ_FROM_CACHE_1S_8S_8S_OP (0 , 12 , NULL , 0 , 124 * HZ_PER_MHZ ),
43+ SPINAND_PAGE_READ_FROM_CACHE_1S_8S_8S_OP (0 , 8 , NULL , 0 , 86 * HZ_PER_MHZ ),
44+ SPINAND_PAGE_READ_FROM_CACHE_1S_1S_8S_OP (0 , 2 , NULL , 0 , 0 ),
3245 SPINAND_PAGE_READ_FROM_CACHE_1S_1S_8S_OP (0 , 1 , NULL, 0 , 133 * HZ_PER_MHZ ),
3346 SPINAND_PAGE_READ_FROM_CACHE_FAST_1S_1S_1S_OP (0 , 1 , NULL , 0 , 0 ),
3447 SPINAND_PAGE_READ_FROM_CACHE_1S_1S_1S_OP (0 , 1 , NULL, 0 , 0 ));
@@ -269,6 +282,79 @@ static int w25n0xjw_hs_cfg(struct spinand_device *spinand)
269282 return 0 ;
270283}
271284
285+ static int w35n0xjw_write_vcr (struct spinand_device * spinand , u8 reg , u8 val )
286+ {
287+ struct spi_mem_op op =
288+ SPI_MEM_OP (SPI_MEM_OP_CMD (0x81 , 1 ),
289+ SPI_MEM_OP_ADDR (3 , reg , 1 ),
290+ SPI_MEM_OP_NO_DUMMY ,
291+ SPI_MEM_OP_DATA_OUT (1 , spinand -> scratchbuf , 1 ));
292+ int ret ;
293+
294+ * spinand -> scratchbuf = val ;
295+
296+ ret = spinand_write_enable_op (spinand );
297+ if (ret )
298+ return ret ;
299+
300+ ret = spi_mem_exec_op (spinand -> spimem , & op );
301+ if (ret )
302+ return ret ;
303+
304+ /*
305+ * Write VCR operation doesn't set the busy bit in SR, which means we
306+ * cannot perform a status poll. Minimum time of 50ns is needed to
307+ * complete the write.
308+ */
309+ ndelay (50 );
310+
311+ return 0 ;
312+ }
313+
314+ static int w35n0xjw_vcr_cfg (struct spinand_device * spinand )
315+ {
316+ const struct spi_mem_op * op ;
317+ unsigned int dummy_cycles ;
318+ bool dtr , single ;
319+ u8 io_mode ;
320+ int ret ;
321+
322+ op = spinand -> op_templates .read_cache ;
323+
324+ single = (op -> cmd .buswidth == 1 && op -> addr .buswidth == 1 && op -> data .buswidth == 1 );
325+ dtr = (op -> cmd .dtr || op -> addr .dtr || op -> data .dtr );
326+ if (single && !dtr )
327+ io_mode = W35N01JW_VCR_IO_MODE_SINGLE_SDR ;
328+ else if (!single && !dtr )
329+ io_mode = W35N01JW_VCR_IO_MODE_OCTAL_SDR ;
330+ else if (!single && dtr )
331+ io_mode = W35N01JW_VCR_IO_MODE_OCTAL_DDR ;
332+ else
333+ return - EINVAL ;
334+
335+ ret = w35n0xjw_write_vcr (spinand , W35N01JW_VCR_IO_MODE , io_mode );
336+ if (ret )
337+ return ret ;
338+
339+ dummy_cycles = ((op -> dummy .nbytes * 8 ) / op -> dummy .buswidth ) / (op -> dummy .dtr ? 2 : 1 );
340+ switch (dummy_cycles ) {
341+ case 8 :
342+ case 12 :
343+ case 16 :
344+ case 20 :
345+ case 24 :
346+ case 28 :
347+ break ;
348+ default :
349+ return - EINVAL ;
350+ }
351+ ret = w35n0xjw_write_vcr (spinand , W35N01JW_VCR_DUMMY_CLOCK_REG , dummy_cycles );
352+ if (ret )
353+ return ret ;
354+
355+ return 0 ;
356+ }
357+
272358static const struct spinand_info winbond_spinand_table [] = {
273359 /* 512M-bit densities */
274360 SPINAND_INFO ("W25N512GW" , /* 1.8V */
@@ -326,7 +412,8 @@ static const struct spinand_info winbond_spinand_table[] = {
326412 & write_cache_octal_variants ,
327413 & update_cache_octal_variants ),
328414 0 ,
329- SPINAND_ECCINFO (& w35n01jw_ooblayout , NULL )),
415+ SPINAND_ECCINFO (& w35n01jw_ooblayout , NULL ),
416+ SPINAND_CONFIGURE_CHIP (w35n0xjw_vcr_cfg )),
330417 SPINAND_INFO ("W35N02JW" , /* 1.8V */
331418 SPINAND_ID (SPINAND_READID_METHOD_OPCODE_DUMMY , 0xdf , 0x22 ),
332419 NAND_MEMORG (1 , 4096 , 128 , 64 , 512 , 10 , 1 , 2 , 1 ),
@@ -335,7 +422,8 @@ static const struct spinand_info winbond_spinand_table[] = {
335422 & write_cache_octal_variants ,
336423 & update_cache_octal_variants ),
337424 0 ,
338- SPINAND_ECCINFO (& w35n01jw_ooblayout , NULL )),
425+ SPINAND_ECCINFO (& w35n01jw_ooblayout , NULL ),
426+ SPINAND_CONFIGURE_CHIP (w35n0xjw_vcr_cfg )),
339427 SPINAND_INFO ("W35N04JW" , /* 1.8V */
340428 SPINAND_ID (SPINAND_READID_METHOD_OPCODE_DUMMY , 0xdf , 0x23 ),
341429 NAND_MEMORG (1 , 4096 , 128 , 64 , 512 , 10 , 1 , 4 , 1 ),
@@ -344,7 +432,8 @@ static const struct spinand_info winbond_spinand_table[] = {
344432 & write_cache_octal_variants ,
345433 & update_cache_octal_variants ),
346434 0 ,
347- SPINAND_ECCINFO (& w35n01jw_ooblayout , NULL )),
435+ SPINAND_ECCINFO (& w35n01jw_ooblayout , NULL ),
436+ SPINAND_CONFIGURE_CHIP (w35n0xjw_vcr_cfg )),
348437 /* 2G-bit densities */
349438 SPINAND_INFO ("W25M02GV" , /* 2x1G-bit 3.3V */
350439 SPINAND_ID (SPINAND_READID_METHOD_OPCODE_DUMMY , 0xab , 0x21 ),
0 commit comments