kernel: add mtk patches
This commit is contained in:
@@ -0,0 +1,708 @@
|
||||
--- a/drivers/mtd/nand/spi/core.c
|
||||
+++ b/drivers/mtd/nand/spi/core.c
|
||||
@@ -16,6 +16,7 @@
|
||||
#include <linux/mtd/spinand.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/slab.h>
|
||||
+#include <linux/string.h>
|
||||
#include <linux/spi/spi.h>
|
||||
#include <linux/spi/spi-mem.h>
|
||||
|
||||
@@ -370,10 +371,11 @@ out:
|
||||
return status & STATUS_BUSY ? -ETIMEDOUT : 0;
|
||||
}
|
||||
|
||||
-static int spinand_read_id_op(struct spinand_device *spinand, u8 *buf)
|
||||
+static int spinand_read_id_op(struct spinand_device *spinand, u8 naddr,
|
||||
+ u8 ndummy, u8 *buf)
|
||||
{
|
||||
- struct spi_mem_op op = SPINAND_READID_OP(0, spinand->scratchbuf,
|
||||
- SPINAND_MAX_ID_LEN);
|
||||
+ struct spi_mem_op op = SPINAND_READID_OP(
|
||||
+ naddr, ndummy, spinand->scratchbuf, SPINAND_MAX_ID_LEN);
|
||||
int ret;
|
||||
|
||||
ret = spi_mem_exec_op(spinand->spimem, &op);
|
||||
@@ -760,24 +762,62 @@ static const struct spinand_manufacturer
|
||||
&winbond_spinand_manufacturer,
|
||||
};
|
||||
|
||||
-static int spinand_manufacturer_detect(struct spinand_device *spinand)
|
||||
+static int spinand_manufacturer_match(struct spinand_device *spinand,
|
||||
+ enum spinand_readid_method rdid_method)
|
||||
{
|
||||
+ u8 *id = spinand->id.data;
|
||||
unsigned int i;
|
||||
int ret;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(spinand_manufacturers); i++) {
|
||||
- ret = spinand_manufacturers[i]->ops->detect(spinand);
|
||||
- if (ret > 0) {
|
||||
- spinand->manufacturer = spinand_manufacturers[i];
|
||||
- return 0;
|
||||
- } else if (ret < 0) {
|
||||
- return ret;
|
||||
- }
|
||||
- }
|
||||
+ const struct spinand_manufacturer *manufacturer =
|
||||
+ spinand_manufacturers[i];
|
||||
+
|
||||
+ if (id[0] != manufacturer->id)
|
||||
+ continue;
|
||||
|
||||
+ ret = spinand_match_and_init(spinand,
|
||||
+ manufacturer->chips,
|
||||
+ manufacturer->nchips,
|
||||
+ rdid_method);
|
||||
+ if (ret < 0)
|
||||
+ continue;
|
||||
+
|
||||
+ spinand->manufacturer = manufacturer;
|
||||
+ return 0;
|
||||
+ }
|
||||
return -ENOTSUPP;
|
||||
}
|
||||
|
||||
+static int spinand_id_detect(struct spinand_device *spinand)
|
||||
+{
|
||||
+ u8 *id = spinand->id.data;
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = spinand_read_id_op(spinand, 0, 0, id);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+ ret = spinand_manufacturer_match(spinand, SPINAND_READID_METHOD_OPCODE);
|
||||
+ if (!ret)
|
||||
+ return 0;
|
||||
+
|
||||
+ ret = spinand_read_id_op(spinand, 1, 0, id);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+ ret = spinand_manufacturer_match(spinand,
|
||||
+ SPINAND_READID_METHOD_OPCODE_ADDR);
|
||||
+ if (!ret)
|
||||
+ return 0;
|
||||
+
|
||||
+ ret = spinand_read_id_op(spinand, 0, 1, id);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+ ret = spinand_manufacturer_match(spinand,
|
||||
+ SPINAND_READID_METHOD_OPCODE_DUMMY);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
static int spinand_manufacturer_init(struct spinand_device *spinand)
|
||||
{
|
||||
if (spinand->manufacturer->ops->init)
|
||||
@@ -833,9 +873,9 @@ spinand_select_op_variant(struct spinand
|
||||
* @spinand: SPI NAND object
|
||||
* @table: SPI NAND device description table
|
||||
* @table_size: size of the device description table
|
||||
+ * @rdid_method: read id method to match
|
||||
*
|
||||
- * Should be used by SPI NAND manufacturer drivers when they want to find a
|
||||
- * match between a device ID retrieved through the READ_ID command and an
|
||||
+ * Match between a device ID retrieved through the READ_ID command and an
|
||||
* entry in the SPI NAND description table. If a match is found, the spinand
|
||||
* object will be initialized with information provided by the matching
|
||||
* spinand_info entry.
|
||||
@@ -844,8 +884,10 @@ spinand_select_op_variant(struct spinand
|
||||
*/
|
||||
int spinand_match_and_init(struct spinand_device *spinand,
|
||||
const struct spinand_info *table,
|
||||
- unsigned int table_size, u16 devid)
|
||||
+ unsigned int table_size,
|
||||
+ enum spinand_readid_method rdid_method)
|
||||
{
|
||||
+ u8 *id = spinand->id.data;
|
||||
struct nand_device *nand = spinand_to_nand(spinand);
|
||||
unsigned int i;
|
||||
|
||||
@@ -853,13 +895,17 @@ int spinand_match_and_init(struct spinan
|
||||
const struct spinand_info *info = &table[i];
|
||||
const struct spi_mem_op *op;
|
||||
|
||||
- if (devid != info->devid)
|
||||
+ if (rdid_method != info->devid.method)
|
||||
+ continue;
|
||||
+
|
||||
+ if (memcmp(id + 1, info->devid.id, info->devid.len))
|
||||
continue;
|
||||
|
||||
nand->memorg = table[i].memorg;
|
||||
nand->eccreq = table[i].eccreq;
|
||||
spinand->eccinfo = table[i].eccinfo;
|
||||
spinand->flags = table[i].flags;
|
||||
+ spinand->id.len = 1 + table[i].devid.len;
|
||||
spinand->select_target = table[i].select_target;
|
||||
|
||||
op = spinand_select_op_variant(spinand,
|
||||
@@ -896,13 +942,7 @@ static int spinand_detect(struct spinand
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
- ret = spinand_read_id_op(spinand, spinand->id.data);
|
||||
- if (ret)
|
||||
- return ret;
|
||||
-
|
||||
- spinand->id.len = SPINAND_MAX_ID_LEN;
|
||||
-
|
||||
- ret = spinand_manufacturer_detect(spinand);
|
||||
+ ret = spinand_id_detect(spinand);
|
||||
if (ret) {
|
||||
dev_err(dev, "unknown raw ID %*phN\n", SPINAND_MAX_ID_LEN,
|
||||
spinand->id.data);
|
||||
--- a/drivers/mtd/nand/spi/gigadevice.c
|
||||
+++ b/drivers/mtd/nand/spi/gigadevice.c
|
||||
@@ -195,7 +195,8 @@ static int gd5fxgq4ufxxg_ecc_get_status(
|
||||
}
|
||||
|
||||
static const struct spinand_info gigadevice_spinand_table[] = {
|
||||
- SPINAND_INFO("GD5F1GQ4xA", 0xF1,
|
||||
+ SPINAND_INFO("GD5F1GQ4xA",
|
||||
+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xf1),
|
||||
NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1),
|
||||
NAND_ECCREQ(8, 512),
|
||||
SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
|
||||
@@ -204,7 +205,8 @@ static const struct spinand_info gigadev
|
||||
SPINAND_HAS_QE_BIT,
|
||||
SPINAND_ECCINFO(&gd5fxgq4xa_ooblayout,
|
||||
gd5fxgq4xa_ecc_get_status)),
|
||||
- SPINAND_INFO("GD5F2GQ4xA", 0xF2,
|
||||
+ SPINAND_INFO("GD5F2GQ4xA",
|
||||
+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xf2),
|
||||
NAND_MEMORG(1, 2048, 64, 64, 2048, 40, 1, 1, 1),
|
||||
NAND_ECCREQ(8, 512),
|
||||
SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
|
||||
@@ -213,7 +215,8 @@ static const struct spinand_info gigadev
|
||||
SPINAND_HAS_QE_BIT,
|
||||
SPINAND_ECCINFO(&gd5fxgq4xa_ooblayout,
|
||||
gd5fxgq4xa_ecc_get_status)),
|
||||
- SPINAND_INFO("GD5F4GQ4xA", 0xF4,
|
||||
+ SPINAND_INFO("GD5F4GQ4xA",
|
||||
+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xf4),
|
||||
NAND_MEMORG(1, 2048, 64, 64, 4096, 80, 1, 1, 1),
|
||||
NAND_ECCREQ(8, 512),
|
||||
SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
|
||||
@@ -222,7 +225,8 @@ static const struct spinand_info gigadev
|
||||
SPINAND_HAS_QE_BIT,
|
||||
SPINAND_ECCINFO(&gd5fxgq4xa_ooblayout,
|
||||
gd5fxgq4xa_ecc_get_status)),
|
||||
- SPINAND_INFO("GD5F1GQ4UExxG", 0xd1,
|
||||
+ SPINAND_INFO("GD5F1GQ4UExxG",
|
||||
+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xd1),
|
||||
NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
|
||||
NAND_ECCREQ(8, 512),
|
||||
SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
|
||||
@@ -231,7 +235,8 @@ static const struct spinand_info gigadev
|
||||
SPINAND_HAS_QE_BIT,
|
||||
SPINAND_ECCINFO(&gd5fxgq4_variant2_ooblayout,
|
||||
gd5fxgq4uexxg_ecc_get_status)),
|
||||
- SPINAND_INFO("GD5F1GQ4UFxxG", 0xb148,
|
||||
+ SPINAND_INFO("GD5F1GQ4UFxxG",
|
||||
+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE, 0xb1, 0x48),
|
||||
NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
|
||||
NAND_ECCREQ(8, 512),
|
||||
SPINAND_INFO_OP_VARIANTS(&read_cache_variants_f,
|
||||
@@ -242,39 +247,13 @@ static const struct spinand_info gigadev
|
||||
gd5fxgq4ufxxg_ecc_get_status)),
|
||||
};
|
||||
|
||||
-static int gigadevice_spinand_detect(struct spinand_device *spinand)
|
||||
-{
|
||||
- u8 *id = spinand->id.data;
|
||||
- u16 did;
|
||||
- int ret;
|
||||
-
|
||||
- /*
|
||||
- * Earlier GDF5-series devices (A,E) return [0][MID][DID]
|
||||
- * Later (F) devices return [MID][DID1][DID2]
|
||||
- */
|
||||
-
|
||||
- if (id[0] == SPINAND_MFR_GIGADEVICE)
|
||||
- did = (id[1] << 8) + id[2];
|
||||
- else if (id[0] == 0 && id[1] == SPINAND_MFR_GIGADEVICE)
|
||||
- did = id[2];
|
||||
- else
|
||||
- return 0;
|
||||
-
|
||||
- ret = spinand_match_and_init(spinand, gigadevice_spinand_table,
|
||||
- ARRAY_SIZE(gigadevice_spinand_table),
|
||||
- did);
|
||||
- if (ret)
|
||||
- return ret;
|
||||
-
|
||||
- return 1;
|
||||
-}
|
||||
-
|
||||
static const struct spinand_manufacturer_ops gigadevice_spinand_manuf_ops = {
|
||||
- .detect = gigadevice_spinand_detect,
|
||||
};
|
||||
|
||||
const struct spinand_manufacturer gigadevice_spinand_manufacturer = {
|
||||
.id = SPINAND_MFR_GIGADEVICE,
|
||||
.name = "GigaDevice",
|
||||
+ .chips = gigadevice_spinand_table,
|
||||
+ .nchips = ARRAY_SIZE(gigadevice_spinand_table),
|
||||
.ops = &gigadevice_spinand_manuf_ops,
|
||||
};
|
||||
--- a/drivers/mtd/nand/spi/macronix.c
|
||||
+++ b/drivers/mtd/nand/spi/macronix.c
|
||||
@@ -99,7 +99,8 @@ static int mx35lf1ge4ab_ecc_get_status(s
|
||||
}
|
||||
|
||||
static const struct spinand_info macronix_spinand_table[] = {
|
||||
- SPINAND_INFO("MX35LF1GE4AB", 0x12,
|
||||
+ SPINAND_INFO("MX35LF1GE4AB",
|
||||
+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x12),
|
||||
NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1),
|
||||
NAND_ECCREQ(4, 512),
|
||||
SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
|
||||
@@ -108,7 +109,8 @@ static const struct spinand_info macroni
|
||||
SPINAND_HAS_QE_BIT,
|
||||
SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
|
||||
mx35lf1ge4ab_ecc_get_status)),
|
||||
- SPINAND_INFO("MX35LF2GE4AB", 0x22,
|
||||
+ SPINAND_INFO("MX35LF2GE4AB",
|
||||
+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x22),
|
||||
NAND_MEMORG(1, 2048, 64, 64, 2048, 40, 2, 1, 1),
|
||||
NAND_ECCREQ(4, 512),
|
||||
SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
|
||||
@@ -118,33 +120,13 @@ static const struct spinand_info macroni
|
||||
SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, NULL)),
|
||||
};
|
||||
|
||||
-static int macronix_spinand_detect(struct spinand_device *spinand)
|
||||
-{
|
||||
- u8 *id = spinand->id.data;
|
||||
- int ret;
|
||||
-
|
||||
- /*
|
||||
- * Macronix SPI NAND read ID needs a dummy byte, so the first byte in
|
||||
- * raw_id is garbage.
|
||||
- */
|
||||
- if (id[1] != SPINAND_MFR_MACRONIX)
|
||||
- return 0;
|
||||
-
|
||||
- ret = spinand_match_and_init(spinand, macronix_spinand_table,
|
||||
- ARRAY_SIZE(macronix_spinand_table),
|
||||
- id[2]);
|
||||
- if (ret)
|
||||
- return ret;
|
||||
-
|
||||
- return 1;
|
||||
-}
|
||||
-
|
||||
static const struct spinand_manufacturer_ops macronix_spinand_manuf_ops = {
|
||||
- .detect = macronix_spinand_detect,
|
||||
};
|
||||
|
||||
const struct spinand_manufacturer macronix_spinand_manufacturer = {
|
||||
.id = SPINAND_MFR_MACRONIX,
|
||||
.name = "Macronix",
|
||||
+ .chips = macronix_spinand_table,
|
||||
+ .nchips = ARRAY_SIZE(macronix_spinand_table),
|
||||
.ops = ¯onix_spinand_manuf_ops,
|
||||
};
|
||||
--- a/drivers/mtd/nand/spi/micron.c
|
||||
+++ b/drivers/mtd/nand/spi/micron.c
|
||||
@@ -91,7 +91,8 @@ static int mt29f2g01abagd_ecc_get_status
|
||||
}
|
||||
|
||||
static const struct spinand_info micron_spinand_table[] = {
|
||||
- SPINAND_INFO("MT29F2G01ABAGD", 0x24,
|
||||
+ SPINAND_INFO("MT29F2G01ABAGD",
|
||||
+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x24),
|
||||
NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 2, 1, 1),
|
||||
NAND_ECCREQ(8, 512),
|
||||
SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
|
||||
@@ -102,32 +103,13 @@ static const struct spinand_info micron_
|
||||
mt29f2g01abagd_ecc_get_status)),
|
||||
};
|
||||
|
||||
-static int micron_spinand_detect(struct spinand_device *spinand)
|
||||
-{
|
||||
- u8 *id = spinand->id.data;
|
||||
- int ret;
|
||||
-
|
||||
- /*
|
||||
- * Micron SPI NAND read ID need a dummy byte,
|
||||
- * so the first byte in raw_id is dummy.
|
||||
- */
|
||||
- if (id[1] != SPINAND_MFR_MICRON)
|
||||
- return 0;
|
||||
-
|
||||
- ret = spinand_match_and_init(spinand, micron_spinand_table,
|
||||
- ARRAY_SIZE(micron_spinand_table), id[2]);
|
||||
- if (ret)
|
||||
- return ret;
|
||||
-
|
||||
- return 1;
|
||||
-}
|
||||
-
|
||||
static const struct spinand_manufacturer_ops micron_spinand_manuf_ops = {
|
||||
- .detect = micron_spinand_detect,
|
||||
};
|
||||
|
||||
const struct spinand_manufacturer micron_spinand_manufacturer = {
|
||||
.id = SPINAND_MFR_MICRON,
|
||||
.name = "Micron",
|
||||
+ .chips = micron_spinand_table,
|
||||
+ .nchips = ARRAY_SIZE(micron_spinand_table),
|
||||
.ops = µn_spinand_manuf_ops,
|
||||
};
|
||||
--- a/drivers/mtd/nand/spi/paragon.c
|
||||
+++ b/drivers/mtd/nand/spi/paragon.c
|
||||
@@ -97,7 +97,8 @@ static const struct mtd_ooblayout_ops pn
|
||||
|
||||
|
||||
static const struct spinand_info paragon_spinand_table[] = {
|
||||
- SPINAND_INFO("PN26G01A", 0xe1,
|
||||
+ SPINAND_INFO("PN26G01A",
|
||||
+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xe1),
|
||||
NAND_MEMORG(1, 2048, 128, 64, 1024, 21, 1, 1, 1),
|
||||
NAND_ECCREQ(8, 512),
|
||||
SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
|
||||
@@ -106,7 +107,8 @@ static const struct spinand_info paragon
|
||||
0,
|
||||
SPINAND_ECCINFO(&pn26g0xa_ooblayout,
|
||||
pn26g0xa_ecc_get_status)),
|
||||
- SPINAND_INFO("PN26G02A", 0xe2,
|
||||
+ SPINAND_INFO("PN26G02A",
|
||||
+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xe2),
|
||||
NAND_MEMORG(1, 2048, 128, 64, 2048, 41, 1, 1, 1),
|
||||
NAND_ECCREQ(8, 512),
|
||||
SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
|
||||
@@ -117,31 +119,13 @@ static const struct spinand_info paragon
|
||||
pn26g0xa_ecc_get_status)),
|
||||
};
|
||||
|
||||
-static int paragon_spinand_detect(struct spinand_device *spinand)
|
||||
-{
|
||||
- u8 *id = spinand->id.data;
|
||||
- int ret;
|
||||
-
|
||||
- /* Read ID returns [0][MID][DID] */
|
||||
-
|
||||
- if (id[1] != SPINAND_MFR_PARAGON)
|
||||
- return 0;
|
||||
-
|
||||
- ret = spinand_match_and_init(spinand, paragon_spinand_table,
|
||||
- ARRAY_SIZE(paragon_spinand_table),
|
||||
- id[2]);
|
||||
- if (ret)
|
||||
- return ret;
|
||||
-
|
||||
- return 1;
|
||||
-}
|
||||
-
|
||||
static const struct spinand_manufacturer_ops paragon_spinand_manuf_ops = {
|
||||
- .detect = paragon_spinand_detect,
|
||||
};
|
||||
|
||||
const struct spinand_manufacturer paragon_spinand_manufacturer = {
|
||||
.id = SPINAND_MFR_PARAGON,
|
||||
.name = "Paragon",
|
||||
+ .chips = paragon_spinand_table,
|
||||
+ .nchips = ARRAY_SIZE(paragon_spinand_table),
|
||||
.ops = ¶gon_spinand_manuf_ops,
|
||||
};
|
||||
--- a/drivers/mtd/nand/spi/toshiba.c
|
||||
+++ b/drivers/mtd/nand/spi/toshiba.c
|
||||
@@ -95,7 +95,8 @@ static int tc58cxgxsx_ecc_get_status(str
|
||||
|
||||
static const struct spinand_info toshiba_spinand_table[] = {
|
||||
/* 3.3V 1Gb */
|
||||
- SPINAND_INFO("TC58CVG0S3", 0xC2,
|
||||
+ SPINAND_INFO("TC58CVG0S3",
|
||||
+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xC2),
|
||||
NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
|
||||
NAND_ECCREQ(8, 512),
|
||||
SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
|
||||
@@ -105,7 +106,8 @@ static const struct spinand_info toshiba
|
||||
SPINAND_ECCINFO(&tc58cxgxsx_ooblayout,
|
||||
tc58cxgxsx_ecc_get_status)),
|
||||
/* 3.3V 2Gb */
|
||||
- SPINAND_INFO("TC58CVG1S3", 0xCB,
|
||||
+ SPINAND_INFO("TC58CVG1S3",
|
||||
+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xCB),
|
||||
NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
|
||||
NAND_ECCREQ(8, 512),
|
||||
SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
|
||||
@@ -115,7 +117,8 @@ static const struct spinand_info toshiba
|
||||
SPINAND_ECCINFO(&tc58cxgxsx_ooblayout,
|
||||
tc58cxgxsx_ecc_get_status)),
|
||||
/* 3.3V 4Gb */
|
||||
- SPINAND_INFO("TC58CVG2S0", 0xCD,
|
||||
+ SPINAND_INFO("TC58CVG2S0",
|
||||
+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xCD),
|
||||
NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 1, 1, 1),
|
||||
NAND_ECCREQ(8, 512),
|
||||
SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
|
||||
@@ -125,7 +128,8 @@ static const struct spinand_info toshiba
|
||||
SPINAND_ECCINFO(&tc58cxgxsx_ooblayout,
|
||||
tc58cxgxsx_ecc_get_status)),
|
||||
/* 1.8V 1Gb */
|
||||
- SPINAND_INFO("TC58CYG0S3", 0xB2,
|
||||
+ SPINAND_INFO("TC58CYG0S3",
|
||||
+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xB2),
|
||||
NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
|
||||
NAND_ECCREQ(8, 512),
|
||||
SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
|
||||
@@ -135,7 +139,8 @@ static const struct spinand_info toshiba
|
||||
SPINAND_ECCINFO(&tc58cxgxsx_ooblayout,
|
||||
tc58cxgxsx_ecc_get_status)),
|
||||
/* 1.8V 2Gb */
|
||||
- SPINAND_INFO("TC58CYG1S3", 0xBB,
|
||||
+ SPINAND_INFO("TC58CYG1S3",
|
||||
+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xBB),
|
||||
NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
|
||||
NAND_ECCREQ(8, 512),
|
||||
SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
|
||||
@@ -145,7 +150,8 @@ static const struct spinand_info toshiba
|
||||
SPINAND_ECCINFO(&tc58cxgxsx_ooblayout,
|
||||
tc58cxgxsx_ecc_get_status)),
|
||||
/* 1.8V 4Gb */
|
||||
- SPINAND_INFO("TC58CYG2S0", 0xBD,
|
||||
+ SPINAND_INFO("TC58CYG2S0",
|
||||
+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xBD),
|
||||
NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 1, 1, 1),
|
||||
NAND_ECCREQ(8, 512),
|
||||
SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
|
||||
@@ -156,33 +162,13 @@ static const struct spinand_info toshiba
|
||||
tc58cxgxsx_ecc_get_status)),
|
||||
};
|
||||
|
||||
-static int toshiba_spinand_detect(struct spinand_device *spinand)
|
||||
-{
|
||||
- u8 *id = spinand->id.data;
|
||||
- int ret;
|
||||
-
|
||||
- /*
|
||||
- * Toshiba SPI NAND read ID needs a dummy byte,
|
||||
- * so the first byte in id is garbage.
|
||||
- */
|
||||
- if (id[1] != SPINAND_MFR_TOSHIBA)
|
||||
- return 0;
|
||||
-
|
||||
- ret = spinand_match_and_init(spinand, toshiba_spinand_table,
|
||||
- ARRAY_SIZE(toshiba_spinand_table),
|
||||
- id[2]);
|
||||
- if (ret)
|
||||
- return ret;
|
||||
-
|
||||
- return 1;
|
||||
-}
|
||||
-
|
||||
static const struct spinand_manufacturer_ops toshiba_spinand_manuf_ops = {
|
||||
- .detect = toshiba_spinand_detect,
|
||||
};
|
||||
|
||||
const struct spinand_manufacturer toshiba_spinand_manufacturer = {
|
||||
.id = SPINAND_MFR_TOSHIBA,
|
||||
.name = "Toshiba",
|
||||
+ .chips = toshiba_spinand_table,
|
||||
+ .nchips = ARRAY_SIZE(toshiba_spinand_table),
|
||||
.ops = &toshiba_spinand_manuf_ops,
|
||||
};
|
||||
--- a/drivers/mtd/nand/spi/winbond.c
|
||||
+++ b/drivers/mtd/nand/spi/winbond.c
|
||||
@@ -75,7 +75,8 @@ static int w25m02gv_select_target(struct
|
||||
}
|
||||
|
||||
static const struct spinand_info winbond_spinand_table[] = {
|
||||
- SPINAND_INFO("W25M02GV", 0xAB,
|
||||
+ SPINAND_INFO("W25M02GV",
|
||||
+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xab),
|
||||
NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 2),
|
||||
NAND_ECCREQ(1, 512),
|
||||
SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
|
||||
@@ -84,7 +85,8 @@ static const struct spinand_info winbond
|
||||
0,
|
||||
SPINAND_ECCINFO(&w25m02gv_ooblayout, NULL),
|
||||
SPINAND_SELECT_TARGET(w25m02gv_select_target)),
|
||||
- SPINAND_INFO("W25N01GV", 0xAA,
|
||||
+ SPINAND_INFO("W25N01GV",
|
||||
+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xaa),
|
||||
NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1),
|
||||
NAND_ECCREQ(1, 512),
|
||||
SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
|
||||
@@ -94,31 +96,6 @@ static const struct spinand_info winbond
|
||||
SPINAND_ECCINFO(&w25m02gv_ooblayout, NULL)),
|
||||
};
|
||||
|
||||
-/**
|
||||
- * winbond_spinand_detect - initialize device related part in spinand_device
|
||||
- * struct if it is a Winbond device.
|
||||
- * @spinand: SPI NAND device structure
|
||||
- */
|
||||
-static int winbond_spinand_detect(struct spinand_device *spinand)
|
||||
-{
|
||||
- u8 *id = spinand->id.data;
|
||||
- int ret;
|
||||
-
|
||||
- /*
|
||||
- * Winbond SPI NAND read ID need a dummy byte,
|
||||
- * so the first byte in raw_id is dummy.
|
||||
- */
|
||||
- if (id[1] != SPINAND_MFR_WINBOND)
|
||||
- return 0;
|
||||
-
|
||||
- ret = spinand_match_and_init(spinand, winbond_spinand_table,
|
||||
- ARRAY_SIZE(winbond_spinand_table), id[2]);
|
||||
- if (ret)
|
||||
- return ret;
|
||||
-
|
||||
- return 1;
|
||||
-}
|
||||
-
|
||||
static int winbond_spinand_init(struct spinand_device *spinand)
|
||||
{
|
||||
struct nand_device *nand = spinand_to_nand(spinand);
|
||||
@@ -138,12 +115,13 @@ static int winbond_spinand_init(struct s
|
||||
}
|
||||
|
||||
static const struct spinand_manufacturer_ops winbond_spinand_manuf_ops = {
|
||||
- .detect = winbond_spinand_detect,
|
||||
.init = winbond_spinand_init,
|
||||
};
|
||||
|
||||
const struct spinand_manufacturer winbond_spinand_manufacturer = {
|
||||
.id = SPINAND_MFR_WINBOND,
|
||||
.name = "Winbond",
|
||||
+ .chips = winbond_spinand_table,
|
||||
+ .nchips = ARRAY_SIZE(winbond_spinand_table),
|
||||
.ops = &winbond_spinand_manuf_ops,
|
||||
};
|
||||
--- a/include/linux/mtd/spinand.h
|
||||
+++ b/include/linux/mtd/spinand.h
|
||||
@@ -32,9 +32,9 @@
|
||||
SPI_MEM_OP_NO_DUMMY, \
|
||||
SPI_MEM_OP_NO_DATA)
|
||||
|
||||
-#define SPINAND_READID_OP(ndummy, buf, len) \
|
||||
+#define SPINAND_READID_OP(naddr, ndummy, buf, len) \
|
||||
SPI_MEM_OP(SPI_MEM_OP_CMD(0x9f, 1), \
|
||||
- SPI_MEM_OP_NO_ADDR, \
|
||||
+ SPI_MEM_OP_ADDR(naddr, 0, 1), \
|
||||
SPI_MEM_OP_DUMMY(ndummy, 1), \
|
||||
SPI_MEM_OP_DATA_IN(len, buf, 1))
|
||||
|
||||
@@ -176,37 +176,46 @@ struct spinand_device;
|
||||
* @data: buffer containing the id bytes. Currently 4 bytes large, but can
|
||||
* be extended if required
|
||||
* @len: ID length
|
||||
- *
|
||||
- * struct_spinand_id->data contains all bytes returned after a READ_ID command,
|
||||
- * including dummy bytes if the chip does not emit ID bytes right after the
|
||||
- * READ_ID command. The responsibility to extract real ID bytes is left to
|
||||
- * struct_manufacurer_ops->detect().
|
||||
*/
|
||||
struct spinand_id {
|
||||
u8 data[SPINAND_MAX_ID_LEN];
|
||||
int len;
|
||||
};
|
||||
|
||||
+enum spinand_readid_method {
|
||||
+ SPINAND_READID_METHOD_OPCODE,
|
||||
+ SPINAND_READID_METHOD_OPCODE_ADDR,
|
||||
+ SPINAND_READID_METHOD_OPCODE_DUMMY,
|
||||
+};
|
||||
+
|
||||
+/**
|
||||
+ * struct spinand_devid - SPI NAND device id structure
|
||||
+ * @id: device id of current chip
|
||||
+ * @len: number of bytes in device id
|
||||
+ * @method: method to read chip id
|
||||
+ * There are 3 possible variants:
|
||||
+ * SPINAND_READID_METHOD_OPCODE: chip id is returned immediately
|
||||
+ * after read_id opcode.
|
||||
+ * SPINAND_READID_METHOD_OPCODE_ADDR: chip id is returned after
|
||||
+ * read_id opcode + 1-byte address.
|
||||
+ * SPINAND_READID_METHOD_OPCODE_DUMMY: chip id is returned after
|
||||
+ * read_id opcode + 1 dummy byte.
|
||||
+ */
|
||||
+struct spinand_devid {
|
||||
+ const u8 *id;
|
||||
+ const u8 len;
|
||||
+ const enum spinand_readid_method method;
|
||||
+};
|
||||
+
|
||||
/**
|
||||
* struct manufacurer_ops - SPI NAND manufacturer specific operations
|
||||
- * @detect: detect a SPI NAND device. Every time a SPI NAND device is probed
|
||||
- * the core calls the struct_manufacurer_ops->detect() hook of each
|
||||
- * registered manufacturer until one of them return 1. Note that
|
||||
- * the first thing to check in this hook is that the manufacturer ID
|
||||
- * in struct_spinand_device->id matches the manufacturer whose
|
||||
- * ->detect() hook has been called. Should return 1 if there's a
|
||||
- * match, 0 if the manufacturer ID does not match and a negative
|
||||
- * error code otherwise. When true is returned, the core assumes
|
||||
- * that properties of the NAND chip (spinand->base.memorg and
|
||||
- * spinand->base.eccreq) have been filled
|
||||
* @init: initialize a SPI NAND device
|
||||
* @cleanup: cleanup a SPI NAND device
|
||||
*
|
||||
* Each SPI NAND manufacturer driver should implement this interface so that
|
||||
- * NAND chips coming from this vendor can be detected and initialized properly.
|
||||
+ * NAND chips coming from this vendor can be initialized properly.
|
||||
*/
|
||||
struct spinand_manufacturer_ops {
|
||||
- int (*detect)(struct spinand_device *spinand);
|
||||
int (*init)(struct spinand_device *spinand);
|
||||
void (*cleanup)(struct spinand_device *spinand);
|
||||
};
|
||||
@@ -215,11 +224,16 @@ struct spinand_manufacturer_ops {
|
||||
* struct spinand_manufacturer - SPI NAND manufacturer instance
|
||||
* @id: manufacturer ID
|
||||
* @name: manufacturer name
|
||||
+ * @devid_len: number of bytes in device ID
|
||||
+ * @chips: supported SPI NANDs under current manufacturer
|
||||
+ * @nchips: number of SPI NANDs available in chips array
|
||||
* @ops: manufacturer operations
|
||||
*/
|
||||
struct spinand_manufacturer {
|
||||
u8 id;
|
||||
char *name;
|
||||
+ const struct spinand_info *chips;
|
||||
+ const size_t nchips;
|
||||
const struct spinand_manufacturer_ops *ops;
|
||||
};
|
||||
|
||||
@@ -291,7 +305,7 @@ struct spinand_ecc_info {
|
||||
*/
|
||||
struct spinand_info {
|
||||
const char *model;
|
||||
- u16 devid;
|
||||
+ struct spinand_devid devid;
|
||||
u32 flags;
|
||||
struct nand_memory_organization memorg;
|
||||
struct nand_ecc_req eccreq;
|
||||
@@ -305,6 +319,13 @@ struct spinand_info {
|
||||
unsigned int target);
|
||||
};
|
||||
|
||||
+#define SPINAND_ID(__method, ...) \
|
||||
+ { \
|
||||
+ .id = (const u8[]){ __VA_ARGS__ }, \
|
||||
+ .len = sizeof((u8[]){ __VA_ARGS__ }), \
|
||||
+ .method = __method, \
|
||||
+ }
|
||||
+
|
||||
#define SPINAND_INFO_OP_VARIANTS(__read, __write, __update) \
|
||||
{ \
|
||||
.read_cache = __read, \
|
||||
@@ -451,9 +472,10 @@ static inline void spinand_set_of_node(s
|
||||
nanddev_set_of_node(&spinand->base, np);
|
||||
}
|
||||
|
||||
-int spinand_match_and_init(struct spinand_device *dev,
|
||||
+int spinand_match_and_init(struct spinand_device *spinand,
|
||||
const struct spinand_info *table,
|
||||
- unsigned int table_size, u16 devid);
|
||||
+ unsigned int table_size,
|
||||
+ enum spinand_readid_method rdid_method);
|
||||
|
||||
int spinand_upd_cfg(struct spinand_device *spinand, u8 mask, u8 val);
|
||||
int spinand_select_target(struct spinand_device *spinand, unsigned int target);
|
||||
@@ -0,0 +1,173 @@
|
||||
From 469b992489852b500d39048aa0013639dfe9f2e6 Mon Sep 17 00:00:00 2001
|
||||
From: Reto Schneider <reto.schneider@husqvarnagroup.com>
|
||||
Date: Thu, 11 Feb 2021 12:36:19 +0100
|
||||
Subject: [PATCH] mtd: spinand: gigadevice: Support GD5F1GQ5UExxG
|
||||
|
||||
The relevant changes to the already existing GD5F1GQ4UExxG support has
|
||||
been determined by consulting the GigaDevice product change notice
|
||||
AN-0392-10, version 1.0 from November 30, 2020.
|
||||
|
||||
As the overlaps are huge, variable names have been generalized
|
||||
accordingly.
|
||||
|
||||
Apart from the lowered ECC strength (4 instead of 8 bits per 512 bytes),
|
||||
the new device ID, and the extra quad IO dummy byte, no changes had to
|
||||
be taken into account.
|
||||
|
||||
New hardware features are not supported, namely:
|
||||
- Power on reset
|
||||
- Unique ID
|
||||
- Double transfer rate (DTR)
|
||||
- Parameter page
|
||||
- Random data quad IO
|
||||
|
||||
The inverted semantic of the "driver strength" register bits, defaulting
|
||||
to 100% instead of 50% for the Q5 devices, got ignored as the driver has
|
||||
never touched them anyway.
|
||||
|
||||
The no longer supported "read from cache during block erase"
|
||||
functionality is not reflected as the current SPI NAND core does not
|
||||
support it anyway.
|
||||
|
||||
Implementation has been tested on MediaTek MT7688 based GARDENA smart
|
||||
Gateways using both, GigaDevice GD5F1GQ5UEYIG and GD5F1GQ4UBYIG.
|
||||
|
||||
Signed-off-by: Reto Schneider <reto.schneider@husqvarnagroup.com>
|
||||
Reviewed-by: Frieder Schrempf <frieder.schrempf@kontron.de>
|
||||
Reviewed-by: Stefan Roese <sr@denx.de>
|
||||
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
|
||||
Link: https://lore.kernel.org/linux-mtd/20210211113619.3502-1-code@reto-schneider.ch
|
||||
---
|
||||
drivers/mtd/nand/spi/gigadevice.c | 69 +++++++++++++++++++++++++++----
|
||||
1 file changed, 60 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/drivers/mtd/nand/spi/gigadevice.c b/drivers/mtd/nand/spi/gigadevice.c
|
||||
index 33c67403c4aa1e..1dd1c589809341 100644
|
||||
--- a/drivers/mtd/nand/spi/gigadevice.c
|
||||
+++ b/drivers/mtd/nand/spi/gigadevice.c
|
||||
@@ -13,7 +13,10 @@
|
||||
#define GD5FXGQ4XA_STATUS_ECC_1_7_BITFLIPS (1 << 4)
|
||||
#define GD5FXGQ4XA_STATUS_ECC_8_BITFLIPS (3 << 4)
|
||||
|
||||
-#define GD5FXGQ4UEXXG_REG_STATUS2 0xf0
|
||||
+#define GD5FXGQ5XE_STATUS_ECC_1_4_BITFLIPS (1 << 4)
|
||||
+#define GD5FXGQ5XE_STATUS_ECC_4_BITFLIPS (3 << 4)
|
||||
+
|
||||
+#define GD5FXGQXXEXXG_REG_STATUS2 0xf0
|
||||
|
||||
#define GD5FXGQ4UXFXXG_STATUS_ECC_MASK (7 << 4)
|
||||
#define GD5FXGQ4UXFXXG_STATUS_ECC_NO_BITFLIPS (0 << 4)
|
||||
@@ -102,7 +105,7 @@ static int gd5fxgq4xa_ecc_get_status(struct spinand_device *spinand,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
-static int gd5fxgq4_variant2_ooblayout_ecc(struct mtd_info *mtd, int section,
|
||||
+static int gd5fxgqx_variant2_ooblayout_ecc(struct mtd_info *mtd, int section,
|
||||
struct mtd_oob_region *region)
|
||||
{
|
||||
if (section)
|
||||
@@ -114,7 +117,7 @@ static int gd5fxgq4_variant2_ooblayout_ecc(struct mtd_info *mtd, int section,
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static int gd5fxgq4_variant2_ooblayout_free(struct mtd_info *mtd, int section,
|
||||
+static int gd5fxgqx_variant2_ooblayout_free(struct mtd_info *mtd, int section,
|
||||
struct mtd_oob_region *region)
|
||||
{
|
||||
if (section)
|
||||
@@ -127,9 +130,10 @@ static int gd5fxgq4_variant2_ooblayout_free(struct mtd_info *mtd, int section,
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static const struct mtd_ooblayout_ops gd5fxgq4_variant2_ooblayout = {
|
||||
- .ecc = gd5fxgq4_variant2_ooblayout_ecc,
|
||||
- .free = gd5fxgq4_variant2_ooblayout_free,
|
||||
+/* Valid for Q4/Q5 and Q6 (untested) devices */
|
||||
+static const struct mtd_ooblayout_ops gd5fxgqx_variant2_ooblayout = {
|
||||
+ .ecc = gd5fxgqx_variant2_ooblayout_ecc,
|
||||
+ .free = gd5fxgqx_variant2_ooblayout_free,
|
||||
};
|
||||
|
||||
static int gd5fxgq4xc_ooblayout_256_ecc(struct mtd_info *mtd, int section,
|
||||
@@ -165,7 +169,7 @@ static int gd5fxgq4uexxg_ecc_get_status(struct spinand_device *spinand,
|
||||
u8 status)
|
||||
{
|
||||
u8 status2;
|
||||
- struct spi_mem_op op = SPINAND_GET_FEATURE_OP(GD5FXGQ4UEXXG_REG_STATUS2,
|
||||
+ struct spi_mem_op op = SPINAND_GET_FEATURE_OP(GD5FXGQXXEXXG_REG_STATUS2,
|
||||
&status2);
|
||||
int ret;
|
||||
|
||||
@@ -203,6 +207,43 @@ static int gd5fxgq4uexxg_ecc_get_status(struct spinand_device *spinand,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
+static int gd5fxgq5xexxg_ecc_get_status(struct spinand_device *spinand,
|
||||
+ u8 status)
|
||||
+{
|
||||
+ u8 status2;
|
||||
+ struct spi_mem_op op = SPINAND_GET_FEATURE_OP(GD5FXGQXXEXXG_REG_STATUS2,
|
||||
+ &status2);
|
||||
+ int ret;
|
||||
+
|
||||
+ switch (status & STATUS_ECC_MASK) {
|
||||
+ case STATUS_ECC_NO_BITFLIPS:
|
||||
+ return 0;
|
||||
+
|
||||
+ case GD5FXGQ5XE_STATUS_ECC_1_4_BITFLIPS:
|
||||
+ /*
|
||||
+ * Read status2 register to determine a more fine grained
|
||||
+ * bit error status
|
||||
+ */
|
||||
+ ret = spi_mem_exec_op(spinand->spimem, &op);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ /*
|
||||
+ * 1 ... 4 bits are flipped (and corrected)
|
||||
+ */
|
||||
+ /* bits sorted this way (1...0): ECCSE1, ECCSE0 */
|
||||
+ return ((status2 & STATUS_ECC_MASK) >> 4) + 1;
|
||||
+
|
||||
+ case STATUS_ECC_UNCOR_ERROR:
|
||||
+ return -EBADMSG;
|
||||
+
|
||||
+ default:
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ return -EINVAL;
|
||||
+}
|
||||
+
|
||||
static int gd5fxgq4ufxxg_ecc_get_status(struct spinand_device *spinand,
|
||||
u8 status)
|
||||
{
|
||||
@@ -282,7 +323,7 @@ static const struct spinand_info gigadevice_spinand_table[] = {
|
||||
&write_cache_variants,
|
||||
&update_cache_variants),
|
||||
SPINAND_HAS_QE_BIT,
|
||||
- SPINAND_ECCINFO(&gd5fxgq4_variant2_ooblayout,
|
||||
+ SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
|
||||
gd5fxgq4uexxg_ecc_get_status)),
|
||||
SPINAND_INFO("GD5F1GQ4UFxxG",
|
||||
SPINAND_ID(SPINAND_READID_METHOD_OPCODE, 0xb1, 0x48),
|
||||
@@ -292,8 +333,18 @@ static const struct spinand_info gigadevice_spinand_table[] = {
|
||||
&write_cache_variants,
|
||||
&update_cache_variants),
|
||||
SPINAND_HAS_QE_BIT,
|
||||
- SPINAND_ECCINFO(&gd5fxgq4_variant2_ooblayout,
|
||||
+ SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
|
||||
gd5fxgq4ufxxg_ecc_get_status)),
|
||||
+ SPINAND_INFO("GD5F1GQ5UExxG",
|
||||
+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x51),
|
||||
+ NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
|
||||
+ NAND_ECCREQ(4, 512),
|
||||
+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
|
||||
+ &write_cache_variants,
|
||||
+ &update_cache_variants),
|
||||
+ SPINAND_HAS_QE_BIT,
|
||||
+ SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
|
||||
+ gd5fxgq5xexxg_ecc_get_status)),
|
||||
};
|
||||
|
||||
static const struct spinand_manufacturer_ops gigadevice_spinand_manuf_ops = {
|
||||
@@ -0,0 +1,40 @@
|
||||
From 051e070d0a019df6be9e21be1fb63352e4c4412e Mon Sep 17 00:00:00 2001
|
||||
From: YouChing Lin <ycllin@mxic.com.tw>
|
||||
Date: Wed, 22 Jul 2020 16:02:57 +0800
|
||||
Subject: [PATCH] mtd: spinand: macronix: Add support for MX31LF1GE4BC
|
||||
|
||||
The Macronix MX31LF1GE4BC is a 3V, 1Gbit (128MB) serial
|
||||
NAND flash device.
|
||||
|
||||
Validated by read, erase, read back, write and read back
|
||||
on Xilinx Zynq PicoZed FPGA board which included
|
||||
Macronix SPI Host (driver/spi/spi-mxic.c).
|
||||
|
||||
Signed-off-by: YouChing Lin <ycllin@mxic.com.tw>
|
||||
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
|
||||
Link: https://lore.kernel.org/linux-mtd/1595404978-31079-2-git-send-email-ycllin@mxic.com.tw
|
||||
---
|
||||
drivers/mtd/nand/spi/macronix.c | 10 ++++++++++
|
||||
1 file changed, 10 insertions(+)
|
||||
|
||||
diff --git a/drivers/mtd/nand/spi/macronix.c b/drivers/mtd/nand/spi/macronix.c
|
||||
index 9ff8debd599418..9ae48ce1c46f91 100644
|
||||
--- a/drivers/mtd/nand/spi/macronix.c
|
||||
+++ b/drivers/mtd/nand/spi/macronix.c
|
||||
@@ -119,6 +119,16 @@ static const struct spinand_info macronix_spinand_table[] = {
|
||||
&update_cache_variants),
|
||||
SPINAND_HAS_QE_BIT,
|
||||
SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, NULL)),
|
||||
+ SPINAND_INFO("MX31LF1GE4BC",
|
||||
+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x1e),
|
||||
+ NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1),
|
||||
+ NAND_ECCREQ(8, 512),
|
||||
+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
|
||||
+ &write_cache_variants,
|
||||
+ &update_cache_variants),
|
||||
+ 0 /*SPINAND_HAS_QE_BIT*/,
|
||||
+ SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
|
||||
+ mx35lf1ge4ab_ecc_get_status)),
|
||||
};
|
||||
|
||||
static const struct spinand_manufacturer_ops macronix_spinand_manuf_ops = {
|
||||
@@ -0,0 +1,40 @@
|
||||
From 75b049bb7f89a58a25592f17baf91d703f0f548e Mon Sep 17 00:00:00 2001
|
||||
From: YouChing Lin <ycllin@mxic.com.tw>
|
||||
Date: Wed, 22 Jul 2020 16:02:58 +0800
|
||||
Subject: [PATCH] mtd: spinand: macronix: Add support for MX31UF1GE4BC
|
||||
|
||||
The Macronix MX31UF1GE4BC is a 1.8V, 1Gbit (128MB) serial
|
||||
NAND flash device.
|
||||
|
||||
Validated by read, erase, read back, write and read back
|
||||
on Xilinx Zynq PicoZed FPGA board which included
|
||||
Macronix SPI Host (driver/spi/spi-mxic.c).
|
||||
|
||||
Signed-off-by: YouChing Lin <ycllin@mxic.com.tw>
|
||||
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
|
||||
Link: https://lore.kernel.org/linux-mtd/1595404978-31079-3-git-send-email-ycllin@mxic.com.tw
|
||||
---
|
||||
drivers/mtd/nand/spi/macronix.c | 10 ++++++++++
|
||||
1 file changed, 10 insertions(+)
|
||||
|
||||
diff --git a/drivers/mtd/nand/spi/macronix.c b/drivers/mtd/nand/spi/macronix.c
|
||||
index 9ae48ce1c46f91..8e801e4c3a006f 100644
|
||||
--- a/drivers/mtd/nand/spi/macronix.c
|
||||
+++ b/drivers/mtd/nand/spi/macronix.c
|
||||
@@ -129,6 +129,16 @@ static const struct spinand_info macronix_spinand_table[] = {
|
||||
0 /*SPINAND_HAS_QE_BIT*/,
|
||||
SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
|
||||
mx35lf1ge4ab_ecc_get_status)),
|
||||
+ SPINAND_INFO("MX31UF1GE4BC",
|
||||
+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x9e),
|
||||
+ NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1),
|
||||
+ NAND_ECCREQ(8, 512),
|
||||
+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
|
||||
+ &write_cache_variants,
|
||||
+ &update_cache_variants),
|
||||
+ 0 /*SPINAND_HAS_QE_BIT*/,
|
||||
+ SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
|
||||
+ mx35lf1ge4ab_ecc_get_status)),
|
||||
};
|
||||
|
||||
static const struct spinand_manufacturer_ops macronix_spinand_manuf_ops = {
|
||||
@@ -0,0 +1,50 @@
|
||||
From 5ece78de88739b4c68263e9f2582380c1fd8314f Mon Sep 17 00:00:00 2001
|
||||
From: YouChing Lin <ycllin@mxic.com.tw>
|
||||
Date: Thu, 5 Nov 2020 15:23:40 +0800
|
||||
Subject: [PATCH] mtd: spinand: macronix: Add support for MX35LFxGE4AD
|
||||
|
||||
The Macronix MX35LF2GE4AD / MX35LF4GE4AD are 3V, 2G / 4Gbit serial
|
||||
SLC NAND flash device (with on-die ECC).
|
||||
|
||||
Validated by read, erase, read back, write, read back and nandtest
|
||||
on Xilinx Zynq PicoZed FPGA board which included Macronix SPI Host
|
||||
(drivers/spi/spi-mxic.c).
|
||||
|
||||
Signed-off-by: YouChing Lin <ycllin@mxic.com.tw>
|
||||
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
|
||||
Link: https://lore.kernel.org/linux-mtd/1604561020-13499-1-git-send-email-ycllin@mxic.com.tw
|
||||
---
|
||||
drivers/mtd/nand/spi/macronix.c | 20 ++++++++++++++++++++
|
||||
1 file changed, 20 insertions(+)
|
||||
|
||||
diff --git a/drivers/mtd/nand/spi/macronix.c b/drivers/mtd/nand/spi/macronix.c
|
||||
index 8e801e4c3a006f..3786b1b03b3b4b 100644
|
||||
--- a/drivers/mtd/nand/spi/macronix.c
|
||||
+++ b/drivers/mtd/nand/spi/macronix.c
|
||||
@@ -119,6 +119,26 @@ static const struct spinand_info macronix_spinand_table[] = {
|
||||
&update_cache_variants),
|
||||
SPINAND_HAS_QE_BIT,
|
||||
SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, NULL)),
|
||||
+ SPINAND_INFO("MX35LF2GE4AD",
|
||||
+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x26),
|
||||
+ NAND_MEMORG(1, 2048, 64, 64, 2048, 40, 1, 1, 1),
|
||||
+ NAND_ECCREQ(8, 512),
|
||||
+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
|
||||
+ &write_cache_variants,
|
||||
+ &update_cache_variants),
|
||||
+ 0,
|
||||
+ SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
|
||||
+ mx35lf1ge4ab_ecc_get_status)),
|
||||
+ SPINAND_INFO("MX35LF4GE4AD",
|
||||
+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x37),
|
||||
+ NAND_MEMORG(1, 4096, 128, 64, 2048, 40, 1, 1, 1),
|
||||
+ NAND_ECCREQ(8, 512),
|
||||
+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
|
||||
+ &write_cache_variants,
|
||||
+ &update_cache_variants),
|
||||
+ 0,
|
||||
+ SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
|
||||
+ mx35lf1ge4ab_ecc_get_status)),
|
||||
SPINAND_INFO("MX31LF1GE4BC",
|
||||
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x1e),
|
||||
NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1),
|
||||
@@ -0,0 +1,58 @@
|
||||
From ee4e0eafa43cfd9008722fe15e17b8bf62fb6e8d Mon Sep 17 00:00:00 2001
|
||||
From: YouChing Lin <ycllin@mxic.com.tw>
|
||||
Date: Thu, 10 Dec 2020 11:22:09 +0800
|
||||
Subject: [PATCH] mtd: spinand: macronix: Add support for MX35LFxG24AD
|
||||
|
||||
The Macronix MX35LF1G24AD(/2G24AD/4G24AD) are 3V, 1G/2G/4Gbit serial
|
||||
SLC NAND flash device (without on-die ECC).
|
||||
|
||||
Validated by read, erase, read back, write, read back on Xilinx Zynq
|
||||
PicoZed FPGA board which included Macronix SPI Host(drivers/spi/spi-mxic.c)
|
||||
& S/W BCH ecc(drivers/mtd/nand/ecc-sw-bch.c) with bug fixing patch
|
||||
(mtd: nand: ecc-bch: Fix the size of calc_buf/code_buf of the BCH).
|
||||
|
||||
Signed-off-by: YouChing Lin <ycllin@mxic.com.tw>
|
||||
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
|
||||
Link: https://lore.kernel.org/linux-mtd/1607570529-22341-3-git-send-email-ycllin@mxic.com.tw
|
||||
---
|
||||
drivers/mtd/nand/spi/macronix.c | 27 +++++++++++++++++++++++++++
|
||||
1 file changed, 27 insertions(+)
|
||||
|
||||
diff --git a/drivers/mtd/nand/spi/macronix.c b/drivers/mtd/nand/spi/macronix.c
|
||||
index 3786b1b03b3b4b..6701aaa21a49df 100644
|
||||
--- a/drivers/mtd/nand/spi/macronix.c
|
||||
+++ b/drivers/mtd/nand/spi/macronix.c
|
||||
@@ -139,6 +139,33 @@ static const struct spinand_info macronix_spinand_table[] = {
|
||||
0,
|
||||
SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
|
||||
mx35lf1ge4ab_ecc_get_status)),
|
||||
+ SPINAND_INFO("MX35LF1G24AD",
|
||||
+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x14),
|
||||
+ NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
|
||||
+ NAND_ECCREQ(8, 512),
|
||||
+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
|
||||
+ &write_cache_variants,
|
||||
+ &update_cache_variants),
|
||||
+ 0,
|
||||
+ SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, NULL)),
|
||||
+ SPINAND_INFO("MX35LF2G24AD",
|
||||
+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x24),
|
||||
+ NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
|
||||
+ NAND_ECCREQ(8, 512),
|
||||
+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
|
||||
+ &write_cache_variants,
|
||||
+ &update_cache_variants),
|
||||
+ 0,
|
||||
+ SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, NULL)),
|
||||
+ SPINAND_INFO("MX35LF4G24AD",
|
||||
+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x35),
|
||||
+ NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 2, 1, 1),
|
||||
+ NAND_ECCREQ(8, 512),
|
||||
+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
|
||||
+ &write_cache_variants,
|
||||
+ &update_cache_variants),
|
||||
+ 0,
|
||||
+ SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, NULL)),
|
||||
SPINAND_INFO("MX31LF1GE4BC",
|
||||
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x1e),
|
||||
NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1),
|
||||
@@ -0,0 +1,170 @@
|
||||
From c374839f9b4475173e536d1eaddff45cb481dbdf Mon Sep 17 00:00:00 2001
|
||||
From: Jaime Liao <jaimeliao@mxic.com.tw>
|
||||
Date: Thu, 20 May 2021 09:45:08 +0800
|
||||
Subject: [PATCH] mtd: spinand: macronix: Add support for serial NAND flash
|
||||
|
||||
Macronix NAND Flash devices are available in different configurations
|
||||
and densities.
|
||||
|
||||
MX"35" means SPI NAND
|
||||
MX35"LF"/"UF" , LF means 3V and UF meands 1.8V
|
||||
MX35LF"2G" , 2G means 2Gbits
|
||||
MX35LF2G"E4"/"24"/"14",
|
||||
E4 means internal ECC and Quad I/O(x4)
|
||||
24 means 8-bit ecc requirement and Quad I/O(x4)
|
||||
14 means 4-bit ecc requirement and Quad I/O(x4)
|
||||
|
||||
MX35LF2G14AC is 3V 2Gbit serial NAND flash device
|
||||
(without on-die ECC)
|
||||
https://www.mxic.com.tw/Lists/Datasheet/Attachments/7926/MX35LF2G14AC,%203V,%202Gb,%20v1.1.pdf
|
||||
|
||||
MX35UF4G24AD is 1.8V 4Gbit serial NAND flash device
|
||||
(without on-die ECC)
|
||||
https://www.mxic.com.tw/Lists/Datasheet/Attachments/7980/MX35UF4G24AD,%201.8V,%204Gb,%20v0.00.pdf
|
||||
|
||||
MX35UF4GE4AD/MX35UF2GE4AD are 1.8V 4G/2Gbit serial
|
||||
NAND flash device with 8-bit on-die ECC
|
||||
https://www.mxic.com.tw/Lists/Datasheet/Attachments/7983/MX35UF4GE4AD,%201.8V,%204Gb,%20v0.00.pdf
|
||||
|
||||
MX35UF2GE4AC/MX35UF1GE4AC are 1.8V 2G/1Gbit serial
|
||||
NAND flash device with 8-bit on-die ECC
|
||||
https://www.mxic.com.tw/Lists/Datasheet/Attachments/7974/MX35UF2GE4AC,%201.8V,%202Gb,%20v1.0.pdf
|
||||
|
||||
MX35UF2G14AC/MX35UF1G14AC are 1.8V 2G/1Gbit serial
|
||||
NAND flash device (without on-die ECC)
|
||||
https://www.mxic.com.tw/Lists/Datasheet/Attachments/7931/MX35UF2G14AC,%201.8V,%202Gb,%20v1.1.pdf
|
||||
|
||||
Validated via normal(default) and QUAD mode by read, erase, read back,
|
||||
on Xilinx Zynq PicoZed FPGA board which included Macronix
|
||||
SPI Host(drivers/spi/spi-mxic.c).
|
||||
|
||||
Signed-off-by: Jaime Liao <jaimeliao@mxic.com.tw>
|
||||
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
|
||||
Link: https://lore.kernel.org/linux-mtd/1621475108-22523-1-git-send-email-jaimeliao@mxic.com.tw
|
||||
---
|
||||
drivers/mtd/nand/spi/macronix.c | 112 ++++++++++++++++++++++++++++++++
|
||||
1 file changed, 112 insertions(+)
|
||||
|
||||
diff --git a/drivers/mtd/nand/spi/macronix.c b/drivers/mtd/nand/spi/macronix.c
|
||||
index 6701aaa21a49df..a9890350db0293 100644
|
||||
--- a/drivers/mtd/nand/spi/macronix.c
|
||||
+++ b/drivers/mtd/nand/spi/macronix.c
|
||||
@@ -186,6 +186,118 @@ static const struct spinand_info macronix_spinand_table[] = {
|
||||
0 /*SPINAND_HAS_QE_BIT*/,
|
||||
SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
|
||||
mx35lf1ge4ab_ecc_get_status)),
|
||||
+
|
||||
+ SPINAND_INFO("MX35LF2G14AC",
|
||||
+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x20),
|
||||
+ NAND_MEMORG(1, 2048, 64, 64, 2048, 40, 2, 1, 1),
|
||||
+ NAND_ECCREQ(4, 512),
|
||||
+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
|
||||
+ &write_cache_variants,
|
||||
+ &update_cache_variants),
|
||||
+ SPINAND_HAS_QE_BIT,
|
||||
+ SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
|
||||
+ mx35lf1ge4ab_ecc_get_status)),
|
||||
+ SPINAND_INFO("MX35UF4G24AD",
|
||||
+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xb5),
|
||||
+ NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 2, 1, 1),
|
||||
+ NAND_ECCREQ(8, 512),
|
||||
+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
|
||||
+ &write_cache_variants,
|
||||
+ &update_cache_variants),
|
||||
+ SPINAND_HAS_QE_BIT,
|
||||
+ SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
|
||||
+ mx35lf1ge4ab_ecc_get_status)),
|
||||
+ SPINAND_INFO("MX35UF4GE4AD",
|
||||
+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xb7),
|
||||
+ NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 1, 1, 1),
|
||||
+ NAND_ECCREQ(8, 512),
|
||||
+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
|
||||
+ &write_cache_variants,
|
||||
+ &update_cache_variants),
|
||||
+ SPINAND_HAS_QE_BIT,
|
||||
+ SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
|
||||
+ mx35lf1ge4ab_ecc_get_status)),
|
||||
+ SPINAND_INFO("MX35UF2G14AC",
|
||||
+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xa0),
|
||||
+ NAND_MEMORG(1, 2048, 64, 64, 2048, 40, 2, 1, 1),
|
||||
+ NAND_ECCREQ(4, 512),
|
||||
+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
|
||||
+ &write_cache_variants,
|
||||
+ &update_cache_variants),
|
||||
+ SPINAND_HAS_QE_BIT,
|
||||
+ SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
|
||||
+ mx35lf1ge4ab_ecc_get_status)),
|
||||
+ SPINAND_INFO("MX35UF2G24AD",
|
||||
+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xa4),
|
||||
+ NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 2, 1, 1),
|
||||
+ NAND_ECCREQ(8, 512),
|
||||
+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
|
||||
+ &write_cache_variants,
|
||||
+ &update_cache_variants),
|
||||
+ SPINAND_HAS_QE_BIT,
|
||||
+ SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
|
||||
+ mx35lf1ge4ab_ecc_get_status)),
|
||||
+ SPINAND_INFO("MX35UF2GE4AD",
|
||||
+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xa6),
|
||||
+ NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
|
||||
+ NAND_ECCREQ(8, 512),
|
||||
+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
|
||||
+ &write_cache_variants,
|
||||
+ &update_cache_variants),
|
||||
+ SPINAND_HAS_QE_BIT,
|
||||
+ SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
|
||||
+ mx35lf1ge4ab_ecc_get_status)),
|
||||
+ SPINAND_INFO("MX35UF2GE4AC",
|
||||
+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xa2),
|
||||
+ NAND_MEMORG(1, 2048, 64, 64, 2048, 40, 1, 1, 1),
|
||||
+ NAND_ECCREQ(4, 512),
|
||||
+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
|
||||
+ &write_cache_variants,
|
||||
+ &update_cache_variants),
|
||||
+ SPINAND_HAS_QE_BIT,
|
||||
+ SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
|
||||
+ mx35lf1ge4ab_ecc_get_status)),
|
||||
+ SPINAND_INFO("MX35UF1G14AC",
|
||||
+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x90),
|
||||
+ NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1),
|
||||
+ NAND_ECCREQ(4, 512),
|
||||
+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
|
||||
+ &write_cache_variants,
|
||||
+ &update_cache_variants),
|
||||
+ SPINAND_HAS_QE_BIT,
|
||||
+ SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
|
||||
+ mx35lf1ge4ab_ecc_get_status)),
|
||||
+ SPINAND_INFO("MX35UF1G24AD",
|
||||
+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x94),
|
||||
+ NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
|
||||
+ NAND_ECCREQ(8, 512),
|
||||
+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
|
||||
+ &write_cache_variants,
|
||||
+ &update_cache_variants),
|
||||
+ SPINAND_HAS_QE_BIT,
|
||||
+ SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
|
||||
+ mx35lf1ge4ab_ecc_get_status)),
|
||||
+ SPINAND_INFO("MX35UF1GE4AD",
|
||||
+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x96),
|
||||
+ NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
|
||||
+ NAND_ECCREQ(8, 512),
|
||||
+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
|
||||
+ &write_cache_variants,
|
||||
+ &update_cache_variants),
|
||||
+ SPINAND_HAS_QE_BIT,
|
||||
+ SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
|
||||
+ mx35lf1ge4ab_ecc_get_status)),
|
||||
+ SPINAND_INFO("MX35UF1GE4AC",
|
||||
+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x92),
|
||||
+ NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1),
|
||||
+ NAND_ECCREQ(4, 512),
|
||||
+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
|
||||
+ &write_cache_variants,
|
||||
+ &update_cache_variants),
|
||||
+ SPINAND_HAS_QE_BIT,
|
||||
+ SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
|
||||
+ mx35lf1ge4ab_ecc_get_status)),
|
||||
+
|
||||
};
|
||||
|
||||
static const struct spinand_manufacturer_ops macronix_spinand_manuf_ops = {
|
||||
@@ -0,0 +1,88 @@
|
||||
From 6f802696c2faf0119781fc3b7977a4eedf9ab239 Mon Sep 17 00:00:00 2001
|
||||
From: Jaime Liao <jaimeliao@mxic.com.tw>
|
||||
Date: Mon, 9 Aug 2021 09:27:52 +0800
|
||||
Subject: [PATCH] mtd: spinand: macronix: Add Quad support for serial NAND
|
||||
flash
|
||||
|
||||
Adding FLAG "SPINAND_HAS_QE_BIT" for Quad mode support on Macronix
|
||||
Serial Flash.
|
||||
Validated via normal(default) and QUAD mode by read, erase, read back,
|
||||
on Xilinx Zynq PicoZed FPGA board which included Macronix
|
||||
SPI Host(drivers/spi/spi-mxic.c).
|
||||
|
||||
Signed-off-by: Jaime Liao <jaimeliao@mxic.com.tw>
|
||||
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
|
||||
Link: https://lore.kernel.org/linux-mtd/1628472472-32008-1-git-send-email-jaimeliao@mxic.com.tw
|
||||
---
|
||||
drivers/mtd/nand/spi/macronix.c | 16 ++++++++--------
|
||||
1 file changed, 8 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/drivers/mtd/nand/spi/macronix.c b/drivers/mtd/nand/spi/macronix.c
|
||||
index a9890350db0293..3f31f1381a62c0 100644
|
||||
--- a/drivers/mtd/nand/spi/macronix.c
|
||||
+++ b/drivers/mtd/nand/spi/macronix.c
|
||||
@@ -126,7 +126,7 @@ static const struct spinand_info macronix_spinand_table[] = {
|
||||
SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
|
||||
&write_cache_variants,
|
||||
&update_cache_variants),
|
||||
- 0,
|
||||
+ SPINAND_HAS_QE_BIT,
|
||||
SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
|
||||
mx35lf1ge4ab_ecc_get_status)),
|
||||
SPINAND_INFO("MX35LF4GE4AD",
|
||||
@@ -136,7 +136,7 @@ static const struct spinand_info macronix_spinand_table[] = {
|
||||
SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
|
||||
&write_cache_variants,
|
||||
&update_cache_variants),
|
||||
- 0,
|
||||
+ SPINAND_HAS_QE_BIT,
|
||||
SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
|
||||
mx35lf1ge4ab_ecc_get_status)),
|
||||
SPINAND_INFO("MX35LF1G24AD",
|
||||
@@ -146,16 +146,16 @@ static const struct spinand_info macronix_spinand_table[] = {
|
||||
SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
|
||||
&write_cache_variants,
|
||||
&update_cache_variants),
|
||||
- 0,
|
||||
+ SPINAND_HAS_QE_BIT,
|
||||
SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, NULL)),
|
||||
SPINAND_INFO("MX35LF2G24AD",
|
||||
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x24),
|
||||
- NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
|
||||
+ NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 2, 1, 1),
|
||||
NAND_ECCREQ(8, 512),
|
||||
SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
|
||||
&write_cache_variants,
|
||||
&update_cache_variants),
|
||||
- 0,
|
||||
+ SPINAND_HAS_QE_BIT,
|
||||
SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, NULL)),
|
||||
SPINAND_INFO("MX35LF4G24AD",
|
||||
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x35),
|
||||
@@ -164,7 +164,7 @@ static const struct spinand_info macronix_spinand_table[] = {
|
||||
SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
|
||||
&write_cache_variants,
|
||||
&update_cache_variants),
|
||||
- 0,
|
||||
+ SPINAND_HAS_QE_BIT,
|
||||
SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, NULL)),
|
||||
SPINAND_INFO("MX31LF1GE4BC",
|
||||
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x1e),
|
||||
@@ -173,7 +173,7 @@ static const struct spinand_info macronix_spinand_table[] = {
|
||||
SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
|
||||
&write_cache_variants,
|
||||
&update_cache_variants),
|
||||
- 0 /*SPINAND_HAS_QE_BIT*/,
|
||||
+ SPINAND_HAS_QE_BIT,
|
||||
SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
|
||||
mx35lf1ge4ab_ecc_get_status)),
|
||||
SPINAND_INFO("MX31UF1GE4BC",
|
||||
@@ -183,7 +183,7 @@ static const struct spinand_info macronix_spinand_table[] = {
|
||||
SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
|
||||
&write_cache_variants,
|
||||
&update_cache_variants),
|
||||
- 0 /*SPINAND_HAS_QE_BIT*/,
|
||||
+ SPINAND_HAS_QE_BIT,
|
||||
SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
|
||||
mx35lf1ge4ab_ecc_get_status)),
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
From d3137043440fb1faaaf2481184f35b9ed0c1f2c2 Mon Sep 17 00:00:00 2001
|
||||
From: Shivamurthy Shastri <sshivamurthy@micron.com>
|
||||
Date: Wed, 11 Mar 2020 18:57:30 +0100
|
||||
Subject: [PATCH] mtd: spinand: micron: Generalize the OOB layout structure and
|
||||
function names
|
||||
|
||||
In order to add new Micron SPI NAND devices, we generalized the OOB
|
||||
layout structure and function names.
|
||||
|
||||
Signed-off-by: Shivamurthy Shastri <sshivamurthy@micron.com>
|
||||
Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com>
|
||||
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
|
||||
Link: https://lore.kernel.org/linux-mtd/20200311175735.2007-2-sshivamurthy@micron.com
|
||||
---
|
||||
drivers/mtd/nand/spi/micron.c | 28 ++++++++++++++--------------
|
||||
1 file changed, 14 insertions(+), 14 deletions(-)
|
||||
|
||||
diff --git a/drivers/mtd/nand/spi/micron.c b/drivers/mtd/nand/spi/micron.c
|
||||
index f56f81325e10ac..cc1ee68421c8e1 100644
|
||||
--- a/drivers/mtd/nand/spi/micron.c
|
||||
+++ b/drivers/mtd/nand/spi/micron.c
|
||||
@@ -34,38 +34,38 @@ static SPINAND_OP_VARIANTS(update_cache_variants,
|
||||
SPINAND_PROG_LOAD_X4(false, 0, NULL, 0),
|
||||
SPINAND_PROG_LOAD(false, 0, NULL, 0));
|
||||
|
||||
-static int mt29f2g01abagd_ooblayout_ecc(struct mtd_info *mtd, int section,
|
||||
- struct mtd_oob_region *region)
|
||||
+static int micron_8_ooblayout_ecc(struct mtd_info *mtd, int section,
|
||||
+ struct mtd_oob_region *region)
|
||||
{
|
||||
if (section)
|
||||
return -ERANGE;
|
||||
|
||||
- region->offset = 64;
|
||||
- region->length = 64;
|
||||
+ region->offset = mtd->oobsize / 2;
|
||||
+ region->length = mtd->oobsize / 2;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static int mt29f2g01abagd_ooblayout_free(struct mtd_info *mtd, int section,
|
||||
- struct mtd_oob_region *region)
|
||||
+static int micron_8_ooblayout_free(struct mtd_info *mtd, int section,
|
||||
+ struct mtd_oob_region *region)
|
||||
{
|
||||
if (section)
|
||||
return -ERANGE;
|
||||
|
||||
/* Reserve 2 bytes for the BBM. */
|
||||
region->offset = 2;
|
||||
- region->length = 62;
|
||||
+ region->length = (mtd->oobsize / 2) - 2;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static const struct mtd_ooblayout_ops mt29f2g01abagd_ooblayout = {
|
||||
- .ecc = mt29f2g01abagd_ooblayout_ecc,
|
||||
- .free = mt29f2g01abagd_ooblayout_free,
|
||||
+static const struct mtd_ooblayout_ops micron_8_ooblayout = {
|
||||
+ .ecc = micron_8_ooblayout_ecc,
|
||||
+ .free = micron_8_ooblayout_free,
|
||||
};
|
||||
|
||||
-static int mt29f2g01abagd_ecc_get_status(struct spinand_device *spinand,
|
||||
- u8 status)
|
||||
+static int micron_8_ecc_get_status(struct spinand_device *spinand,
|
||||
+ u8 status)
|
||||
{
|
||||
switch (status & MICRON_STATUS_ECC_MASK) {
|
||||
case STATUS_ECC_NO_BITFLIPS:
|
||||
@@ -99,8 +99,8 @@ static const struct spinand_info micron_spinand_table[] = {
|
||||
&write_cache_variants,
|
||||
&update_cache_variants),
|
||||
0,
|
||||
- SPINAND_ECCINFO(&mt29f2g01abagd_ooblayout,
|
||||
- mt29f2g01abagd_ecc_get_status)),
|
||||
+ SPINAND_ECCINFO(µn_8_ooblayout,
|
||||
+ micron_8_ecc_get_status)),
|
||||
};
|
||||
|
||||
static const struct spinand_manufacturer_ops micron_spinand_manuf_ops = {
|
||||
@@ -0,0 +1,29 @@
|
||||
From 8511a3a9937e30949b34bea46c3dc3f65d11034b Mon Sep 17 00:00:00 2001
|
||||
From: Shivamurthy Shastri <sshivamurthy@micron.com>
|
||||
Date: Wed, 11 Mar 2020 18:57:31 +0100
|
||||
Subject: [PATCH] mtd: spinand: micron: Describe the SPI NAND device
|
||||
MT29F2G01ABAGD
|
||||
|
||||
Add the SPI NAND device MT29F2G01ABAGD series number, size and voltage
|
||||
details as a comment.
|
||||
|
||||
Signed-off-by: Shivamurthy Shastri <sshivamurthy@micron.com>
|
||||
Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com>
|
||||
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
|
||||
Link: https://lore.kernel.org/linux-mtd/20200311175735.2007-3-sshivamurthy@micron.com
|
||||
---
|
||||
drivers/mtd/nand/spi/micron.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/drivers/mtd/nand/spi/micron.c b/drivers/mtd/nand/spi/micron.c
|
||||
index cc1ee68421c8e1..4727933c894bc8 100644
|
||||
--- a/drivers/mtd/nand/spi/micron.c
|
||||
+++ b/drivers/mtd/nand/spi/micron.c
|
||||
@@ -91,6 +91,7 @@ static int micron_8_ecc_get_status(struct spinand_device *spinand,
|
||||
}
|
||||
|
||||
static const struct spinand_info micron_spinand_table[] = {
|
||||
+ /* M79A 2Gb 3.3V */
|
||||
SPINAND_INFO("MT29F2G01ABAGD",
|
||||
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x24),
|
||||
NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 2, 1, 1),
|
||||
@@ -0,0 +1,59 @@
|
||||
From a15335a17f4abf48ed9739c3b119232f9392cb60 Mon Sep 17 00:00:00 2001
|
||||
From: Shivamurthy Shastri <sshivamurthy@micron.com>
|
||||
Date: Wed, 11 Mar 2020 18:57:32 +0100
|
||||
Subject: [PATCH] mtd: spinand: micron: Add new Micron SPI NAND devices
|
||||
|
||||
Add device table for M79A and M78A series Micron SPI NAND devices.
|
||||
|
||||
Signed-off-by: Shivamurthy Shastri <sshivamurthy@micron.com>
|
||||
Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com>
|
||||
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
|
||||
Link: https://lore.kernel.org/linux-mtd/20200311175735.2007-4-sshivamurthy@micron.com
|
||||
---
|
||||
drivers/mtd/nand/spi/micron.c | 33 +++++++++++++++++++++++++++++++++
|
||||
1 file changed, 33 insertions(+)
|
||||
|
||||
diff --git a/drivers/mtd/nand/spi/micron.c b/drivers/mtd/nand/spi/micron.c
|
||||
index 4727933c894bc8..26925714a9fbac 100644
|
||||
--- a/drivers/mtd/nand/spi/micron.c
|
||||
+++ b/drivers/mtd/nand/spi/micron.c
|
||||
@@ -102,6 +102,39 @@ static const struct spinand_info micron_spinand_table[] = {
|
||||
0,
|
||||
SPINAND_ECCINFO(µn_8_ooblayout,
|
||||
micron_8_ecc_get_status)),
|
||||
+ /* M79A 2Gb 1.8V */
|
||||
+ SPINAND_INFO("MT29F2G01ABBGD",
|
||||
+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x25),
|
||||
+ NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 2, 1, 1),
|
||||
+ NAND_ECCREQ(8, 512),
|
||||
+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
|
||||
+ &write_cache_variants,
|
||||
+ &update_cache_variants),
|
||||
+ 0,
|
||||
+ SPINAND_ECCINFO(µn_8_ooblayout,
|
||||
+ micron_8_ecc_get_status)),
|
||||
+ /* M78A 1Gb 3.3V */
|
||||
+ SPINAND_INFO("MT29F1G01ABAFD",
|
||||
+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x14),
|
||||
+ NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
|
||||
+ NAND_ECCREQ(8, 512),
|
||||
+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
|
||||
+ &write_cache_variants,
|
||||
+ &update_cache_variants),
|
||||
+ 0,
|
||||
+ SPINAND_ECCINFO(µn_8_ooblayout,
|
||||
+ micron_8_ecc_get_status)),
|
||||
+ /* M78A 1Gb 1.8V */
|
||||
+ SPINAND_INFO("MT29F1G01ABAFD",
|
||||
+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x15),
|
||||
+ NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
|
||||
+ NAND_ECCREQ(8, 512),
|
||||
+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
|
||||
+ &write_cache_variants,
|
||||
+ &update_cache_variants),
|
||||
+ 0,
|
||||
+ SPINAND_ECCINFO(µn_8_ooblayout,
|
||||
+ micron_8_ecc_get_status)),
|
||||
};
|
||||
|
||||
static const struct spinand_manufacturer_ops micron_spinand_manuf_ops = {
|
||||
@@ -0,0 +1,79 @@
|
||||
From 0bc68af9137dc3f30b161de4ce546c7799f88d1e Mon Sep 17 00:00:00 2001
|
||||
From: Shivamurthy Shastri <sshivamurthy@micron.com>
|
||||
Date: Wed, 11 Mar 2020 18:57:33 +0100
|
||||
Subject: [PATCH] mtd: spinand: micron: identify SPI NAND device with
|
||||
Continuous Read mode
|
||||
|
||||
Add SPINAND_HAS_CR_FEAT_BIT flag to identify the SPI NAND device with
|
||||
the Continuous Read mode.
|
||||
|
||||
Some of the Micron SPI NAND devices have the "Continuous Read" feature
|
||||
enabled by default, which does not fit the subsystem needs.
|
||||
|
||||
In this mode, the READ CACHE command doesn't require the starting column
|
||||
address. The device always output the data starting from the first
|
||||
column of the cache register, and once the end of the cache register
|
||||
reached, the data output continues through the next page. With the
|
||||
continuous read mode, it is possible to read out the entire block using
|
||||
a single READ command, and once the end of the block reached, the output
|
||||
pins become High-Z state. However, during this mode the read command
|
||||
doesn't output the OOB area.
|
||||
|
||||
Hence, we disable the feature at probe time.
|
||||
|
||||
Signed-off-by: Shivamurthy Shastri <sshivamurthy@micron.com>
|
||||
Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com>
|
||||
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
|
||||
Link: https://lore.kernel.org/linux-mtd/20200311175735.2007-5-sshivamurthy@micron.com
|
||||
---
|
||||
drivers/mtd/nand/spi/micron.c | 16 ++++++++++++++++
|
||||
include/linux/mtd/spinand.h | 1 +
|
||||
2 files changed, 17 insertions(+)
|
||||
|
||||
diff --git a/drivers/mtd/nand/spi/micron.c b/drivers/mtd/nand/spi/micron.c
|
||||
index 26925714a9fbac..956f7710aca263 100644
|
||||
--- a/drivers/mtd/nand/spi/micron.c
|
||||
+++ b/drivers/mtd/nand/spi/micron.c
|
||||
@@ -18,6 +18,8 @@
|
||||
#define MICRON_STATUS_ECC_4TO6_BITFLIPS (3 << 4)
|
||||
#define MICRON_STATUS_ECC_7TO8_BITFLIPS (5 << 4)
|
||||
|
||||
+#define MICRON_CFG_CR BIT(0)
|
||||
+
|
||||
static SPINAND_OP_VARIANTS(read_cache_variants,
|
||||
SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 2, NULL, 0),
|
||||
SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0),
|
||||
@@ -137,7 +139,21 @@ static const struct spinand_info micron_spinand_table[] = {
|
||||
micron_8_ecc_get_status)),
|
||||
};
|
||||
|
||||
+static int micron_spinand_init(struct spinand_device *spinand)
|
||||
+{
|
||||
+ /*
|
||||
+ * M70A device series enable Continuous Read feature at Power-up,
|
||||
+ * which is not supported. Disable this bit to avoid any possible
|
||||
+ * failure.
|
||||
+ */
|
||||
+ if (spinand->flags & SPINAND_HAS_CR_FEAT_BIT)
|
||||
+ return spinand_upd_cfg(spinand, MICRON_CFG_CR, 0);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static const struct spinand_manufacturer_ops micron_spinand_manuf_ops = {
|
||||
+ .init = micron_spinand_init,
|
||||
};
|
||||
|
||||
const struct spinand_manufacturer micron_spinand_manufacturer = {
|
||||
diff --git a/include/linux/mtd/spinand.h b/include/linux/mtd/spinand.h
|
||||
index f4c4ae87181b27..1077c45721ff25 100644
|
||||
--- a/include/linux/mtd/spinand.h
|
||||
+++ b/include/linux/mtd/spinand.h
|
||||
@@ -284,6 +284,7 @@ struct spinand_ecc_info {
|
||||
};
|
||||
|
||||
#define SPINAND_HAS_QE_BIT BIT(0)
|
||||
+#define SPINAND_HAS_CR_FEAT_BIT BIT(1)
|
||||
|
||||
/**
|
||||
* struct spinand_info - Structure used to describe SPI NAND chips
|
||||
@@ -0,0 +1,48 @@
|
||||
From a7e5daccc310c3b892ae5e598cadb7a9274c2547 Mon Sep 17 00:00:00 2001
|
||||
From: Shivamurthy Shastri <sshivamurthy@micron.com>
|
||||
Date: Wed, 11 Mar 2020 18:57:34 +0100
|
||||
Subject: [PATCH] mtd: spinand: micron: Add M70A series Micron SPI NAND devices
|
||||
|
||||
Add device table for M70A series Micron SPI NAND devices.
|
||||
|
||||
Signed-off-by: Shivamurthy Shastri <sshivamurthy@micron.com>
|
||||
Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com>
|
||||
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
|
||||
Link: https://lore.kernel.org/linux-mtd/20200311175735.2007-6-sshivamurthy@micron.com
|
||||
---
|
||||
drivers/mtd/nand/spi/micron.c | 22 ++++++++++++++++++++++
|
||||
1 file changed, 22 insertions(+)
|
||||
|
||||
diff --git a/drivers/mtd/nand/spi/micron.c b/drivers/mtd/nand/spi/micron.c
|
||||
index 956f7710aca263..d6fd630087822c 100644
|
||||
--- a/drivers/mtd/nand/spi/micron.c
|
||||
+++ b/drivers/mtd/nand/spi/micron.c
|
||||
@@ -137,6 +137,28 @@ static const struct spinand_info micron_spinand_table[] = {
|
||||
0,
|
||||
SPINAND_ECCINFO(µn_8_ooblayout,
|
||||
micron_8_ecc_get_status)),
|
||||
+ /* M70A 4Gb 3.3V */
|
||||
+ SPINAND_INFO("MT29F4G01ABAFD",
|
||||
+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x34),
|
||||
+ NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 1, 1, 1),
|
||||
+ NAND_ECCREQ(8, 512),
|
||||
+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
|
||||
+ &write_cache_variants,
|
||||
+ &update_cache_variants),
|
||||
+ SPINAND_HAS_CR_FEAT_BIT,
|
||||
+ SPINAND_ECCINFO(µn_8_ooblayout,
|
||||
+ micron_8_ecc_get_status)),
|
||||
+ /* M70A 4Gb 1.8V */
|
||||
+ SPINAND_INFO("MT29F4G01ABBFD",
|
||||
+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x35),
|
||||
+ NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 1, 1, 1),
|
||||
+ NAND_ECCREQ(8, 512),
|
||||
+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
|
||||
+ &write_cache_variants,
|
||||
+ &update_cache_variants),
|
||||
+ SPINAND_HAS_CR_FEAT_BIT,
|
||||
+ SPINAND_ECCINFO(µn_8_ooblayout,
|
||||
+ micron_8_ecc_get_status)),
|
||||
};
|
||||
|
||||
static int micron_spinand_init(struct spinand_device *spinand)
|
||||
@@ -0,0 +1,109 @@
|
||||
From 9f9ae0c253c1e058fbc845e26c4a32a7d777f0dc Mon Sep 17 00:00:00 2001
|
||||
From: Shivamurthy Shastri <sshivamurthy@micron.com>
|
||||
Date: Wed, 11 Mar 2020 18:57:35 +0100
|
||||
Subject: [PATCH] mtd: spinand: micron: Add new Micron SPI NAND devices with
|
||||
multiple dies
|
||||
|
||||
Add device table for new Micron SPI NAND devices, which have multiple
|
||||
dies.
|
||||
|
||||
Also, enable support to select the dies.
|
||||
|
||||
Signed-off-by: Shivamurthy Shastri <sshivamurthy@micron.com>
|
||||
Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com>
|
||||
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
|
||||
Link: https://lore.kernel.org/linux-mtd/20200311175735.2007-7-sshivamurthy@micron.com
|
||||
---
|
||||
drivers/mtd/nand/spi/micron.c | 58 +++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 58 insertions(+)
|
||||
|
||||
diff --git a/drivers/mtd/nand/spi/micron.c b/drivers/mtd/nand/spi/micron.c
|
||||
index d6fd630087822c..5d370cfcdaaaa9 100644
|
||||
--- a/drivers/mtd/nand/spi/micron.c
|
||||
+++ b/drivers/mtd/nand/spi/micron.c
|
||||
@@ -20,6 +20,14 @@
|
||||
|
||||
#define MICRON_CFG_CR BIT(0)
|
||||
|
||||
+/*
|
||||
+ * As per datasheet, die selection is done by the 6th bit of Die
|
||||
+ * Select Register (Address 0xD0).
|
||||
+ */
|
||||
+#define MICRON_DIE_SELECT_REG 0xD0
|
||||
+
|
||||
+#define MICRON_SELECT_DIE(x) ((x) << 6)
|
||||
+
|
||||
static SPINAND_OP_VARIANTS(read_cache_variants,
|
||||
SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 2, NULL, 0),
|
||||
SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0),
|
||||
@@ -66,6 +74,20 @@ static const struct mtd_ooblayout_ops micron_8_ooblayout = {
|
||||
.free = micron_8_ooblayout_free,
|
||||
};
|
||||
|
||||
+static int micron_select_target(struct spinand_device *spinand,
|
||||
+ unsigned int target)
|
||||
+{
|
||||
+ struct spi_mem_op op = SPINAND_SET_FEATURE_OP(MICRON_DIE_SELECT_REG,
|
||||
+ spinand->scratchbuf);
|
||||
+
|
||||
+ if (target > 1)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ *spinand->scratchbuf = MICRON_SELECT_DIE(target);
|
||||
+
|
||||
+ return spi_mem_exec_op(spinand->spimem, &op);
|
||||
+}
|
||||
+
|
||||
static int micron_8_ecc_get_status(struct spinand_device *spinand,
|
||||
u8 status)
|
||||
{
|
||||
@@ -137,6 +159,18 @@ static const struct spinand_info micron_spinand_table[] = {
|
||||
0,
|
||||
SPINAND_ECCINFO(µn_8_ooblayout,
|
||||
micron_8_ecc_get_status)),
|
||||
+ /* M79A 4Gb 3.3V */
|
||||
+ SPINAND_INFO("MT29F4G01ADAGD",
|
||||
+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x36),
|
||||
+ NAND_MEMORG(1, 2048, 128, 64, 2048, 80, 2, 1, 2),
|
||||
+ NAND_ECCREQ(8, 512),
|
||||
+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
|
||||
+ &write_cache_variants,
|
||||
+ &update_cache_variants),
|
||||
+ 0,
|
||||
+ SPINAND_ECCINFO(µn_8_ooblayout,
|
||||
+ micron_8_ecc_get_status),
|
||||
+ SPINAND_SELECT_TARGET(micron_select_target)),
|
||||
/* M70A 4Gb 3.3V */
|
||||
SPINAND_INFO("MT29F4G01ABAFD",
|
||||
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x34),
|
||||
@@ -159,6 +193,30 @@ static const struct spinand_info micron_spinand_table[] = {
|
||||
SPINAND_HAS_CR_FEAT_BIT,
|
||||
SPINAND_ECCINFO(µn_8_ooblayout,
|
||||
micron_8_ecc_get_status)),
|
||||
+ /* M70A 8Gb 3.3V */
|
||||
+ SPINAND_INFO("MT29F8G01ADAFD",
|
||||
+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x46),
|
||||
+ NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 1, 1, 2),
|
||||
+ NAND_ECCREQ(8, 512),
|
||||
+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
|
||||
+ &write_cache_variants,
|
||||
+ &update_cache_variants),
|
||||
+ SPINAND_HAS_CR_FEAT_BIT,
|
||||
+ SPINAND_ECCINFO(µn_8_ooblayout,
|
||||
+ micron_8_ecc_get_status),
|
||||
+ SPINAND_SELECT_TARGET(micron_select_target)),
|
||||
+ /* M70A 8Gb 1.8V */
|
||||
+ SPINAND_INFO("MT29F8G01ADBFD",
|
||||
+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x47),
|
||||
+ NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 1, 1, 2),
|
||||
+ NAND_ECCREQ(8, 512),
|
||||
+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
|
||||
+ &write_cache_variants,
|
||||
+ &update_cache_variants),
|
||||
+ SPINAND_HAS_CR_FEAT_BIT,
|
||||
+ SPINAND_ECCINFO(µn_8_ooblayout,
|
||||
+ micron_8_ecc_get_status),
|
||||
+ SPINAND_SELECT_TARGET(micron_select_target)),
|
||||
};
|
||||
|
||||
static int micron_spinand_init(struct spinand_device *spinand)
|
||||
@@ -0,0 +1,159 @@
|
||||
From bdb84a22b02b0c2ca76bb3e3e16942338f67999b Mon Sep 17 00:00:00 2001
|
||||
From: Thirumalesha Narasimhappa <nthirumalesha7@gmail.com>
|
||||
Date: Sun, 8 Nov 2020 19:37:34 +0800
|
||||
Subject: [PATCH] mtd: spinand: micron: Use more specific names
|
||||
|
||||
Rename the read/write/update of SPINAND_OP_VARIANTS() to more
|
||||
specialized names.
|
||||
|
||||
Signed-off-by: Thirumalesha Narasimhappa <nthirumalesha7@gmail.com>
|
||||
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
|
||||
Link: https://lore.kernel.org/linux-mtd/20201108113735.2533-2-nthirumalesha7@gmail.com
|
||||
---
|
||||
drivers/mtd/nand/spi/micron.c | 60 +++++++++++++++++------------------
|
||||
1 file changed, 30 insertions(+), 30 deletions(-)
|
||||
|
||||
diff --git a/drivers/mtd/nand/spi/micron.c b/drivers/mtd/nand/spi/micron.c
|
||||
index 5d370cfcdaaaa9..afe3ba37dcfb8e 100644
|
||||
--- a/drivers/mtd/nand/spi/micron.c
|
||||
+++ b/drivers/mtd/nand/spi/micron.c
|
||||
@@ -28,7 +28,7 @@
|
||||
|
||||
#define MICRON_SELECT_DIE(x) ((x) << 6)
|
||||
|
||||
-static SPINAND_OP_VARIANTS(read_cache_variants,
|
||||
+static SPINAND_OP_VARIANTS(quadio_read_cache_variants,
|
||||
SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 2, NULL, 0),
|
||||
SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0),
|
||||
SPINAND_PAGE_READ_FROM_CACHE_DUALIO_OP(0, 1, NULL, 0),
|
||||
@@ -36,11 +36,11 @@ static SPINAND_OP_VARIANTS(read_cache_variants,
|
||||
SPINAND_PAGE_READ_FROM_CACHE_OP(true, 0, 1, NULL, 0),
|
||||
SPINAND_PAGE_READ_FROM_CACHE_OP(false, 0, 1, NULL, 0));
|
||||
|
||||
-static SPINAND_OP_VARIANTS(write_cache_variants,
|
||||
+static SPINAND_OP_VARIANTS(x4_write_cache_variants,
|
||||
SPINAND_PROG_LOAD_X4(true, 0, NULL, 0),
|
||||
SPINAND_PROG_LOAD(true, 0, NULL, 0));
|
||||
|
||||
-static SPINAND_OP_VARIANTS(update_cache_variants,
|
||||
+static SPINAND_OP_VARIANTS(x4_update_cache_variants,
|
||||
SPINAND_PROG_LOAD_X4(false, 0, NULL, 0),
|
||||
SPINAND_PROG_LOAD(false, 0, NULL, 0));
|
||||
|
||||
@@ -120,9 +120,9 @@ static const struct spinand_info micron_spinand_table[] = {
|
||||
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x24),
|
||||
NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 2, 1, 1),
|
||||
NAND_ECCREQ(8, 512),
|
||||
- SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
|
||||
- &write_cache_variants,
|
||||
- &update_cache_variants),
|
||||
+ SPINAND_INFO_OP_VARIANTS(&quadio_read_cache_variants,
|
||||
+ &x4_write_cache_variants,
|
||||
+ &x4_update_cache_variants),
|
||||
0,
|
||||
SPINAND_ECCINFO(µn_8_ooblayout,
|
||||
micron_8_ecc_get_status)),
|
||||
@@ -131,9 +131,9 @@ static const struct spinand_info micron_spinand_table[] = {
|
||||
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x25),
|
||||
NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 2, 1, 1),
|
||||
NAND_ECCREQ(8, 512),
|
||||
- SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
|
||||
- &write_cache_variants,
|
||||
- &update_cache_variants),
|
||||
+ SPINAND_INFO_OP_VARIANTS(&quadio_read_cache_variants,
|
||||
+ &x4_write_cache_variants,
|
||||
+ &x4_update_cache_variants),
|
||||
0,
|
||||
SPINAND_ECCINFO(µn_8_ooblayout,
|
||||
micron_8_ecc_get_status)),
|
||||
@@ -142,9 +142,9 @@ static const struct spinand_info micron_spinand_table[] = {
|
||||
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x14),
|
||||
NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
|
||||
NAND_ECCREQ(8, 512),
|
||||
- SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
|
||||
- &write_cache_variants,
|
||||
- &update_cache_variants),
|
||||
+ SPINAND_INFO_OP_VARIANTS(&quadio_read_cache_variants,
|
||||
+ &x4_write_cache_variants,
|
||||
+ &x4_update_cache_variants),
|
||||
0,
|
||||
SPINAND_ECCINFO(µn_8_ooblayout,
|
||||
micron_8_ecc_get_status)),
|
||||
@@ -153,9 +153,9 @@ static const struct spinand_info micron_spinand_table[] = {
|
||||
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x15),
|
||||
NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
|
||||
NAND_ECCREQ(8, 512),
|
||||
- SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
|
||||
- &write_cache_variants,
|
||||
- &update_cache_variants),
|
||||
+ SPINAND_INFO_OP_VARIANTS(&quadio_read_cache_variants,
|
||||
+ &x4_write_cache_variants,
|
||||
+ &x4_update_cache_variants),
|
||||
0,
|
||||
SPINAND_ECCINFO(µn_8_ooblayout,
|
||||
micron_8_ecc_get_status)),
|
||||
@@ -164,9 +164,9 @@ static const struct spinand_info micron_spinand_table[] = {
|
||||
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x36),
|
||||
NAND_MEMORG(1, 2048, 128, 64, 2048, 80, 2, 1, 2),
|
||||
NAND_ECCREQ(8, 512),
|
||||
- SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
|
||||
- &write_cache_variants,
|
||||
- &update_cache_variants),
|
||||
+ SPINAND_INFO_OP_VARIANTS(&quadio_read_cache_variants,
|
||||
+ &x4_write_cache_variants,
|
||||
+ &x4_update_cache_variants),
|
||||
0,
|
||||
SPINAND_ECCINFO(µn_8_ooblayout,
|
||||
micron_8_ecc_get_status),
|
||||
@@ -176,9 +176,9 @@ static const struct spinand_info micron_spinand_table[] = {
|
||||
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x34),
|
||||
NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 1, 1, 1),
|
||||
NAND_ECCREQ(8, 512),
|
||||
- SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
|
||||
- &write_cache_variants,
|
||||
- &update_cache_variants),
|
||||
+ SPINAND_INFO_OP_VARIANTS(&quadio_read_cache_variants,
|
||||
+ &x4_write_cache_variants,
|
||||
+ &x4_update_cache_variants),
|
||||
SPINAND_HAS_CR_FEAT_BIT,
|
||||
SPINAND_ECCINFO(µn_8_ooblayout,
|
||||
micron_8_ecc_get_status)),
|
||||
@@ -187,9 +187,9 @@ static const struct spinand_info micron_spinand_table[] = {
|
||||
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x35),
|
||||
NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 1, 1, 1),
|
||||
NAND_ECCREQ(8, 512),
|
||||
- SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
|
||||
- &write_cache_variants,
|
||||
- &update_cache_variants),
|
||||
+ SPINAND_INFO_OP_VARIANTS(&quadio_read_cache_variants,
|
||||
+ &x4_write_cache_variants,
|
||||
+ &x4_update_cache_variants),
|
||||
SPINAND_HAS_CR_FEAT_BIT,
|
||||
SPINAND_ECCINFO(µn_8_ooblayout,
|
||||
micron_8_ecc_get_status)),
|
||||
@@ -198,9 +198,9 @@ static const struct spinand_info micron_spinand_table[] = {
|
||||
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x46),
|
||||
NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 1, 1, 2),
|
||||
NAND_ECCREQ(8, 512),
|
||||
- SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
|
||||
- &write_cache_variants,
|
||||
- &update_cache_variants),
|
||||
+ SPINAND_INFO_OP_VARIANTS(&quadio_read_cache_variants,
|
||||
+ &x4_write_cache_variants,
|
||||
+ &x4_update_cache_variants),
|
||||
SPINAND_HAS_CR_FEAT_BIT,
|
||||
SPINAND_ECCINFO(µn_8_ooblayout,
|
||||
micron_8_ecc_get_status),
|
||||
@@ -210,9 +210,9 @@ static const struct spinand_info micron_spinand_table[] = {
|
||||
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x47),
|
||||
NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 1, 1, 2),
|
||||
NAND_ECCREQ(8, 512),
|
||||
- SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
|
||||
- &write_cache_variants,
|
||||
- &update_cache_variants),
|
||||
+ SPINAND_INFO_OP_VARIANTS(&quadio_read_cache_variants,
|
||||
+ &x4_write_cache_variants,
|
||||
+ &x4_update_cache_variants),
|
||||
SPINAND_HAS_CR_FEAT_BIT,
|
||||
SPINAND_ECCINFO(µn_8_ooblayout,
|
||||
micron_8_ecc_get_status),
|
||||
@@ -0,0 +1,104 @@
|
||||
From 8c573d9419bf61f7b66b6114f1171f3a8a4a0e38 Mon Sep 17 00:00:00 2001
|
||||
From: Thirumalesha Narasimhappa <nthirumalesha7@gmail.com>
|
||||
Date: Sun, 8 Nov 2020 19:37:35 +0800
|
||||
Subject: [PATCH] mtd: spinand: micron: Add support for MT29F2G01AAAED
|
||||
|
||||
The MT29F2G01AAAED is a single die, 2Gb Micron SPI NAND Flash with 4-bit
|
||||
ECC
|
||||
|
||||
Signed-off-by: Thirumalesha Narasimhappa <nthirumalesha7@gmail.com>
|
||||
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
|
||||
Link: https://lore.kernel.org/linux-mtd/20201108113735.2533-3-nthirumalesha7@gmail.com
|
||||
---
|
||||
drivers/mtd/nand/spi/micron.c | 64 +++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 64 insertions(+)
|
||||
|
||||
diff --git a/drivers/mtd/nand/spi/micron.c b/drivers/mtd/nand/spi/micron.c
|
||||
index afe3ba37dcfb8e..50b7295bc92226 100644
|
||||
--- a/drivers/mtd/nand/spi/micron.c
|
||||
+++ b/drivers/mtd/nand/spi/micron.c
|
||||
@@ -44,6 +44,19 @@ static SPINAND_OP_VARIANTS(x4_update_cache_variants,
|
||||
SPINAND_PROG_LOAD_X4(false, 0, NULL, 0),
|
||||
SPINAND_PROG_LOAD(false, 0, NULL, 0));
|
||||
|
||||
+/* Micron MT29F2G01AAAED Device */
|
||||
+static SPINAND_OP_VARIANTS(x4_read_cache_variants,
|
||||
+ SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0),
|
||||
+ SPINAND_PAGE_READ_FROM_CACHE_X2_OP(0, 1, NULL, 0),
|
||||
+ SPINAND_PAGE_READ_FROM_CACHE_OP(true, 0, 1, NULL, 0),
|
||||
+ SPINAND_PAGE_READ_FROM_CACHE_OP(false, 0, 1, NULL, 0));
|
||||
+
|
||||
+static SPINAND_OP_VARIANTS(x1_write_cache_variants,
|
||||
+ SPINAND_PROG_LOAD(true, 0, NULL, 0));
|
||||
+
|
||||
+static SPINAND_OP_VARIANTS(x1_update_cache_variants,
|
||||
+ SPINAND_PROG_LOAD(false, 0, NULL, 0));
|
||||
+
|
||||
static int micron_8_ooblayout_ecc(struct mtd_info *mtd, int section,
|
||||
struct mtd_oob_region *region)
|
||||
{
|
||||
@@ -74,6 +87,47 @@ static const struct mtd_ooblayout_ops micron_8_ooblayout = {
|
||||
.free = micron_8_ooblayout_free,
|
||||
};
|
||||
|
||||
+static int micron_4_ooblayout_ecc(struct mtd_info *mtd, int section,
|
||||
+ struct mtd_oob_region *region)
|
||||
+{
|
||||
+ struct spinand_device *spinand = mtd_to_spinand(mtd);
|
||||
+
|
||||
+ if (section >= spinand->base.memorg.pagesize /
|
||||
+ mtd->ecc_step_size)
|
||||
+ return -ERANGE;
|
||||
+
|
||||
+ region->offset = (section * 16) + 8;
|
||||
+ region->length = 8;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int micron_4_ooblayout_free(struct mtd_info *mtd, int section,
|
||||
+ struct mtd_oob_region *region)
|
||||
+{
|
||||
+ struct spinand_device *spinand = mtd_to_spinand(mtd);
|
||||
+
|
||||
+ if (section >= spinand->base.memorg.pagesize /
|
||||
+ mtd->ecc_step_size)
|
||||
+ return -ERANGE;
|
||||
+
|
||||
+ if (section) {
|
||||
+ region->offset = 16 * section;
|
||||
+ region->length = 8;
|
||||
+ } else {
|
||||
+ /* section 0 has two bytes reserved for the BBM */
|
||||
+ region->offset = 2;
|
||||
+ region->length = 6;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static const struct mtd_ooblayout_ops micron_4_ooblayout = {
|
||||
+ .ecc = micron_4_ooblayout_ecc,
|
||||
+ .free = micron_4_ooblayout_free,
|
||||
+};
|
||||
+
|
||||
static int micron_select_target(struct spinand_device *spinand,
|
||||
unsigned int target)
|
||||
{
|
||||
@@ -217,6 +271,16 @@ static const struct spinand_info micron_spinand_table[] = {
|
||||
SPINAND_ECCINFO(µn_8_ooblayout,
|
||||
micron_8_ecc_get_status),
|
||||
SPINAND_SELECT_TARGET(micron_select_target)),
|
||||
+ /* M69A 2Gb 3.3V */
|
||||
+ SPINAND_INFO("MT29F2G01AAAED",
|
||||
+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x9F),
|
||||
+ NAND_MEMORG(1, 2048, 64, 64, 2048, 80, 2, 1, 1),
|
||||
+ NAND_ECCREQ(4, 512),
|
||||
+ SPINAND_INFO_OP_VARIANTS(&x4_read_cache_variants,
|
||||
+ &x1_write_cache_variants,
|
||||
+ &x1_update_cache_variants),
|
||||
+ 0,
|
||||
+ SPINAND_ECCINFO(µn_4_ooblayout, NULL)),
|
||||
};
|
||||
|
||||
static int micron_spinand_init(struct spinand_device *spinand)
|
||||
@@ -0,0 +1,170 @@
|
||||
From 6b49e58d6d9dab031a16af2af5439f28a37c4cd9 Mon Sep 17 00:00:00 2001
|
||||
From: Yoshio Furuyama <ytc-mb-yfuruyama7@kioxia.com>
|
||||
Date: Tue, 24 Mar 2020 15:49:44 +0900
|
||||
Subject: [PATCH] mtd: spinand: toshiba: Rename function name to change suffix
|
||||
and prefix (8Gbit)
|
||||
|
||||
The suffix was changed from "G" to "J" to classify between 1st generation
|
||||
and 2nd generation serial NAND devices (which now belong to the Kioxia
|
||||
brand).
|
||||
As reference that's
|
||||
1st generation device of 1Gbit product is "TC58CVG0S3HRAIG"
|
||||
2nd generation device of 1Gbit product is "TC58CVG0S3HRAIJ".
|
||||
|
||||
The 8Gbit type "TH58CxG3S0HRAIJ" is new to Kioxia's serial NAND lineup and
|
||||
the prefix was changed from "TC58" to "TH58".
|
||||
|
||||
Thus the functions were renamed from tc58cxgxsx_*() to tx58cxgxsxraix_*().
|
||||
|
||||
Signed-off-by: Yoshio Furuyama <ytc-mb-yfuruyama7@kioxia.com>
|
||||
Reviewed-by: Frieder Schrempf <frieder.schrempf@kontron.de>
|
||||
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
|
||||
Link: https://lore.kernel.org/linux-mtd/0dedd9869569a17625822dba87878254d253ba0e.1584949601.git.ytc-mb-yfuruyama7@kioxia.com
|
||||
---
|
||||
drivers/mtd/nand/spi/toshiba.c | 60 +++++++++++++++++-----------------
|
||||
1 file changed, 30 insertions(+), 30 deletions(-)
|
||||
|
||||
--- a/drivers/mtd/nand/spi/toshiba.c
|
||||
+++ b/drivers/mtd/nand/spi/toshiba.c
|
||||
@@ -25,8 +25,8 @@ static SPINAND_OP_VARIANTS(write_cache_v
|
||||
static SPINAND_OP_VARIANTS(update_cache_variants,
|
||||
SPINAND_PROG_LOAD(false, 0, NULL, 0));
|
||||
|
||||
-static int tc58cxgxsx_ooblayout_ecc(struct mtd_info *mtd, int section,
|
||||
- struct mtd_oob_region *region)
|
||||
+static int tx58cxgxsxraix_ooblayout_ecc(struct mtd_info *mtd, int section,
|
||||
+ struct mtd_oob_region *region)
|
||||
{
|
||||
if (section > 0)
|
||||
return -ERANGE;
|
||||
@@ -37,8 +37,8 @@ static int tc58cxgxsx_ooblayout_ecc(stru
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static int tc58cxgxsx_ooblayout_free(struct mtd_info *mtd, int section,
|
||||
- struct mtd_oob_region *region)
|
||||
+static int tx58cxgxsxraix_ooblayout_free(struct mtd_info *mtd, int section,
|
||||
+ struct mtd_oob_region *region)
|
||||
{
|
||||
if (section > 0)
|
||||
return -ERANGE;
|
||||
@@ -50,13 +50,13 @@ static int tc58cxgxsx_ooblayout_free(str
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static const struct mtd_ooblayout_ops tc58cxgxsx_ooblayout = {
|
||||
- .ecc = tc58cxgxsx_ooblayout_ecc,
|
||||
- .free = tc58cxgxsx_ooblayout_free,
|
||||
+static const struct mtd_ooblayout_ops tx58cxgxsxraix_ooblayout = {
|
||||
+ .ecc = tx58cxgxsxraix_ooblayout_ecc,
|
||||
+ .free = tx58cxgxsxraix_ooblayout_free,
|
||||
};
|
||||
|
||||
-static int tc58cxgxsx_ecc_get_status(struct spinand_device *spinand,
|
||||
- u8 status)
|
||||
+static int tx58cxgxsxraix_ecc_get_status(struct spinand_device *spinand,
|
||||
+ u8 status)
|
||||
{
|
||||
struct nand_device *nand = spinand_to_nand(spinand);
|
||||
u8 mbf = 0;
|
||||
@@ -95,7 +95,7 @@ static int tc58cxgxsx_ecc_get_status(str
|
||||
|
||||
static const struct spinand_info toshiba_spinand_table[] = {
|
||||
/* 3.3V 1Gb */
|
||||
- SPINAND_INFO("TC58CVG0S3",
|
||||
+ SPINAND_INFO("TC58CVG0S3HRAIG",
|
||||
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xC2),
|
||||
NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
|
||||
NAND_ECCREQ(8, 512),
|
||||
@@ -103,10 +103,10 @@ static const struct spinand_info toshiba
|
||||
&write_cache_variants,
|
||||
&update_cache_variants),
|
||||
0,
|
||||
- SPINAND_ECCINFO(&tc58cxgxsx_ooblayout,
|
||||
- tc58cxgxsx_ecc_get_status)),
|
||||
+ SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
|
||||
+ tx58cxgxsxraix_ecc_get_status)),
|
||||
/* 3.3V 2Gb */
|
||||
- SPINAND_INFO("TC58CVG1S3",
|
||||
+ SPINAND_INFO("TC58CVG1S3HRAIG",
|
||||
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xCB),
|
||||
NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
|
||||
NAND_ECCREQ(8, 512),
|
||||
@@ -114,10 +114,10 @@ static const struct spinand_info toshiba
|
||||
&write_cache_variants,
|
||||
&update_cache_variants),
|
||||
0,
|
||||
- SPINAND_ECCINFO(&tc58cxgxsx_ooblayout,
|
||||
- tc58cxgxsx_ecc_get_status)),
|
||||
+ SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
|
||||
+ tx58cxgxsxraix_ecc_get_status)),
|
||||
/* 3.3V 4Gb */
|
||||
- SPINAND_INFO("TC58CVG2S0",
|
||||
+ SPINAND_INFO("TC58CVG2S0HRAIG",
|
||||
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xCD),
|
||||
NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 1, 1, 1),
|
||||
NAND_ECCREQ(8, 512),
|
||||
@@ -125,10 +125,21 @@ static const struct spinand_info toshiba
|
||||
&write_cache_variants,
|
||||
&update_cache_variants),
|
||||
0,
|
||||
- SPINAND_ECCINFO(&tc58cxgxsx_ooblayout,
|
||||
- tc58cxgxsx_ecc_get_status)),
|
||||
+ SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
|
||||
+ tx58cxgxsxraix_ecc_get_status)),
|
||||
+ /* 3.3V 4Gb */
|
||||
+ SPINAND_INFO("TC58CVG2S0HRAIJ",
|
||||
+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xED),
|
||||
+ NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 1, 1, 1),
|
||||
+ NAND_ECCREQ(8, 512),
|
||||
+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
|
||||
+ &write_cache_variants,
|
||||
+ &update_cache_variants),
|
||||
+ 0,
|
||||
+ SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
|
||||
+ tx58cxgxsxraix_ecc_get_status)),
|
||||
/* 1.8V 1Gb */
|
||||
- SPINAND_INFO("TC58CYG0S3",
|
||||
+ SPINAND_INFO("TC58CYG0S3HRAIG",
|
||||
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xB2),
|
||||
NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
|
||||
NAND_ECCREQ(8, 512),
|
||||
@@ -136,10 +147,10 @@ static const struct spinand_info toshiba
|
||||
&write_cache_variants,
|
||||
&update_cache_variants),
|
||||
0,
|
||||
- SPINAND_ECCINFO(&tc58cxgxsx_ooblayout,
|
||||
- tc58cxgxsx_ecc_get_status)),
|
||||
+ SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
|
||||
+ tx58cxgxsxraix_ecc_get_status)),
|
||||
/* 1.8V 2Gb */
|
||||
- SPINAND_INFO("TC58CYG1S3",
|
||||
+ SPINAND_INFO("TC58CYG1S3HRAIG",
|
||||
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xBB),
|
||||
NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
|
||||
NAND_ECCREQ(8, 512),
|
||||
@@ -147,10 +158,10 @@ static const struct spinand_info toshiba
|
||||
&write_cache_variants,
|
||||
&update_cache_variants),
|
||||
0,
|
||||
- SPINAND_ECCINFO(&tc58cxgxsx_ooblayout,
|
||||
- tc58cxgxsx_ecc_get_status)),
|
||||
+ SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
|
||||
+ tx58cxgxsxraix_ecc_get_status)),
|
||||
/* 1.8V 4Gb */
|
||||
- SPINAND_INFO("TC58CYG2S0",
|
||||
+ SPINAND_INFO("TC58CYG2S0HRAIG",
|
||||
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xBD),
|
||||
NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 1, 1, 1),
|
||||
NAND_ECCREQ(8, 512),
|
||||
@@ -158,8 +169,8 @@ static const struct spinand_info toshiba
|
||||
&write_cache_variants,
|
||||
&update_cache_variants),
|
||||
0,
|
||||
- SPINAND_ECCINFO(&tc58cxgxsx_ooblayout,
|
||||
- tc58cxgxsx_ecc_get_status)),
|
||||
+ SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
|
||||
+ tx58cxgxsxraix_ecc_get_status)),
|
||||
};
|
||||
|
||||
static const struct spinand_manufacturer_ops toshiba_spinand_manuf_ops = {
|
||||
@@ -0,0 +1,205 @@
|
||||
From 798fcdd010006e87b3154d6454c657af7b033002 Mon Sep 17 00:00:00 2001
|
||||
From: Yoshio Furuyama <ytc-mb-yfuruyama7@kioxia.com>
|
||||
Date: Tue, 24 Mar 2020 15:49:55 +0900
|
||||
Subject: [PATCH] mtd: spinand: toshiba: Support for new Kioxia Serial NAND
|
||||
|
||||
Add support for new Kioxia products.
|
||||
The new Kioxia products support program load x4 command, and have
|
||||
HOLD_D bit which is equivalent to QE bit.
|
||||
|
||||
Signed-off-by: Yoshio Furuyama <ytc-mb-yfuruyama7@kioxia.com>
|
||||
Reviewed-by: Frieder Schrempf <frieder.schrempf@kontron.de>
|
||||
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
|
||||
Link: https://lore.kernel.org/linux-mtd/aa69e455beedc5ce0d7141359b9364ed8aec9e65.1584949601.git.ytc-mb-yfuruyama7@kioxia.com
|
||||
---
|
||||
drivers/mtd/nand/spi/toshiba.c | 128 ++++++++++++++++++++++++++++-----
|
||||
1 file changed, 111 insertions(+), 17 deletions(-)
|
||||
|
||||
diff --git a/drivers/mtd/nand/spi/toshiba.c b/drivers/mtd/nand/spi/toshiba.c
|
||||
index 5d217dd4b2539a..bc801d83343e5c 100644
|
||||
--- a/drivers/mtd/nand/spi/toshiba.c
|
||||
+++ b/drivers/mtd/nand/spi/toshiba.c
|
||||
@@ -20,6 +20,18 @@ static SPINAND_OP_VARIANTS(read_cache_variants,
|
||||
SPINAND_PAGE_READ_FROM_CACHE_OP(true, 0, 1, NULL, 0),
|
||||
SPINAND_PAGE_READ_FROM_CACHE_OP(false, 0, 1, NULL, 0));
|
||||
|
||||
+static SPINAND_OP_VARIANTS(write_cache_x4_variants,
|
||||
+ SPINAND_PROG_LOAD_X4(true, 0, NULL, 0),
|
||||
+ SPINAND_PROG_LOAD(true, 0, NULL, 0));
|
||||
+
|
||||
+static SPINAND_OP_VARIANTS(update_cache_x4_variants,
|
||||
+ SPINAND_PROG_LOAD_X4(false, 0, NULL, 0),
|
||||
+ SPINAND_PROG_LOAD(false, 0, NULL, 0));
|
||||
+
|
||||
+/**
|
||||
+ * Backward compatibility for 1st generation Serial NAND devices
|
||||
+ * which don't support Quad Program Load operation.
|
||||
+ */
|
||||
static SPINAND_OP_VARIANTS(write_cache_variants,
|
||||
SPINAND_PROG_LOAD(true, 0, NULL, 0));
|
||||
|
||||
@@ -95,7 +107,7 @@ static int tx58cxgxsxraix_ecc_get_status(struct spinand_device *spinand,
|
||||
}
|
||||
|
||||
static const struct spinand_info toshiba_spinand_table[] = {
|
||||
- /* 3.3V 1Gb */
|
||||
+ /* 3.3V 1Gb (1st generation) */
|
||||
SPINAND_INFO("TC58CVG0S3HRAIG",
|
||||
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xC2),
|
||||
NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
|
||||
@@ -106,7 +118,7 @@ static const struct spinand_info toshiba_spinand_table[] = {
|
||||
0,
|
||||
SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
|
||||
tx58cxgxsxraix_ecc_get_status)),
|
||||
- /* 3.3V 2Gb */
|
||||
+ /* 3.3V 2Gb (1st generation) */
|
||||
SPINAND_INFO("TC58CVG1S3HRAIG",
|
||||
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xCB),
|
||||
NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
|
||||
@@ -117,7 +129,7 @@ static const struct spinand_info toshiba_spinand_table[] = {
|
||||
0,
|
||||
SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
|
||||
tx58cxgxsxraix_ecc_get_status)),
|
||||
- /* 3.3V 4Gb */
|
||||
+ /* 3.3V 4Gb (1st generation) */
|
||||
SPINAND_INFO("TC58CVG2S0HRAIG",
|
||||
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xCD),
|
||||
NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 1, 1, 1),
|
||||
@@ -128,18 +140,7 @@ static const struct spinand_info toshiba_spinand_table[] = {
|
||||
0,
|
||||
SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
|
||||
tx58cxgxsxraix_ecc_get_status)),
|
||||
- /* 3.3V 4Gb */
|
||||
- SPINAND_INFO("TC58CVG2S0HRAIJ",
|
||||
- SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xED),
|
||||
- NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 1, 1, 1),
|
||||
- NAND_ECCREQ(8, 512),
|
||||
- SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
|
||||
- &write_cache_variants,
|
||||
- &update_cache_variants),
|
||||
- 0,
|
||||
- SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
|
||||
- tx58cxgxsxraix_ecc_get_status)),
|
||||
- /* 1.8V 1Gb */
|
||||
+ /* 1.8V 1Gb (1st generation) */
|
||||
SPINAND_INFO("TC58CYG0S3HRAIG",
|
||||
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xB2),
|
||||
NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
|
||||
@@ -150,7 +151,7 @@ static const struct spinand_info toshiba_spinand_table[] = {
|
||||
0,
|
||||
SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
|
||||
tx58cxgxsxraix_ecc_get_status)),
|
||||
- /* 1.8V 2Gb */
|
||||
+ /* 1.8V 2Gb (1st generation) */
|
||||
SPINAND_INFO("TC58CYG1S3HRAIG",
|
||||
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xBB),
|
||||
NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
|
||||
@@ -161,7 +162,7 @@ static const struct spinand_info toshiba_spinand_table[] = {
|
||||
0,
|
||||
SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
|
||||
tx58cxgxsxraix_ecc_get_status)),
|
||||
- /* 1.8V 4Gb */
|
||||
+ /* 1.8V 4Gb (1st generation) */
|
||||
SPINAND_INFO("TC58CYG2S0HRAIG",
|
||||
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xBD),
|
||||
NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 1, 1, 1),
|
||||
@@ -172,6 +173,99 @@ static const struct spinand_info toshiba_spinand_table[] = {
|
||||
0,
|
||||
SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
|
||||
tx58cxgxsxraix_ecc_get_status)),
|
||||
+
|
||||
+ /*
|
||||
+ * 2nd generation serial nand has HOLD_D which is equivalent to
|
||||
+ * QE_BIT.
|
||||
+ */
|
||||
+ /* 3.3V 1Gb (2nd generation) */
|
||||
+ SPINAND_INFO("TC58CVG0S3HRAIJ",
|
||||
+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xE2),
|
||||
+ NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
|
||||
+ NAND_ECCREQ(8, 512),
|
||||
+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
|
||||
+ &write_cache_x4_variants,
|
||||
+ &update_cache_x4_variants),
|
||||
+ SPINAND_HAS_QE_BIT,
|
||||
+ SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
|
||||
+ tx58cxgxsxraix_ecc_get_status)),
|
||||
+ /* 3.3V 2Gb (2nd generation) */
|
||||
+ SPINAND_INFO("TC58CVG1S3HRAIJ",
|
||||
+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xEB),
|
||||
+ NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
|
||||
+ NAND_ECCREQ(8, 512),
|
||||
+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
|
||||
+ &write_cache_x4_variants,
|
||||
+ &update_cache_x4_variants),
|
||||
+ SPINAND_HAS_QE_BIT,
|
||||
+ SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
|
||||
+ tx58cxgxsxraix_ecc_get_status)),
|
||||
+ /* 3.3V 4Gb (2nd generation) */
|
||||
+ SPINAND_INFO("TC58CVG2S0HRAIJ",
|
||||
+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xED),
|
||||
+ NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 1, 1, 1),
|
||||
+ NAND_ECCREQ(8, 512),
|
||||
+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
|
||||
+ &write_cache_x4_variants,
|
||||
+ &update_cache_x4_variants),
|
||||
+ SPINAND_HAS_QE_BIT,
|
||||
+ SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
|
||||
+ tx58cxgxsxraix_ecc_get_status)),
|
||||
+ /* 3.3V 8Gb (2nd generation) */
|
||||
+ SPINAND_INFO("TH58CVG3S0HRAIJ",
|
||||
+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xE4),
|
||||
+ NAND_MEMORG(1, 4096, 256, 64, 4096, 80, 1, 1, 1),
|
||||
+ NAND_ECCREQ(8, 512),
|
||||
+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
|
||||
+ &write_cache_x4_variants,
|
||||
+ &update_cache_x4_variants),
|
||||
+ SPINAND_HAS_QE_BIT,
|
||||
+ SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
|
||||
+ tx58cxgxsxraix_ecc_get_status)),
|
||||
+ /* 1.8V 1Gb (2nd generation) */
|
||||
+ SPINAND_INFO("TC58CYG0S3HRAIJ",
|
||||
+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xD2),
|
||||
+ NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
|
||||
+ NAND_ECCREQ(8, 512),
|
||||
+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
|
||||
+ &write_cache_x4_variants,
|
||||
+ &update_cache_x4_variants),
|
||||
+ SPINAND_HAS_QE_BIT,
|
||||
+ SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
|
||||
+ tx58cxgxsxraix_ecc_get_status)),
|
||||
+ /* 1.8V 2Gb (2nd generation) */
|
||||
+ SPINAND_INFO("TC58CYG1S3HRAIJ",
|
||||
+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xDB),
|
||||
+ NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
|
||||
+ NAND_ECCREQ(8, 512),
|
||||
+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
|
||||
+ &write_cache_x4_variants,
|
||||
+ &update_cache_x4_variants),
|
||||
+ SPINAND_HAS_QE_BIT,
|
||||
+ SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
|
||||
+ tx58cxgxsxraix_ecc_get_status)),
|
||||
+ /* 1.8V 4Gb (2nd generation) */
|
||||
+ SPINAND_INFO("TC58CYG2S0HRAIJ",
|
||||
+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xDD),
|
||||
+ NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 1, 1, 1),
|
||||
+ NAND_ECCREQ(8, 512),
|
||||
+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
|
||||
+ &write_cache_x4_variants,
|
||||
+ &update_cache_x4_variants),
|
||||
+ SPINAND_HAS_QE_BIT,
|
||||
+ SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
|
||||
+ tx58cxgxsxraix_ecc_get_status)),
|
||||
+ /* 1.8V 8Gb (2nd generation) */
|
||||
+ SPINAND_INFO("TH58CYG3S0HRAIJ",
|
||||
+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xD4),
|
||||
+ NAND_MEMORG(1, 4096, 256, 64, 4096, 80, 1, 1, 1),
|
||||
+ NAND_ECCREQ(8, 512),
|
||||
+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
|
||||
+ &write_cache_x4_variants,
|
||||
+ &update_cache_x4_variants),
|
||||
+ SPINAND_HAS_QE_BIT,
|
||||
+ SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout,
|
||||
+ tx58cxgxsxraix_ecc_get_status)),
|
||||
};
|
||||
|
||||
static const struct spinand_manufacturer_ops toshiba_spinand_manuf_ops = {
|
||||
@@ -0,0 +1,47 @@
|
||||
drivers: spi: backport PM improvement for SPI framework
|
||||
|
||||
Fix PM improvement for SPI framework.
|
||||
As to set_cs takes effect immediately, power spi
|
||||
is needed when setup spi.
|
||||
|
||||
(cherry picked from commit d948e6ca189985495a21cd622c31e30e72b6b688)
|
||||
Link: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/drivers/spi/spi.c?h=v5.16-rc4&id=d948e6ca189985495a21cd622c31e30e72b6b688
|
||||
(cherry picked from commit 57a9460705f105e1d79d1410c5cfe285beda8986)
|
||||
Link: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/drivers/spi/spi.c?h=v5.16-rc4&id=57a9460705f105e1d79d1410c5cfe285beda8986
|
||||
|
||||
--- a/drivers/spi/spi.c
|
||||
+++ b/drivers/spi/spi.c
|
||||
@@ -3170,7 +3170,29 @@ int spi_setup(struct spi_device *spi)
|
||||
if (spi->controller->setup)
|
||||
status = spi->controller->setup(spi);
|
||||
|
||||
- spi_set_cs(spi, false);
|
||||
+ if (spi->controller->auto_runtime_pm && spi->controller->set_cs) {
|
||||
+ status = pm_runtime_get_sync(spi->controller->dev.parent);
|
||||
+ if (status < 0) {
|
||||
+ pm_runtime_put_noidle(spi->controller->dev.parent);
|
||||
+ dev_err(&spi->controller->dev, "Failed to power device: %d\n",
|
||||
+ status);
|
||||
+ return status;
|
||||
+ }
|
||||
+
|
||||
+ /*
|
||||
+ * We do not want to return positive value from pm_runtime_get,
|
||||
+ * there are many instances of devices calling spi_setup() and
|
||||
+ * checking for a non-zero return value instead of a negative
|
||||
+ * return value.
|
||||
+ */
|
||||
+ status = 0;
|
||||
+
|
||||
+ spi_set_cs(spi, false);
|
||||
+ pm_runtime_mark_last_busy(spi->controller->dev.parent);
|
||||
+ pm_runtime_put_autosuspend(spi->controller->dev.parent);
|
||||
+ } else {
|
||||
+ spi_set_cs(spi, false);
|
||||
+ }
|
||||
|
||||
if (spi->rt && !spi->controller->rt) {
|
||||
spi->controller->rt = true;
|
||||
--
|
||||
2.18.0
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
--- a/drivers/mtd/Kconfig
|
||||
+++ b/drivers/mtd/Kconfig
|
||||
@@ -228,6 +228,8 @@ source "drivers/mtd/ubi/Kconfig"
|
||||
|
||||
source "drivers/mtd/hyperbus/Kconfig"
|
||||
|
||||
+source "drivers/mtd/nmbm/Kconfig"
|
||||
+
|
||||
source "drivers/mtd/composite/Kconfig"
|
||||
|
||||
endif # MTD
|
||||
--- a/drivers/mtd/Makefile
|
||||
+++ b/drivers/mtd/Makefile
|
||||
@@ -33,5 +33,7 @@ obj-$(CONFIG_MTD_SPI_NOR) += spi-nor/
|
||||
obj-$(CONFIG_MTD_UBI) += ubi/
|
||||
obj-$(CONFIG_MTD_HYPERBUS) += hyperbus/
|
||||
|
||||
+obj-y += nmbm/
|
||||
+
|
||||
# Composite drivers must be loaded last
|
||||
obj-y += composite/
|
||||
@@ -0,0 +1,35 @@
|
||||
--- a/drivers/mtd/ubi/block.c
|
||||
+++ b/drivers/mtd/ubi/block.c
|
||||
@@ -97,6 +97,12 @@ static DEFINE_IDR(ubiblock_minor_idr);
|
||||
static DEFINE_MUTEX(devices_mutex);
|
||||
static int ubiblock_major;
|
||||
|
||||
+static char rootfs_volume[256] = "rootfs";
|
||||
+module_param_string(rootfs_volume, rootfs_volume, sizeof(rootfs_volume), 0444);
|
||||
+
|
||||
+static bool no_default_rootdev;
|
||||
+module_param(no_default_rootdev, bool, 0444);
|
||||
+
|
||||
static int __init ubiblock_set_param(const char *val,
|
||||
const struct kernel_param *kp)
|
||||
{
|
||||
@@ -460,8 +466,9 @@ int ubiblock_create(struct ubi_volume_in
|
||||
dev->ubi_num, dev->vol_id, vi->name);
|
||||
mutex_unlock(&devices_mutex);
|
||||
|
||||
- if (!strcmp(vi->name, "rootfs") &&
|
||||
+ if (!strcmp(vi->name, rootfs_volume) &&
|
||||
IS_ENABLED(CONFIG_MTD_ROOTFS_ROOT_DEV) &&
|
||||
+ !no_default_rootdev &&
|
||||
ROOT_DEV == 0) {
|
||||
pr_notice("ubiblock: device ubiblock%d_%d (%s) set to be root filesystem\n",
|
||||
dev->ubi_num, dev->vol_id, vi->name);
|
||||
@@ -681,7 +688,7 @@ static void __init ubiblock_create_auto_
|
||||
struct ubi_volume_info vi;
|
||||
|
||||
for (ubi_num = 0; ubi_num < UBI_MAX_DEVICES; ubi_num++) {
|
||||
- desc = ubi_open_volume_nm(ubi_num, "rootfs", UBI_READONLY);
|
||||
+ desc = ubi_open_volume_nm(ubi_num, rootfs_volume, UBI_READONLY);
|
||||
if (IS_ERR(desc))
|
||||
continue;
|
||||
|
||||
Reference in New Issue
Block a user