powerpc/mm: Avoid calling arch_enter/leave_lazy_mmu() in set_ptes
[platform/kernel/linux-starfive.git] / drivers / mtd / nand / spi / micron.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (c) 2016-2017 Micron Technology, Inc.
4  *
5  * Authors:
6  *      Peter Pan <peterpandong@micron.com>
7  */
8
9 #include <linux/device.h>
10 #include <linux/kernel.h>
11 #include <linux/mtd/spinand.h>
12
13 #define SPINAND_MFR_MICRON              0x2c
14
15 #define MICRON_STATUS_ECC_MASK          GENMASK(7, 4)
16 #define MICRON_STATUS_ECC_NO_BITFLIPS   (0 << 4)
17 #define MICRON_STATUS_ECC_1TO3_BITFLIPS (1 << 4)
18 #define MICRON_STATUS_ECC_4TO6_BITFLIPS (3 << 4)
19 #define MICRON_STATUS_ECC_7TO8_BITFLIPS (5 << 4)
20
21 #define MICRON_CFG_CR                   BIT(0)
22
23 /*
24  * As per datasheet, die selection is done by the 6th bit of Die
25  * Select Register (Address 0xD0).
26  */
27 #define MICRON_DIE_SELECT_REG   0xD0
28
29 #define MICRON_SELECT_DIE(x)    ((x) << 6)
30
31 static SPINAND_OP_VARIANTS(quadio_read_cache_variants,
32                 SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 2, NULL, 0),
33                 SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0),
34                 SPINAND_PAGE_READ_FROM_CACHE_DUALIO_OP(0, 1, NULL, 0),
35                 SPINAND_PAGE_READ_FROM_CACHE_X2_OP(0, 1, NULL, 0),
36                 SPINAND_PAGE_READ_FROM_CACHE_OP(true, 0, 1, NULL, 0),
37                 SPINAND_PAGE_READ_FROM_CACHE_OP(false, 0, 1, NULL, 0));
38
39 static SPINAND_OP_VARIANTS(x4_write_cache_variants,
40                 SPINAND_PROG_LOAD_X4(true, 0, NULL, 0),
41                 SPINAND_PROG_LOAD(true, 0, NULL, 0));
42
43 static SPINAND_OP_VARIANTS(x4_update_cache_variants,
44                 SPINAND_PROG_LOAD_X4(false, 0, NULL, 0),
45                 SPINAND_PROG_LOAD(false, 0, NULL, 0));
46
47 /* Micron  MT29F2G01AAAED Device */
48 static SPINAND_OP_VARIANTS(x4_read_cache_variants,
49                            SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0),
50                            SPINAND_PAGE_READ_FROM_CACHE_X2_OP(0, 1, NULL, 0),
51                            SPINAND_PAGE_READ_FROM_CACHE_OP(true, 0, 1, NULL, 0),
52                            SPINAND_PAGE_READ_FROM_CACHE_OP(false, 0, 1, NULL, 0));
53
54 static SPINAND_OP_VARIANTS(x1_write_cache_variants,
55                            SPINAND_PROG_LOAD(true, 0, NULL, 0));
56
57 static SPINAND_OP_VARIANTS(x1_update_cache_variants,
58                            SPINAND_PROG_LOAD(false, 0, NULL, 0));
59
60 static int micron_8_ooblayout_ecc(struct mtd_info *mtd, int section,
61                                   struct mtd_oob_region *region)
62 {
63         if (section)
64                 return -ERANGE;
65
66         region->offset = mtd->oobsize / 2;
67         region->length = mtd->oobsize / 2;
68
69         return 0;
70 }
71
72 static int micron_8_ooblayout_free(struct mtd_info *mtd, int section,
73                                    struct mtd_oob_region *region)
74 {
75         if (section)
76                 return -ERANGE;
77
78         /* Reserve 2 bytes for the BBM. */
79         region->offset = 2;
80         region->length = (mtd->oobsize / 2) - 2;
81
82         return 0;
83 }
84
85 static const struct mtd_ooblayout_ops micron_8_ooblayout = {
86         .ecc = micron_8_ooblayout_ecc,
87         .free = micron_8_ooblayout_free,
88 };
89
90 static int micron_4_ooblayout_ecc(struct mtd_info *mtd, int section,
91                                   struct mtd_oob_region *region)
92 {
93         struct spinand_device *spinand = mtd_to_spinand(mtd);
94
95         if (section >= spinand->base.memorg.pagesize /
96                         mtd->ecc_step_size)
97                 return -ERANGE;
98
99         region->offset = (section * 16) + 8;
100         region->length = 8;
101
102         return 0;
103 }
104
105 static int micron_4_ooblayout_free(struct mtd_info *mtd, int section,
106                                    struct mtd_oob_region *region)
107 {
108         struct spinand_device *spinand = mtd_to_spinand(mtd);
109
110         if (section >= spinand->base.memorg.pagesize /
111                         mtd->ecc_step_size)
112                 return -ERANGE;
113
114         if (section) {
115                 region->offset = 16 * section;
116                 region->length = 8;
117         } else {
118                 /* section 0 has two bytes reserved for the BBM */
119                 region->offset = 2;
120                 region->length = 6;
121         }
122
123         return 0;
124 }
125
126 static const struct mtd_ooblayout_ops micron_4_ooblayout = {
127         .ecc = micron_4_ooblayout_ecc,
128         .free = micron_4_ooblayout_free,
129 };
130
131 static int micron_select_target(struct spinand_device *spinand,
132                                 unsigned int target)
133 {
134         struct spi_mem_op op = SPINAND_SET_FEATURE_OP(MICRON_DIE_SELECT_REG,
135                                                       spinand->scratchbuf);
136
137         if (target > 1)
138                 return -EINVAL;
139
140         *spinand->scratchbuf = MICRON_SELECT_DIE(target);
141
142         return spi_mem_exec_op(spinand->spimem, &op);
143 }
144
145 static int micron_8_ecc_get_status(struct spinand_device *spinand,
146                                    u8 status)
147 {
148         switch (status & MICRON_STATUS_ECC_MASK) {
149         case STATUS_ECC_NO_BITFLIPS:
150                 return 0;
151
152         case STATUS_ECC_UNCOR_ERROR:
153                 return -EBADMSG;
154
155         case MICRON_STATUS_ECC_1TO3_BITFLIPS:
156                 return 3;
157
158         case MICRON_STATUS_ECC_4TO6_BITFLIPS:
159                 return 6;
160
161         case MICRON_STATUS_ECC_7TO8_BITFLIPS:
162                 return 8;
163
164         default:
165                 break;
166         }
167
168         return -EINVAL;
169 }
170
171 static const struct spinand_info micron_spinand_table[] = {
172         /* M79A 2Gb 3.3V */
173         SPINAND_INFO("MT29F2G01ABAGD",
174                      SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x24),
175                      NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 2, 1, 1),
176                      NAND_ECCREQ(8, 512),
177                      SPINAND_INFO_OP_VARIANTS(&quadio_read_cache_variants,
178                                               &x4_write_cache_variants,
179                                               &x4_update_cache_variants),
180                      0,
181                      SPINAND_ECCINFO(&micron_8_ooblayout,
182                                      micron_8_ecc_get_status)),
183         /* M79A 2Gb 1.8V */
184         SPINAND_INFO("MT29F2G01ABBGD",
185                      SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x25),
186                      NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 2, 1, 1),
187                      NAND_ECCREQ(8, 512),
188                      SPINAND_INFO_OP_VARIANTS(&quadio_read_cache_variants,
189                                               &x4_write_cache_variants,
190                                               &x4_update_cache_variants),
191                      0,
192                      SPINAND_ECCINFO(&micron_8_ooblayout,
193                                      micron_8_ecc_get_status)),
194         /* M78A 1Gb 3.3V */
195         SPINAND_INFO("MT29F1G01ABAFD",
196                      SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x14),
197                      NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
198                      NAND_ECCREQ(8, 512),
199                      SPINAND_INFO_OP_VARIANTS(&quadio_read_cache_variants,
200                                               &x4_write_cache_variants,
201                                               &x4_update_cache_variants),
202                      0,
203                      SPINAND_ECCINFO(&micron_8_ooblayout,
204                                      micron_8_ecc_get_status)),
205         /* M78A 1Gb 1.8V */
206         SPINAND_INFO("MT29F1G01ABAFD",
207                      SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x15),
208                      NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
209                      NAND_ECCREQ(8, 512),
210                      SPINAND_INFO_OP_VARIANTS(&quadio_read_cache_variants,
211                                               &x4_write_cache_variants,
212                                               &x4_update_cache_variants),
213                      0,
214                      SPINAND_ECCINFO(&micron_8_ooblayout,
215                                      micron_8_ecc_get_status)),
216         /* M79A 4Gb 3.3V */
217         SPINAND_INFO("MT29F4G01ADAGD",
218                      SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x36),
219                      NAND_MEMORG(1, 2048, 128, 64, 2048, 80, 2, 1, 2),
220                      NAND_ECCREQ(8, 512),
221                      SPINAND_INFO_OP_VARIANTS(&quadio_read_cache_variants,
222                                               &x4_write_cache_variants,
223                                               &x4_update_cache_variants),
224                      0,
225                      SPINAND_ECCINFO(&micron_8_ooblayout,
226                                      micron_8_ecc_get_status),
227                      SPINAND_SELECT_TARGET(micron_select_target)),
228         /* M70A 4Gb 3.3V */
229         SPINAND_INFO("MT29F4G01ABAFD",
230                      SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x34),
231                      NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 1, 1, 1),
232                      NAND_ECCREQ(8, 512),
233                      SPINAND_INFO_OP_VARIANTS(&quadio_read_cache_variants,
234                                               &x4_write_cache_variants,
235                                               &x4_update_cache_variants),
236                      SPINAND_HAS_CR_FEAT_BIT,
237                      SPINAND_ECCINFO(&micron_8_ooblayout,
238                                      micron_8_ecc_get_status)),
239         /* M70A 4Gb 1.8V */
240         SPINAND_INFO("MT29F4G01ABBFD",
241                      SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x35),
242                      NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 1, 1, 1),
243                      NAND_ECCREQ(8, 512),
244                      SPINAND_INFO_OP_VARIANTS(&quadio_read_cache_variants,
245                                               &x4_write_cache_variants,
246                                               &x4_update_cache_variants),
247                      SPINAND_HAS_CR_FEAT_BIT,
248                      SPINAND_ECCINFO(&micron_8_ooblayout,
249                                      micron_8_ecc_get_status)),
250         /* M70A 8Gb 3.3V */
251         SPINAND_INFO("MT29F8G01ADAFD",
252                      SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x46),
253                      NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 1, 1, 2),
254                      NAND_ECCREQ(8, 512),
255                      SPINAND_INFO_OP_VARIANTS(&quadio_read_cache_variants,
256                                               &x4_write_cache_variants,
257                                               &x4_update_cache_variants),
258                      SPINAND_HAS_CR_FEAT_BIT,
259                      SPINAND_ECCINFO(&micron_8_ooblayout,
260                                      micron_8_ecc_get_status),
261                      SPINAND_SELECT_TARGET(micron_select_target)),
262         /* M70A 8Gb 1.8V */
263         SPINAND_INFO("MT29F8G01ADBFD",
264                      SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x47),
265                      NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 1, 1, 2),
266                      NAND_ECCREQ(8, 512),
267                      SPINAND_INFO_OP_VARIANTS(&quadio_read_cache_variants,
268                                               &x4_write_cache_variants,
269                                               &x4_update_cache_variants),
270                      SPINAND_HAS_CR_FEAT_BIT,
271                      SPINAND_ECCINFO(&micron_8_ooblayout,
272                                      micron_8_ecc_get_status),
273                      SPINAND_SELECT_TARGET(micron_select_target)),
274         /* M69A 2Gb 3.3V */
275         SPINAND_INFO("MT29F2G01AAAED",
276                      SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x9F),
277                      NAND_MEMORG(1, 2048, 64, 64, 2048, 80, 2, 1, 1),
278                      NAND_ECCREQ(4, 512),
279                      SPINAND_INFO_OP_VARIANTS(&x4_read_cache_variants,
280                                               &x1_write_cache_variants,
281                                               &x1_update_cache_variants),
282                      0,
283                      SPINAND_ECCINFO(&micron_4_ooblayout, NULL)),
284 };
285
286 static int micron_spinand_init(struct spinand_device *spinand)
287 {
288         /*
289          * M70A device series enable Continuous Read feature at Power-up,
290          * which is not supported. Disable this bit to avoid any possible
291          * failure.
292          */
293         if (spinand->flags & SPINAND_HAS_CR_FEAT_BIT)
294                 return spinand_upd_cfg(spinand, MICRON_CFG_CR, 0);
295
296         return 0;
297 }
298
299 static const struct spinand_manufacturer_ops micron_spinand_manuf_ops = {
300         .init = micron_spinand_init,
301 };
302
303 const struct spinand_manufacturer micron_spinand_manufacturer = {
304         .id = SPINAND_MFR_MICRON,
305         .name = "Micron",
306         .chips = micron_spinand_table,
307         .nchips = ARRAY_SIZE(micron_spinand_table),
308         .ops = &micron_spinand_manuf_ops,
309 };