11
11
#include <linux/kernel.h>
12
12
#include <linux/mtd/spinand.h>
13
13
#include <linux/units.h>
14
+ #include <linux/delay.h>
14
15
15
16
#define SPINAND_MFR_WINBOND 0xEF
16
17
21
22
#define W25N0XJW_SR4 0xD0
22
23
#define W25N0XJW_SR4_HS BIT(2)
23
24
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
+
24
32
/*
25
33
* "X2" in the core is equivalent to "dual output" in the datasheets,
26
34
* "X4" in the core is equivalent to "quad output" in the datasheets.
27
35
*/
28
36
29
37
static 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 ),
30
39
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 ),
31
41
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 ),
32
45
SPINAND_PAGE_READ_FROM_CACHE_1S_1S_8S_OP (0 , 1 , NULL, 0 , 133 * HZ_PER_MHZ ),
33
46
SPINAND_PAGE_READ_FROM_CACHE_FAST_1S_1S_1S_OP (0 , 1 , NULL , 0 , 0 ),
34
47
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)
269
282
return 0 ;
270
283
}
271
284
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
+
272
358
static const struct spinand_info winbond_spinand_table [] = {
273
359
/* 512M-bit densities */
274
360
SPINAND_INFO ("W25N512GW" , /* 1.8V */
@@ -326,7 +412,8 @@ static const struct spinand_info winbond_spinand_table[] = {
326
412
& write_cache_octal_variants ,
327
413
& update_cache_octal_variants ),
328
414
0 ,
329
- SPINAND_ECCINFO (& w35n01jw_ooblayout , NULL )),
415
+ SPINAND_ECCINFO (& w35n01jw_ooblayout , NULL ),
416
+ SPINAND_CONFIGURE_CHIP (w35n0xjw_vcr_cfg )),
330
417
SPINAND_INFO ("W35N02JW" , /* 1.8V */
331
418
SPINAND_ID (SPINAND_READID_METHOD_OPCODE_DUMMY , 0xdf , 0x22 ),
332
419
NAND_MEMORG (1 , 4096 , 128 , 64 , 512 , 10 , 1 , 2 , 1 ),
@@ -335,7 +422,8 @@ static const struct spinand_info winbond_spinand_table[] = {
335
422
& write_cache_octal_variants ,
336
423
& update_cache_octal_variants ),
337
424
0 ,
338
- SPINAND_ECCINFO (& w35n01jw_ooblayout , NULL )),
425
+ SPINAND_ECCINFO (& w35n01jw_ooblayout , NULL ),
426
+ SPINAND_CONFIGURE_CHIP (w35n0xjw_vcr_cfg )),
339
427
SPINAND_INFO ("W35N04JW" , /* 1.8V */
340
428
SPINAND_ID (SPINAND_READID_METHOD_OPCODE_DUMMY , 0xdf , 0x23 ),
341
429
NAND_MEMORG (1 , 4096 , 128 , 64 , 512 , 10 , 1 , 4 , 1 ),
@@ -344,7 +432,8 @@ static const struct spinand_info winbond_spinand_table[] = {
344
432
& write_cache_octal_variants ,
345
433
& update_cache_octal_variants ),
346
434
0 ,
347
- SPINAND_ECCINFO (& w35n01jw_ooblayout , NULL )),
435
+ SPINAND_ECCINFO (& w35n01jw_ooblayout , NULL ),
436
+ SPINAND_CONFIGURE_CHIP (w35n0xjw_vcr_cfg )),
348
437
/* 2G-bit densities */
349
438
SPINAND_INFO ("W25M02GV" , /* 2x1G-bit 3.3V */
350
439
SPINAND_ID (SPINAND_READID_METHOD_OPCODE_DUMMY , 0xab , 0x21 ),
0 commit comments