1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (c) 2018 Macronix 4 * 5 * Author: Boris Brezillon <boris.brezillon@bootlin.com> 6 */ 7 8 #ifndef __UBOOT__ 9 #include <linux/device.h> 10 #include <linux/kernel.h> 11 #endif 12 #include <linux/mtd/spinand.h> 13 14 #define SPINAND_MFR_MACRONIX 0xC2 15 #define MACRONIX_ECCSR_MASK 0x0F 16 17 static SPINAND_OP_VARIANTS(read_cache_variants, 18 SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0), 19 SPINAND_PAGE_READ_FROM_CACHE_X2_OP(0, 1, NULL, 0), 20 SPINAND_PAGE_READ_FROM_CACHE_OP(true, 0, 1, NULL, 0), 21 SPINAND_PAGE_READ_FROM_CACHE_OP(false, 0, 1, NULL, 0)); 22 23 static SPINAND_OP_VARIANTS(write_cache_variants, 24 SPINAND_PROG_LOAD_X4(true, 0, NULL, 0), 25 SPINAND_PROG_LOAD(true, 0, NULL, 0)); 26 27 static SPINAND_OP_VARIANTS(update_cache_variants, 28 SPINAND_PROG_LOAD_X4(false, 0, NULL, 0), 29 SPINAND_PROG_LOAD(false, 0, NULL, 0)); 30 31 static int mx35lfxge4ab_ooblayout_ecc(struct mtd_info *mtd, int section, 32 struct mtd_oob_region *region) 33 { 34 return -ERANGE; 35 } 36 37 static int mx35lfxge4ab_ooblayout_free(struct mtd_info *mtd, int section, 38 struct mtd_oob_region *region) 39 { 40 if (section) 41 return -ERANGE; 42 43 region->offset = 2; 44 region->length = mtd->oobsize - 2; 45 46 return 0; 47 } 48 49 static const struct mtd_ooblayout_ops mx35lfxge4ab_ooblayout = { 50 .ecc = mx35lfxge4ab_ooblayout_ecc, 51 .rfree = mx35lfxge4ab_ooblayout_free, 52 }; 53 54 static int mx35ufxge4ac_ooblayout_free(struct mtd_info *mtd, int section, 55 struct mtd_oob_region *region) 56 { 57 if (section > 3) 58 return -ERANGE; 59 60 region->offset = (16 * section) + 2; 61 region->length = 14; 62 63 return 0; 64 } 65 66 static const struct mtd_ooblayout_ops mx35ufxge4ac_ooblayout = { 67 .ecc = mx35lfxge4ab_ooblayout_ecc, 68 .rfree = mx35ufxge4ac_ooblayout_free, 69 }; 70 71 static int mx35lf1ge4ab_get_eccsr(struct spinand_device *spinand, u8 *eccsr) 72 { 73 struct spi_mem_op op = SPI_MEM_OP(SPI_MEM_OP_CMD(0x7c, 1), 74 SPI_MEM_OP_NO_ADDR, 75 SPI_MEM_OP_DUMMY(1, 1), 76 SPI_MEM_OP_DATA_IN(1, eccsr, 1)); 77 78 int ret = spi_mem_exec_op(spinand->slave, &op); 79 if (ret) 80 return ret; 81 82 *eccsr &= MACRONIX_ECCSR_MASK; 83 return 0; 84 } 85 86 static int mx35lf1ge4ab_ecc_get_status(struct spinand_device *spinand, 87 u8 status) 88 { 89 struct nand_device *nand = spinand_to_nand(spinand); 90 u8 eccsr; 91 92 switch (status & STATUS_ECC_MASK) { 93 case STATUS_ECC_NO_BITFLIPS: 94 return 0; 95 96 case STATUS_ECC_UNCOR_ERROR: 97 return -EBADMSG; 98 99 case STATUS_ECC_HAS_BITFLIPS: 100 /* 101 * Let's try to retrieve the real maximum number of bitflips 102 * in order to avoid forcing the wear-leveling layer to move 103 * data around if it's not necessary. 104 */ 105 if (mx35lf1ge4ab_get_eccsr(spinand, &eccsr)) 106 return nand->eccreq.strength; 107 108 if (WARN_ON(eccsr > nand->eccreq.strength || !eccsr)) 109 return nand->eccreq.strength; 110 111 return eccsr; 112 113 default: 114 break; 115 } 116 117 return -EINVAL; 118 } 119 120 static const struct spinand_info macronix_spinand_table[] = { 121 SPINAND_INFO("MX35LF1GE4AB", 122 SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x12), 123 NAND_MEMORG(1, 2048, 64, 64, 1024, 1, 1, 1), 124 NAND_ECCREQ(4, 512), 125 SPINAND_INFO_OP_VARIANTS(&read_cache_variants, 126 &write_cache_variants, 127 &update_cache_variants), 128 SPINAND_HAS_QE_BIT, 129 SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, 130 mx35lf1ge4ab_ecc_get_status)), 131 SPINAND_INFO("MX35LF2GE4AB", 132 SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x22), 133 NAND_MEMORG(1, 2048, 64, 64, 2048, 2, 1, 1), 134 NAND_ECCREQ(4, 512), 135 SPINAND_INFO_OP_VARIANTS(&read_cache_variants, 136 &write_cache_variants, 137 &update_cache_variants), 138 SPINAND_HAS_QE_BIT, 139 SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, NULL)), 140 SPINAND_INFO("MX35LF2GE4AD", 141 SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x26), 142 NAND_MEMORG(1, 2048, 64, 64, 2048, 2, 1, 1), 143 NAND_ECCREQ(8, 512), 144 SPINAND_INFO_OP_VARIANTS(&read_cache_variants, 145 &write_cache_variants, 146 &update_cache_variants), 147 SPINAND_HAS_QE_BIT, 148 SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, 149 mx35lf1ge4ab_ecc_get_status)), 150 SPINAND_INFO("MX35LF4GE4AD", 151 SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x37), 152 NAND_MEMORG(1, 4096, 128, 64, 2048, 2, 1, 1), 153 NAND_ECCREQ(8, 512), 154 SPINAND_INFO_OP_VARIANTS(&read_cache_variants, 155 &write_cache_variants, 156 &update_cache_variants), 157 SPINAND_HAS_QE_BIT, 158 SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, 159 mx35lf1ge4ab_ecc_get_status)), 160 SPINAND_INFO("MX35UF1GE4AC", 161 SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x92), 162 NAND_MEMORG(1, 2048, 64, 64, 1024, 1, 1, 1), 163 NAND_ECCREQ(4, 512), 164 SPINAND_INFO_OP_VARIANTS(&read_cache_variants, 165 &write_cache_variants, 166 &update_cache_variants), 167 SPINAND_HAS_QE_BIT, 168 SPINAND_ECCINFO(&mx35ufxge4ac_ooblayout, 169 mx35lf1ge4ab_ecc_get_status)), 170 SPINAND_INFO("MX35UF2GE4AC", 171 SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xA2), 172 NAND_MEMORG(1, 2048, 64, 64, 2048, 1, 1, 1), 173 NAND_ECCREQ(4, 512), 174 SPINAND_INFO_OP_VARIANTS(&read_cache_variants, 175 &write_cache_variants, 176 &update_cache_variants), 177 SPINAND_HAS_QE_BIT, 178 SPINAND_ECCINFO(&mx35ufxge4ac_ooblayout, 179 mx35lf1ge4ab_ecc_get_status)), 180 }; 181 182 static const struct spinand_manufacturer_ops macronix_spinand_manuf_ops = { 183 }; 184 185 const struct spinand_manufacturer macronix_spinand_manufacturer = { 186 .id = SPINAND_MFR_MACRONIX, 187 .name = "Macronix", 188 .chips = macronix_spinand_table, 189 .nchips = ARRAY_SIZE(macronix_spinand_table), 190 .ops = ¯onix_spinand_manuf_ops, 191 }; 192