mirror of
https://github.com/u-boot/u-boot.git
synced 2025-05-08 19:11:53 +00:00
mtd/spinand: sync supported devices with linux-5.15.43
This adds more supported spinand devices from the Linux kernel implementation. This does not include the latest kernel implementation as this would require a substantial amount of extra work due to the missing ECC engine abstraction layer in U-Boot. Signed-off-by: Mikhail Kshevetskiy <mikhail.kshevetskiy@iopsys.eu> Signed-off-by: Frieder Schrempf <frieder.schrempf@kontron.de> (commit message) Link: https://lore.kernel.org/all/20230110115843.391630-3-frieder@fris.de Signed-off-by: Dario Binacchi <dario.binacchi@amarulasolutions.com>
This commit is contained in:
parent
2572470c89
commit
8acaec923b
10 changed files with 626 additions and 102 deletions
|
@ -1,4 +1,4 @@
|
|||
# SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
spinand-objs := core.o gigadevice.o macronix.o micron.o toshiba.o winbond.o
|
||||
spinand-objs := core.o gigadevice.o macronix.o micron.o paragon.o toshiba.o winbond.o
|
||||
obj-$(CONFIG_MTD_SPI_NAND) += spinand.o
|
||||
|
|
|
@ -825,6 +825,7 @@ static const struct spinand_manufacturer *spinand_manufacturers[] = {
|
|||
&gigadevice_spinand_manufacturer,
|
||||
¯onix_spinand_manufacturer,
|
||||
µn_spinand_manufacturer,
|
||||
¶gon_spinand_manufacturer,
|
||||
&toshiba_spinand_manufacturer,
|
||||
&winbond_spinand_manufacturer,
|
||||
};
|
||||
|
|
|
@ -7,13 +7,13 @@
|
|||
*/
|
||||
|
||||
#ifndef __UBOOT__
|
||||
#include <malloc.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/kernel.h>
|
||||
#endif
|
||||
#include <linux/mtd/spinand.h>
|
||||
|
||||
#define SPINAND_MFR_GIGADEVICE 0xC8
|
||||
|
||||
#define GD5FXGQ4XA_STATUS_ECC_1_7_BITFLIPS (1 << 4)
|
||||
#define GD5FXGQ4XA_STATUS_ECC_8_BITFLIPS (3 << 4)
|
||||
|
||||
|
@ -22,8 +22,12 @@
|
|||
|
||||
#define GD5FXGQXXEXXG_REG_STATUS2 0xf0
|
||||
|
||||
/* Q4 devices, QUADIO: Dummy bytes valid for 1 and 2 GBit variants */
|
||||
static SPINAND_OP_VARIANTS(gd5fxgq4_read_cache_variants,
|
||||
#define GD5FXGQ4UXFXXG_STATUS_ECC_MASK (7 << 4)
|
||||
#define GD5FXGQ4UXFXXG_STATUS_ECC_NO_BITFLIPS (0 << 4)
|
||||
#define GD5FXGQ4UXFXXG_STATUS_ECC_1_3_BITFLIPS (1 << 4)
|
||||
#define GD5FXGQ4UXFXXG_STATUS_ECC_UNCOR_ERROR (7 << 4)
|
||||
|
||||
static SPINAND_OP_VARIANTS(read_cache_variants,
|
||||
SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 1, NULL, 0),
|
||||
SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0),
|
||||
SPINAND_PAGE_READ_FROM_CACHE_DUALIO_OP(0, 1, NULL, 0),
|
||||
|
@ -31,14 +35,13 @@ static SPINAND_OP_VARIANTS(gd5fxgq4_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));
|
||||
|
||||
/* Q5 devices, QUADIO: Dummy bytes only valid for 1 GBit variants */
|
||||
static SPINAND_OP_VARIANTS(gd5f1gq5_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),
|
||||
static SPINAND_OP_VARIANTS(read_cache_variants_f,
|
||||
SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 1, NULL, 0),
|
||||
SPINAND_PAGE_READ_FROM_CACHE_X4_OP_3A(0, 1, NULL, 0),
|
||||
SPINAND_PAGE_READ_FROM_CACHE_DUALIO_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));
|
||||
SPINAND_PAGE_READ_FROM_CACHE_X2_OP_3A(0, 1, NULL, 0),
|
||||
SPINAND_PAGE_READ_FROM_CACHE_OP_3A(true, 0, 1, NULL, 0),
|
||||
SPINAND_PAGE_READ_FROM_CACHE_OP_3A(false, 0, 0, NULL, 0));
|
||||
|
||||
static SPINAND_OP_VARIANTS(write_cache_variants,
|
||||
SPINAND_PROG_LOAD_X4(true, 0, NULL, 0),
|
||||
|
@ -48,7 +51,65 @@ static SPINAND_OP_VARIANTS(update_cache_variants,
|
|||
SPINAND_PROG_LOAD_X4(false, 0, NULL, 0),
|
||||
SPINAND_PROG_LOAD(false, 0, NULL, 0));
|
||||
|
||||
static int gd5fxgqxxexxg_ooblayout_ecc(struct mtd_info *mtd, int section,
|
||||
static int gd5fxgq4xa_ooblayout_ecc(struct mtd_info *mtd, int section,
|
||||
struct mtd_oob_region *region)
|
||||
{
|
||||
if (section > 3)
|
||||
return -ERANGE;
|
||||
|
||||
region->offset = (16 * section) + 8;
|
||||
region->length = 8;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int gd5fxgq4xa_ooblayout_free(struct mtd_info *mtd, int section,
|
||||
struct mtd_oob_region *region)
|
||||
{
|
||||
if (section > 3)
|
||||
return -ERANGE;
|
||||
|
||||
if (section) {
|
||||
region->offset = 16 * section;
|
||||
region->length = 8;
|
||||
} else {
|
||||
/* section 0 has one byte reserved for bad block mark */
|
||||
region->offset = 1;
|
||||
region->length = 7;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct mtd_ooblayout_ops gd5fxgq4xa_ooblayout = {
|
||||
.ecc = gd5fxgq4xa_ooblayout_ecc,
|
||||
.rfree = gd5fxgq4xa_ooblayout_free,
|
||||
};
|
||||
|
||||
static int gd5fxgq4xa_ecc_get_status(struct spinand_device *spinand,
|
||||
u8 status)
|
||||
{
|
||||
switch (status & STATUS_ECC_MASK) {
|
||||
case STATUS_ECC_NO_BITFLIPS:
|
||||
return 0;
|
||||
|
||||
case GD5FXGQ4XA_STATUS_ECC_1_7_BITFLIPS:
|
||||
/* 1-7 bits are flipped. return the maximum. */
|
||||
return 7;
|
||||
|
||||
case GD5FXGQ4XA_STATUS_ECC_8_BITFLIPS:
|
||||
return 8;
|
||||
|
||||
case STATUS_ECC_UNCOR_ERROR:
|
||||
return -EBADMSG;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int gd5fxgqx_variant2_ooblayout_ecc(struct mtd_info *mtd, int section,
|
||||
struct mtd_oob_region *region)
|
||||
{
|
||||
if (section)
|
||||
|
@ -60,7 +121,7 @@ static int gd5fxgqxxexxg_ooblayout_ecc(struct mtd_info *mtd, int section,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int gd5fxgqxxexxg_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)
|
||||
|
@ -73,7 +134,42 @@ static int gd5fxgqxxexxg_ooblayout_free(struct mtd_info *mtd, int section,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int gd5fxgq4xexxg_ecc_get_status(struct spinand_device *spinand,
|
||||
/* Valid for Q4/Q5 and Q6 (untested) devices */
|
||||
static const struct mtd_ooblayout_ops gd5fxgqx_variant2_ooblayout = {
|
||||
.ecc = gd5fxgqx_variant2_ooblayout_ecc,
|
||||
.rfree = gd5fxgqx_variant2_ooblayout_free,
|
||||
};
|
||||
|
||||
static int gd5fxgq4xc_ooblayout_256_ecc(struct mtd_info *mtd, int section,
|
||||
struct mtd_oob_region *oobregion)
|
||||
{
|
||||
if (section)
|
||||
return -ERANGE;
|
||||
|
||||
oobregion->offset = 128;
|
||||
oobregion->length = 128;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int gd5fxgq4xc_ooblayout_256_free(struct mtd_info *mtd, int section,
|
||||
struct mtd_oob_region *oobregion)
|
||||
{
|
||||
if (section)
|
||||
return -ERANGE;
|
||||
|
||||
oobregion->offset = 1;
|
||||
oobregion->length = 127;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct mtd_ooblayout_ops gd5fxgq4xc_oob_256_ops = {
|
||||
.ecc = gd5fxgq4xc_ooblayout_256_ecc,
|
||||
.rfree = gd5fxgq4xc_ooblayout_256_free,
|
||||
};
|
||||
|
||||
static int gd5fxgq4uexxg_ecc_get_status(struct spinand_device *spinand,
|
||||
u8 status)
|
||||
{
|
||||
u8 status2;
|
||||
|
@ -152,31 +248,106 @@ static int gd5fxgq5xexxg_ecc_get_status(struct spinand_device *spinand,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
static const struct mtd_ooblayout_ops gd5fxgqxxexxg_ooblayout = {
|
||||
.ecc = gd5fxgqxxexxg_ooblayout_ecc,
|
||||
.rfree = gd5fxgqxxexxg_ooblayout_free,
|
||||
};
|
||||
static int gd5fxgq4ufxxg_ecc_get_status(struct spinand_device *spinand,
|
||||
u8 status)
|
||||
{
|
||||
switch (status & GD5FXGQ4UXFXXG_STATUS_ECC_MASK) {
|
||||
case GD5FXGQ4UXFXXG_STATUS_ECC_NO_BITFLIPS:
|
||||
return 0;
|
||||
|
||||
case GD5FXGQ4UXFXXG_STATUS_ECC_1_3_BITFLIPS:
|
||||
return 3;
|
||||
|
||||
case GD5FXGQ4UXFXXG_STATUS_ECC_UNCOR_ERROR:
|
||||
return -EBADMSG;
|
||||
|
||||
default: /* (2 << 4) through (6 << 4) are 4-8 corrected errors */
|
||||
return ((status & GD5FXGQ4UXFXXG_STATUS_ECC_MASK) >> 4) + 2;
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static const struct spinand_info gigadevice_spinand_table[] = {
|
||||
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,
|
||||
&write_cache_variants,
|
||||
&update_cache_variants),
|
||||
SPINAND_HAS_QE_BIT,
|
||||
SPINAND_ECCINFO(&gd5fxgq4xa_ooblayout,
|
||||
gd5fxgq4xa_ecc_get_status)),
|
||||
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,
|
||||
&write_cache_variants,
|
||||
&update_cache_variants),
|
||||
SPINAND_HAS_QE_BIT,
|
||||
SPINAND_ECCINFO(&gd5fxgq4xa_ooblayout,
|
||||
gd5fxgq4xa_ecc_get_status)),
|
||||
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,
|
||||
&write_cache_variants,
|
||||
&update_cache_variants),
|
||||
SPINAND_HAS_QE_BIT,
|
||||
SPINAND_ECCINFO(&gd5fxgq4xa_ooblayout,
|
||||
gd5fxgq4xa_ecc_get_status)),
|
||||
SPINAND_INFO("GD5F4GQ4RC",
|
||||
SPINAND_ID(SPINAND_READID_METHOD_OPCODE, 0xa4, 0x68),
|
||||
NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 1, 1, 1),
|
||||
NAND_ECCREQ(8, 512),
|
||||
SPINAND_INFO_OP_VARIANTS(&read_cache_variants_f,
|
||||
&write_cache_variants,
|
||||
&update_cache_variants),
|
||||
SPINAND_HAS_QE_BIT,
|
||||
SPINAND_ECCINFO(&gd5fxgq4xc_oob_256_ops,
|
||||
gd5fxgq4ufxxg_ecc_get_status)),
|
||||
SPINAND_INFO("GD5F4GQ4UC",
|
||||
SPINAND_ID(SPINAND_READID_METHOD_OPCODE, 0xb4, 0x68),
|
||||
NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 1, 1, 1),
|
||||
NAND_ECCREQ(8, 512),
|
||||
SPINAND_INFO_OP_VARIANTS(&read_cache_variants_f,
|
||||
&write_cache_variants,
|
||||
&update_cache_variants),
|
||||
SPINAND_HAS_QE_BIT,
|
||||
SPINAND_ECCINFO(&gd5fxgq4xc_oob_256_ops,
|
||||
gd5fxgq4ufxxg_ecc_get_status)),
|
||||
SPINAND_INFO("GD5F1GQ4UExxG",
|
||||
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xd1),
|
||||
NAND_MEMORG(1, 2048, 128, 64, 1024, 1, 1, 1),
|
||||
NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
|
||||
NAND_ECCREQ(8, 512),
|
||||
SPINAND_INFO_OP_VARIANTS(&gd5fxgq4_read_cache_variants,
|
||||
SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
|
||||
&write_cache_variants,
|
||||
&update_cache_variants),
|
||||
0,
|
||||
SPINAND_ECCINFO(&gd5fxgqxxexxg_ooblayout,
|
||||
gd5fxgq4xexxg_ecc_get_status)),
|
||||
SPINAND_HAS_QE_BIT,
|
||||
SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
|
||||
gd5fxgq4uexxg_ecc_get_status)),
|
||||
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,
|
||||
&write_cache_variants,
|
||||
&update_cache_variants),
|
||||
SPINAND_HAS_QE_BIT,
|
||||
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, 1, 1, 1),
|
||||
NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
|
||||
NAND_ECCREQ(4, 512),
|
||||
SPINAND_INFO_OP_VARIANTS(&gd5f1gq5_read_cache_variants,
|
||||
SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
|
||||
&write_cache_variants,
|
||||
&update_cache_variants),
|
||||
0,
|
||||
SPINAND_ECCINFO(&gd5fxgqxxexxg_ooblayout,
|
||||
SPINAND_HAS_QE_BIT,
|
||||
SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout,
|
||||
gd5fxgq5xexxg_ecc_get_status)),
|
||||
};
|
||||
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
*/
|
||||
|
||||
#ifndef __UBOOT__
|
||||
#include <malloc.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/kernel.h>
|
||||
#endif
|
||||
|
@ -16,7 +15,6 @@
|
|||
#define SPINAND_MFR_MACRONIX 0xC2
|
||||
#define MACRONIX_ECCSR_MASK 0x0F
|
||||
|
||||
|
||||
static SPINAND_OP_VARIANTS(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),
|
||||
|
@ -62,7 +60,6 @@ static int mx35lf1ge4ab_get_eccsr(struct spinand_device *spinand, u8 *eccsr)
|
|||
SPI_MEM_OP_DATA_IN(1, eccsr, 1));
|
||||
|
||||
int ret = spi_mem_exec_op(spinand->slave, &op);
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
@ -107,7 +104,7 @@ static int mx35lf1ge4ab_ecc_get_status(struct spinand_device *spinand,
|
|||
static const struct spinand_info macronix_spinand_table[] = {
|
||||
SPINAND_INFO("MX35LF1GE4AB",
|
||||
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x12),
|
||||
NAND_MEMORG(1, 2048, 64, 64, 1024, 1, 1, 1),
|
||||
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,
|
||||
|
@ -117,16 +114,124 @@ static const struct spinand_info macronix_spinand_table[] = {
|
|||
mx35lf1ge4ab_ecc_get_status)),
|
||||
SPINAND_INFO("MX35LF2GE4AB",
|
||||
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x22),
|
||||
NAND_MEMORG(1, 2048, 64, 64, 2048, 2, 1, 1),
|
||||
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, 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),
|
||||
SPINAND_HAS_QE_BIT,
|
||||
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),
|
||||
SPINAND_HAS_QE_BIT,
|
||||
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),
|
||||
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, 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, 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),
|
||||
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),
|
||||
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),
|
||||
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, 1, 1, 1),
|
||||
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,
|
||||
|
@ -136,7 +241,7 @@ static const struct spinand_info macronix_spinand_table[] = {
|
|||
mx35lf1ge4ab_ecc_get_status)),
|
||||
SPINAND_INFO("MX35UF2GE4AD",
|
||||
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xa6),
|
||||
NAND_MEMORG(1, 2048, 128, 64, 2048, 1, 1, 1),
|
||||
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,
|
||||
|
@ -146,7 +251,7 @@ static const struct spinand_info macronix_spinand_table[] = {
|
|||
mx35lf1ge4ab_ecc_get_status)),
|
||||
SPINAND_INFO("MX35UF2GE4AC",
|
||||
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xa2),
|
||||
NAND_MEMORG(1, 2048, 64, 64, 2048, 1, 1, 1),
|
||||
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,
|
||||
|
@ -154,9 +259,29 @@ static const struct spinand_info macronix_spinand_table[] = {
|
|||
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, 1, 1, 1),
|
||||
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,
|
||||
|
@ -166,7 +291,7 @@ static const struct spinand_info macronix_spinand_table[] = {
|
|||
mx35lf1ge4ab_ecc_get_status)),
|
||||
SPINAND_INFO("MX35UF1GE4AC",
|
||||
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x92),
|
||||
NAND_MEMORG(1, 2048, 64, 64, 1024, 1, 1, 1),
|
||||
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,
|
||||
|
|
|
@ -7,11 +7,9 @@
|
|||
*/
|
||||
|
||||
#ifndef __UBOOT__
|
||||
#include <malloc.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/kernel.h>
|
||||
#endif
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/mtd/spinand.h>
|
||||
|
||||
#define SPINAND_MFR_MICRON 0x2c
|
||||
|
@ -32,7 +30,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),
|
||||
|
@ -40,14 +38,27 @@ 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));
|
||||
|
||||
/* 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)
|
||||
{
|
||||
|
@ -78,6 +89,47 @@ static const struct mtd_ooblayout_ops micron_8_ooblayout = {
|
|||
.rfree = 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,
|
||||
.rfree = micron_4_ooblayout_free,
|
||||
};
|
||||
|
||||
static int micron_select_target(struct spinand_device *spinand,
|
||||
unsigned int target)
|
||||
{
|
||||
|
@ -122,55 +174,55 @@ 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, 2, 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),
|
||||
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)),
|
||||
/* M79A 2Gb 1.8V */
|
||||
SPINAND_INFO("MT29F2G01ABBGD",
|
||||
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x25),
|
||||
NAND_MEMORG(1, 2048, 128, 64, 2048, 2, 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),
|
||||
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)),
|
||||
/* M78A 1Gb 3.3V */
|
||||
SPINAND_INFO("MT29F1G01ABAFD",
|
||||
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x14),
|
||||
NAND_MEMORG(1, 2048, 128, 64, 1024, 1, 1, 1),
|
||||
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)),
|
||||
/* M78A 1Gb 1.8V */
|
||||
SPINAND_INFO("MT29F1G01ABAFD",
|
||||
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x15),
|
||||
NAND_MEMORG(1, 2048, 128, 64, 1024, 1, 1, 1),
|
||||
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)),
|
||||
/* M79A 4Gb 3.3V */
|
||||
SPINAND_INFO("MT29F4G01ADAGD",
|
||||
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x36),
|
||||
NAND_MEMORG(1, 2048, 128, 64, 2048, 2, 1, 2),
|
||||
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),
|
||||
|
@ -178,33 +230,33 @@ static const struct spinand_info micron_spinand_table[] = {
|
|||
/* M70A 4Gb 3.3V */
|
||||
SPINAND_INFO("MT29F4G01ABAFD",
|
||||
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x34),
|
||||
NAND_MEMORG(1, 4096, 256, 64, 2048, 1, 1, 1),
|
||||
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)),
|
||||
/* M70A 4Gb 1.8V */
|
||||
SPINAND_INFO("MT29F4G01ABBFD",
|
||||
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x35),
|
||||
NAND_MEMORG(1, 4096, 256, 64, 2048, 1, 1, 1),
|
||||
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)),
|
||||
/* M70A 8Gb 3.3V */
|
||||
SPINAND_INFO("MT29F8G01ADAFD",
|
||||
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x46),
|
||||
NAND_MEMORG(1, 4096, 256, 64, 2048, 1, 1, 2),
|
||||
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),
|
||||
|
@ -212,15 +264,25 @@ static const struct spinand_info micron_spinand_table[] = {
|
|||
/* M70A 8Gb 1.8V */
|
||||
SPINAND_INFO("MT29F8G01ADBFD",
|
||||
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x47),
|
||||
NAND_MEMORG(1, 4096, 256, 64, 2048, 1, 1, 2),
|
||||
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),
|
||||
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)
|
||||
|
|
133
drivers/mtd/nand/spi/paragon.c
Normal file
133
drivers/mtd/nand/spi/paragon.c
Normal file
|
@ -0,0 +1,133 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Copyright (C) 2019 Jeff Kletsky
|
||||
*
|
||||
* Author: Jeff Kletsky <git-commits@allycomm.com>
|
||||
*/
|
||||
|
||||
#ifndef __UBOOT__
|
||||
#include <linux/device.h>
|
||||
#include <linux/kernel.h>
|
||||
#endif
|
||||
#include <linux/mtd/spinand.h>
|
||||
|
||||
|
||||
#define SPINAND_MFR_PARAGON 0xa1
|
||||
|
||||
|
||||
#define PN26G0XA_STATUS_ECC_BITMASK (3 << 4)
|
||||
|
||||
#define PN26G0XA_STATUS_ECC_NONE_DETECTED (0 << 4)
|
||||
#define PN26G0XA_STATUS_ECC_1_7_CORRECTED (1 << 4)
|
||||
#define PN26G0XA_STATUS_ECC_ERRORED (2 << 4)
|
||||
#define PN26G0XA_STATUS_ECC_8_CORRECTED (3 << 4)
|
||||
|
||||
|
||||
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),
|
||||
SPINAND_PAGE_READ_FROM_CACHE_DUALIO_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(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,
|
||||
SPINAND_PROG_LOAD_X4(false, 0, NULL, 0),
|
||||
SPINAND_PROG_LOAD(false, 0, NULL, 0));
|
||||
|
||||
|
||||
static int pn26g0xa_ooblayout_ecc(struct mtd_info *mtd, int section,
|
||||
struct mtd_oob_region *region)
|
||||
{
|
||||
if (section > 3)
|
||||
return -ERANGE;
|
||||
|
||||
region->offset = 6 + (15 * section); /* 4 BBM + 2 user bytes */
|
||||
region->length = 13;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int pn26g0xa_ooblayout_free(struct mtd_info *mtd, int section,
|
||||
struct mtd_oob_region *region)
|
||||
{
|
||||
if (section > 4)
|
||||
return -ERANGE;
|
||||
|
||||
if (section == 4) {
|
||||
region->offset = 64;
|
||||
region->length = 64;
|
||||
} else {
|
||||
region->offset = 4 + (15 * section);
|
||||
region->length = 2;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int pn26g0xa_ecc_get_status(struct spinand_device *spinand,
|
||||
u8 status)
|
||||
{
|
||||
switch (status & PN26G0XA_STATUS_ECC_BITMASK) {
|
||||
case PN26G0XA_STATUS_ECC_NONE_DETECTED:
|
||||
return 0;
|
||||
|
||||
case PN26G0XA_STATUS_ECC_1_7_CORRECTED:
|
||||
return 7; /* Return upper limit by convention */
|
||||
|
||||
case PN26G0XA_STATUS_ECC_8_CORRECTED:
|
||||
return 8;
|
||||
|
||||
case PN26G0XA_STATUS_ECC_ERRORED:
|
||||
return -EBADMSG;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static const struct mtd_ooblayout_ops pn26g0xa_ooblayout = {
|
||||
.ecc = pn26g0xa_ooblayout_ecc,
|
||||
.rfree = pn26g0xa_ooblayout_free,
|
||||
};
|
||||
|
||||
|
||||
static const struct spinand_info paragon_spinand_table[] = {
|
||||
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,
|
||||
&write_cache_variants,
|
||||
&update_cache_variants),
|
||||
0,
|
||||
SPINAND_ECCINFO(&pn26g0xa_ooblayout,
|
||||
pn26g0xa_ecc_get_status)),
|
||||
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,
|
||||
&write_cache_variants,
|
||||
&update_cache_variants),
|
||||
0,
|
||||
SPINAND_ECCINFO(&pn26g0xa_ooblayout,
|
||||
pn26g0xa_ecc_get_status)),
|
||||
};
|
||||
|
||||
static const struct spinand_manufacturer_ops paragon_spinand_manuf_ops = {
|
||||
};
|
||||
|
||||
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,
|
||||
};
|
|
@ -7,13 +7,13 @@
|
|||
*/
|
||||
|
||||
#ifndef __UBOOT__
|
||||
#include <malloc.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/kernel.h>
|
||||
#endif
|
||||
#include <linux/bug.h>
|
||||
#include <linux/mtd/spinand.h>
|
||||
|
||||
/* Kioxia is new name of Toshiba memory. */
|
||||
#define SPINAND_MFR_TOSHIBA 0x98
|
||||
#define TOSH_STATUS_ECC_HAS_BITFLIPS_T (3 << 4)
|
||||
|
||||
|
@ -31,7 +31,7 @@ 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.
|
||||
*/
|
||||
|
@ -113,7 +113,7 @@ static const struct spinand_info toshiba_spinand_table[] = {
|
|||
/* 3.3V 1Gb (1st generation) */
|
||||
SPINAND_INFO("TC58CVG0S3HRAIG",
|
||||
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xC2),
|
||||
NAND_MEMORG(1, 2048, 128, 64, 1024, 1, 1, 1),
|
||||
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,
|
||||
|
@ -124,7 +124,7 @@ static const struct spinand_info toshiba_spinand_table[] = {
|
|||
/* 3.3V 2Gb (1st generation) */
|
||||
SPINAND_INFO("TC58CVG1S3HRAIG",
|
||||
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xCB),
|
||||
NAND_MEMORG(1, 2048, 128, 64, 2048, 1, 1, 1),
|
||||
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,
|
||||
|
@ -135,7 +135,7 @@ static const struct spinand_info toshiba_spinand_table[] = {
|
|||
/* 3.3V 4Gb (1st generation) */
|
||||
SPINAND_INFO("TC58CVG2S0HRAIG",
|
||||
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xCD),
|
||||
NAND_MEMORG(1, 4096, 256, 64, 2048, 1, 1, 1),
|
||||
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,
|
||||
|
@ -146,7 +146,7 @@ static const struct spinand_info toshiba_spinand_table[] = {
|
|||
/* 1.8V 1Gb (1st generation) */
|
||||
SPINAND_INFO("TC58CYG0S3HRAIG",
|
||||
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xB2),
|
||||
NAND_MEMORG(1, 2048, 128, 64, 1024, 1, 1, 1),
|
||||
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,
|
||||
|
@ -157,7 +157,7 @@ static const struct spinand_info toshiba_spinand_table[] = {
|
|||
/* 1.8V 2Gb (1st generation) */
|
||||
SPINAND_INFO("TC58CYG1S3HRAIG",
|
||||
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xBB),
|
||||
NAND_MEMORG(1, 2048, 128, 64, 2048, 1, 1, 1),
|
||||
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,
|
||||
|
@ -168,7 +168,7 @@ static const struct spinand_info toshiba_spinand_table[] = {
|
|||
/* 1.8V 4Gb (1st generation) */
|
||||
SPINAND_INFO("TC58CYG2S0HRAIG",
|
||||
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xBD),
|
||||
NAND_MEMORG(1, 4096, 256, 64, 2048, 1, 1, 1),
|
||||
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,
|
||||
|
@ -184,7 +184,7 @@ static const struct spinand_info toshiba_spinand_table[] = {
|
|||
/* 3.3V 1Gb (2nd generation) */
|
||||
SPINAND_INFO("TC58CVG0S3HRAIJ",
|
||||
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xE2),
|
||||
NAND_MEMORG(1, 2048, 128, 64, 1024, 1, 1, 1),
|
||||
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,
|
||||
|
@ -195,7 +195,7 @@ static const struct spinand_info toshiba_spinand_table[] = {
|
|||
/* 3.3V 2Gb (2nd generation) */
|
||||
SPINAND_INFO("TC58CVG1S3HRAIJ",
|
||||
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xEB),
|
||||
NAND_MEMORG(1, 2048, 128, 64, 2048, 1, 1, 1),
|
||||
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,
|
||||
|
@ -206,7 +206,7 @@ static const struct spinand_info toshiba_spinand_table[] = {
|
|||
/* 3.3V 4Gb (2nd generation) */
|
||||
SPINAND_INFO("TC58CVG2S0HRAIJ",
|
||||
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xED),
|
||||
NAND_MEMORG(1, 4096, 256, 64, 2048, 1, 1, 1),
|
||||
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,
|
||||
|
@ -217,7 +217,7 @@ static const struct spinand_info toshiba_spinand_table[] = {
|
|||
/* 3.3V 8Gb (2nd generation) */
|
||||
SPINAND_INFO("TH58CVG3S0HRAIJ",
|
||||
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xE4),
|
||||
NAND_MEMORG(1, 4096, 256, 64, 4096, 1, 1, 1),
|
||||
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,
|
||||
|
@ -228,7 +228,7 @@ static const struct spinand_info toshiba_spinand_table[] = {
|
|||
/* 1.8V 1Gb (2nd generation) */
|
||||
SPINAND_INFO("TC58CYG0S3HRAIJ",
|
||||
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xD2),
|
||||
NAND_MEMORG(1, 2048, 128, 64, 1024, 1, 1, 1),
|
||||
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,
|
||||
|
@ -239,7 +239,7 @@ static const struct spinand_info toshiba_spinand_table[] = {
|
|||
/* 1.8V 2Gb (2nd generation) */
|
||||
SPINAND_INFO("TC58CYG1S3HRAIJ",
|
||||
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xDB),
|
||||
NAND_MEMORG(1, 2048, 128, 64, 2048, 1, 1, 1),
|
||||
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,
|
||||
|
@ -250,7 +250,7 @@ static const struct spinand_info toshiba_spinand_table[] = {
|
|||
/* 1.8V 4Gb (2nd generation) */
|
||||
SPINAND_INFO("TC58CYG2S0HRAIJ",
|
||||
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xDD),
|
||||
NAND_MEMORG(1, 4096, 256, 64, 2048, 1, 1, 1),
|
||||
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,
|
||||
|
@ -261,7 +261,7 @@ static const struct spinand_info toshiba_spinand_table[] = {
|
|||
/* 1.8V 8Gb (2nd generation) */
|
||||
SPINAND_INFO("TH58CYG3S0HRAIJ",
|
||||
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xD4),
|
||||
NAND_MEMORG(1, 4096, 256, 64, 4096, 1, 1, 1),
|
||||
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,
|
||||
|
|
|
@ -8,11 +8,9 @@
|
|||
*/
|
||||
|
||||
#ifndef __UBOOT__
|
||||
#include <malloc.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/kernel.h>
|
||||
#endif
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/mtd/spinand.h>
|
||||
|
||||
#define SPINAND_MFR_WINBOND 0xEF
|
||||
|
@ -81,7 +79,7 @@ static int w25m02gv_select_target(struct spinand_device *spinand,
|
|||
static const struct spinand_info winbond_spinand_table[] = {
|
||||
SPINAND_INFO("W25M02GV",
|
||||
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xab),
|
||||
NAND_MEMORG(1, 2048, 64, 64, 1024, 1, 1, 2),
|
||||
NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 2),
|
||||
NAND_ECCREQ(1, 512),
|
||||
SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
|
||||
&write_cache_variants,
|
||||
|
@ -91,7 +89,7 @@ static const struct spinand_info winbond_spinand_table[] = {
|
|||
SPINAND_SELECT_TARGET(w25m02gv_select_target)),
|
||||
SPINAND_INFO("W25N01GV",
|
||||
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xaa),
|
||||
NAND_MEMORG(1, 2048, 64, 64, 1024, 1, 1, 1),
|
||||
NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1),
|
||||
NAND_ECCREQ(1, 512),
|
||||
SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
|
||||
&write_cache_variants,
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
* @oobsize: OOB area size
|
||||
* @pages_per_eraseblock: number of pages per eraseblock
|
||||
* @eraseblocks_per_lun: number of eraseblocks per LUN (Logical Unit Number)
|
||||
* @max_bad_eraseblocks_per_lun: maximum number of eraseblocks per LUN
|
||||
* @planes_per_lun: number of planes per LUN
|
||||
* @luns_per_target: number of LUN per target (target is a synonym for die)
|
||||
* @ntargets: total number of targets exposed by the NAND device
|
||||
|
@ -29,18 +30,20 @@ struct nand_memory_organization {
|
|||
unsigned int oobsize;
|
||||
unsigned int pages_per_eraseblock;
|
||||
unsigned int eraseblocks_per_lun;
|
||||
unsigned int max_bad_eraseblocks_per_lun;
|
||||
unsigned int planes_per_lun;
|
||||
unsigned int luns_per_target;
|
||||
unsigned int ntargets;
|
||||
};
|
||||
|
||||
#define NAND_MEMORG(bpc, ps, os, ppe, epl, ppl, lpt, nt) \
|
||||
#define NAND_MEMORG(bpc, ps, os, ppe, epl, mbb, ppl, lpt, nt) \
|
||||
{ \
|
||||
.bits_per_cell = (bpc), \
|
||||
.pagesize = (ps), \
|
||||
.oobsize = (os), \
|
||||
.pages_per_eraseblock = (ppe), \
|
||||
.eraseblocks_per_lun = (epl), \
|
||||
.max_bad_eraseblocks_per_lun = (mbb), \
|
||||
.planes_per_lun = (ppl), \
|
||||
.luns_per_target = (lpt), \
|
||||
.ntargets = (nt), \
|
||||
|
|
|
@ -75,30 +75,60 @@
|
|||
SPI_MEM_OP_DUMMY(ndummy, 1), \
|
||||
SPI_MEM_OP_DATA_IN(len, buf, 1))
|
||||
|
||||
#define SPINAND_PAGE_READ_FROM_CACHE_OP_3A(fast, addr, ndummy, buf, len) \
|
||||
SPI_MEM_OP(SPI_MEM_OP_CMD(fast ? 0x0b : 0x03, 1), \
|
||||
SPI_MEM_OP_ADDR(3, addr, 1), \
|
||||
SPI_MEM_OP_DUMMY(ndummy, 1), \
|
||||
SPI_MEM_OP_DATA_IN(len, buf, 1))
|
||||
|
||||
#define SPINAND_PAGE_READ_FROM_CACHE_X2_OP(addr, ndummy, buf, len) \
|
||||
SPI_MEM_OP(SPI_MEM_OP_CMD(0x3b, 1), \
|
||||
SPI_MEM_OP_ADDR(2, addr, 1), \
|
||||
SPI_MEM_OP_DUMMY(ndummy, 1), \
|
||||
SPI_MEM_OP_DATA_IN(len, buf, 2))
|
||||
|
||||
#define SPINAND_PAGE_READ_FROM_CACHE_X2_OP_3A(addr, ndummy, buf, len) \
|
||||
SPI_MEM_OP(SPI_MEM_OP_CMD(0x3b, 1), \
|
||||
SPI_MEM_OP_ADDR(3, addr, 1), \
|
||||
SPI_MEM_OP_DUMMY(ndummy, 1), \
|
||||
SPI_MEM_OP_DATA_IN(len, buf, 2))
|
||||
|
||||
#define SPINAND_PAGE_READ_FROM_CACHE_X4_OP(addr, ndummy, buf, len) \
|
||||
SPI_MEM_OP(SPI_MEM_OP_CMD(0x6b, 1), \
|
||||
SPI_MEM_OP_ADDR(2, addr, 1), \
|
||||
SPI_MEM_OP_DUMMY(ndummy, 1), \
|
||||
SPI_MEM_OP_DATA_IN(len, buf, 4))
|
||||
|
||||
#define SPINAND_PAGE_READ_FROM_CACHE_X4_OP_3A(addr, ndummy, buf, len) \
|
||||
SPI_MEM_OP(SPI_MEM_OP_CMD(0x6b, 1), \
|
||||
SPI_MEM_OP_ADDR(3, addr, 1), \
|
||||
SPI_MEM_OP_DUMMY(ndummy, 1), \
|
||||
SPI_MEM_OP_DATA_IN(len, buf, 4))
|
||||
|
||||
#define SPINAND_PAGE_READ_FROM_CACHE_DUALIO_OP(addr, ndummy, buf, len) \
|
||||
SPI_MEM_OP(SPI_MEM_OP_CMD(0xbb, 1), \
|
||||
SPI_MEM_OP_ADDR(2, addr, 2), \
|
||||
SPI_MEM_OP_DUMMY(ndummy, 2), \
|
||||
SPI_MEM_OP_DATA_IN(len, buf, 2))
|
||||
|
||||
#define SPINAND_PAGE_READ_FROM_CACHE_DUALIO_OP_3A(addr, ndummy, buf, len) \
|
||||
SPI_MEM_OP(SPI_MEM_OP_CMD(0xbb, 1), \
|
||||
SPI_MEM_OP_ADDR(3, addr, 2), \
|
||||
SPI_MEM_OP_DUMMY(ndummy, 2), \
|
||||
SPI_MEM_OP_DATA_IN(len, buf, 2))
|
||||
|
||||
#define SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(addr, ndummy, buf, len) \
|
||||
SPI_MEM_OP(SPI_MEM_OP_CMD(0xeb, 1), \
|
||||
SPI_MEM_OP_ADDR(2, addr, 4), \
|
||||
SPI_MEM_OP_DUMMY(ndummy, 4), \
|
||||
SPI_MEM_OP_DATA_IN(len, buf, 4))
|
||||
|
||||
#define SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP_3A(addr, ndummy, buf, len) \
|
||||
SPI_MEM_OP(SPI_MEM_OP_CMD(0xeb, 1), \
|
||||
SPI_MEM_OP_ADDR(3, addr, 4), \
|
||||
SPI_MEM_OP_DUMMY(ndummy, 4), \
|
||||
SPI_MEM_OP_DATA_IN(len, buf, 4))
|
||||
|
||||
#define SPINAND_PROG_EXEC_OP(addr) \
|
||||
SPI_MEM_OP(SPI_MEM_OP_CMD(0x10, 1), \
|
||||
SPI_MEM_OP_ADDR(3, addr, 1), \
|
||||
|
@ -218,6 +248,7 @@ struct spinand_manufacturer {
|
|||
extern const struct spinand_manufacturer gigadevice_spinand_manufacturer;
|
||||
extern const struct spinand_manufacturer macronix_spinand_manufacturer;
|
||||
extern const struct spinand_manufacturer micron_spinand_manufacturer;
|
||||
extern const struct spinand_manufacturer paragon_spinand_manufacturer;
|
||||
extern const struct spinand_manufacturer toshiba_spinand_manufacturer;
|
||||
extern const struct spinand_manufacturer winbond_spinand_manufacturer;
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue