Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * Copyright (c) 2018 Macronix
0004  *
0005  * Author: Boris Brezillon <boris.brezillon@bootlin.com>
0006  */
0007 
0008 #include <linux/device.h>
0009 #include <linux/kernel.h>
0010 #include <linux/mtd/spinand.h>
0011 
0012 #define SPINAND_MFR_MACRONIX        0xC2
0013 #define MACRONIX_ECCSR_MASK     0x0F
0014 
0015 static SPINAND_OP_VARIANTS(read_cache_variants,
0016         SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0),
0017         SPINAND_PAGE_READ_FROM_CACHE_X2_OP(0, 1, NULL, 0),
0018         SPINAND_PAGE_READ_FROM_CACHE_OP(true, 0, 1, NULL, 0),
0019         SPINAND_PAGE_READ_FROM_CACHE_OP(false, 0, 1, NULL, 0));
0020 
0021 static SPINAND_OP_VARIANTS(write_cache_variants,
0022         SPINAND_PROG_LOAD_X4(true, 0, NULL, 0),
0023         SPINAND_PROG_LOAD(false, 0, NULL, 0));
0024 
0025 static SPINAND_OP_VARIANTS(update_cache_variants,
0026         SPINAND_PROG_LOAD_X4(false, 0, NULL, 0),
0027         SPINAND_PROG_LOAD(false, 0, NULL, 0));
0028 
0029 static int mx35lfxge4ab_ooblayout_ecc(struct mtd_info *mtd, int section,
0030                       struct mtd_oob_region *region)
0031 {
0032     return -ERANGE;
0033 }
0034 
0035 static int mx35lfxge4ab_ooblayout_free(struct mtd_info *mtd, int section,
0036                        struct mtd_oob_region *region)
0037 {
0038     if (section)
0039         return -ERANGE;
0040 
0041     region->offset = 2;
0042     region->length = mtd->oobsize - 2;
0043 
0044     return 0;
0045 }
0046 
0047 static const struct mtd_ooblayout_ops mx35lfxge4ab_ooblayout = {
0048     .ecc = mx35lfxge4ab_ooblayout_ecc,
0049     .free = mx35lfxge4ab_ooblayout_free,
0050 };
0051 
0052 static int mx35lf1ge4ab_get_eccsr(struct spinand_device *spinand, u8 *eccsr)
0053 {
0054     struct spi_mem_op op = SPI_MEM_OP(SPI_MEM_OP_CMD(0x7c, 1),
0055                       SPI_MEM_OP_NO_ADDR,
0056                       SPI_MEM_OP_DUMMY(1, 1),
0057                       SPI_MEM_OP_DATA_IN(1, eccsr, 1));
0058 
0059     int ret = spi_mem_exec_op(spinand->spimem, &op);
0060     if (ret)
0061         return ret;
0062 
0063     *eccsr &= MACRONIX_ECCSR_MASK;
0064     return 0;
0065 }
0066 
0067 static int mx35lf1ge4ab_ecc_get_status(struct spinand_device *spinand,
0068                        u8 status)
0069 {
0070     struct nand_device *nand = spinand_to_nand(spinand);
0071     u8 eccsr;
0072 
0073     switch (status & STATUS_ECC_MASK) {
0074     case STATUS_ECC_NO_BITFLIPS:
0075         return 0;
0076 
0077     case STATUS_ECC_UNCOR_ERROR:
0078         return -EBADMSG;
0079 
0080     case STATUS_ECC_HAS_BITFLIPS:
0081         /*
0082          * Let's try to retrieve the real maximum number of bitflips
0083          * in order to avoid forcing the wear-leveling layer to move
0084          * data around if it's not necessary.
0085          */
0086         if (mx35lf1ge4ab_get_eccsr(spinand, &eccsr))
0087             return nanddev_get_ecc_conf(nand)->strength;
0088 
0089         if (WARN_ON(eccsr > nanddev_get_ecc_conf(nand)->strength ||
0090                 !eccsr))
0091             return nanddev_get_ecc_conf(nand)->strength;
0092 
0093         return eccsr;
0094 
0095     default:
0096         break;
0097     }
0098 
0099     return -EINVAL;
0100 }
0101 
0102 static const struct spinand_info macronix_spinand_table[] = {
0103     SPINAND_INFO("MX35LF1GE4AB",
0104              SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x12),
0105              NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1),
0106              NAND_ECCREQ(4, 512),
0107              SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
0108                           &write_cache_variants,
0109                           &update_cache_variants),
0110              SPINAND_HAS_QE_BIT,
0111              SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
0112                      mx35lf1ge4ab_ecc_get_status)),
0113     SPINAND_INFO("MX35LF2GE4AB",
0114              SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x22),
0115              NAND_MEMORG(1, 2048, 64, 64, 2048, 40, 2, 1, 1),
0116              NAND_ECCREQ(4, 512),
0117              SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
0118                           &write_cache_variants,
0119                           &update_cache_variants),
0120              SPINAND_HAS_QE_BIT,
0121              SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, NULL)),
0122     SPINAND_INFO("MX35LF2GE4AD",
0123              SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x26),
0124              NAND_MEMORG(1, 2048, 64, 64, 2048, 40, 1, 1, 1),
0125              NAND_ECCREQ(8, 512),
0126              SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
0127                           &write_cache_variants,
0128                           &update_cache_variants),
0129              SPINAND_HAS_QE_BIT,
0130              SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
0131                      mx35lf1ge4ab_ecc_get_status)),
0132     SPINAND_INFO("MX35LF4GE4AD",
0133              SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x37),
0134              NAND_MEMORG(1, 4096, 128, 64, 2048, 40, 1, 1, 1),
0135              NAND_ECCREQ(8, 512),
0136              SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
0137                           &write_cache_variants,
0138                           &update_cache_variants),
0139              SPINAND_HAS_QE_BIT,
0140              SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
0141                      mx35lf1ge4ab_ecc_get_status)),
0142     SPINAND_INFO("MX35LF1G24AD",
0143              SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x14),
0144              NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
0145              NAND_ECCREQ(8, 512),
0146              SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
0147                           &write_cache_variants,
0148                           &update_cache_variants),
0149              SPINAND_HAS_QE_BIT,
0150              SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, NULL)),
0151     SPINAND_INFO("MX35LF2G24AD",
0152              SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x24),
0153              NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 2, 1, 1),
0154              NAND_ECCREQ(8, 512),
0155              SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
0156                           &write_cache_variants,
0157                           &update_cache_variants),
0158              SPINAND_HAS_QE_BIT,
0159              SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, NULL)),
0160     SPINAND_INFO("MX35LF4G24AD",
0161              SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x35),
0162              NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 2, 1, 1),
0163              NAND_ECCREQ(8, 512),
0164              SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
0165                           &write_cache_variants,
0166                           &update_cache_variants),
0167              SPINAND_HAS_QE_BIT,
0168              SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, NULL)),
0169     SPINAND_INFO("MX31LF1GE4BC",
0170              SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x1e),
0171              NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1),
0172              NAND_ECCREQ(8, 512),
0173              SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
0174                           &write_cache_variants,
0175                           &update_cache_variants),
0176              SPINAND_HAS_QE_BIT,
0177              SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
0178                      mx35lf1ge4ab_ecc_get_status)),
0179     SPINAND_INFO("MX31UF1GE4BC",
0180              SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x9e),
0181              NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1),
0182              NAND_ECCREQ(8, 512),
0183              SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
0184                           &write_cache_variants,
0185                           &update_cache_variants),
0186              SPINAND_HAS_QE_BIT,
0187              SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
0188                      mx35lf1ge4ab_ecc_get_status)),
0189 
0190     SPINAND_INFO("MX35LF2G14AC",
0191              SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x20),
0192              NAND_MEMORG(1, 2048, 64, 64, 2048, 40, 2, 1, 1),
0193              NAND_ECCREQ(4, 512),
0194              SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
0195                           &write_cache_variants,
0196                           &update_cache_variants),
0197              SPINAND_HAS_QE_BIT,
0198              SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
0199                      mx35lf1ge4ab_ecc_get_status)),
0200     SPINAND_INFO("MX35UF4G24AD",
0201              SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xb5),
0202              NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 2, 1, 1),
0203              NAND_ECCREQ(8, 512),
0204              SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
0205                           &write_cache_variants,
0206                           &update_cache_variants),
0207              SPINAND_HAS_QE_BIT,
0208              SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
0209                      mx35lf1ge4ab_ecc_get_status)),
0210     SPINAND_INFO("MX35UF4GE4AD",
0211              SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xb7),
0212              NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 1, 1, 1),
0213              NAND_ECCREQ(8, 512),
0214              SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
0215                           &write_cache_variants,
0216                           &update_cache_variants),
0217              SPINAND_HAS_QE_BIT,
0218              SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
0219                      mx35lf1ge4ab_ecc_get_status)),
0220     SPINAND_INFO("MX35UF2G14AC",
0221              SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xa0),
0222              NAND_MEMORG(1, 2048, 64, 64, 2048, 40, 2, 1, 1),
0223              NAND_ECCREQ(4, 512),
0224              SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
0225                           &write_cache_variants,
0226                           &update_cache_variants),
0227              SPINAND_HAS_QE_BIT,
0228              SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
0229                      mx35lf1ge4ab_ecc_get_status)),
0230     SPINAND_INFO("MX35UF2G24AD",
0231              SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xa4),
0232              NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 2, 1, 1),
0233              NAND_ECCREQ(8, 512),
0234              SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
0235                           &write_cache_variants,
0236                           &update_cache_variants),
0237              SPINAND_HAS_QE_BIT,
0238              SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
0239                      mx35lf1ge4ab_ecc_get_status)),
0240     SPINAND_INFO("MX35UF2GE4AD",
0241              SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xa6),
0242              NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
0243              NAND_ECCREQ(8, 512),
0244              SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
0245                           &write_cache_variants,
0246                           &update_cache_variants),
0247              SPINAND_HAS_QE_BIT,
0248              SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
0249                      mx35lf1ge4ab_ecc_get_status)),
0250     SPINAND_INFO("MX35UF2GE4AC",
0251              SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xa2),
0252              NAND_MEMORG(1, 2048, 64, 64, 2048, 40, 1, 1, 1),
0253              NAND_ECCREQ(4, 512),
0254              SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
0255                           &write_cache_variants,
0256                           &update_cache_variants),
0257              SPINAND_HAS_QE_BIT,
0258              SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
0259                      mx35lf1ge4ab_ecc_get_status)),
0260     SPINAND_INFO("MX35UF1G14AC",
0261              SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x90),
0262              NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1),
0263              NAND_ECCREQ(4, 512),
0264              SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
0265                           &write_cache_variants,
0266                           &update_cache_variants),
0267              SPINAND_HAS_QE_BIT,
0268              SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
0269                      mx35lf1ge4ab_ecc_get_status)),
0270     SPINAND_INFO("MX35UF1G24AD",
0271              SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x94),
0272              NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
0273              NAND_ECCREQ(8, 512),
0274              SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
0275                           &write_cache_variants,
0276                           &update_cache_variants),
0277              SPINAND_HAS_QE_BIT,
0278              SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
0279                      mx35lf1ge4ab_ecc_get_status)),
0280     SPINAND_INFO("MX35UF1GE4AD",
0281              SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x96),
0282              NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
0283              NAND_ECCREQ(8, 512),
0284              SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
0285                           &write_cache_variants,
0286                           &update_cache_variants),
0287              SPINAND_HAS_QE_BIT,
0288              SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
0289                      mx35lf1ge4ab_ecc_get_status)),
0290     SPINAND_INFO("MX35UF1GE4AC",
0291              SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x92),
0292              NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1),
0293              NAND_ECCREQ(4, 512),
0294              SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
0295                           &write_cache_variants,
0296                           &update_cache_variants),
0297              SPINAND_HAS_QE_BIT,
0298              SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
0299                      mx35lf1ge4ab_ecc_get_status)),
0300 
0301 };
0302 
0303 static const struct spinand_manufacturer_ops macronix_spinand_manuf_ops = {
0304 };
0305 
0306 const struct spinand_manufacturer macronix_spinand_manufacturer = {
0307     .id = SPINAND_MFR_MACRONIX,
0308     .name = "Macronix",
0309     .chips = macronix_spinand_table,
0310     .nchips = ARRAY_SIZE(macronix_spinand_table),
0311     .ops = &macronix_spinand_manuf_ops,
0312 };