mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-29 13:53:33 +00:00
mtd: spinand: Add support for XTX XT26xxxDxxxxx
Add Support XTX Technology XT26G01DXXXXX, XT26G11DXXXXX, XT26Q01DXXXXX, XT26G02DXXXXX, XT26G12DXXXXX, XT26Q02DXXXXX, XT26G04DXXXXX, and XT26Q04DXXXXX SPI NAND. These are 3V/1.8V 1G/2G/4Gbit serial SLC NAND flash device with on-die ECC(8bit strength per 512bytes). Datasheet Links: - http://www.xtxtech.com/download/?AId=458 - http://www.xtxtech.com/download/?AId=495 Signed-off-by: Bruce Suen <bruce_suen@163.com> Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com> Link: https://lore.kernel.org/linux-mtd/20231012102412.10581-1-bruce_suen@163.com
This commit is contained in:
parent
6a804fb72d
commit
d656610ea7
1 changed files with 134 additions and 0 deletions
|
@ -4,6 +4,7 @@
|
|||
* Felix Matouschek <felix@matouschek.org>
|
||||
*/
|
||||
|
||||
#include <linux/bitfield.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/mtd/spinand.h>
|
||||
|
@ -15,6 +16,12 @@
|
|||
#define XT26G0XA_STATUS_ECC_8_CORRECTED (3 << 4)
|
||||
#define XT26G0XA_STATUS_ECC_UNCOR_ERROR (2 << 4)
|
||||
|
||||
#define XT26XXXD_STATUS_ECC3_ECC2_MASK GENMASK(7, 6)
|
||||
#define XT26XXXD_STATUS_ECC_NO_DETECTED (0)
|
||||
#define XT26XXXD_STATUS_ECC_1_7_CORRECTED (1)
|
||||
#define XT26XXXD_STATUS_ECC_8_CORRECTED (3)
|
||||
#define XT26XXXD_STATUS_ECC_UNCOR_ERROR (2)
|
||||
|
||||
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),
|
||||
|
@ -84,6 +91,53 @@ static int xt26g0xa_ecc_get_status(struct spinand_device *spinand,
|
|||
return status >> 2;
|
||||
}
|
||||
|
||||
static int xt26xxxd_ooblayout_ecc(struct mtd_info *mtd, int section,
|
||||
struct mtd_oob_region *region)
|
||||
{
|
||||
if (section)
|
||||
return -ERANGE;
|
||||
|
||||
region->offset = mtd->oobsize / 2;
|
||||
region->length = mtd->oobsize / 2;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int xt26xxxd_ooblayout_free(struct mtd_info *mtd, int section,
|
||||
struct mtd_oob_region *region)
|
||||
{
|
||||
if (section)
|
||||
return -ERANGE;
|
||||
|
||||
region->offset = 2;
|
||||
region->length = mtd->oobsize / 2 - 2;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct mtd_ooblayout_ops xt26xxxd_ooblayout = {
|
||||
.ecc = xt26xxxd_ooblayout_ecc,
|
||||
.free = xt26xxxd_ooblayout_free,
|
||||
};
|
||||
|
||||
static int xt26xxxd_ecc_get_status(struct spinand_device *spinand,
|
||||
u8 status)
|
||||
{
|
||||
switch (FIELD_GET(STATUS_ECC_MASK, status)) {
|
||||
case XT26XXXD_STATUS_ECC_NO_DETECTED:
|
||||
return 0;
|
||||
case XT26XXXD_STATUS_ECC_UNCOR_ERROR:
|
||||
return -EBADMSG;
|
||||
case XT26XXXD_STATUS_ECC_1_7_CORRECTED:
|
||||
return 4 + FIELD_GET(XT26XXXD_STATUS_ECC3_ECC2_MASK, status);
|
||||
case XT26XXXD_STATUS_ECC_8_CORRECTED:
|
||||
return 8;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
static const struct spinand_info xtx_spinand_table[] = {
|
||||
SPINAND_INFO("XT26G01A",
|
||||
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xE1),
|
||||
|
@ -115,6 +169,86 @@ static const struct spinand_info xtx_spinand_table[] = {
|
|||
SPINAND_HAS_QE_BIT,
|
||||
SPINAND_ECCINFO(&xt26g0xa_ooblayout,
|
||||
xt26g0xa_ecc_get_status)),
|
||||
SPINAND_INFO("XT26G01D",
|
||||
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0x31),
|
||||
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(&xt26xxxd_ooblayout,
|
||||
xt26xxxd_ecc_get_status)),
|
||||
SPINAND_INFO("XT26G11D",
|
||||
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0x34),
|
||||
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(&xt26xxxd_ooblayout,
|
||||
xt26xxxd_ecc_get_status)),
|
||||
SPINAND_INFO("XT26Q01D",
|
||||
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0x51),
|
||||
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(&xt26xxxd_ooblayout,
|
||||
xt26xxxd_ecc_get_status)),
|
||||
SPINAND_INFO("XT26G02D",
|
||||
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0x32),
|
||||
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(&xt26xxxd_ooblayout,
|
||||
xt26xxxd_ecc_get_status)),
|
||||
SPINAND_INFO("XT26G12D",
|
||||
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0x35),
|
||||
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(&xt26xxxd_ooblayout,
|
||||
xt26xxxd_ecc_get_status)),
|
||||
SPINAND_INFO("XT26Q02D",
|
||||
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0x52),
|
||||
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(&xt26xxxd_ooblayout,
|
||||
xt26xxxd_ecc_get_status)),
|
||||
SPINAND_INFO("XT26G04D",
|
||||
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0x33),
|
||||
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(&xt26xxxd_ooblayout,
|
||||
xt26xxxd_ecc_get_status)),
|
||||
SPINAND_INFO("XT26Q04D",
|
||||
SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0x53),
|
||||
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(&xt26xxxd_ooblayout,
|
||||
xt26xxxd_ecc_get_status)),
|
||||
};
|
||||
|
||||
static const struct spinand_manufacturer_ops xtx_spinand_manuf_ops = {
|
||||
|
|
Loading…
Reference in a new issue