hc
2023-12-11 d2ccde1c8e90d38cee87a1b0309ad2827f3fd30d
kernel/drivers/mtd/nand/raw/nand_macronix.c
....@@ -1,21 +1,144 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*
23 * Copyright (C) 2017 Free Electrons
34 * Copyright (C) 2017 NextThing Co
45 *
56 * Author: Boris Brezillon <boris.brezillon@free-electrons.com>
6
- *
7
- * This program is free software; you can redistribute it and/or modify
8
- * it under the terms of the GNU General Public License as published by
9
- * the Free Software Foundation; either version 2 of the License, or
10
- * (at your option) any later version.
11
- *
12
- * This program is distributed in the hope that it will be useful,
13
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
- * GNU General Public License for more details.
167 */
178
18
-#include <linux/mtd/rawnand.h>
9
+#include "linux/delay.h"
10
+#include "internals.h"
11
+
12
+#define MACRONIX_READ_RETRY_BIT BIT(0)
13
+#define MACRONIX_NUM_READ_RETRY_MODES 6
14
+
15
+#define ONFI_FEATURE_ADDR_MXIC_PROTECTION 0xA0
16
+#define MXIC_BLOCK_PROTECTION_ALL_LOCK 0x38
17
+#define MXIC_BLOCK_PROTECTION_ALL_UNLOCK 0x0
18
+
19
+#define ONFI_FEATURE_ADDR_MXIC_RANDOMIZER 0xB0
20
+#define MACRONIX_RANDOMIZER_BIT BIT(1)
21
+#define MACRONIX_RANDOMIZER_ENPGM BIT(0)
22
+#define MACRONIX_RANDOMIZER_RANDEN BIT(1)
23
+#define MACRONIX_RANDOMIZER_RANDOPT BIT(2)
24
+#define MACRONIX_RANDOMIZER_MODE_ENTER \
25
+ (MACRONIX_RANDOMIZER_ENPGM | \
26
+ MACRONIX_RANDOMIZER_RANDEN | \
27
+ MACRONIX_RANDOMIZER_RANDOPT)
28
+#define MACRONIX_RANDOMIZER_MODE_EXIT \
29
+ (MACRONIX_RANDOMIZER_RANDEN | \
30
+ MACRONIX_RANDOMIZER_RANDOPT)
31
+
32
+#define MXIC_CMD_POWER_DOWN 0xB9
33
+
34
+struct nand_onfi_vendor_macronix {
35
+ u8 reserved;
36
+ u8 reliability_func;
37
+} __packed;
38
+
39
+static int macronix_nand_setup_read_retry(struct nand_chip *chip, int mode)
40
+{
41
+ u8 feature[ONFI_SUBFEATURE_PARAM_LEN];
42
+
43
+ if (!chip->parameters.supports_set_get_features ||
44
+ !test_bit(ONFI_FEATURE_ADDR_READ_RETRY,
45
+ chip->parameters.set_feature_list))
46
+ return -ENOTSUPP;
47
+
48
+ feature[0] = mode;
49
+ return nand_set_features(chip, ONFI_FEATURE_ADDR_READ_RETRY, feature);
50
+}
51
+
52
+static int macronix_nand_randomizer_check_enable(struct nand_chip *chip)
53
+{
54
+ u8 feature[ONFI_SUBFEATURE_PARAM_LEN];
55
+ int ret;
56
+
57
+ ret = nand_get_features(chip, ONFI_FEATURE_ADDR_MXIC_RANDOMIZER,
58
+ feature);
59
+ if (ret < 0)
60
+ return ret;
61
+
62
+ if (feature[0])
63
+ return feature[0];
64
+
65
+ feature[0] = MACRONIX_RANDOMIZER_MODE_ENTER;
66
+ ret = nand_set_features(chip, ONFI_FEATURE_ADDR_MXIC_RANDOMIZER,
67
+ feature);
68
+ if (ret < 0)
69
+ return ret;
70
+
71
+ /* RANDEN and RANDOPT OTP bits are programmed */
72
+ feature[0] = 0x0;
73
+ ret = nand_prog_page_op(chip, 0, 0, feature, 1);
74
+ if (ret < 0)
75
+ return ret;
76
+
77
+ ret = nand_get_features(chip, ONFI_FEATURE_ADDR_MXIC_RANDOMIZER,
78
+ feature);
79
+ if (ret < 0)
80
+ return ret;
81
+
82
+ feature[0] &= MACRONIX_RANDOMIZER_MODE_EXIT;
83
+ ret = nand_set_features(chip, ONFI_FEATURE_ADDR_MXIC_RANDOMIZER,
84
+ feature);
85
+ if (ret < 0)
86
+ return ret;
87
+
88
+ return 0;
89
+}
90
+
91
+static void macronix_nand_onfi_init(struct nand_chip *chip)
92
+{
93
+ struct nand_parameters *p = &chip->parameters;
94
+ struct nand_onfi_vendor_macronix *mxic;
95
+ struct device_node *dn = nand_get_flash_node(chip);
96
+ int rand_otp = 0;
97
+ int ret;
98
+
99
+ if (!p->onfi)
100
+ return;
101
+
102
+ if (of_find_property(dn, "mxic,enable-randomizer-otp", NULL))
103
+ rand_otp = 1;
104
+
105
+ mxic = (struct nand_onfi_vendor_macronix *)p->onfi->vendor;
106
+ /* Subpage write is prohibited in randomizer operatoin */
107
+ if (rand_otp && chip->options & NAND_NO_SUBPAGE_WRITE &&
108
+ mxic->reliability_func & MACRONIX_RANDOMIZER_BIT) {
109
+ if (p->supports_set_get_features) {
110
+ bitmap_set(p->set_feature_list,
111
+ ONFI_FEATURE_ADDR_MXIC_RANDOMIZER, 1);
112
+ bitmap_set(p->get_feature_list,
113
+ ONFI_FEATURE_ADDR_MXIC_RANDOMIZER, 1);
114
+ ret = macronix_nand_randomizer_check_enable(chip);
115
+ if (ret < 0) {
116
+ bitmap_clear(p->set_feature_list,
117
+ ONFI_FEATURE_ADDR_MXIC_RANDOMIZER,
118
+ 1);
119
+ bitmap_clear(p->get_feature_list,
120
+ ONFI_FEATURE_ADDR_MXIC_RANDOMIZER,
121
+ 1);
122
+ pr_info("Macronix NAND randomizer failed\n");
123
+ } else {
124
+ pr_info("Macronix NAND randomizer enabled\n");
125
+ }
126
+ }
127
+ }
128
+
129
+ if ((mxic->reliability_func & MACRONIX_READ_RETRY_BIT) == 0)
130
+ return;
131
+
132
+ chip->read_retries = MACRONIX_NUM_READ_RETRY_MODES;
133
+ chip->ops.setup_read_retry = macronix_nand_setup_read_retry;
134
+
135
+ if (p->supports_set_get_features) {
136
+ bitmap_set(p->set_feature_list,
137
+ ONFI_FEATURE_ADDR_READ_RETRY, 1);
138
+ bitmap_set(p->get_feature_list,
139
+ ONFI_FEATURE_ADDR_READ_RETRY, 1);
140
+ }
141
+}
19142
20143 /*
21144 * Macronix AC series does not support using SET/GET_FEATURES to change
....@@ -24,7 +147,7 @@
24147 */
25148 static void macronix_nand_fix_broken_get_timings(struct nand_chip *chip)
26149 {
27
- unsigned int i;
150
+ int i;
28151 static const char * const broken_get_timings[] = {
29152 "MX30LF1G18AC",
30153 "MX30LF1G28AC",
....@@ -33,17 +156,21 @@
33156 "MX30LF4G18AC",
34157 "MX30LF4G28AC",
35158 "MX60LF8G18AC",
159
+ "MX30UF1G18AC",
160
+ "MX30UF1G16AC",
161
+ "MX30UF2G18AC",
162
+ "MX30UF2G16AC",
163
+ "MX30UF4G18AC",
164
+ "MX30UF4G16AC",
165
+ "MX30UF4G28AC",
36166 };
37167
38168 if (!chip->parameters.supports_set_get_features)
39169 return;
40170
41
- for (i = 0; i < ARRAY_SIZE(broken_get_timings); i++) {
42
- if (!strcmp(broken_get_timings[i], chip->parameters.model))
43
- break;
44
- }
45
-
46
- if (i == ARRAY_SIZE(broken_get_timings))
171
+ i = match_string(broken_get_timings, ARRAY_SIZE(broken_get_timings),
172
+ chip->parameters.model);
173
+ if (i < 0)
47174 return;
48175
49176 bitmap_clear(chip->parameters.get_feature_list,
....@@ -52,12 +179,152 @@
52179 ONFI_FEATURE_ADDR_TIMING_MODE, 1);
53180 }
54181
182
+/*
183
+ * Macronix NAND supports Block Protection by Protectoin(PT) pin;
184
+ * active high at power-on which protects the entire chip even the #WP is
185
+ * disabled. Lock/unlock protection area can be partition according to
186
+ * protection bits, i.e. upper 1/2 locked, upper 1/4 locked and so on.
187
+ */
188
+static int mxic_nand_lock(struct nand_chip *chip, loff_t ofs, uint64_t len)
189
+{
190
+ u8 feature[ONFI_SUBFEATURE_PARAM_LEN];
191
+ int ret;
192
+
193
+ feature[0] = MXIC_BLOCK_PROTECTION_ALL_LOCK;
194
+ nand_select_target(chip, 0);
195
+ ret = nand_set_features(chip, ONFI_FEATURE_ADDR_MXIC_PROTECTION,
196
+ feature);
197
+ nand_deselect_target(chip);
198
+ if (ret)
199
+ pr_err("%s all blocks failed\n", __func__);
200
+
201
+ return ret;
202
+}
203
+
204
+static int mxic_nand_unlock(struct nand_chip *chip, loff_t ofs, uint64_t len)
205
+{
206
+ u8 feature[ONFI_SUBFEATURE_PARAM_LEN];
207
+ int ret;
208
+
209
+ feature[0] = MXIC_BLOCK_PROTECTION_ALL_UNLOCK;
210
+ nand_select_target(chip, 0);
211
+ ret = nand_set_features(chip, ONFI_FEATURE_ADDR_MXIC_PROTECTION,
212
+ feature);
213
+ nand_deselect_target(chip);
214
+ if (ret)
215
+ pr_err("%s all blocks failed\n", __func__);
216
+
217
+ return ret;
218
+}
219
+
220
+static void macronix_nand_block_protection_support(struct nand_chip *chip)
221
+{
222
+ u8 feature[ONFI_SUBFEATURE_PARAM_LEN];
223
+ int ret;
224
+
225
+ bitmap_set(chip->parameters.get_feature_list,
226
+ ONFI_FEATURE_ADDR_MXIC_PROTECTION, 1);
227
+
228
+ feature[0] = MXIC_BLOCK_PROTECTION_ALL_UNLOCK;
229
+ nand_select_target(chip, 0);
230
+ ret = nand_get_features(chip, ONFI_FEATURE_ADDR_MXIC_PROTECTION,
231
+ feature);
232
+ nand_deselect_target(chip);
233
+ if (ret || feature[0] != MXIC_BLOCK_PROTECTION_ALL_LOCK) {
234
+ if (ret)
235
+ pr_err("Block protection check failed\n");
236
+
237
+ bitmap_clear(chip->parameters.get_feature_list,
238
+ ONFI_FEATURE_ADDR_MXIC_PROTECTION, 1);
239
+ return;
240
+ }
241
+
242
+ bitmap_set(chip->parameters.set_feature_list,
243
+ ONFI_FEATURE_ADDR_MXIC_PROTECTION, 1);
244
+
245
+ chip->ops.lock_area = mxic_nand_lock;
246
+ chip->ops.unlock_area = mxic_nand_unlock;
247
+}
248
+
249
+static int nand_power_down_op(struct nand_chip *chip)
250
+{
251
+ int ret;
252
+
253
+ if (nand_has_exec_op(chip)) {
254
+ struct nand_op_instr instrs[] = {
255
+ NAND_OP_CMD(MXIC_CMD_POWER_DOWN, 0),
256
+ };
257
+
258
+ struct nand_operation op = NAND_OPERATION(chip->cur_cs, instrs);
259
+
260
+ ret = nand_exec_op(chip, &op);
261
+ if (ret)
262
+ return ret;
263
+
264
+ } else {
265
+ chip->legacy.cmdfunc(chip, MXIC_CMD_POWER_DOWN, -1, -1);
266
+ }
267
+
268
+ return 0;
269
+}
270
+
271
+static int mxic_nand_suspend(struct nand_chip *chip)
272
+{
273
+ int ret;
274
+
275
+ nand_select_target(chip, 0);
276
+ ret = nand_power_down_op(chip);
277
+ if (ret < 0)
278
+ pr_err("Suspending MXIC NAND chip failed (%d)\n", ret);
279
+ nand_deselect_target(chip);
280
+
281
+ return ret;
282
+}
283
+
284
+static void mxic_nand_resume(struct nand_chip *chip)
285
+{
286
+ /*
287
+ * Toggle #CS pin to resume NAND device and don't care
288
+ * of the others CLE, #WE, #RE pins status.
289
+ * A NAND controller ensure it is able to assert/de-assert #CS
290
+ * by sending any byte over the NAND bus.
291
+ * i.e.,
292
+ * NAND power down command or reset command w/o R/B# status checking.
293
+ */
294
+ nand_select_target(chip, 0);
295
+ nand_power_down_op(chip);
296
+ /* The minimum of a recovery time tRDP is 35 us */
297
+ usleep_range(35, 100);
298
+ nand_deselect_target(chip);
299
+}
300
+
301
+static void macronix_nand_deep_power_down_support(struct nand_chip *chip)
302
+{
303
+ int i;
304
+ static const char * const deep_power_down_dev[] = {
305
+ "MX30UF1G28AD",
306
+ "MX30UF2G28AD",
307
+ "MX30UF4G28AD",
308
+ };
309
+
310
+ i = match_string(deep_power_down_dev, ARRAY_SIZE(deep_power_down_dev),
311
+ chip->parameters.model);
312
+ if (i < 0)
313
+ return;
314
+
315
+ chip->ops.suspend = mxic_nand_suspend;
316
+ chip->ops.resume = mxic_nand_resume;
317
+}
318
+
55319 static int macronix_nand_init(struct nand_chip *chip)
56320 {
57321 if (nand_is_slc(chip))
58
- chip->bbt_options |= NAND_BBT_SCAN2NDPAGE;
322
+ chip->options |= NAND_BBM_FIRSTPAGE | NAND_BBM_SECONDPAGE;
59323
60324 macronix_nand_fix_broken_get_timings(chip);
325
+ macronix_nand_onfi_init(chip);
326
+ macronix_nand_block_protection_support(chip);
327
+ macronix_nand_deep_power_down_support(chip);
61328
62329 return 0;
63330 }