xref: /openbmc/linux/drivers/mtd/nand/raw/nand_macronix.c (revision 1ac731c529cd4d6adbce134754b51ff7d822b145)
1c942fddfSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later
293db446aSBoris Brezillon /*
393db446aSBoris Brezillon  * Copyright (C) 2017 Free Electrons
493db446aSBoris Brezillon  * Copyright (C) 2017 NextThing Co
593db446aSBoris Brezillon  *
693db446aSBoris Brezillon  * Author: Boris Brezillon <boris.brezillon@free-electrons.com>
793db446aSBoris Brezillon  */
893db446aSBoris Brezillon 
919301d54SMason Yang #include <linux/slab.h>
10348d56a8SBoris Brezillon #include "linux/delay.h"
1193db446aSBoris Brezillon #include "internals.h"
1233535b85SMason Yang 
1333535b85SMason Yang #define MACRONIX_READ_RETRY_BIT BIT(0)
1433535b85SMason Yang #define MACRONIX_NUM_READ_RETRY_MODES 6
1503a539c7SMason Yang 
1603a539c7SMason Yang #define ONFI_FEATURE_ADDR_MXIC_PROTECTION 0xA0
1703a539c7SMason Yang #define MXIC_BLOCK_PROTECTION_ALL_LOCK 0x38
1803a539c7SMason Yang #define MXIC_BLOCK_PROTECTION_ALL_UNLOCK 0x0
1984234652SMason Yang 
2084234652SMason Yang #define ONFI_FEATURE_ADDR_MXIC_RANDOMIZER 0xB0
2184234652SMason Yang #define MACRONIX_RANDOMIZER_BIT BIT(1)
2284234652SMason Yang #define MACRONIX_RANDOMIZER_ENPGM BIT(0)
2384234652SMason Yang #define MACRONIX_RANDOMIZER_RANDEN BIT(1)
2484234652SMason Yang #define MACRONIX_RANDOMIZER_RANDOPT BIT(2)
2584234652SMason Yang #define MACRONIX_RANDOMIZER_MODE_ENTER	\
2684234652SMason Yang 	(MACRONIX_RANDOMIZER_ENPGM |	\
2784234652SMason Yang 	 MACRONIX_RANDOMIZER_RANDEN |	\
2884234652SMason Yang 	 MACRONIX_RANDOMIZER_RANDOPT)
2984234652SMason Yang #define MACRONIX_RANDOMIZER_MODE_EXIT	\
3084234652SMason Yang 	(MACRONIX_RANDOMIZER_RANDEN |	\
3184234652SMason Yang 	 MACRONIX_RANDOMIZER_RANDOPT)
3219301d54SMason Yang 
3319301d54SMason Yang #define MXIC_CMD_POWER_DOWN 0xB9
3433535b85SMason Yang 
3533535b85SMason Yang #define ONFI_FEATURE_ADDR_30LFXG18AC_OTP	0x90
3633535b85SMason Yang #define MACRONIX_30LFXG18AC_OTP_START_PAGE	2
3733535b85SMason Yang #define MACRONIX_30LFXG18AC_OTP_PAGES		30
3833535b85SMason Yang #define MACRONIX_30LFXG18AC_OTP_PAGE_SIZE	2112
3933535b85SMason Yang #define MACRONIX_30LFXG18AC_OTP_SIZE_BYTES	\
4033535b85SMason Yang 	(MACRONIX_30LFXG18AC_OTP_PAGES *	\
4133535b85SMason Yang 	 MACRONIX_30LFXG18AC_OTP_PAGE_SIZE)
4233535b85SMason Yang 
4333535b85SMason Yang #define MACRONIX_30LFXG18AC_OTP_EN		BIT(0)
4433535b85SMason Yang 
4533535b85SMason Yang struct nand_onfi_vendor_macronix {
4633535b85SMason Yang 	u8 reserved;
4733535b85SMason Yang 	u8 reliability_func;
4833535b85SMason Yang } __packed;
4933535b85SMason Yang 
macronix_nand_setup_read_retry(struct nand_chip * chip,int mode)5033535b85SMason Yang static int macronix_nand_setup_read_retry(struct nand_chip *chip, int mode)
5133535b85SMason Yang {
5284234652SMason Yang 	u8 feature[ONFI_SUBFEATURE_PARAM_LEN];
5384234652SMason Yang 
5484234652SMason Yang 	if (!chip->parameters.supports_set_get_features ||
5584234652SMason Yang 	    !test_bit(ONFI_FEATURE_ADDR_READ_RETRY,
5684234652SMason Yang 		      chip->parameters.set_feature_list))
5784234652SMason Yang 		return -ENOTSUPP;
5884234652SMason Yang 
5984234652SMason Yang 	feature[0] = mode;
6084234652SMason Yang 	return nand_set_features(chip, ONFI_FEATURE_ADDR_READ_RETRY, feature);
6184234652SMason Yang }
6284234652SMason Yang 
macronix_nand_randomizer_check_enable(struct nand_chip * chip)6384234652SMason Yang static int macronix_nand_randomizer_check_enable(struct nand_chip *chip)
6484234652SMason Yang {
6584234652SMason Yang 	u8 feature[ONFI_SUBFEATURE_PARAM_LEN];
6684234652SMason Yang 	int ret;
6784234652SMason Yang 
6884234652SMason Yang 	ret = nand_get_features(chip, ONFI_FEATURE_ADDR_MXIC_RANDOMIZER,
6984234652SMason Yang 				feature);
7084234652SMason Yang 	if (ret < 0)
7184234652SMason Yang 		return ret;
7284234652SMason Yang 
7384234652SMason Yang 	if (feature[0])
7484234652SMason Yang 		return feature[0];
7584234652SMason Yang 
7684234652SMason Yang 	feature[0] = MACRONIX_RANDOMIZER_MODE_ENTER;
7784234652SMason Yang 	ret = nand_set_features(chip, ONFI_FEATURE_ADDR_MXIC_RANDOMIZER,
7884234652SMason Yang 				feature);
7984234652SMason Yang 	if (ret < 0)
8084234652SMason Yang 		return ret;
8184234652SMason Yang 
8284234652SMason Yang 	/* RANDEN and RANDOPT OTP bits are programmed */
8384234652SMason Yang 	feature[0] = 0x0;
8484234652SMason Yang 	ret = nand_prog_page_op(chip, 0, 0, feature, 1);
8584234652SMason Yang 	if (ret < 0)
8684234652SMason Yang 		return ret;
8784234652SMason Yang 
8884234652SMason Yang 	ret = nand_get_features(chip, ONFI_FEATURE_ADDR_MXIC_RANDOMIZER,
8984234652SMason Yang 				feature);
9084234652SMason Yang 	if (ret < 0)
9133535b85SMason Yang 		return ret;
9233535b85SMason Yang 
9333535b85SMason Yang 	feature[0] &= MACRONIX_RANDOMIZER_MODE_EXIT;
9433535b85SMason Yang 	ret = nand_set_features(chip, ONFI_FEATURE_ADDR_MXIC_RANDOMIZER,
9584234652SMason Yang 				feature);
96*57150c40SRob Herring 	if (ret < 0)
9784234652SMason Yang 		return ret;
9833535b85SMason Yang 
9933535b85SMason Yang 	return 0;
10033535b85SMason Yang }
10133535b85SMason Yang 
macronix_nand_onfi_init(struct nand_chip * chip)102*57150c40SRob Herring static void macronix_nand_onfi_init(struct nand_chip *chip)
10384234652SMason Yang {
10433535b85SMason Yang 	struct nand_parameters *p = &chip->parameters;
10584234652SMason Yang 	struct nand_onfi_vendor_macronix *mxic;
10684234652SMason Yang 	struct device_node *dn = nand_get_flash_node(chip);
10784234652SMason Yang 	int rand_otp;
10884234652SMason Yang 	int ret;
10984234652SMason Yang 
11084234652SMason Yang 	if (!p->onfi)
11184234652SMason Yang 		return;
11284234652SMason Yang 
11384234652SMason Yang 	rand_otp = of_property_read_bool(dn, "mxic,enable-randomizer-otp");
11484234652SMason Yang 
11584234652SMason Yang 	mxic = (struct nand_onfi_vendor_macronix *)p->onfi->vendor;
11684234652SMason Yang 	/* Subpage write is prohibited in randomizer operatoin */
11784234652SMason Yang 	if (rand_otp && chip->options & NAND_NO_SUBPAGE_WRITE &&
11884234652SMason Yang 	    mxic->reliability_func & MACRONIX_RANDOMIZER_BIT) {
11984234652SMason Yang 		if (p->supports_set_get_features) {
12084234652SMason Yang 			bitmap_set(p->set_feature_list,
12184234652SMason Yang 				   ONFI_FEATURE_ADDR_MXIC_RANDOMIZER, 1);
12284234652SMason Yang 			bitmap_set(p->get_feature_list,
12384234652SMason Yang 				   ONFI_FEATURE_ADDR_MXIC_RANDOMIZER, 1);
12484234652SMason Yang 			ret = macronix_nand_randomizer_check_enable(chip);
12584234652SMason Yang 			if (ret < 0) {
12684234652SMason Yang 				bitmap_clear(p->set_feature_list,
12784234652SMason Yang 					     ONFI_FEATURE_ADDR_MXIC_RANDOMIZER,
12833535b85SMason Yang 					     1);
12933535b85SMason Yang 				bitmap_clear(p->get_feature_list,
13033535b85SMason Yang 					     ONFI_FEATURE_ADDR_MXIC_RANDOMIZER,
13133535b85SMason Yang 					     1);
1328e8b2706SMiquel Raynal 				pr_info("Macronix NAND randomizer failed\n");
13333535b85SMason Yang 			} else {
13433535b85SMason Yang 				pr_info("Macronix NAND randomizer enabled\n");
13533535b85SMason Yang 			}
13633535b85SMason Yang 		}
13733535b85SMason Yang 	}
13833535b85SMason Yang 
13933535b85SMason Yang 	if ((mxic->reliability_func & MACRONIX_READ_RETRY_BIT) == 0)
14033535b85SMason Yang 		return;
14133535b85SMason Yang 
14234c5c01eSMiquel Raynal 	chip->read_retries = MACRONIX_NUM_READ_RETRY_MODES;
143fe3dd97dSMason Yang 	chip->ops.setup_read_retry = macronix_nand_setup_read_retry;
14434c5c01eSMiquel Raynal 
14534c5c01eSMiquel Raynal 	if (p->supports_set_get_features) {
14634c5c01eSMiquel Raynal 		bitmap_set(p->set_feature_list,
147fe3dd97dSMason Yang 			   ONFI_FEATURE_ADDR_READ_RETRY, 1);
148fe3dd97dSMason Yang 		bitmap_set(p->get_feature_list,
149db7b6aecSYueHaibing 			   ONFI_FEATURE_ADDR_READ_RETRY, 1);
150fe3dd97dSMason Yang 	}
151fe3dd97dSMason Yang }
152fe3dd97dSMason Yang 
153fe3dd97dSMason Yang /*
154fe3dd97dSMason Yang  * Macronix AC series does not support using SET/GET_FEATURES to change
155fe3dd97dSMason Yang  * the timings unlike what is declared in the parameter page. Unflag
156fe3dd97dSMason Yang  * this feature to avoid unnecessary downturns.
157fe3dd97dSMason Yang  */
macronix_nand_fix_broken_get_timings(struct nand_chip * chip)158acc9d62bSMason Yang static void macronix_nand_fix_broken_get_timings(struct nand_chip *chip)
159acc9d62bSMason Yang {
160acc9d62bSMason Yang 	int i;
161acc9d62bSMason Yang 	static const char * const broken_get_timings[] = {
162acc9d62bSMason Yang 		"MX30LF1G18AC",
163acc9d62bSMason Yang 		"MX30LF1G28AC",
164acc9d62bSMason Yang 		"MX30LF2G18AC",
165fe3dd97dSMason Yang 		"MX30LF2G28AC",
166fe3dd97dSMason Yang 		"MX30LF4G18AC",
167fe3dd97dSMason Yang 		"MX30LF4G28AC",
168fe3dd97dSMason Yang 		"MX60LF8G18AC",
169fe3dd97dSMason Yang 		"MX30UF1G18AC",
170db7b6aecSYueHaibing 		"MX30UF1G16AC",
171db7b6aecSYueHaibing 		"MX30UF2G18AC",
172db7b6aecSYueHaibing 		"MX30UF2G16AC",
173fe3dd97dSMason Yang 		"MX30UF4G18AC",
174fe3dd97dSMason Yang 		"MX30UF4G16AC",
17534c5c01eSMiquel Raynal 		"MX30UF4G28AC",
17634c5c01eSMiquel Raynal 	};
17734c5c01eSMiquel Raynal 
17834c5c01eSMiquel Raynal 	if (!chip->parameters.supports_set_get_features)
17934c5c01eSMiquel Raynal 		return;
18034c5c01eSMiquel Raynal 
18103a539c7SMason Yang 	i = match_string(broken_get_timings, ARRAY_SIZE(broken_get_timings),
18203a539c7SMason Yang 			 chip->parameters.model);
18303a539c7SMason Yang 	if (i < 0)
18403a539c7SMason Yang 		return;
18503a539c7SMason Yang 
18603a539c7SMason Yang 	bitmap_clear(chip->parameters.get_feature_list,
18703a539c7SMason Yang 		     ONFI_FEATURE_ADDR_TIMING_MODE, 1);
18803a539c7SMason Yang 	bitmap_clear(chip->parameters.set_feature_list,
18903a539c7SMason Yang 		     ONFI_FEATURE_ADDR_TIMING_MODE, 1);
19003a539c7SMason Yang }
19103a539c7SMason Yang 
19203a539c7SMason Yang /*
19303a539c7SMason Yang  * Macronix NAND supports Block Protection by Protectoin(PT) pin;
19403a539c7SMason Yang  * active high at power-on which protects the entire chip even the #WP is
19503a539c7SMason Yang  * disabled. Lock/unlock protection area can be partition according to
19603a539c7SMason Yang  * protection bits, i.e. upper 1/2 locked, upper 1/4 locked and so on.
19703a539c7SMason Yang  */
mxic_nand_lock(struct nand_chip * chip,loff_t ofs,uint64_t len)19803a539c7SMason Yang static int mxic_nand_lock(struct nand_chip *chip, loff_t ofs, uint64_t len)
19903a539c7SMason Yang {
20003a539c7SMason Yang 	u8 feature[ONFI_SUBFEATURE_PARAM_LEN];
20103a539c7SMason Yang 	int ret;
20203a539c7SMason Yang 
20303a539c7SMason Yang 	feature[0] = MXIC_BLOCK_PROTECTION_ALL_LOCK;
20403a539c7SMason Yang 	nand_select_target(chip, 0);
20503a539c7SMason Yang 	ret = nand_set_features(chip, ONFI_FEATURE_ADDR_MXIC_PROTECTION,
20603a539c7SMason Yang 				feature);
20703a539c7SMason Yang 	nand_deselect_target(chip);
20803a539c7SMason Yang 	if (ret)
20903a539c7SMason Yang 		pr_err("%s all blocks failed\n", __func__);
21003a539c7SMason Yang 
21103a539c7SMason Yang 	return ret;
21203a539c7SMason Yang }
21303a539c7SMason Yang 
mxic_nand_unlock(struct nand_chip * chip,loff_t ofs,uint64_t len)21403a539c7SMason Yang static int mxic_nand_unlock(struct nand_chip *chip, loff_t ofs, uint64_t len)
21503a539c7SMason Yang {
21603a539c7SMason Yang 	u8 feature[ONFI_SUBFEATURE_PARAM_LEN];
21703a539c7SMason Yang 	int ret;
21803a539c7SMason Yang 
21903a539c7SMason Yang 	feature[0] = MXIC_BLOCK_PROTECTION_ALL_UNLOCK;
22003a539c7SMason Yang 	nand_select_target(chip, 0);
22103a539c7SMason Yang 	ret = nand_set_features(chip, ONFI_FEATURE_ADDR_MXIC_PROTECTION,
22203a539c7SMason Yang 				feature);
22303a539c7SMason Yang 	nand_deselect_target(chip);
22403a539c7SMason Yang 	if (ret)
22503a539c7SMason Yang 		pr_err("%s all blocks failed\n", __func__);
22603a539c7SMason Yang 
22703a539c7SMason Yang 	return ret;
22803a539c7SMason Yang }
22903a539c7SMason Yang 
macronix_nand_block_protection_support(struct nand_chip * chip)23003a539c7SMason Yang static void macronix_nand_block_protection_support(struct nand_chip *chip)
23103a539c7SMason Yang {
23203a539c7SMason Yang 	u8 feature[ONFI_SUBFEATURE_PARAM_LEN];
23303a539c7SMason Yang 	int ret;
23403a539c7SMason Yang 
23503a539c7SMason Yang 	bitmap_set(chip->parameters.get_feature_list,
23603a539c7SMason Yang 		   ONFI_FEATURE_ADDR_MXIC_PROTECTION, 1);
23703a539c7SMason Yang 
23803a539c7SMason Yang 	feature[0] = MXIC_BLOCK_PROTECTION_ALL_UNLOCK;
23903a539c7SMason Yang 	nand_select_target(chip, 0);
24003a539c7SMason Yang 	ret = nand_get_features(chip, ONFI_FEATURE_ADDR_MXIC_PROTECTION,
24103a539c7SMason Yang 				feature);
24203a539c7SMason Yang 	nand_deselect_target(chip);
24303a539c7SMason Yang 	if (ret || feature[0] != MXIC_BLOCK_PROTECTION_ALL_LOCK) {
2448e8b2706SMiquel Raynal 		if (ret)
2458e8b2706SMiquel Raynal 			pr_err("Block protection check failed\n");
24603a539c7SMason Yang 
24703a539c7SMason Yang 		bitmap_clear(chip->parameters.get_feature_list,
24819301d54SMason Yang 			     ONFI_FEATURE_ADDR_MXIC_PROTECTION, 1);
24919301d54SMason Yang 		return;
25019301d54SMason Yang 	}
25119301d54SMason Yang 
25219301d54SMason Yang 	bitmap_set(chip->parameters.set_feature_list,
25319301d54SMason Yang 		   ONFI_FEATURE_ADDR_MXIC_PROTECTION, 1);
25419301d54SMason Yang 
25519301d54SMason Yang 	chip->ops.lock_area = mxic_nand_lock;
25619301d54SMason Yang 	chip->ops.unlock_area = mxic_nand_unlock;
25719301d54SMason Yang }
25819301d54SMason Yang 
nand_power_down_op(struct nand_chip * chip)25919301d54SMason Yang static int nand_power_down_op(struct nand_chip *chip)
26019301d54SMason Yang {
26119301d54SMason Yang 	int ret;
26219301d54SMason Yang 
26319301d54SMason Yang 	if (nand_has_exec_op(chip)) {
26419301d54SMason Yang 		struct nand_op_instr instrs[] = {
26519301d54SMason Yang 			NAND_OP_CMD(MXIC_CMD_POWER_DOWN, 0),
26619301d54SMason Yang 		};
26719301d54SMason Yang 
26819301d54SMason Yang 		struct nand_operation op = NAND_OPERATION(chip->cur_cs, instrs);
26919301d54SMason Yang 
27019301d54SMason Yang 		ret = nand_exec_op(chip, &op);
27119301d54SMason Yang 		if (ret)
27219301d54SMason Yang 			return ret;
27319301d54SMason Yang 
27419301d54SMason Yang 	} else {
27519301d54SMason Yang 		chip->legacy.cmdfunc(chip, MXIC_CMD_POWER_DOWN, -1, -1);
27619301d54SMason Yang 	}
27719301d54SMason Yang 
27819301d54SMason Yang 	return 0;
27919301d54SMason Yang }
28019301d54SMason Yang 
mxic_nand_suspend(struct nand_chip * chip)28119301d54SMason Yang static int mxic_nand_suspend(struct nand_chip *chip)
28219301d54SMason Yang {
28319301d54SMason Yang 	int ret;
28419301d54SMason Yang 
28519301d54SMason Yang 	nand_select_target(chip, 0);
28619301d54SMason Yang 	ret = nand_power_down_op(chip);
28719301d54SMason Yang 	if (ret < 0)
28819301d54SMason Yang 		pr_err("Suspending MXIC NAND chip failed (%d)\n", ret);
28919301d54SMason Yang 	nand_deselect_target(chip);
29019301d54SMason Yang 
29119301d54SMason Yang 	return ret;
29219301d54SMason Yang }
29319301d54SMason Yang 
mxic_nand_resume(struct nand_chip * chip)29419301d54SMason Yang static void mxic_nand_resume(struct nand_chip *chip)
29519301d54SMason Yang {
29619301d54SMason Yang 	/*
29719301d54SMason Yang 	 * Toggle #CS pin to resume NAND device and don't care
29819301d54SMason Yang 	 * of the others CLE, #WE, #RE pins status.
29919301d54SMason Yang 	 * A NAND controller ensure it is able to assert/de-assert #CS
30019301d54SMason Yang 	 * by sending any byte over the NAND bus.
30119301d54SMason Yang 	 * i.e.,
30219301d54SMason Yang 	 * NAND power down command or reset command w/o R/B# status checking.
30319301d54SMason Yang 	 */
30419301d54SMason Yang 	nand_select_target(chip, 0);
30519301d54SMason Yang 	nand_power_down_op(chip);
30619301d54SMason Yang 	/* The minimum of a recovery time tRDP is 35 us */
30719301d54SMason Yang 	usleep_range(35, 100);
30819301d54SMason Yang 	nand_deselect_target(chip);
30919301d54SMason Yang }
31019301d54SMason Yang 
macronix_nand_deep_power_down_support(struct nand_chip * chip)31119301d54SMason Yang static void macronix_nand_deep_power_down_support(struct nand_chip *chip)
31219301d54SMason Yang {
31319301d54SMason Yang 	int i;
3148e8b2706SMiquel Raynal 	static const char * const deep_power_down_dev[] = {
3158e8b2706SMiquel Raynal 		"MX30UF1G28AD",
31619301d54SMason Yang 		"MX30UF2G28AD",
31719301d54SMason Yang 		"MX30UF4G28AD",
318fe3dd97dSMason Yang 	};
319fe3dd97dSMason Yang 
320fe3dd97dSMason Yang 	i = match_string(deep_power_down_dev, ARRAY_SIZE(deep_power_down_dev),
321bb592548SFrieder Schrempf 			 chip->parameters.model);
322fe3dd97dSMason Yang 	if (i < 0)
323fe3dd97dSMason Yang 		return;
32433535b85SMason Yang 
32503a539c7SMason Yang 	chip->ops.suspend = mxic_nand_suspend;
32619301d54SMason Yang 	chip->ops.resume = mxic_nand_resume;
327fe3dd97dSMason Yang }
32893db446aSBoris Brezillon 
macronix_30lfxg18ac_get_otp_info(struct mtd_info * mtd,size_t len,size_t * retlen,struct otp_info * buf)32993db446aSBoris Brezillon static int macronix_30lfxg18ac_get_otp_info(struct mtd_info *mtd, size_t len,
33093db446aSBoris Brezillon 					    size_t *retlen,
33193db446aSBoris Brezillon 					    struct otp_info *buf)
33293db446aSBoris Brezillon {
33393db446aSBoris Brezillon 	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 
macronix_30lfxg18ac_otp_enable(struct nand_chip * nand)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(nand, ONFI_FEATURE_ADDR_30LFXG18AC_OTP,
360 				 feature_buf);
361 }
362 
macronix_30lfxg18ac_otp_disable(struct nand_chip * nand)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(nand, ONFI_FEATURE_ADDR_30LFXG18AC_OTP,
368 				 feature_buf);
369 }
370 
__macronix_30lfxg18ac_rw_otp(struct mtd_info * mtd,loff_t offs_in_flash,size_t len,size_t * retlen,u_char * buf,bool write)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(nand, 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(nand, phys_page, offs_in_page,
405 						&buf[bytes_handled], bytes_to_handle);
406 		else
407 			ret = nand_read_page_op(nand, phys_page, offs_in_page,
408 						&buf[bytes_handled], 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(nand);
429 
430 	return ret;
431 }
432 
macronix_30lfxg18ac_write_otp(struct mtd_info * mtd,loff_t to,size_t len,size_t * rlen,const u_char * buf)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, to, len, rlen, (u_char *)buf,
438 					    true);
439 }
440 
macronix_30lfxg18ac_read_otp(struct mtd_info * mtd,loff_t from,size_t len,size_t * rlen,u_char * buf)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, from, len, rlen, buf, false);
446 }
447 
macronix_30lfxg18ac_lock_otp(struct mtd_info * mtd,loff_t from,size_t len)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 
macronix_nand_setup_otp(struct nand_chip * chip)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(supported_otp_models,
465 			 ARRAY_SIZE(supported_otp_models),
466 			 chip->parameters.model) < 0)
467 		return;
468 
469 	if (!chip->parameters.supports_set_get_features)
470 		return;
471 
472 	bitmap_set(chip->parameters.get_feature_list,
473 		   ONFI_FEATURE_ADDR_30LFXG18AC_OTP, 1);
474 	bitmap_set(chip->parameters.set_feature_list,
475 		   ONFI_FEATURE_ADDR_30LFXG18AC_OTP, 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 
macronix_nand_init(struct nand_chip * chip)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