| --- a/drivers/mtd/nand/spi/micron.c |
| +++ b/drivers/mtd/nand/spi/micron.c |
| @@ -18,7 +18,9 @@ |
| #define MICRON_STATUS_ECC_4TO6_BITFLIPS (3 << 4) |
| #define MICRON_STATUS_ECC_7TO8_BITFLIPS (5 << 4) |
| |
| -static SPINAND_OP_VARIANTS(read_cache_variants, |
| +#define MICRON_CFG_CR BIT(0) |
| + |
| +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), |
| @@ -26,46 +28,46 @@ static SPINAND_OP_VARIANTS(read_cache_va |
| 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)); |
| |
| -static int mt29f2g01abagd_ooblayout_ecc(struct mtd_info *mtd, int section, |
| - struct mtd_oob_region *region) |
| +static int micron_8_ooblayout_ecc(struct mtd_info *mtd, int section, |
| + struct mtd_oob_region *region) |
| { |
| if (section) |
| return -ERANGE; |
| |
| - region->offset = 64; |
| - region->length = 64; |
| + region->offset = mtd->oobsize / 2; |
| + region->length = mtd->oobsize / 2; |
| |
| return 0; |
| } |
| |
| -static int mt29f2g01abagd_ooblayout_free(struct mtd_info *mtd, int section, |
| - struct mtd_oob_region *region) |
| +static int micron_8_ooblayout_free(struct mtd_info *mtd, int section, |
| + struct mtd_oob_region *region) |
| { |
| if (section) |
| return -ERANGE; |
| |
| /* Reserve 2 bytes for the BBM. */ |
| region->offset = 2; |
| - region->length = 62; |
| + region->length = (mtd->oobsize / 2) - 2; |
| |
| return 0; |
| } |
| |
| -static const struct mtd_ooblayout_ops mt29f2g01abagd_ooblayout = { |
| - .ecc = mt29f2g01abagd_ooblayout_ecc, |
| - .free = mt29f2g01abagd_ooblayout_free, |
| +static const struct mtd_ooblayout_ops micron_8_ooblayout = { |
| + .ecc = micron_8_ooblayout_ecc, |
| + .free = micron_8_ooblayout_free, |
| }; |
| |
| -static int mt29f2g01abagd_ecc_get_status(struct spinand_device *spinand, |
| - u8 status) |
| +static int micron_8_ecc_get_status(struct spinand_device *spinand, |
| + u8 status) |
| { |
| switch (status & MICRON_STATUS_ECC_MASK) { |
| case STATUS_ECC_NO_BITFLIPS: |
| @@ -94,12 +96,21 @@ static const struct spinand_info micron_ |
| SPINAND_INFO("MT29F2G01ABAGD", 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_INFO_OP_VARIANTS(&quadio_read_cache_variants, |
| + &x4_write_cache_variants, |
| + &x4_update_cache_variants), |
| 0, |
| - SPINAND_ECCINFO(&mt29f2g01abagd_ooblayout, |
| - mt29f2g01abagd_ecc_get_status)), |
| + SPINAND_ECCINFO(µn_8_ooblayout, |
| + micron_8_ecc_get_status)), |
| + SPINAND_INFO("MT29F4G01ABAFD", 0x34, |
| + NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 1, 1, 1), |
| + NAND_ECCREQ(8, 512), |
| + 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)), |
| }; |
| |
| static int micron_spinand_detect(struct spinand_device *spinand) |
| --- a/include/linux/mtd/spinand.h |
| +++ b/include/linux/mtd/spinand.h |
| @@ -270,6 +270,7 @@ struct spinand_ecc_info { |
| }; |
| |
| #define SPINAND_HAS_QE_BIT BIT(0) |
| +#define SPINAND_HAS_CR_FEAT_BIT BIT(1) |
| |
| /** |
| * struct spinand_info - Structure used to describe SPI NAND chips |