blob: 8f8f1da15a2f2024a26f06290344c6b845cdaa94 [file] [log] [blame]
developer41370d52022-03-16 16:01:59 +08001From 9f9ae0c253c1e058fbc845e26c4a32a7d777f0dc Mon Sep 17 00:00:00 2001
2From: Shivamurthy Shastri <sshivamurthy@micron.com>
3Date: Wed, 11 Mar 2020 18:57:35 +0100
4Subject: [PATCH] mtd: spinand: micron: Add new Micron SPI NAND devices with
5 multiple dies
6
7Add device table for new Micron SPI NAND devices, which have multiple
8dies.
9
10Also, enable support to select the dies.
11
12Signed-off-by: Shivamurthy Shastri <sshivamurthy@micron.com>
13Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com>
14Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
15Link: https://lore.kernel.org/linux-mtd/20200311175735.2007-7-sshivamurthy@micron.com
16---
17 drivers/mtd/nand/spi/micron.c | 58 +++++++++++++++++++++++++++++++++++
18 1 file changed, 58 insertions(+)
19
20diff --git a/drivers/mtd/nand/spi/micron.c b/drivers/mtd/nand/spi/micron.c
21index d6fd630087822c..5d370cfcdaaaa9 100644
22--- a/drivers/mtd/nand/spi/micron.c
23+++ b/drivers/mtd/nand/spi/micron.c
24@@ -20,6 +20,14 @@
25
26 #define MICRON_CFG_CR BIT(0)
27
28+/*
29+ * As per datasheet, die selection is done by the 6th bit of Die
30+ * Select Register (Address 0xD0).
31+ */
32+#define MICRON_DIE_SELECT_REG 0xD0
33+
34+#define MICRON_SELECT_DIE(x) ((x) << 6)
35+
36 static SPINAND_OP_VARIANTS(read_cache_variants,
37 SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 2, NULL, 0),
38 SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0),
39@@ -66,6 +74,20 @@ static const struct mtd_ooblayout_ops micron_8_ooblayout = {
40 .free = micron_8_ooblayout_free,
41 };
42
43+static int micron_select_target(struct spinand_device *spinand,
44+ unsigned int target)
45+{
46+ struct spi_mem_op op = SPINAND_SET_FEATURE_OP(MICRON_DIE_SELECT_REG,
47+ spinand->scratchbuf);
48+
49+ if (target > 1)
50+ return -EINVAL;
51+
52+ *spinand->scratchbuf = MICRON_SELECT_DIE(target);
53+
54+ return spi_mem_exec_op(spinand->spimem, &op);
55+}
56+
57 static int micron_8_ecc_get_status(struct spinand_device *spinand,
58 u8 status)
59 {
60@@ -137,6 +159,18 @@ static const struct spinand_info micron_spinand_table[] = {
61 0,
62 SPINAND_ECCINFO(&micron_8_ooblayout,
63 micron_8_ecc_get_status)),
64+ /* M79A 4Gb 3.3V */
65+ SPINAND_INFO("MT29F4G01ADAGD",
66+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x36),
67+ NAND_MEMORG(1, 2048, 128, 64, 2048, 80, 2, 1, 2),
68+ NAND_ECCREQ(8, 512),
69+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
70+ &write_cache_variants,
71+ &update_cache_variants),
72+ 0,
73+ SPINAND_ECCINFO(&micron_8_ooblayout,
74+ micron_8_ecc_get_status),
75+ SPINAND_SELECT_TARGET(micron_select_target)),
76 /* M70A 4Gb 3.3V */
77 SPINAND_INFO("MT29F4G01ABAFD",
78 SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x34),
79@@ -159,6 +193,30 @@ static const struct spinand_info micron_spinand_table[] = {
80 SPINAND_HAS_CR_FEAT_BIT,
81 SPINAND_ECCINFO(&micron_8_ooblayout,
82 micron_8_ecc_get_status)),
83+ /* M70A 8Gb 3.3V */
84+ SPINAND_INFO("MT29F8G01ADAFD",
85+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x46),
86+ NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 1, 1, 2),
87+ NAND_ECCREQ(8, 512),
88+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
89+ &write_cache_variants,
90+ &update_cache_variants),
91+ SPINAND_HAS_CR_FEAT_BIT,
92+ SPINAND_ECCINFO(&micron_8_ooblayout,
93+ micron_8_ecc_get_status),
94+ SPINAND_SELECT_TARGET(micron_select_target)),
95+ /* M70A 8Gb 1.8V */
96+ SPINAND_INFO("MT29F8G01ADBFD",
97+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x47),
98+ NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 1, 1, 2),
99+ NAND_ECCREQ(8, 512),
100+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
101+ &write_cache_variants,
102+ &update_cache_variants),
103+ SPINAND_HAS_CR_FEAT_BIT,
104+ SPINAND_ECCINFO(&micron_8_ooblayout,
105+ micron_8_ecc_get_status),
106+ SPINAND_SELECT_TARGET(micron_select_target)),
107 };
108
109 static int micron_spinand_init(struct spinand_device *spinand)