developer | 5d148cb | 2023-06-02 13:08:11 +0800 | [diff] [blame] | 1 | From 2f8ed664925318dacb6a92ca6383b5589cc2f7e1 Mon Sep 17 00:00:00 2001 |
| 2 | From: Sam Shih <sam.shih@mediatek.com> |
| 3 | Date: Fri, 2 Jun 2023 13:06:09 +0800 |
| 4 | Subject: [PATCH] |
| 5 | [spi-and-storage][999-2311-mtd-spinand-gigadevice-Support-GD5F1GQ5UExxG.patch] |
developer | 41370d5 | 2022-03-16 16:01:59 +0800 | [diff] [blame] | 6 | |
developer | 41370d5 | 2022-03-16 16:01:59 +0800 | [diff] [blame] | 7 | --- |
| 8 | drivers/mtd/nand/spi/gigadevice.c | 69 +++++++++++++++++++++++++++---- |
| 9 | 1 file changed, 60 insertions(+), 9 deletions(-) |
| 10 | |
| 11 | diff --git a/drivers/mtd/nand/spi/gigadevice.c b/drivers/mtd/nand/spi/gigadevice.c |
developer | 5d148cb | 2023-06-02 13:08:11 +0800 | [diff] [blame] | 12 | index a34c5ede1..937a04ce6 100644 |
developer | 41370d5 | 2022-03-16 16:01:59 +0800 | [diff] [blame] | 13 | --- a/drivers/mtd/nand/spi/gigadevice.c |
| 14 | +++ b/drivers/mtd/nand/spi/gigadevice.c |
| 15 | @@ -13,7 +13,10 @@ |
| 16 | #define GD5FXGQ4XA_STATUS_ECC_1_7_BITFLIPS (1 << 4) |
| 17 | #define GD5FXGQ4XA_STATUS_ECC_8_BITFLIPS (3 << 4) |
| 18 | |
| 19 | -#define GD5FXGQ4UEXXG_REG_STATUS2 0xf0 |
| 20 | +#define GD5FXGQ5XE_STATUS_ECC_1_4_BITFLIPS (1 << 4) |
| 21 | +#define GD5FXGQ5XE_STATUS_ECC_4_BITFLIPS (3 << 4) |
| 22 | + |
| 23 | +#define GD5FXGQXXEXXG_REG_STATUS2 0xf0 |
| 24 | |
| 25 | #define GD5FXGQ4UXFXXG_STATUS_ECC_MASK (7 << 4) |
| 26 | #define GD5FXGQ4UXFXXG_STATUS_ECC_NO_BITFLIPS (0 << 4) |
| 27 | @@ -102,7 +105,7 @@ static int gd5fxgq4xa_ecc_get_status(struct spinand_device *spinand, |
| 28 | return -EINVAL; |
| 29 | } |
| 30 | |
| 31 | -static int gd5fxgq4_variant2_ooblayout_ecc(struct mtd_info *mtd, int section, |
| 32 | +static int gd5fxgqx_variant2_ooblayout_ecc(struct mtd_info *mtd, int section, |
| 33 | struct mtd_oob_region *region) |
| 34 | { |
| 35 | if (section) |
| 36 | @@ -114,7 +117,7 @@ static int gd5fxgq4_variant2_ooblayout_ecc(struct mtd_info *mtd, int section, |
| 37 | return 0; |
| 38 | } |
| 39 | |
| 40 | -static int gd5fxgq4_variant2_ooblayout_free(struct mtd_info *mtd, int section, |
| 41 | +static int gd5fxgqx_variant2_ooblayout_free(struct mtd_info *mtd, int section, |
| 42 | struct mtd_oob_region *region) |
| 43 | { |
| 44 | if (section) |
developer | 5d148cb | 2023-06-02 13:08:11 +0800 | [diff] [blame] | 45 | @@ -127,16 +130,17 @@ static int gd5fxgq4_variant2_ooblayout_free(struct mtd_info *mtd, int section, |
developer | 41370d5 | 2022-03-16 16:01:59 +0800 | [diff] [blame] | 46 | return 0; |
| 47 | } |
| 48 | |
| 49 | -static const struct mtd_ooblayout_ops gd5fxgq4_variant2_ooblayout = { |
| 50 | - .ecc = gd5fxgq4_variant2_ooblayout_ecc, |
| 51 | - .free = gd5fxgq4_variant2_ooblayout_free, |
| 52 | +/* Valid for Q4/Q5 and Q6 (untested) devices */ |
| 53 | +static const struct mtd_ooblayout_ops gd5fxgqx_variant2_ooblayout = { |
| 54 | + .ecc = gd5fxgqx_variant2_ooblayout_ecc, |
| 55 | + .free = gd5fxgqx_variant2_ooblayout_free, |
| 56 | }; |
| 57 | |
developer | 5d148cb | 2023-06-02 13:08:11 +0800 | [diff] [blame] | 58 | static int gd5fxgq4uexxg_ecc_get_status(struct spinand_device *spinand, |
developer | 41370d5 | 2022-03-16 16:01:59 +0800 | [diff] [blame] | 59 | u8 status) |
| 60 | { |
| 61 | u8 status2; |
| 62 | - struct spi_mem_op op = SPINAND_GET_FEATURE_OP(GD5FXGQ4UEXXG_REG_STATUS2, |
| 63 | + struct spi_mem_op op = SPINAND_GET_FEATURE_OP(GD5FXGQXXEXXG_REG_STATUS2, |
| 64 | &status2); |
| 65 | int ret; |
| 66 | |
developer | 5d148cb | 2023-06-02 13:08:11 +0800 | [diff] [blame] | 67 | @@ -174,6 +178,43 @@ static int gd5fxgq4uexxg_ecc_get_status(struct spinand_device *spinand, |
developer | 41370d5 | 2022-03-16 16:01:59 +0800 | [diff] [blame] | 68 | return -EINVAL; |
| 69 | } |
| 70 | |
| 71 | +static int gd5fxgq5xexxg_ecc_get_status(struct spinand_device *spinand, |
| 72 | + u8 status) |
| 73 | +{ |
| 74 | + u8 status2; |
| 75 | + struct spi_mem_op op = SPINAND_GET_FEATURE_OP(GD5FXGQXXEXXG_REG_STATUS2, |
| 76 | + &status2); |
| 77 | + int ret; |
| 78 | + |
| 79 | + switch (status & STATUS_ECC_MASK) { |
| 80 | + case STATUS_ECC_NO_BITFLIPS: |
| 81 | + return 0; |
| 82 | + |
| 83 | + case GD5FXGQ5XE_STATUS_ECC_1_4_BITFLIPS: |
| 84 | + /* |
| 85 | + * Read status2 register to determine a more fine grained |
| 86 | + * bit error status |
| 87 | + */ |
| 88 | + ret = spi_mem_exec_op(spinand->spimem, &op); |
| 89 | + if (ret) |
| 90 | + return ret; |
| 91 | + |
| 92 | + /* |
| 93 | + * 1 ... 4 bits are flipped (and corrected) |
| 94 | + */ |
| 95 | + /* bits sorted this way (1...0): ECCSE1, ECCSE0 */ |
| 96 | + return ((status2 & STATUS_ECC_MASK) >> 4) + 1; |
| 97 | + |
| 98 | + case STATUS_ECC_UNCOR_ERROR: |
| 99 | + return -EBADMSG; |
| 100 | + |
| 101 | + default: |
| 102 | + break; |
| 103 | + } |
| 104 | + |
| 105 | + return -EINVAL; |
| 106 | +} |
| 107 | + |
| 108 | static int gd5fxgq4ufxxg_ecc_get_status(struct spinand_device *spinand, |
| 109 | u8 status) |
| 110 | { |
developer | 5d148cb | 2023-06-02 13:08:11 +0800 | [diff] [blame] | 111 | @@ -233,7 +274,7 @@ static const struct spinand_info gigadevice_spinand_table[] = { |
developer | 41370d5 | 2022-03-16 16:01:59 +0800 | [diff] [blame] | 112 | &write_cache_variants, |
| 113 | &update_cache_variants), |
| 114 | SPINAND_HAS_QE_BIT, |
| 115 | - SPINAND_ECCINFO(&gd5fxgq4_variant2_ooblayout, |
| 116 | + SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout, |
| 117 | gd5fxgq4uexxg_ecc_get_status)), |
| 118 | SPINAND_INFO("GD5F1GQ4UFxxG", |
| 119 | SPINAND_ID(SPINAND_READID_METHOD_OPCODE, 0xb1, 0x48), |
developer | 5d148cb | 2023-06-02 13:08:11 +0800 | [diff] [blame] | 120 | @@ -243,8 +284,18 @@ static const struct spinand_info gigadevice_spinand_table[] = { |
developer | 41370d5 | 2022-03-16 16:01:59 +0800 | [diff] [blame] | 121 | &write_cache_variants, |
| 122 | &update_cache_variants), |
| 123 | SPINAND_HAS_QE_BIT, |
| 124 | - SPINAND_ECCINFO(&gd5fxgq4_variant2_ooblayout, |
| 125 | + SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout, |
| 126 | gd5fxgq4ufxxg_ecc_get_status)), |
| 127 | + SPINAND_INFO("GD5F1GQ5UExxG", |
| 128 | + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x51), |
| 129 | + NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1), |
| 130 | + NAND_ECCREQ(4, 512), |
| 131 | + SPINAND_INFO_OP_VARIANTS(&read_cache_variants, |
| 132 | + &write_cache_variants, |
| 133 | + &update_cache_variants), |
| 134 | + SPINAND_HAS_QE_BIT, |
| 135 | + SPINAND_ECCINFO(&gd5fxgqx_variant2_ooblayout, |
| 136 | + gd5fxgq5xexxg_ecc_get_status)), |
| 137 | }; |
| 138 | |
| 139 | static const struct spinand_manufacturer_ops gigadevice_spinand_manuf_ops = { |
developer | 5d148cb | 2023-06-02 13:08:11 +0800 | [diff] [blame] | 140 | -- |
| 141 | 2.34.1 |
| 142 | |