blob: e3e81e57b7ffb5f3a8236cc1ebecf6e8a01de5dc [file] [log] [blame]
developer5d148cb2023-06-02 13:08:11 +08001From 2f8ed664925318dacb6a92ca6383b5589cc2f7e1 Mon Sep 17 00:00:00 2001
2From: Sam Shih <sam.shih@mediatek.com>
3Date: Fri, 2 Jun 2023 13:06:09 +0800
4Subject: [PATCH]
5 [spi-and-storage][999-2311-mtd-spinand-gigadevice-Support-GD5F1GQ5UExxG.patch]
developer41370d52022-03-16 16:01:59 +08006
developer41370d52022-03-16 16:01:59 +08007---
8 drivers/mtd/nand/spi/gigadevice.c | 69 +++++++++++++++++++++++++++----
9 1 file changed, 60 insertions(+), 9 deletions(-)
10
11diff --git a/drivers/mtd/nand/spi/gigadevice.c b/drivers/mtd/nand/spi/gigadevice.c
developer5d148cb2023-06-02 13:08:11 +080012index a34c5ede1..937a04ce6 100644
developer41370d52022-03-16 16:01:59 +080013--- 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)
developer5d148cb2023-06-02 13:08:11 +080045@@ -127,16 +130,17 @@ static int gd5fxgq4_variant2_ooblayout_free(struct mtd_info *mtd, int section,
developer41370d52022-03-16 16:01:59 +080046 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
developer5d148cb2023-06-02 13:08:11 +080058 static int gd5fxgq4uexxg_ecc_get_status(struct spinand_device *spinand,
developer41370d52022-03-16 16:01:59 +080059 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
developer5d148cb2023-06-02 13:08:11 +080067@@ -174,6 +178,43 @@ static int gd5fxgq4uexxg_ecc_get_status(struct spinand_device *spinand,
developer41370d52022-03-16 16:01:59 +080068 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 {
developer5d148cb2023-06-02 13:08:11 +0800111@@ -233,7 +274,7 @@ static const struct spinand_info gigadevice_spinand_table[] = {
developer41370d52022-03-16 16:01:59 +0800112 &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),
developer5d148cb2023-06-02 13:08:11 +0800120@@ -243,8 +284,18 @@ static const struct spinand_info gigadevice_spinand_table[] = {
developer41370d52022-03-16 16:01:59 +0800121 &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 = {
developer5d148cb2023-06-02 13:08:11 +0800140--
1412.34.1
142