162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Copyright (c) 2018 Macronix 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Author: Boris Brezillon <boris.brezillon@bootlin.com> 662306a36Sopenharmony_ci */ 762306a36Sopenharmony_ci 862306a36Sopenharmony_ci#include <linux/device.h> 962306a36Sopenharmony_ci#include <linux/kernel.h> 1062306a36Sopenharmony_ci#include <linux/mtd/spinand.h> 1162306a36Sopenharmony_ci 1262306a36Sopenharmony_ci#define SPINAND_MFR_MACRONIX 0xC2 1362306a36Sopenharmony_ci#define MACRONIX_ECCSR_MASK 0x0F 1462306a36Sopenharmony_ci 1562306a36Sopenharmony_cistatic SPINAND_OP_VARIANTS(read_cache_variants, 1662306a36Sopenharmony_ci SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0), 1762306a36Sopenharmony_ci SPINAND_PAGE_READ_FROM_CACHE_X2_OP(0, 1, NULL, 0), 1862306a36Sopenharmony_ci SPINAND_PAGE_READ_FROM_CACHE_OP(true, 0, 1, NULL, 0), 1962306a36Sopenharmony_ci SPINAND_PAGE_READ_FROM_CACHE_OP(false, 0, 1, NULL, 0)); 2062306a36Sopenharmony_ci 2162306a36Sopenharmony_cistatic SPINAND_OP_VARIANTS(write_cache_variants, 2262306a36Sopenharmony_ci SPINAND_PROG_LOAD_X4(true, 0, NULL, 0), 2362306a36Sopenharmony_ci SPINAND_PROG_LOAD(false, 0, NULL, 0)); 2462306a36Sopenharmony_ci 2562306a36Sopenharmony_cistatic SPINAND_OP_VARIANTS(update_cache_variants, 2662306a36Sopenharmony_ci SPINAND_PROG_LOAD_X4(false, 0, NULL, 0), 2762306a36Sopenharmony_ci SPINAND_PROG_LOAD(false, 0, NULL, 0)); 2862306a36Sopenharmony_ci 2962306a36Sopenharmony_cistatic int mx35lfxge4ab_ooblayout_ecc(struct mtd_info *mtd, int section, 3062306a36Sopenharmony_ci struct mtd_oob_region *region) 3162306a36Sopenharmony_ci{ 3262306a36Sopenharmony_ci return -ERANGE; 3362306a36Sopenharmony_ci} 3462306a36Sopenharmony_ci 3562306a36Sopenharmony_cistatic int mx35lfxge4ab_ooblayout_free(struct mtd_info *mtd, int section, 3662306a36Sopenharmony_ci struct mtd_oob_region *region) 3762306a36Sopenharmony_ci{ 3862306a36Sopenharmony_ci if (section) 3962306a36Sopenharmony_ci return -ERANGE; 4062306a36Sopenharmony_ci 4162306a36Sopenharmony_ci region->offset = 2; 4262306a36Sopenharmony_ci region->length = mtd->oobsize - 2; 4362306a36Sopenharmony_ci 4462306a36Sopenharmony_ci return 0; 4562306a36Sopenharmony_ci} 4662306a36Sopenharmony_ci 4762306a36Sopenharmony_cistatic const struct mtd_ooblayout_ops mx35lfxge4ab_ooblayout = { 4862306a36Sopenharmony_ci .ecc = mx35lfxge4ab_ooblayout_ecc, 4962306a36Sopenharmony_ci .free = mx35lfxge4ab_ooblayout_free, 5062306a36Sopenharmony_ci}; 5162306a36Sopenharmony_ci 5262306a36Sopenharmony_cistatic int mx35lf1ge4ab_get_eccsr(struct spinand_device *spinand, u8 *eccsr) 5362306a36Sopenharmony_ci{ 5462306a36Sopenharmony_ci struct spi_mem_op op = SPI_MEM_OP(SPI_MEM_OP_CMD(0x7c, 1), 5562306a36Sopenharmony_ci SPI_MEM_OP_NO_ADDR, 5662306a36Sopenharmony_ci SPI_MEM_OP_DUMMY(1, 1), 5762306a36Sopenharmony_ci SPI_MEM_OP_DATA_IN(1, eccsr, 1)); 5862306a36Sopenharmony_ci 5962306a36Sopenharmony_ci int ret = spi_mem_exec_op(spinand->spimem, &op); 6062306a36Sopenharmony_ci if (ret) 6162306a36Sopenharmony_ci return ret; 6262306a36Sopenharmony_ci 6362306a36Sopenharmony_ci *eccsr &= MACRONIX_ECCSR_MASK; 6462306a36Sopenharmony_ci return 0; 6562306a36Sopenharmony_ci} 6662306a36Sopenharmony_ci 6762306a36Sopenharmony_cistatic int mx35lf1ge4ab_ecc_get_status(struct spinand_device *spinand, 6862306a36Sopenharmony_ci u8 status) 6962306a36Sopenharmony_ci{ 7062306a36Sopenharmony_ci struct nand_device *nand = spinand_to_nand(spinand); 7162306a36Sopenharmony_ci u8 eccsr; 7262306a36Sopenharmony_ci 7362306a36Sopenharmony_ci switch (status & STATUS_ECC_MASK) { 7462306a36Sopenharmony_ci case STATUS_ECC_NO_BITFLIPS: 7562306a36Sopenharmony_ci return 0; 7662306a36Sopenharmony_ci 7762306a36Sopenharmony_ci case STATUS_ECC_UNCOR_ERROR: 7862306a36Sopenharmony_ci return -EBADMSG; 7962306a36Sopenharmony_ci 8062306a36Sopenharmony_ci case STATUS_ECC_HAS_BITFLIPS: 8162306a36Sopenharmony_ci /* 8262306a36Sopenharmony_ci * Let's try to retrieve the real maximum number of bitflips 8362306a36Sopenharmony_ci * in order to avoid forcing the wear-leveling layer to move 8462306a36Sopenharmony_ci * data around if it's not necessary. 8562306a36Sopenharmony_ci */ 8662306a36Sopenharmony_ci if (mx35lf1ge4ab_get_eccsr(spinand, spinand->scratchbuf)) 8762306a36Sopenharmony_ci return nanddev_get_ecc_conf(nand)->strength; 8862306a36Sopenharmony_ci 8962306a36Sopenharmony_ci eccsr = *spinand->scratchbuf; 9062306a36Sopenharmony_ci if (WARN_ON(eccsr > nanddev_get_ecc_conf(nand)->strength || 9162306a36Sopenharmony_ci !eccsr)) 9262306a36Sopenharmony_ci return nanddev_get_ecc_conf(nand)->strength; 9362306a36Sopenharmony_ci 9462306a36Sopenharmony_ci return eccsr; 9562306a36Sopenharmony_ci 9662306a36Sopenharmony_ci default: 9762306a36Sopenharmony_ci break; 9862306a36Sopenharmony_ci } 9962306a36Sopenharmony_ci 10062306a36Sopenharmony_ci return -EINVAL; 10162306a36Sopenharmony_ci} 10262306a36Sopenharmony_ci 10362306a36Sopenharmony_cistatic const struct spinand_info macronix_spinand_table[] = { 10462306a36Sopenharmony_ci SPINAND_INFO("MX35LF1GE4AB", 10562306a36Sopenharmony_ci SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x12), 10662306a36Sopenharmony_ci NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1), 10762306a36Sopenharmony_ci NAND_ECCREQ(4, 512), 10862306a36Sopenharmony_ci SPINAND_INFO_OP_VARIANTS(&read_cache_variants, 10962306a36Sopenharmony_ci &write_cache_variants, 11062306a36Sopenharmony_ci &update_cache_variants), 11162306a36Sopenharmony_ci SPINAND_HAS_QE_BIT, 11262306a36Sopenharmony_ci SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, 11362306a36Sopenharmony_ci mx35lf1ge4ab_ecc_get_status)), 11462306a36Sopenharmony_ci SPINAND_INFO("MX35LF2GE4AB", 11562306a36Sopenharmony_ci SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x22), 11662306a36Sopenharmony_ci NAND_MEMORG(1, 2048, 64, 64, 2048, 40, 2, 1, 1), 11762306a36Sopenharmony_ci NAND_ECCREQ(4, 512), 11862306a36Sopenharmony_ci SPINAND_INFO_OP_VARIANTS(&read_cache_variants, 11962306a36Sopenharmony_ci &write_cache_variants, 12062306a36Sopenharmony_ci &update_cache_variants), 12162306a36Sopenharmony_ci SPINAND_HAS_QE_BIT, 12262306a36Sopenharmony_ci SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, NULL)), 12362306a36Sopenharmony_ci SPINAND_INFO("MX35LF2GE4AD", 12462306a36Sopenharmony_ci SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x26), 12562306a36Sopenharmony_ci NAND_MEMORG(1, 2048, 64, 64, 2048, 40, 1, 1, 1), 12662306a36Sopenharmony_ci NAND_ECCREQ(8, 512), 12762306a36Sopenharmony_ci SPINAND_INFO_OP_VARIANTS(&read_cache_variants, 12862306a36Sopenharmony_ci &write_cache_variants, 12962306a36Sopenharmony_ci &update_cache_variants), 13062306a36Sopenharmony_ci SPINAND_HAS_QE_BIT, 13162306a36Sopenharmony_ci SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, 13262306a36Sopenharmony_ci mx35lf1ge4ab_ecc_get_status)), 13362306a36Sopenharmony_ci SPINAND_INFO("MX35LF4GE4AD", 13462306a36Sopenharmony_ci SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x37), 13562306a36Sopenharmony_ci NAND_MEMORG(1, 4096, 128, 64, 2048, 40, 1, 1, 1), 13662306a36Sopenharmony_ci NAND_ECCREQ(8, 512), 13762306a36Sopenharmony_ci SPINAND_INFO_OP_VARIANTS(&read_cache_variants, 13862306a36Sopenharmony_ci &write_cache_variants, 13962306a36Sopenharmony_ci &update_cache_variants), 14062306a36Sopenharmony_ci SPINAND_HAS_QE_BIT, 14162306a36Sopenharmony_ci SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, 14262306a36Sopenharmony_ci mx35lf1ge4ab_ecc_get_status)), 14362306a36Sopenharmony_ci SPINAND_INFO("MX35LF1G24AD", 14462306a36Sopenharmony_ci SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x14), 14562306a36Sopenharmony_ci NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1), 14662306a36Sopenharmony_ci NAND_ECCREQ(8, 512), 14762306a36Sopenharmony_ci SPINAND_INFO_OP_VARIANTS(&read_cache_variants, 14862306a36Sopenharmony_ci &write_cache_variants, 14962306a36Sopenharmony_ci &update_cache_variants), 15062306a36Sopenharmony_ci SPINAND_HAS_QE_BIT, 15162306a36Sopenharmony_ci SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, NULL)), 15262306a36Sopenharmony_ci SPINAND_INFO("MX35LF2G24AD", 15362306a36Sopenharmony_ci SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x24), 15462306a36Sopenharmony_ci NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 2, 1, 1), 15562306a36Sopenharmony_ci NAND_ECCREQ(8, 512), 15662306a36Sopenharmony_ci SPINAND_INFO_OP_VARIANTS(&read_cache_variants, 15762306a36Sopenharmony_ci &write_cache_variants, 15862306a36Sopenharmony_ci &update_cache_variants), 15962306a36Sopenharmony_ci SPINAND_HAS_QE_BIT, 16062306a36Sopenharmony_ci SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, NULL)), 16162306a36Sopenharmony_ci SPINAND_INFO("MX35LF4G24AD", 16262306a36Sopenharmony_ci SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x35), 16362306a36Sopenharmony_ci NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 2, 1, 1), 16462306a36Sopenharmony_ci NAND_ECCREQ(8, 512), 16562306a36Sopenharmony_ci SPINAND_INFO_OP_VARIANTS(&read_cache_variants, 16662306a36Sopenharmony_ci &write_cache_variants, 16762306a36Sopenharmony_ci &update_cache_variants), 16862306a36Sopenharmony_ci SPINAND_HAS_QE_BIT, 16962306a36Sopenharmony_ci SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, NULL)), 17062306a36Sopenharmony_ci SPINAND_INFO("MX31LF1GE4BC", 17162306a36Sopenharmony_ci SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x1e), 17262306a36Sopenharmony_ci NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1), 17362306a36Sopenharmony_ci NAND_ECCREQ(8, 512), 17462306a36Sopenharmony_ci SPINAND_INFO_OP_VARIANTS(&read_cache_variants, 17562306a36Sopenharmony_ci &write_cache_variants, 17662306a36Sopenharmony_ci &update_cache_variants), 17762306a36Sopenharmony_ci SPINAND_HAS_QE_BIT, 17862306a36Sopenharmony_ci SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, 17962306a36Sopenharmony_ci mx35lf1ge4ab_ecc_get_status)), 18062306a36Sopenharmony_ci SPINAND_INFO("MX31UF1GE4BC", 18162306a36Sopenharmony_ci SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x9e), 18262306a36Sopenharmony_ci NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1), 18362306a36Sopenharmony_ci NAND_ECCREQ(8, 512), 18462306a36Sopenharmony_ci SPINAND_INFO_OP_VARIANTS(&read_cache_variants, 18562306a36Sopenharmony_ci &write_cache_variants, 18662306a36Sopenharmony_ci &update_cache_variants), 18762306a36Sopenharmony_ci SPINAND_HAS_QE_BIT, 18862306a36Sopenharmony_ci SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, 18962306a36Sopenharmony_ci mx35lf1ge4ab_ecc_get_status)), 19062306a36Sopenharmony_ci 19162306a36Sopenharmony_ci SPINAND_INFO("MX35LF2G14AC", 19262306a36Sopenharmony_ci SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x20), 19362306a36Sopenharmony_ci NAND_MEMORG(1, 2048, 64, 64, 2048, 40, 2, 1, 1), 19462306a36Sopenharmony_ci NAND_ECCREQ(4, 512), 19562306a36Sopenharmony_ci SPINAND_INFO_OP_VARIANTS(&read_cache_variants, 19662306a36Sopenharmony_ci &write_cache_variants, 19762306a36Sopenharmony_ci &update_cache_variants), 19862306a36Sopenharmony_ci SPINAND_HAS_QE_BIT, 19962306a36Sopenharmony_ci SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, 20062306a36Sopenharmony_ci mx35lf1ge4ab_ecc_get_status)), 20162306a36Sopenharmony_ci SPINAND_INFO("MX35UF4G24AD", 20262306a36Sopenharmony_ci SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xb5), 20362306a36Sopenharmony_ci NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 2, 1, 1), 20462306a36Sopenharmony_ci NAND_ECCREQ(8, 512), 20562306a36Sopenharmony_ci SPINAND_INFO_OP_VARIANTS(&read_cache_variants, 20662306a36Sopenharmony_ci &write_cache_variants, 20762306a36Sopenharmony_ci &update_cache_variants), 20862306a36Sopenharmony_ci SPINAND_HAS_QE_BIT, 20962306a36Sopenharmony_ci SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, 21062306a36Sopenharmony_ci mx35lf1ge4ab_ecc_get_status)), 21162306a36Sopenharmony_ci SPINAND_INFO("MX35UF4GE4AD", 21262306a36Sopenharmony_ci SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xb7), 21362306a36Sopenharmony_ci NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 1, 1, 1), 21462306a36Sopenharmony_ci NAND_ECCREQ(8, 512), 21562306a36Sopenharmony_ci SPINAND_INFO_OP_VARIANTS(&read_cache_variants, 21662306a36Sopenharmony_ci &write_cache_variants, 21762306a36Sopenharmony_ci &update_cache_variants), 21862306a36Sopenharmony_ci SPINAND_HAS_QE_BIT, 21962306a36Sopenharmony_ci SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, 22062306a36Sopenharmony_ci mx35lf1ge4ab_ecc_get_status)), 22162306a36Sopenharmony_ci SPINAND_INFO("MX35UF2G14AC", 22262306a36Sopenharmony_ci SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xa0), 22362306a36Sopenharmony_ci NAND_MEMORG(1, 2048, 64, 64, 2048, 40, 2, 1, 1), 22462306a36Sopenharmony_ci NAND_ECCREQ(4, 512), 22562306a36Sopenharmony_ci SPINAND_INFO_OP_VARIANTS(&read_cache_variants, 22662306a36Sopenharmony_ci &write_cache_variants, 22762306a36Sopenharmony_ci &update_cache_variants), 22862306a36Sopenharmony_ci SPINAND_HAS_QE_BIT, 22962306a36Sopenharmony_ci SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, 23062306a36Sopenharmony_ci mx35lf1ge4ab_ecc_get_status)), 23162306a36Sopenharmony_ci SPINAND_INFO("MX35UF2G24AD", 23262306a36Sopenharmony_ci SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xa4), 23362306a36Sopenharmony_ci NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 2, 1, 1), 23462306a36Sopenharmony_ci NAND_ECCREQ(8, 512), 23562306a36Sopenharmony_ci SPINAND_INFO_OP_VARIANTS(&read_cache_variants, 23662306a36Sopenharmony_ci &write_cache_variants, 23762306a36Sopenharmony_ci &update_cache_variants), 23862306a36Sopenharmony_ci SPINAND_HAS_QE_BIT, 23962306a36Sopenharmony_ci SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, 24062306a36Sopenharmony_ci mx35lf1ge4ab_ecc_get_status)), 24162306a36Sopenharmony_ci SPINAND_INFO("MX35UF2GE4AD", 24262306a36Sopenharmony_ci SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xa6), 24362306a36Sopenharmony_ci NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1), 24462306a36Sopenharmony_ci NAND_ECCREQ(8, 512), 24562306a36Sopenharmony_ci SPINAND_INFO_OP_VARIANTS(&read_cache_variants, 24662306a36Sopenharmony_ci &write_cache_variants, 24762306a36Sopenharmony_ci &update_cache_variants), 24862306a36Sopenharmony_ci SPINAND_HAS_QE_BIT, 24962306a36Sopenharmony_ci SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, 25062306a36Sopenharmony_ci mx35lf1ge4ab_ecc_get_status)), 25162306a36Sopenharmony_ci SPINAND_INFO("MX35UF2GE4AC", 25262306a36Sopenharmony_ci SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xa2), 25362306a36Sopenharmony_ci NAND_MEMORG(1, 2048, 64, 64, 2048, 40, 1, 1, 1), 25462306a36Sopenharmony_ci NAND_ECCREQ(4, 512), 25562306a36Sopenharmony_ci SPINAND_INFO_OP_VARIANTS(&read_cache_variants, 25662306a36Sopenharmony_ci &write_cache_variants, 25762306a36Sopenharmony_ci &update_cache_variants), 25862306a36Sopenharmony_ci SPINAND_HAS_QE_BIT, 25962306a36Sopenharmony_ci SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, 26062306a36Sopenharmony_ci mx35lf1ge4ab_ecc_get_status)), 26162306a36Sopenharmony_ci SPINAND_INFO("MX35UF1G14AC", 26262306a36Sopenharmony_ci SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x90), 26362306a36Sopenharmony_ci NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1), 26462306a36Sopenharmony_ci NAND_ECCREQ(4, 512), 26562306a36Sopenharmony_ci SPINAND_INFO_OP_VARIANTS(&read_cache_variants, 26662306a36Sopenharmony_ci &write_cache_variants, 26762306a36Sopenharmony_ci &update_cache_variants), 26862306a36Sopenharmony_ci SPINAND_HAS_QE_BIT, 26962306a36Sopenharmony_ci SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, 27062306a36Sopenharmony_ci mx35lf1ge4ab_ecc_get_status)), 27162306a36Sopenharmony_ci SPINAND_INFO("MX35UF1G24AD", 27262306a36Sopenharmony_ci SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x94), 27362306a36Sopenharmony_ci NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1), 27462306a36Sopenharmony_ci NAND_ECCREQ(8, 512), 27562306a36Sopenharmony_ci SPINAND_INFO_OP_VARIANTS(&read_cache_variants, 27662306a36Sopenharmony_ci &write_cache_variants, 27762306a36Sopenharmony_ci &update_cache_variants), 27862306a36Sopenharmony_ci SPINAND_HAS_QE_BIT, 27962306a36Sopenharmony_ci SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, 28062306a36Sopenharmony_ci mx35lf1ge4ab_ecc_get_status)), 28162306a36Sopenharmony_ci SPINAND_INFO("MX35UF1GE4AD", 28262306a36Sopenharmony_ci SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x96), 28362306a36Sopenharmony_ci NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1), 28462306a36Sopenharmony_ci NAND_ECCREQ(8, 512), 28562306a36Sopenharmony_ci SPINAND_INFO_OP_VARIANTS(&read_cache_variants, 28662306a36Sopenharmony_ci &write_cache_variants, 28762306a36Sopenharmony_ci &update_cache_variants), 28862306a36Sopenharmony_ci SPINAND_HAS_QE_BIT, 28962306a36Sopenharmony_ci SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, 29062306a36Sopenharmony_ci mx35lf1ge4ab_ecc_get_status)), 29162306a36Sopenharmony_ci SPINAND_INFO("MX35UF1GE4AC", 29262306a36Sopenharmony_ci SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x92), 29362306a36Sopenharmony_ci NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1), 29462306a36Sopenharmony_ci NAND_ECCREQ(4, 512), 29562306a36Sopenharmony_ci SPINAND_INFO_OP_VARIANTS(&read_cache_variants, 29662306a36Sopenharmony_ci &write_cache_variants, 29762306a36Sopenharmony_ci &update_cache_variants), 29862306a36Sopenharmony_ci SPINAND_HAS_QE_BIT, 29962306a36Sopenharmony_ci SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, 30062306a36Sopenharmony_ci mx35lf1ge4ab_ecc_get_status)), 30162306a36Sopenharmony_ci 30262306a36Sopenharmony_ci SPINAND_INFO("MX31LF2GE4BC", 30362306a36Sopenharmony_ci SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x2e), 30462306a36Sopenharmony_ci NAND_MEMORG(1, 2048, 64, 64, 2048, 40, 1, 1, 1), 30562306a36Sopenharmony_ci NAND_ECCREQ(8, 512), 30662306a36Sopenharmony_ci SPINAND_INFO_OP_VARIANTS(&read_cache_variants, 30762306a36Sopenharmony_ci &write_cache_variants, 30862306a36Sopenharmony_ci &update_cache_variants), 30962306a36Sopenharmony_ci SPINAND_HAS_QE_BIT, 31062306a36Sopenharmony_ci SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, 31162306a36Sopenharmony_ci mx35lf1ge4ab_ecc_get_status)), 31262306a36Sopenharmony_ci SPINAND_INFO("MX3UF2GE4BC", 31362306a36Sopenharmony_ci SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xae), 31462306a36Sopenharmony_ci NAND_MEMORG(1, 2048, 64, 64, 2048, 40, 1, 1, 1), 31562306a36Sopenharmony_ci NAND_ECCREQ(8, 512), 31662306a36Sopenharmony_ci SPINAND_INFO_OP_VARIANTS(&read_cache_variants, 31762306a36Sopenharmony_ci &write_cache_variants, 31862306a36Sopenharmony_ci &update_cache_variants), 31962306a36Sopenharmony_ci SPINAND_HAS_QE_BIT, 32062306a36Sopenharmony_ci SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, 32162306a36Sopenharmony_ci mx35lf1ge4ab_ecc_get_status)), 32262306a36Sopenharmony_ci}; 32362306a36Sopenharmony_ci 32462306a36Sopenharmony_cistatic const struct spinand_manufacturer_ops macronix_spinand_manuf_ops = { 32562306a36Sopenharmony_ci}; 32662306a36Sopenharmony_ci 32762306a36Sopenharmony_ciconst struct spinand_manufacturer macronix_spinand_manufacturer = { 32862306a36Sopenharmony_ci .id = SPINAND_MFR_MACRONIX, 32962306a36Sopenharmony_ci .name = "Macronix", 33062306a36Sopenharmony_ci .chips = macronix_spinand_table, 33162306a36Sopenharmony_ci .nchips = ARRAY_SIZE(macronix_spinand_table), 33262306a36Sopenharmony_ci .ops = ¯onix_spinand_manuf_ops, 33362306a36Sopenharmony_ci}; 334