kernel: bump 5.15 to 5.15.116
[openwrt/openwrt.git] / target / linux / generic / backport-5.15 / 331-v5.19-mtd-spinand-Add-support-for-XTX-XT26G0xA.patch
1 From f4c5c7f9d2e5ab005d57826b740b694b042a737c Mon Sep 17 00:00:00 2001
2 From: Felix Matouschek <felix@matouschek.org>
3 Date: Mon, 18 Apr 2022 15:28:03 +0200
4 Subject: [PATCH 1/1] mtd: spinand: Add support for XTX XT26G0xA
5
6 Add support for XTX Technology XT26G01AXXXXX, XTX26G02AXXXXX and
7 XTX26G04AXXXXX SPI NAND.
8
9 These are 3V, 1G/2G/4Gbit serial SLC NAND flash devices with on-die ECC
10 (8bit strength per 512bytes).
11
12 Tested on Teltonika RUTX10 flashed with OpenWrt.
13
14 Links:
15 - http://www.xtxtech.com/download/?AId=225
16 - https://datasheet.lcsc.com/szlcsc/2005251034_XTX-XT26G01AWSEGA_C558841.pdf
17 Signed-off-by: Felix Matouschek <felix@matouschek.org>
18 Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
19 Link: https://lore.kernel.org/linux-mtd/20220418132803.664103-1-felix@matouschek.org
20 ---
21 drivers/mtd/nand/spi/Makefile | 2 +-
22 drivers/mtd/nand/spi/core.c | 1 +
23 drivers/mtd/nand/spi/xtx.c | 129 ++++++++++++++++++++++++++++++++++
24 include/linux/mtd/spinand.h | 1 +
25 4 files changed, 132 insertions(+), 1 deletion(-)
26 create mode 100644 drivers/mtd/nand/spi/xtx.c
27
28 --- a/drivers/mtd/nand/spi/Makefile
29 +++ b/drivers/mtd/nand/spi/Makefile
30 @@ -1,3 +1,3 @@
31 # SPDX-License-Identifier: GPL-2.0
32 -spinand-objs := core.o gigadevice.o macronix.o micron.o paragon.o toshiba.o winbond.o
33 +spinand-objs := core.o gigadevice.o macronix.o micron.o paragon.o toshiba.o winbond.o xtx.o
34 obj-$(CONFIG_MTD_SPI_NAND) += spinand.o
35 --- a/drivers/mtd/nand/spi/core.c
36 +++ b/drivers/mtd/nand/spi/core.c
37 @@ -902,6 +902,7 @@ static const struct spinand_manufacturer
38 &paragon_spinand_manufacturer,
39 &toshiba_spinand_manufacturer,
40 &winbond_spinand_manufacturer,
41 + &xtx_spinand_manufacturer,
42 };
43
44 static int spinand_manufacturer_match(struct spinand_device *spinand,
45 --- /dev/null
46 +++ b/drivers/mtd/nand/spi/xtx.c
47 @@ -0,0 +1,129 @@
48 +// SPDX-License-Identifier: GPL-2.0
49 +/*
50 + * Author:
51 + * Felix Matouschek <felix@matouschek.org>
52 + */
53 +
54 +#include <linux/device.h>
55 +#include <linux/kernel.h>
56 +#include <linux/mtd/spinand.h>
57 +
58 +#define SPINAND_MFR_XTX 0x0B
59 +
60 +#define XT26G0XA_STATUS_ECC_MASK GENMASK(5, 2)
61 +#define XT26G0XA_STATUS_ECC_NO_DETECTED (0 << 2)
62 +#define XT26G0XA_STATUS_ECC_8_CORRECTED (3 << 4)
63 +#define XT26G0XA_STATUS_ECC_UNCOR_ERROR (2 << 4)
64 +
65 +static SPINAND_OP_VARIANTS(read_cache_variants,
66 + SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 1, NULL, 0),
67 + SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0),
68 + SPINAND_PAGE_READ_FROM_CACHE_DUALIO_OP(0, 1, NULL, 0),
69 + SPINAND_PAGE_READ_FROM_CACHE_X2_OP(0, 1, NULL, 0),
70 + SPINAND_PAGE_READ_FROM_CACHE_OP(true, 0, 1, NULL, 0),
71 + SPINAND_PAGE_READ_FROM_CACHE_OP(false, 0, 1, NULL, 0));
72 +
73 +static SPINAND_OP_VARIANTS(write_cache_variants,
74 + SPINAND_PROG_LOAD_X4(true, 0, NULL, 0),
75 + SPINAND_PROG_LOAD(true, 0, NULL, 0));
76 +
77 +static SPINAND_OP_VARIANTS(update_cache_variants,
78 + SPINAND_PROG_LOAD_X4(false, 0, NULL, 0),
79 + SPINAND_PROG_LOAD(false, 0, NULL, 0));
80 +
81 +static int xt26g0xa_ooblayout_ecc(struct mtd_info *mtd, int section,
82 + struct mtd_oob_region *region)
83 +{
84 + if (section)
85 + return -ERANGE;
86 +
87 + region->offset = 48;
88 + region->length = 16;
89 +
90 + return 0;
91 +}
92 +
93 +static int xt26g0xa_ooblayout_free(struct mtd_info *mtd, int section,
94 + struct mtd_oob_region *region)
95 +{
96 + if (section)
97 + return -ERANGE;
98 +
99 + region->offset = 1;
100 + region->length = 47;
101 +
102 + return 0;
103 +}
104 +
105 +static const struct mtd_ooblayout_ops xt26g0xa_ooblayout = {
106 + .ecc = xt26g0xa_ooblayout_ecc,
107 + .free = xt26g0xa_ooblayout_free,
108 +};
109 +
110 +static int xt26g0xa_ecc_get_status(struct spinand_device *spinand,
111 + u8 status)
112 +{
113 + status = status & XT26G0XA_STATUS_ECC_MASK;
114 +
115 + switch (status) {
116 + case XT26G0XA_STATUS_ECC_NO_DETECTED:
117 + return 0;
118 + case XT26G0XA_STATUS_ECC_8_CORRECTED:
119 + return 8;
120 + case XT26G0XA_STATUS_ECC_UNCOR_ERROR:
121 + return -EBADMSG;
122 + default:
123 + break;
124 + }
125 +
126 + /* At this point values greater than (2 << 4) are invalid */
127 + if (status > XT26G0XA_STATUS_ECC_UNCOR_ERROR)
128 + return -EINVAL;
129 +
130 + /* (1 << 2) through (7 << 2) are 1-7 corrected errors */
131 + return status >> 2;
132 +}
133 +
134 +static const struct spinand_info xtx_spinand_table[] = {
135 + SPINAND_INFO("XT26G01A",
136 + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xE1),
137 + NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1),
138 + NAND_ECCREQ(8, 512),
139 + SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
140 + &write_cache_variants,
141 + &update_cache_variants),
142 + SPINAND_HAS_QE_BIT,
143 + SPINAND_ECCINFO(&xt26g0xa_ooblayout,
144 + xt26g0xa_ecc_get_status)),
145 + SPINAND_INFO("XT26G02A",
146 + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xE2),
147 + NAND_MEMORG(1, 2048, 64, 64, 2048, 40, 1, 1, 1),
148 + NAND_ECCREQ(8, 512),
149 + SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
150 + &write_cache_variants,
151 + &update_cache_variants),
152 + SPINAND_HAS_QE_BIT,
153 + SPINAND_ECCINFO(&xt26g0xa_ooblayout,
154 + xt26g0xa_ecc_get_status)),
155 + SPINAND_INFO("XT26G04A",
156 + SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0xE3),
157 + NAND_MEMORG(1, 2048, 64, 128, 2048, 40, 1, 1, 1),
158 + NAND_ECCREQ(8, 512),
159 + SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
160 + &write_cache_variants,
161 + &update_cache_variants),
162 + SPINAND_HAS_QE_BIT,
163 + SPINAND_ECCINFO(&xt26g0xa_ooblayout,
164 + xt26g0xa_ecc_get_status)),
165 +};
166 +
167 +static const struct spinand_manufacturer_ops xtx_spinand_manuf_ops = {
168 +};
169 +
170 +const struct spinand_manufacturer xtx_spinand_manufacturer = {
171 + .id = SPINAND_MFR_XTX,
172 + .name = "XTX",
173 + .chips = xtx_spinand_table,
174 + .nchips = ARRAY_SIZE(xtx_spinand_table),
175 + .ops = &xtx_spinand_manuf_ops,
176 +};
177 --- a/include/linux/mtd/spinand.h
178 +++ b/include/linux/mtd/spinand.h
179 @@ -266,6 +266,7 @@ extern const struct spinand_manufacturer
180 extern const struct spinand_manufacturer paragon_spinand_manufacturer;
181 extern const struct spinand_manufacturer toshiba_spinand_manufacturer;
182 extern const struct spinand_manufacturer winbond_spinand_manufacturer;
183 +extern const struct spinand_manufacturer xtx_spinand_manufacturer;
184
185 /**
186 * struct spinand_op_variants - SPI NAND operation variants