1 | // SPDX-License-Identifier: GPL-2.0-or-later |
2 | /* |
3 | * Copyright (C) 2017 Free Electrons |
4 | * Copyright (C) 2017 NextThing Co |
5 | * |
6 | * Author: Boris Brezillon <boris.brezillon@free-electrons.com> |
7 | */ |
8 | |
9 | #include <linux/slab.h> |
10 | #include "linux/delay.h" |
11 | #include "internals.h" |
12 | |
13 | #define MACRONIX_READ_RETRY_BIT BIT(0) |
14 | #define MACRONIX_NUM_READ_RETRY_MODES 6 |
15 | |
16 | #define ONFI_FEATURE_ADDR_MXIC_PROTECTION 0xA0 |
17 | #define MXIC_BLOCK_PROTECTION_ALL_LOCK 0x38 |
18 | #define MXIC_BLOCK_PROTECTION_ALL_UNLOCK 0x0 |
19 | |
20 | #define ONFI_FEATURE_ADDR_MXIC_RANDOMIZER 0xB0 |
21 | #define MACRONIX_RANDOMIZER_BIT BIT(1) |
22 | #define MACRONIX_RANDOMIZER_ENPGM BIT(0) |
23 | #define MACRONIX_RANDOMIZER_RANDEN BIT(1) |
24 | #define MACRONIX_RANDOMIZER_RANDOPT BIT(2) |
25 | #define MACRONIX_RANDOMIZER_MODE_ENTER \ |
26 | (MACRONIX_RANDOMIZER_ENPGM | \ |
27 | MACRONIX_RANDOMIZER_RANDEN | \ |
28 | MACRONIX_RANDOMIZER_RANDOPT) |
29 | #define MACRONIX_RANDOMIZER_MODE_EXIT \ |
30 | (MACRONIX_RANDOMIZER_RANDEN | \ |
31 | MACRONIX_RANDOMIZER_RANDOPT) |
32 | |
33 | #define MXIC_CMD_POWER_DOWN 0xB9 |
34 | |
35 | #define ONFI_FEATURE_ADDR_30LFXG18AC_OTP 0x90 |
36 | #define MACRONIX_30LFXG18AC_OTP_START_PAGE 2 |
37 | #define MACRONIX_30LFXG18AC_OTP_PAGES 30 |
38 | #define MACRONIX_30LFXG18AC_OTP_PAGE_SIZE 2112 |
39 | #define MACRONIX_30LFXG18AC_OTP_SIZE_BYTES \ |
40 | (MACRONIX_30LFXG18AC_OTP_PAGES * \ |
41 | MACRONIX_30LFXG18AC_OTP_PAGE_SIZE) |
42 | |
43 | #define MACRONIX_30LFXG18AC_OTP_EN BIT(0) |
44 | |
45 | struct nand_onfi_vendor_macronix { |
46 | u8 reserved; |
47 | u8 reliability_func; |
48 | } __packed; |
49 | |
50 | static int macronix_nand_setup_read_retry(struct nand_chip *chip, int mode) |
51 | { |
52 | u8 feature[ONFI_SUBFEATURE_PARAM_LEN]; |
53 | |
54 | if (!chip->parameters.supports_set_get_features || |
55 | !test_bit(ONFI_FEATURE_ADDR_READ_RETRY, |
56 | chip->parameters.set_feature_list)) |
57 | return -ENOTSUPP; |
58 | |
59 | feature[0] = mode; |
60 | return nand_set_features(chip, ONFI_FEATURE_ADDR_READ_RETRY, subfeature_param: feature); |
61 | } |
62 | |
63 | static int macronix_nand_randomizer_check_enable(struct nand_chip *chip) |
64 | { |
65 | u8 feature[ONFI_SUBFEATURE_PARAM_LEN]; |
66 | int ret; |
67 | |
68 | ret = nand_get_features(chip, ONFI_FEATURE_ADDR_MXIC_RANDOMIZER, |
69 | subfeature_param: feature); |
70 | if (ret < 0) |
71 | return ret; |
72 | |
73 | if (feature[0]) |
74 | return feature[0]; |
75 | |
76 | feature[0] = MACRONIX_RANDOMIZER_MODE_ENTER; |
77 | ret = nand_set_features(chip, ONFI_FEATURE_ADDR_MXIC_RANDOMIZER, |
78 | subfeature_param: feature); |
79 | if (ret < 0) |
80 | return ret; |
81 | |
82 | /* RANDEN and RANDOPT OTP bits are programmed */ |
83 | feature[0] = 0x0; |
84 | ret = nand_prog_page_op(chip, page: 0, offset_in_page: 0, buf: feature, len: 1); |
85 | if (ret < 0) |
86 | return ret; |
87 | |
88 | ret = nand_get_features(chip, ONFI_FEATURE_ADDR_MXIC_RANDOMIZER, |
89 | subfeature_param: feature); |
90 | if (ret < 0) |
91 | return ret; |
92 | |
93 | feature[0] &= MACRONIX_RANDOMIZER_MODE_EXIT; |
94 | ret = nand_set_features(chip, ONFI_FEATURE_ADDR_MXIC_RANDOMIZER, |
95 | subfeature_param: feature); |
96 | if (ret < 0) |
97 | return ret; |
98 | |
99 | return 0; |
100 | } |
101 | |
102 | static void macronix_nand_onfi_init(struct nand_chip *chip) |
103 | { |
104 | struct nand_parameters *p = &chip->parameters; |
105 | struct nand_onfi_vendor_macronix *mxic; |
106 | struct device_node *dn = nand_get_flash_node(chip); |
107 | int rand_otp; |
108 | int ret; |
109 | |
110 | if (!p->onfi) |
111 | return; |
112 | |
113 | rand_otp = of_property_read_bool(np: dn, propname: "mxic,enable-randomizer-otp" ); |
114 | |
115 | mxic = (struct nand_onfi_vendor_macronix *)p->onfi->vendor; |
116 | /* Subpage write is prohibited in randomizer operatoin */ |
117 | if (rand_otp && chip->options & NAND_NO_SUBPAGE_WRITE && |
118 | mxic->reliability_func & MACRONIX_RANDOMIZER_BIT) { |
119 | if (p->supports_set_get_features) { |
120 | bitmap_set(map: p->set_feature_list, |
121 | ONFI_FEATURE_ADDR_MXIC_RANDOMIZER, nbits: 1); |
122 | bitmap_set(map: p->get_feature_list, |
123 | ONFI_FEATURE_ADDR_MXIC_RANDOMIZER, nbits: 1); |
124 | ret = macronix_nand_randomizer_check_enable(chip); |
125 | if (ret < 0) { |
126 | bitmap_clear(map: p->set_feature_list, |
127 | ONFI_FEATURE_ADDR_MXIC_RANDOMIZER, |
128 | nbits: 1); |
129 | bitmap_clear(map: p->get_feature_list, |
130 | ONFI_FEATURE_ADDR_MXIC_RANDOMIZER, |
131 | nbits: 1); |
132 | pr_info("Macronix NAND randomizer failed\n" ); |
133 | } else { |
134 | pr_info("Macronix NAND randomizer enabled\n" ); |
135 | } |
136 | } |
137 | } |
138 | |
139 | if ((mxic->reliability_func & MACRONIX_READ_RETRY_BIT) == 0) |
140 | return; |
141 | |
142 | chip->read_retries = MACRONIX_NUM_READ_RETRY_MODES; |
143 | chip->ops.setup_read_retry = macronix_nand_setup_read_retry; |
144 | |
145 | if (p->supports_set_get_features) { |
146 | bitmap_set(map: p->set_feature_list, |
147 | ONFI_FEATURE_ADDR_READ_RETRY, nbits: 1); |
148 | bitmap_set(map: p->get_feature_list, |
149 | ONFI_FEATURE_ADDR_READ_RETRY, nbits: 1); |
150 | } |
151 | } |
152 | |
153 | /* |
154 | * Macronix AC series does not support using SET/GET_FEATURES to change |
155 | * the timings unlike what is declared in the parameter page. Unflag |
156 | * this feature to avoid unnecessary downturns. |
157 | */ |
158 | static void macronix_nand_fix_broken_get_timings(struct nand_chip *chip) |
159 | { |
160 | int i; |
161 | static const char * const broken_get_timings[] = { |
162 | "MX30LF1G18AC" , |
163 | "MX30LF1G28AC" , |
164 | "MX30LF2G18AC" , |
165 | "MX30LF2G28AC" , |
166 | "MX30LF4G18AC" , |
167 | "MX30LF4G28AC" , |
168 | "MX60LF8G18AC" , |
169 | "MX30UF1G18AC" , |
170 | "MX30UF1G16AC" , |
171 | "MX30UF2G18AC" , |
172 | "MX30UF2G16AC" , |
173 | "MX30UF4G18AC" , |
174 | "MX30UF4G16AC" , |
175 | "MX30UF4G28AC" , |
176 | }; |
177 | |
178 | if (!chip->parameters.supports_set_get_features) |
179 | return; |
180 | |
181 | i = match_string(array: broken_get_timings, ARRAY_SIZE(broken_get_timings), |
182 | string: chip->parameters.model); |
183 | if (i < 0) |
184 | return; |
185 | |
186 | bitmap_clear(map: chip->parameters.get_feature_list, |
187 | ONFI_FEATURE_ADDR_TIMING_MODE, nbits: 1); |
188 | bitmap_clear(map: chip->parameters.set_feature_list, |
189 | ONFI_FEATURE_ADDR_TIMING_MODE, nbits: 1); |
190 | } |
191 | |
192 | /* |
193 | * Macronix NAND supports Block Protection by Protectoin(PT) pin; |
194 | * active high at power-on which protects the entire chip even the #WP is |
195 | * disabled. Lock/unlock protection area can be partition according to |
196 | * protection bits, i.e. upper 1/2 locked, upper 1/4 locked and so on. |
197 | */ |
198 | static int mxic_nand_lock(struct nand_chip *chip, loff_t ofs, uint64_t len) |
199 | { |
200 | u8 feature[ONFI_SUBFEATURE_PARAM_LEN]; |
201 | int ret; |
202 | |
203 | feature[0] = MXIC_BLOCK_PROTECTION_ALL_LOCK; |
204 | nand_select_target(chip, cs: 0); |
205 | ret = nand_set_features(chip, ONFI_FEATURE_ADDR_MXIC_PROTECTION, |
206 | subfeature_param: feature); |
207 | nand_deselect_target(chip); |
208 | if (ret) |
209 | pr_err("%s all blocks failed\n" , __func__); |
210 | |
211 | return ret; |
212 | } |
213 | |
214 | static int mxic_nand_unlock(struct nand_chip *chip, loff_t ofs, uint64_t len) |
215 | { |
216 | u8 feature[ONFI_SUBFEATURE_PARAM_LEN]; |
217 | int ret; |
218 | |
219 | feature[0] = MXIC_BLOCK_PROTECTION_ALL_UNLOCK; |
220 | nand_select_target(chip, cs: 0); |
221 | ret = nand_set_features(chip, ONFI_FEATURE_ADDR_MXIC_PROTECTION, |
222 | subfeature_param: feature); |
223 | nand_deselect_target(chip); |
224 | if (ret) |
225 | pr_err("%s all blocks failed\n" , __func__); |
226 | |
227 | return ret; |
228 | } |
229 | |
230 | static void macronix_nand_block_protection_support(struct nand_chip *chip) |
231 | { |
232 | u8 feature[ONFI_SUBFEATURE_PARAM_LEN]; |
233 | int ret; |
234 | |
235 | bitmap_set(map: chip->parameters.get_feature_list, |
236 | ONFI_FEATURE_ADDR_MXIC_PROTECTION, nbits: 1); |
237 | |
238 | feature[0] = MXIC_BLOCK_PROTECTION_ALL_UNLOCK; |
239 | nand_select_target(chip, cs: 0); |
240 | ret = nand_get_features(chip, ONFI_FEATURE_ADDR_MXIC_PROTECTION, |
241 | subfeature_param: feature); |
242 | nand_deselect_target(chip); |
243 | if (ret || feature[0] != MXIC_BLOCK_PROTECTION_ALL_LOCK) { |
244 | if (ret) |
245 | pr_err("Block protection check failed\n" ); |
246 | |
247 | bitmap_clear(map: chip->parameters.get_feature_list, |
248 | ONFI_FEATURE_ADDR_MXIC_PROTECTION, nbits: 1); |
249 | return; |
250 | } |
251 | |
252 | bitmap_set(map: chip->parameters.set_feature_list, |
253 | ONFI_FEATURE_ADDR_MXIC_PROTECTION, nbits: 1); |
254 | |
255 | chip->ops.lock_area = mxic_nand_lock; |
256 | chip->ops.unlock_area = mxic_nand_unlock; |
257 | } |
258 | |
259 | static int nand_power_down_op(struct nand_chip *chip) |
260 | { |
261 | int ret; |
262 | |
263 | if (nand_has_exec_op(chip)) { |
264 | struct nand_op_instr instrs[] = { |
265 | NAND_OP_CMD(MXIC_CMD_POWER_DOWN, 0), |
266 | }; |
267 | |
268 | struct nand_operation op = NAND_OPERATION(chip->cur_cs, instrs); |
269 | |
270 | ret = nand_exec_op(chip, op: &op); |
271 | if (ret) |
272 | return ret; |
273 | |
274 | } else { |
275 | chip->legacy.cmdfunc(chip, MXIC_CMD_POWER_DOWN, -1, -1); |
276 | } |
277 | |
278 | return 0; |
279 | } |
280 | |
281 | static int mxic_nand_suspend(struct nand_chip *chip) |
282 | { |
283 | int ret; |
284 | |
285 | nand_select_target(chip, cs: 0); |
286 | ret = nand_power_down_op(chip); |
287 | if (ret < 0) |
288 | pr_err("Suspending MXIC NAND chip failed (%d)\n" , ret); |
289 | nand_deselect_target(chip); |
290 | |
291 | return ret; |
292 | } |
293 | |
294 | static void mxic_nand_resume(struct nand_chip *chip) |
295 | { |
296 | /* |
297 | * Toggle #CS pin to resume NAND device and don't care |
298 | * of the others CLE, #WE, #RE pins status. |
299 | * A NAND controller ensure it is able to assert/de-assert #CS |
300 | * by sending any byte over the NAND bus. |
301 | * i.e., |
302 | * NAND power down command or reset command w/o R/B# status checking. |
303 | */ |
304 | nand_select_target(chip, cs: 0); |
305 | nand_power_down_op(chip); |
306 | /* The minimum of a recovery time tRDP is 35 us */ |
307 | usleep_range(min: 35, max: 100); |
308 | nand_deselect_target(chip); |
309 | } |
310 | |
311 | static void macronix_nand_deep_power_down_support(struct nand_chip *chip) |
312 | { |
313 | int i; |
314 | static const char * const deep_power_down_dev[] = { |
315 | "MX30UF1G28AD" , |
316 | "MX30UF2G28AD" , |
317 | "MX30UF4G28AD" , |
318 | }; |
319 | |
320 | i = match_string(array: deep_power_down_dev, ARRAY_SIZE(deep_power_down_dev), |
321 | string: chip->parameters.model); |
322 | if (i < 0) |
323 | return; |
324 | |
325 | chip->ops.suspend = mxic_nand_suspend; |
326 | chip->ops.resume = mxic_nand_resume; |
327 | } |
328 | |
329 | static int macronix_30lfxg18ac_get_otp_info(struct mtd_info *mtd, size_t len, |
330 | size_t *retlen, |
331 | struct otp_info *buf) |
332 | { |
333 | if (len < sizeof(*buf)) |
334 | return -EINVAL; |
335 | |
336 | /* Always report that OTP is unlocked. Reason is that this |
337 | * type of flash chip doesn't provide way to check that OTP |
338 | * is locked or not: subfeature parameter is implemented as |
339 | * volatile register. Technically OTP region could be locked |
340 | * and become readonly, but as there is no way to check it, |
341 | * don't allow to lock it ('_lock_user_prot_reg' callback |
342 | * always returns -EOPNOTSUPP) and thus we report that OTP |
343 | * is unlocked. |
344 | */ |
345 | buf->locked = 0; |
346 | buf->start = 0; |
347 | buf->length = MACRONIX_30LFXG18AC_OTP_SIZE_BYTES; |
348 | |
349 | *retlen = sizeof(*buf); |
350 | |
351 | return 0; |
352 | } |
353 | |
354 | static int macronix_30lfxg18ac_otp_enable(struct nand_chip *nand) |
355 | { |
356 | u8 feature_buf[ONFI_SUBFEATURE_PARAM_LEN] = { 0 }; |
357 | |
358 | feature_buf[0] = MACRONIX_30LFXG18AC_OTP_EN; |
359 | return nand_set_features(chip: nand, ONFI_FEATURE_ADDR_30LFXG18AC_OTP, |
360 | subfeature_param: feature_buf); |
361 | } |
362 | |
363 | static int macronix_30lfxg18ac_otp_disable(struct nand_chip *nand) |
364 | { |
365 | u8 feature_buf[ONFI_SUBFEATURE_PARAM_LEN] = { 0 }; |
366 | |
367 | return nand_set_features(chip: nand, ONFI_FEATURE_ADDR_30LFXG18AC_OTP, |
368 | subfeature_param: feature_buf); |
369 | } |
370 | |
371 | static int __macronix_30lfxg18ac_rw_otp(struct mtd_info *mtd, |
372 | loff_t offs_in_flash, |
373 | size_t len, size_t *retlen, |
374 | u_char *buf, bool write) |
375 | { |
376 | struct nand_chip *nand; |
377 | size_t bytes_handled; |
378 | off_t offs_in_page; |
379 | u64 page; |
380 | int ret; |
381 | |
382 | nand = mtd_to_nand(mtd); |
383 | nand_select_target(chip: nand, cs: 0); |
384 | |
385 | ret = macronix_30lfxg18ac_otp_enable(nand); |
386 | if (ret) |
387 | goto out_otp; |
388 | |
389 | page = offs_in_flash; |
390 | /* 'page' will be result of division. */ |
391 | offs_in_page = do_div(page, MACRONIX_30LFXG18AC_OTP_PAGE_SIZE); |
392 | bytes_handled = 0; |
393 | |
394 | while (bytes_handled < len && |
395 | page < MACRONIX_30LFXG18AC_OTP_PAGES) { |
396 | size_t bytes_to_handle; |
397 | u64 phys_page = page + MACRONIX_30LFXG18AC_OTP_START_PAGE; |
398 | |
399 | bytes_to_handle = min_t(size_t, len - bytes_handled, |
400 | MACRONIX_30LFXG18AC_OTP_PAGE_SIZE - |
401 | offs_in_page); |
402 | |
403 | if (write) |
404 | ret = nand_prog_page_op(chip: nand, page: phys_page, offset_in_page: offs_in_page, |
405 | buf: &buf[bytes_handled], len: bytes_to_handle); |
406 | else |
407 | ret = nand_read_page_op(chip: nand, page: phys_page, offset_in_page: offs_in_page, |
408 | buf: &buf[bytes_handled], len: bytes_to_handle); |
409 | if (ret) |
410 | goto out_otp; |
411 | |
412 | bytes_handled += bytes_to_handle; |
413 | offs_in_page = 0; |
414 | page++; |
415 | } |
416 | |
417 | *retlen = bytes_handled; |
418 | |
419 | out_otp: |
420 | if (ret) |
421 | dev_err(&mtd->dev, "failed to perform OTP IO: %i\n" , ret); |
422 | |
423 | ret = macronix_30lfxg18ac_otp_disable(nand); |
424 | if (ret) |
425 | dev_err(&mtd->dev, "failed to leave OTP mode after %s\n" , |
426 | write ? "write" : "read" ); |
427 | |
428 | nand_deselect_target(chip: nand); |
429 | |
430 | return ret; |
431 | } |
432 | |
433 | static int macronix_30lfxg18ac_write_otp(struct mtd_info *mtd, loff_t to, |
434 | size_t len, size_t *rlen, |
435 | const u_char *buf) |
436 | { |
437 | return __macronix_30lfxg18ac_rw_otp(mtd, offs_in_flash: to, len, retlen: rlen, buf: (u_char *)buf, |
438 | write: true); |
439 | } |
440 | |
441 | static int macronix_30lfxg18ac_read_otp(struct mtd_info *mtd, loff_t from, |
442 | size_t len, size_t *rlen, |
443 | u_char *buf) |
444 | { |
445 | return __macronix_30lfxg18ac_rw_otp(mtd, offs_in_flash: from, len, retlen: rlen, buf, write: false); |
446 | } |
447 | |
448 | static int macronix_30lfxg18ac_lock_otp(struct mtd_info *mtd, loff_t from, |
449 | size_t len) |
450 | { |
451 | /* See comment in 'macronix_30lfxg18ac_get_otp_info()'. */ |
452 | return -EOPNOTSUPP; |
453 | } |
454 | |
455 | static void macronix_nand_setup_otp(struct nand_chip *chip) |
456 | { |
457 | static const char * const supported_otp_models[] = { |
458 | "MX30LF1G18AC" , |
459 | "MX30LF2G18AC" , |
460 | "MX30LF4G18AC" , |
461 | }; |
462 | struct mtd_info *mtd; |
463 | |
464 | if (match_string(array: supported_otp_models, |
465 | ARRAY_SIZE(supported_otp_models), |
466 | string: chip->parameters.model) < 0) |
467 | return; |
468 | |
469 | if (!chip->parameters.supports_set_get_features) |
470 | return; |
471 | |
472 | bitmap_set(map: chip->parameters.get_feature_list, |
473 | ONFI_FEATURE_ADDR_30LFXG18AC_OTP, nbits: 1); |
474 | bitmap_set(map: chip->parameters.set_feature_list, |
475 | ONFI_FEATURE_ADDR_30LFXG18AC_OTP, nbits: 1); |
476 | |
477 | mtd = nand_to_mtd(chip); |
478 | mtd->_get_user_prot_info = macronix_30lfxg18ac_get_otp_info; |
479 | mtd->_read_user_prot_reg = macronix_30lfxg18ac_read_otp; |
480 | mtd->_write_user_prot_reg = macronix_30lfxg18ac_write_otp; |
481 | mtd->_lock_user_prot_reg = macronix_30lfxg18ac_lock_otp; |
482 | } |
483 | |
484 | static int macronix_nand_init(struct nand_chip *chip) |
485 | { |
486 | if (nand_is_slc(chip)) |
487 | chip->options |= NAND_BBM_FIRSTPAGE | NAND_BBM_SECONDPAGE; |
488 | |
489 | macronix_nand_fix_broken_get_timings(chip); |
490 | macronix_nand_onfi_init(chip); |
491 | macronix_nand_block_protection_support(chip); |
492 | macronix_nand_deep_power_down_support(chip); |
493 | macronix_nand_setup_otp(chip); |
494 | |
495 | return 0; |
496 | } |
497 | |
498 | const struct nand_manufacturer_ops macronix_nand_manuf_ops = { |
499 | .init = macronix_nand_init, |
500 | }; |
501 | |