|
| 1 | +To: Miquel Raynal < [email protected]>, |
| 2 | + Richard Weinberger < [email protected]>, Vignesh Raghavendra < [email protected]>, |
| 3 | + |
| 4 | + |
| 5 | +From: Mikhail Zhilkin < [email protected]> |
| 6 | +Subject: [PATCH] mtd: spinand: add support for FudanMicro FM25S01BI3 |
| 7 | + |
| 8 | +Add support for FudanMicro FM25S01BI3 SPI NAND. |
| 9 | + |
| 10 | +Link: https://www.fmsh.com/nvm/FM25S01BI3_ds_eng.pdf |
| 11 | + |
| 12 | +Signed-off-by: Mikhail Zhilkin < [email protected]> |
| 13 | +Link: https://lore.kernel.org/linux-mtd/ [email protected] |
| 14 | +--- |
| 15 | + drivers/mtd/nand/spi/fmsh.c | 72 +++++++++++++++++++++++++++++++++++++ |
| 16 | + 1 file changed, 72 insertions(+) |
| 17 | + |
| 18 | +--- a/drivers/mtd/nand/spi/fmsh.c |
| 19 | ++++ b/drivers/mtd/nand/spi/fmsh.c |
| 20 | +@@ -9,6 +9,13 @@ |
| 21 | + #include <linux/kernel.h> |
| 22 | + #include <linux/mtd/spinand.h> |
| 23 | + |
| 24 | ++#define FM25S01BI3_STATUS_ECC_MASK (7 << 4) |
| 25 | ++ #define FM25S01BI3_STATUS_ECC_NO_BITFLIPS (0 << 4) |
| 26 | ++ #define FM25S01BI3_STATUS_ECC_1_3_BITFLIPS (1 << 4) |
| 27 | ++ #define FM25S01BI3_STATUS_ECC_UNCOR_ERROR (2 << 4) |
| 28 | ++ #define FM25S01BI3_STATUS_ECC_4_6_BITFLIPS (3 << 4) |
| 29 | ++ #define FM25S01BI3_STATUS_ECC_7_8_BITFLIPS (5 << 4) |
| 30 | ++ |
| 31 | + #define SPINAND_MFR_FMSH 0xA1 |
| 32 | + |
| 33 | + static SPINAND_OP_VARIANTS(read_cache_variants, |
| 34 | +@@ -45,11 +52,66 @@ static int fm25s01a_ooblayout_free(struc |
| 35 | + return 0; |
| 36 | + } |
| 37 | + |
| 38 | ++static int fm25s01bi3_ecc_get_status(struct spinand_device *spinand, |
| 39 | ++ u8 status) |
| 40 | ++{ |
| 41 | ++ switch (status & FM25S01BI3_STATUS_ECC_MASK) { |
| 42 | ++ case FM25S01BI3_STATUS_ECC_NO_BITFLIPS: |
| 43 | ++ return 0; |
| 44 | ++ |
| 45 | ++ case FM25S01BI3_STATUS_ECC_UNCOR_ERROR: |
| 46 | ++ return -EBADMSG; |
| 47 | ++ |
| 48 | ++ case FM25S01BI3_STATUS_ECC_1_3_BITFLIPS: |
| 49 | ++ return 3; |
| 50 | ++ |
| 51 | ++ case FM25S01BI3_STATUS_ECC_4_6_BITFLIPS: |
| 52 | ++ return 6; |
| 53 | ++ |
| 54 | ++ case FM25S01BI3_STATUS_ECC_7_8_BITFLIPS: |
| 55 | ++ return 8; |
| 56 | ++ |
| 57 | ++ default: |
| 58 | ++ break; |
| 59 | ++ } |
| 60 | ++ |
| 61 | ++ return -EINVAL; |
| 62 | ++} |
| 63 | ++ |
| 64 | ++static int fm25s01bi3_ooblayout_ecc(struct mtd_info *mtd, int section, |
| 65 | ++ struct mtd_oob_region *region) |
| 66 | ++{ |
| 67 | ++ if (section) |
| 68 | ++ return -ERANGE; |
| 69 | ++ |
| 70 | ++ region->offset = 64; |
| 71 | ++ region->length = 64; |
| 72 | ++ |
| 73 | ++ return 0; |
| 74 | ++} |
| 75 | ++ |
| 76 | ++static int fm25s01bi3_ooblayout_free(struct mtd_info *mtd, int section, |
| 77 | ++ struct mtd_oob_region *region) |
| 78 | ++{ |
| 79 | ++ if (section > 3) |
| 80 | ++ return -ERANGE; |
| 81 | ++ |
| 82 | ++ region->offset = (16 * section) + 4; |
| 83 | ++ region->length = 12; |
| 84 | ++ |
| 85 | ++ return 0; |
| 86 | ++} |
| 87 | ++ |
| 88 | + static const struct mtd_ooblayout_ops fm25s01a_ooblayout = { |
| 89 | + .ecc = fm25s01a_ooblayout_ecc, |
| 90 | + .free = fm25s01a_ooblayout_free, |
| 91 | + }; |
| 92 | + |
| 93 | ++static const struct mtd_ooblayout_ops fm25s01bi3_ooblayout = { |
| 94 | ++ .ecc = fm25s01bi3_ooblayout_ecc, |
| 95 | ++ .free = fm25s01bi3_ooblayout_free, |
| 96 | ++}; |
| 97 | ++ |
| 98 | + static const struct spinand_info fmsh_spinand_table[] = { |
| 99 | + SPINAND_INFO("FM25S01A", |
| 100 | + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xE4), |
| 101 | +@@ -60,6 +122,16 @@ static const struct spinand_info fmsh_sp |
| 102 | + &update_cache_variants), |
| 103 | + 0, |
| 104 | + SPINAND_ECCINFO(&fm25s01a_ooblayout, NULL)), |
| 105 | ++ SPINAND_INFO("FM25S01BI3", |
| 106 | ++ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xd4), |
| 107 | ++ NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1), |
| 108 | ++ NAND_ECCREQ(8, 512), |
| 109 | ++ SPINAND_INFO_OP_VARIANTS(&read_cache_variants, |
| 110 | ++ &write_cache_variants, |
| 111 | ++ &update_cache_variants), |
| 112 | ++ SPINAND_HAS_QE_BIT, |
| 113 | ++ SPINAND_ECCINFO(&fm25s01bi3_ooblayout, |
| 114 | ++ fm25s01bi3_ecc_get_status)), |
| 115 | + }; |
| 116 | + |
| 117 | + static const struct spinand_manufacturer_ops fmsh_spinand_manuf_ops = { |
0 commit comments