xref: /linux/drivers/mtd/nand/raw/nand_toshiba.c (revision cbecf716ca618fd44feda6bd9a64a8179d031fc5)
1c942fddfSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later
29b2d61f8SBoris Brezillon /*
39b2d61f8SBoris Brezillon  * Copyright (C) 2017 Free Electrons
49b2d61f8SBoris Brezillon  * Copyright (C) 2017 NextThing Co
59b2d61f8SBoris Brezillon  *
69b2d61f8SBoris Brezillon  * Author: Boris Brezillon <boris.brezillon@free-electrons.com>
79b2d61f8SBoris Brezillon  */
89b2d61f8SBoris Brezillon 
9348d56a8SBoris Brezillon #include "internals.h"
109b2d61f8SBoris Brezillon 
11f223713fSKOBAYASHI Yoshitake /* Bit for detecting BENAND */
12f223713fSKOBAYASHI Yoshitake #define TOSHIBA_NAND_ID4_IS_BENAND		BIT(7)
13f223713fSKOBAYASHI Yoshitake 
14f223713fSKOBAYASHI Yoshitake /* Recommended to rewrite for BENAND */
15f223713fSKOBAYASHI Yoshitake #define TOSHIBA_NAND_STATUS_REWRITE_RECOMMENDED	BIT(3)
16f223713fSKOBAYASHI Yoshitake 
17fca88925SYoshio Furuyama /* ECC Status Read Command for BENAND */
18fca88925SYoshio Furuyama #define TOSHIBA_NAND_CMD_ECC_STATUS_READ	0x7A
19fca88925SYoshio Furuyama 
20fca88925SYoshio Furuyama /* ECC Status Mask for BENAND */
21fca88925SYoshio Furuyama #define TOSHIBA_NAND_ECC_STATUS_MASK		0x0F
22fca88925SYoshio Furuyama 
23fca88925SYoshio Furuyama /* Uncorrectable Error for BENAND */
24fca88925SYoshio Furuyama #define TOSHIBA_NAND_ECC_STATUS_UNCORR		0x0F
25fca88925SYoshio Furuyama 
26fca88925SYoshio Furuyama /* Max ECC Steps for BENAND */
27fca88925SYoshio Furuyama #define TOSHIBA_NAND_MAX_ECC_STEPS		8
28fca88925SYoshio Furuyama 
29fca88925SYoshio Furuyama static int toshiba_nand_benand_read_eccstatus_op(struct nand_chip *chip,
30fca88925SYoshio Furuyama 						 u8 *buf)
31fca88925SYoshio Furuyama {
32fca88925SYoshio Furuyama 	u8 *ecc_status = buf;
33fca88925SYoshio Furuyama 
34fca88925SYoshio Furuyama 	if (nand_has_exec_op(chip)) {
35fca88925SYoshio Furuyama 		const struct nand_sdr_timings *sdr =
36e0160cd4SMiquel Raynal 			nand_get_sdr_timings(nand_get_interface_config(chip));
37fca88925SYoshio Furuyama 		struct nand_op_instr instrs[] = {
38fca88925SYoshio Furuyama 			NAND_OP_CMD(TOSHIBA_NAND_CMD_ECC_STATUS_READ,
39fca88925SYoshio Furuyama 				    PSEC_TO_NSEC(sdr->tADL_min)),
40fca88925SYoshio Furuyama 			NAND_OP_8BIT_DATA_IN(chip->ecc.steps, ecc_status, 0),
41fca88925SYoshio Furuyama 		};
42fca88925SYoshio Furuyama 		struct nand_operation op = NAND_OPERATION(chip->cur_cs, instrs);
43fca88925SYoshio Furuyama 
44fca88925SYoshio Furuyama 		return nand_exec_op(chip, &op);
45fca88925SYoshio Furuyama 	}
46fca88925SYoshio Furuyama 
47fca88925SYoshio Furuyama 	return -ENOTSUPP;
48fca88925SYoshio Furuyama }
49fca88925SYoshio Furuyama 
50e9836761SMiquel Raynal static int toshiba_nand_benand_eccstatus(struct nand_chip *chip)
51f223713fSKOBAYASHI Yoshitake {
52e9836761SMiquel Raynal 	struct mtd_info *mtd = nand_to_mtd(chip);
53f223713fSKOBAYASHI Yoshitake 	int ret;
54f223713fSKOBAYASHI Yoshitake 	unsigned int max_bitflips = 0;
55fca88925SYoshio Furuyama 	u8 status, ecc_status[TOSHIBA_NAND_MAX_ECC_STEPS];
56f223713fSKOBAYASHI Yoshitake 
57f223713fSKOBAYASHI Yoshitake 	/* Check Status */
58fca88925SYoshio Furuyama 	ret = toshiba_nand_benand_read_eccstatus_op(chip, ecc_status);
59fca88925SYoshio Furuyama 	if (!ret) {
60fca88925SYoshio Furuyama 		unsigned int i, bitflips = 0;
61fca88925SYoshio Furuyama 
62fca88925SYoshio Furuyama 		for (i = 0; i < chip->ecc.steps; i++) {
63fca88925SYoshio Furuyama 			bitflips = ecc_status[i] & TOSHIBA_NAND_ECC_STATUS_MASK;
64fca88925SYoshio Furuyama 			if (bitflips == TOSHIBA_NAND_ECC_STATUS_UNCORR) {
65fca88925SYoshio Furuyama 				mtd->ecc_stats.failed++;
66fca88925SYoshio Furuyama 			} else {
67fca88925SYoshio Furuyama 				mtd->ecc_stats.corrected += bitflips;
68fca88925SYoshio Furuyama 				max_bitflips = max(max_bitflips, bitflips);
69fca88925SYoshio Furuyama 			}
70fca88925SYoshio Furuyama 		}
71fca88925SYoshio Furuyama 
72fca88925SYoshio Furuyama 		return max_bitflips;
73fca88925SYoshio Furuyama 	}
74fca88925SYoshio Furuyama 
75fca88925SYoshio Furuyama 	/*
76fca88925SYoshio Furuyama 	 * Fallback to regular status check if
77fca88925SYoshio Furuyama 	 * toshiba_nand_benand_read_eccstatus_op() failed.
78fca88925SYoshio Furuyama 	 */
79f223713fSKOBAYASHI Yoshitake 	ret = nand_status_op(chip, &status);
80f223713fSKOBAYASHI Yoshitake 	if (ret)
81f223713fSKOBAYASHI Yoshitake 		return ret;
82f223713fSKOBAYASHI Yoshitake 
83f223713fSKOBAYASHI Yoshitake 	if (status & NAND_STATUS_FAIL) {
84f223713fSKOBAYASHI Yoshitake 		/* uncorrected */
85f223713fSKOBAYASHI Yoshitake 		mtd->ecc_stats.failed++;
86f223713fSKOBAYASHI Yoshitake 	} else if (status & TOSHIBA_NAND_STATUS_REWRITE_RECOMMENDED) {
87f223713fSKOBAYASHI Yoshitake 		/* corrected */
88f223713fSKOBAYASHI Yoshitake 		max_bitflips = mtd->bitflip_threshold;
89f223713fSKOBAYASHI Yoshitake 		mtd->ecc_stats.corrected += max_bitflips;
90f223713fSKOBAYASHI Yoshitake 	}
91f223713fSKOBAYASHI Yoshitake 
92f223713fSKOBAYASHI Yoshitake 	return max_bitflips;
93f223713fSKOBAYASHI Yoshitake }
94f223713fSKOBAYASHI Yoshitake 
95f223713fSKOBAYASHI Yoshitake static int
96b9761687SBoris Brezillon toshiba_nand_read_page_benand(struct nand_chip *chip, uint8_t *buf,
97f223713fSKOBAYASHI Yoshitake 			      int oob_required, int page)
98f223713fSKOBAYASHI Yoshitake {
99f223713fSKOBAYASHI Yoshitake 	int ret;
100f223713fSKOBAYASHI Yoshitake 
101b9761687SBoris Brezillon 	ret = nand_read_page_raw(chip, buf, oob_required, page);
102f223713fSKOBAYASHI Yoshitake 	if (ret)
103f223713fSKOBAYASHI Yoshitake 		return ret;
104f223713fSKOBAYASHI Yoshitake 
105e9836761SMiquel Raynal 	return toshiba_nand_benand_eccstatus(chip);
106f223713fSKOBAYASHI Yoshitake }
107f223713fSKOBAYASHI Yoshitake 
108f223713fSKOBAYASHI Yoshitake static int
109b9761687SBoris Brezillon toshiba_nand_read_subpage_benand(struct nand_chip *chip, uint32_t data_offs,
110f223713fSKOBAYASHI Yoshitake 				 uint32_t readlen, uint8_t *bufpoi, int page)
111f223713fSKOBAYASHI Yoshitake {
112f223713fSKOBAYASHI Yoshitake 	int ret;
113f223713fSKOBAYASHI Yoshitake 
114f223713fSKOBAYASHI Yoshitake 	ret = nand_read_page_op(chip, page, data_offs,
115f223713fSKOBAYASHI Yoshitake 				bufpoi + data_offs, readlen);
116f223713fSKOBAYASHI Yoshitake 	if (ret)
117f223713fSKOBAYASHI Yoshitake 		return ret;
118f223713fSKOBAYASHI Yoshitake 
119e9836761SMiquel Raynal 	return toshiba_nand_benand_eccstatus(chip);
120f223713fSKOBAYASHI Yoshitake }
121f223713fSKOBAYASHI Yoshitake 
122f223713fSKOBAYASHI Yoshitake static void toshiba_nand_benand_init(struct nand_chip *chip)
123f223713fSKOBAYASHI Yoshitake {
124f223713fSKOBAYASHI Yoshitake 	struct mtd_info *mtd = nand_to_mtd(chip);
125f223713fSKOBAYASHI Yoshitake 
126f223713fSKOBAYASHI Yoshitake 	/*
127f223713fSKOBAYASHI Yoshitake 	 * On BENAND, the entire OOB region can be used by the MTD user.
128f223713fSKOBAYASHI Yoshitake 	 * The calculated ECC bytes are stored into other isolated
129f223713fSKOBAYASHI Yoshitake 	 * area which is not accessible to users.
130f223713fSKOBAYASHI Yoshitake 	 * This is why chip->ecc.bytes = 0.
131f223713fSKOBAYASHI Yoshitake 	 */
132f223713fSKOBAYASHI Yoshitake 	chip->ecc.bytes = 0;
133f223713fSKOBAYASHI Yoshitake 	chip->ecc.size = 512;
134f223713fSKOBAYASHI Yoshitake 	chip->ecc.strength = 8;
135f223713fSKOBAYASHI Yoshitake 	chip->ecc.read_page = toshiba_nand_read_page_benand;
136f223713fSKOBAYASHI Yoshitake 	chip->ecc.read_subpage = toshiba_nand_read_subpage_benand;
137f223713fSKOBAYASHI Yoshitake 	chip->ecc.write_page = nand_write_page_raw;
138f223713fSKOBAYASHI Yoshitake 	chip->ecc.read_page_raw = nand_read_page_raw_notsupp;
139f223713fSKOBAYASHI Yoshitake 	chip->ecc.write_page_raw = nand_write_page_raw_notsupp;
140f223713fSKOBAYASHI Yoshitake 
141f223713fSKOBAYASHI Yoshitake 	chip->options |= NAND_SUBPAGE_READ;
142f223713fSKOBAYASHI Yoshitake 
143*1e3b37aaSMiquel Raynal 	mtd_set_ooblayout(mtd, nand_get_large_page_ooblayout());
144f223713fSKOBAYASHI Yoshitake }
145f223713fSKOBAYASHI Yoshitake 
1469b2d61f8SBoris Brezillon static void toshiba_nand_decode_id(struct nand_chip *chip)
1479b2d61f8SBoris Brezillon {
14853576c7bSMiquel Raynal 	struct nand_device *base = &chip->base;
14953576c7bSMiquel Raynal 	struct nand_ecc_props requirements = {};
1509b2d61f8SBoris Brezillon 	struct mtd_info *mtd = nand_to_mtd(chip);
151629a442cSBoris Brezillon 	struct nand_memory_organization *memorg;
152629a442cSBoris Brezillon 
153629a442cSBoris Brezillon 	memorg = nanddev_get_memorg(&chip->base);
1549b2d61f8SBoris Brezillon 
1559b2d61f8SBoris Brezillon 	nand_decode_ext_id(chip);
1569b2d61f8SBoris Brezillon 
1579b2d61f8SBoris Brezillon 	/*
1589b2d61f8SBoris Brezillon 	 * Toshiba 24nm raw SLC (i.e., not BENAND) have 32B OOB per
1599b2d61f8SBoris Brezillon 	 * 512B page. For Toshiba SLC, we decode the 5th/6th byte as
1609b2d61f8SBoris Brezillon 	 * follows:
1619b2d61f8SBoris Brezillon 	 * - ID byte 6, bits[2:0]: 100b -> 43nm, 101b -> 32nm,
1629b2d61f8SBoris Brezillon 	 *                         110b -> 24nm
1639b2d61f8SBoris Brezillon 	 * - ID byte 5, bit[7]:    1 -> BENAND, 0 -> raw SLC
1649b2d61f8SBoris Brezillon 	 */
1659b2d61f8SBoris Brezillon 	if (chip->id.len >= 6 && nand_is_slc(chip) &&
1669b2d61f8SBoris Brezillon 	    (chip->id.data[5] & 0x7) == 0x6 /* 24nm */ &&
167fca88925SYoshio Furuyama 	    !(chip->id.data[4] & TOSHIBA_NAND_ID4_IS_BENAND) /* !BENAND */) {
168629a442cSBoris Brezillon 		memorg->oobsize = 32 * memorg->pagesize >> 9;
169629a442cSBoris Brezillon 		mtd->oobsize = memorg->oobsize;
170629a442cSBoris Brezillon 	}
171fb3bff5bSKOBAYASHI Yoshitake 
172fb3bff5bSKOBAYASHI Yoshitake 	/*
173fb3bff5bSKOBAYASHI Yoshitake 	 * Extract ECC requirements from 6th id byte.
174fb3bff5bSKOBAYASHI Yoshitake 	 * For Toshiba SLC, ecc requrements are as follows:
175fb3bff5bSKOBAYASHI Yoshitake 	 *  - 43nm: 1 bit ECC for each 512Byte is required.
176fb3bff5bSKOBAYASHI Yoshitake 	 *  - 32nm: 4 bit ECC for each 512Byte is required.
177fb3bff5bSKOBAYASHI Yoshitake 	 *  - 24nm: 8 bit ECC for each 512Byte is required.
178fb3bff5bSKOBAYASHI Yoshitake 	 */
179fb3bff5bSKOBAYASHI Yoshitake 	if (chip->id.len >= 6 && nand_is_slc(chip)) {
18053576c7bSMiquel Raynal 		requirements.step_size = 512;
181fb3bff5bSKOBAYASHI Yoshitake 		switch (chip->id.data[5] & 0x7) {
182fb3bff5bSKOBAYASHI Yoshitake 		case 0x4:
18353576c7bSMiquel Raynal 			requirements.strength = 1;
184fb3bff5bSKOBAYASHI Yoshitake 			break;
185fb3bff5bSKOBAYASHI Yoshitake 		case 0x5:
18653576c7bSMiquel Raynal 			requirements.strength = 4;
187fb3bff5bSKOBAYASHI Yoshitake 			break;
188fb3bff5bSKOBAYASHI Yoshitake 		case 0x6:
18953576c7bSMiquel Raynal 			requirements.strength = 8;
190fb3bff5bSKOBAYASHI Yoshitake 			break;
191fb3bff5bSKOBAYASHI Yoshitake 		default:
192fb3bff5bSKOBAYASHI Yoshitake 			WARN(1, "Could not get ECC info");
19353576c7bSMiquel Raynal 			requirements.step_size = 0;
194fb3bff5bSKOBAYASHI Yoshitake 			break;
195fb3bff5bSKOBAYASHI Yoshitake 		}
196fb3bff5bSKOBAYASHI Yoshitake 	}
19753576c7bSMiquel Raynal 
19853576c7bSMiquel Raynal 	nanddev_set_ecc_requirements(base, &requirements);
1999b2d61f8SBoris Brezillon }
2009b2d61f8SBoris Brezillon 
2012f36bae1SMiquel Raynal static int
2022f36bae1SMiquel Raynal tc58teg5dclta00_choose_interface_config(struct nand_chip *chip,
2032f36bae1SMiquel Raynal 					struct nand_interface_config *iface)
2042f36bae1SMiquel Raynal {
2052f36bae1SMiquel Raynal 	onfi_fill_interface_config(chip, iface, NAND_SDR_IFACE, 5);
2062f36bae1SMiquel Raynal 
2072f36bae1SMiquel Raynal 	return nand_choose_best_sdr_timings(chip, iface, NULL);
2082f36bae1SMiquel Raynal }
2092f36bae1SMiquel Raynal 
2100d0245b9SMiquel Raynal static int
2110d0245b9SMiquel Raynal tc58nvg0s3e_choose_interface_config(struct nand_chip *chip,
2120d0245b9SMiquel Raynal 				    struct nand_interface_config *iface)
2130d0245b9SMiquel Raynal {
2140d0245b9SMiquel Raynal 	onfi_fill_interface_config(chip, iface, NAND_SDR_IFACE, 2);
2150d0245b9SMiquel Raynal 
2160d0245b9SMiquel Raynal 	return nand_choose_best_sdr_timings(chip, iface, NULL);
2170d0245b9SMiquel Raynal }
2180d0245b9SMiquel Raynal 
2196d469f86SRickard x Andersson static int
2206d469f86SRickard x Andersson th58nvg2s3hbai4_choose_interface_config(struct nand_chip *chip,
2216d469f86SRickard x Andersson 					struct nand_interface_config *iface)
2226d469f86SRickard x Andersson {
2236d469f86SRickard x Andersson 	struct nand_sdr_timings *sdr = &iface->timings.sdr;
2246d469f86SRickard x Andersson 
2256d469f86SRickard x Andersson 	/* Start with timings from the closest timing mode, mode 4. */
2266d469f86SRickard x Andersson 	onfi_fill_interface_config(chip, iface, NAND_SDR_IFACE, 4);
2276d469f86SRickard x Andersson 
2286d469f86SRickard x Andersson 	/* Patch timings that differ from mode 4. */
2296d469f86SRickard x Andersson 	sdr->tALS_min = 12000;
2306d469f86SRickard x Andersson 	sdr->tCHZ_max = 20000;
2316d469f86SRickard x Andersson 	sdr->tCLS_min = 12000;
2326d469f86SRickard x Andersson 	sdr->tCOH_min = 0;
2336d469f86SRickard x Andersson 	sdr->tDS_min = 12000;
2346d469f86SRickard x Andersson 	sdr->tRHOH_min = 25000;
2356d469f86SRickard x Andersson 	sdr->tRHW_min = 30000;
2366d469f86SRickard x Andersson 	sdr->tRHZ_max = 60000;
2376d469f86SRickard x Andersson 	sdr->tWHR_min = 60000;
2386d469f86SRickard x Andersson 
2396d469f86SRickard x Andersson 	/* Patch timings not part of onfi timing mode. */
2406d469f86SRickard x Andersson 	sdr->tPROG_max = 700000000;
2416d469f86SRickard x Andersson 	sdr->tBERS_max = 5000000000;
2426d469f86SRickard x Andersson 
2436d469f86SRickard x Andersson 	return nand_choose_best_sdr_timings(chip, iface, sdr);
2446d469f86SRickard x Andersson }
2456d469f86SRickard x Andersson 
2465338ef99SBoris Brezillon static int tc58teg5dclta00_init(struct nand_chip *chip)
2475338ef99SBoris Brezillon {
248d652f3a5SBoris Brezillon 	struct mtd_info *mtd = nand_to_mtd(chip);
249d652f3a5SBoris Brezillon 
2502f36bae1SMiquel Raynal 	chip->ops.choose_interface_config =
2512f36bae1SMiquel Raynal 		&tc58teg5dclta00_choose_interface_config;
2525338ef99SBoris Brezillon 	chip->options |= NAND_NEED_SCRAMBLING;
253d652f3a5SBoris Brezillon 	mtd_set_pairing_scheme(mtd, &dist3_pairing_scheme);
2545338ef99SBoris Brezillon 
2555338ef99SBoris Brezillon 	return 0;
2565338ef99SBoris Brezillon }
2575338ef99SBoris Brezillon 
2580d0245b9SMiquel Raynal static int tc58nvg0s3e_init(struct nand_chip *chip)
2590d0245b9SMiquel Raynal {
2600d0245b9SMiquel Raynal 	chip->ops.choose_interface_config =
2610d0245b9SMiquel Raynal 		&tc58nvg0s3e_choose_interface_config;
2620d0245b9SMiquel Raynal 
2630d0245b9SMiquel Raynal 	return 0;
2640d0245b9SMiquel Raynal }
2650d0245b9SMiquel Raynal 
2666d469f86SRickard x Andersson static int th58nvg2s3hbai4_init(struct nand_chip *chip)
2676d469f86SRickard x Andersson {
2686d469f86SRickard x Andersson 	chip->ops.choose_interface_config =
2696d469f86SRickard x Andersson 		&th58nvg2s3hbai4_choose_interface_config;
2706d469f86SRickard x Andersson 
2716d469f86SRickard x Andersson 	return 0;
2726d469f86SRickard x Andersson }
2736d469f86SRickard x Andersson 
2749b2d61f8SBoris Brezillon static int toshiba_nand_init(struct nand_chip *chip)
2759b2d61f8SBoris Brezillon {
2769b2d61f8SBoris Brezillon 	if (nand_is_slc(chip))
277bb592548SFrieder Schrempf 		chip->options |= NAND_BBM_FIRSTPAGE | NAND_BBM_SECONDPAGE;
2789b2d61f8SBoris Brezillon 
279f223713fSKOBAYASHI Yoshitake 	/* Check that chip is BENAND and ECC mode is on-die */
280bace41f8SMiquel Raynal 	if (nand_is_slc(chip) &&
281bace41f8SMiquel Raynal 	    chip->ecc.engine_type == NAND_ECC_ENGINE_TYPE_ON_DIE &&
282f223713fSKOBAYASHI Yoshitake 	    chip->id.data[4] & TOSHIBA_NAND_ID4_IS_BENAND)
283f223713fSKOBAYASHI Yoshitake 		toshiba_nand_benand_init(chip);
284f223713fSKOBAYASHI Yoshitake 
2855338ef99SBoris Brezillon 	if (!strcmp("TC58TEG5DCLTA00", chip->parameters.model))
2865338ef99SBoris Brezillon 		tc58teg5dclta00_init(chip);
2870d0245b9SMiquel Raynal 	if (!strncmp("TC58NVG0S3E", chip->parameters.model,
2880d0245b9SMiquel Raynal 		     sizeof("TC58NVG0S3E") - 1))
2890d0245b9SMiquel Raynal 		tc58nvg0s3e_init(chip);
2906d469f86SRickard x Andersson 	if (!strncmp("TH58NVG2S3HBAI4", chip->parameters.model,
2916d469f86SRickard x Andersson 		     sizeof("TH58NVG2S3HBAI4") - 1))
2926d469f86SRickard x Andersson 		th58nvg2s3hbai4_init(chip);
2935338ef99SBoris Brezillon 
2949b2d61f8SBoris Brezillon 	return 0;
2959b2d61f8SBoris Brezillon }
2969b2d61f8SBoris Brezillon 
2979b2d61f8SBoris Brezillon const struct nand_manufacturer_ops toshiba_nand_manuf_ops = {
2989b2d61f8SBoris Brezillon 	.detect = toshiba_nand_decode_id,
2999b2d61f8SBoris Brezillon 	.init = toshiba_nand_init,
3009b2d61f8SBoris Brezillon };
301