xref: /linux/drivers/mtd/nand/raw/nand_hynix.c (revision cbecf716ca618fd44feda6bd9a64a8179d031fc5)
1c942fddfSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later
201389b6bSBoris Brezillon /*
301389b6bSBoris Brezillon  * Copyright (C) 2017 Free Electrons
401389b6bSBoris Brezillon  * Copyright (C) 2017 NextThing Co
501389b6bSBoris Brezillon  *
601389b6bSBoris Brezillon  * Author: Boris Brezillon <boris.brezillon@free-electrons.com>
701389b6bSBoris Brezillon  */
801389b6bSBoris Brezillon 
978f3482dSBoris Brezillon #include <linux/sizes.h>
10626994e0SBoris Brezillon #include <linux/slab.h>
11626994e0SBoris Brezillon 
12348d56a8SBoris Brezillon #include "internals.h"
13348d56a8SBoris Brezillon 
14626994e0SBoris Brezillon #define NAND_HYNIX_CMD_SET_PARAMS	0x36
15626994e0SBoris Brezillon #define NAND_HYNIX_CMD_APPLY_PARAMS	0x16
16626994e0SBoris Brezillon 
17626994e0SBoris Brezillon #define NAND_HYNIX_1XNM_RR_REPEAT	8
18626994e0SBoris Brezillon 
19626994e0SBoris Brezillon /**
20626994e0SBoris Brezillon  * struct hynix_read_retry - read-retry data
21626994e0SBoris Brezillon  * @nregs: number of register to set when applying a new read-retry mode
22626994e0SBoris Brezillon  * @regs: register offsets (NAND chip dependent)
23626994e0SBoris Brezillon  * @values: array of values to set in registers. The array size is equal to
24626994e0SBoris Brezillon  *	    (nregs * nmodes)
25626994e0SBoris Brezillon  */
26626994e0SBoris Brezillon struct hynix_read_retry {
27626994e0SBoris Brezillon 	int nregs;
28626994e0SBoris Brezillon 	const u8 *regs;
2949f1c330SGustavo A. R. Silva 	u8 values[];
30626994e0SBoris Brezillon };
31626994e0SBoris Brezillon 
32626994e0SBoris Brezillon /**
33626994e0SBoris Brezillon  * struct hynix_nand - private Hynix NAND struct
34626994e0SBoris Brezillon  * @nand_technology: manufacturing process expressed in picometer
35626994e0SBoris Brezillon  * @read_retry: read-retry information
36626994e0SBoris Brezillon  */
37626994e0SBoris Brezillon struct hynix_nand {
38626994e0SBoris Brezillon 	const struct hynix_read_retry *read_retry;
39626994e0SBoris Brezillon };
40626994e0SBoris Brezillon 
41626994e0SBoris Brezillon /**
42626994e0SBoris Brezillon  * struct hynix_read_retry_otp - structure describing how the read-retry OTP
43626994e0SBoris Brezillon  *				 area
44626994e0SBoris Brezillon  * @nregs: number of hynix private registers to set before reading the reading
45626994e0SBoris Brezillon  *	   the OTP area
46626994e0SBoris Brezillon  * @regs: registers that should be configured
47626994e0SBoris Brezillon  * @values: values that should be set in regs
48626994e0SBoris Brezillon  * @page: the address to pass to the READ_PAGE command. Depends on the NAND
49626994e0SBoris Brezillon  *	  chip
50626994e0SBoris Brezillon  * @size: size of the read-retry OTP section
51626994e0SBoris Brezillon  */
52626994e0SBoris Brezillon struct hynix_read_retry_otp {
53626994e0SBoris Brezillon 	int nregs;
54626994e0SBoris Brezillon 	const u8 *regs;
55626994e0SBoris Brezillon 	const u8 *values;
56626994e0SBoris Brezillon 	int page;
57626994e0SBoris Brezillon 	int size;
58626994e0SBoris Brezillon };
5901389b6bSBoris Brezillon 
6078f3482dSBoris Brezillon static bool hynix_nand_has_valid_jedecid(struct nand_chip *chip)
6101389b6bSBoris Brezillon {
6297d90da8SBoris Brezillon 	u8 jedecid[5] = { };
6397d90da8SBoris Brezillon 	int ret;
6497d90da8SBoris Brezillon 
6597d90da8SBoris Brezillon 	ret = nand_readid_op(chip, 0x40, jedecid, sizeof(jedecid));
6697d90da8SBoris Brezillon 	if (ret)
6797d90da8SBoris Brezillon 		return false;
6897d90da8SBoris Brezillon 
6997d90da8SBoris Brezillon 	return !strncmp("JEDEC", jedecid, sizeof(jedecid));
7097d90da8SBoris Brezillon }
7197d90da8SBoris Brezillon 
7297d90da8SBoris Brezillon static int hynix_nand_cmd_op(struct nand_chip *chip, u8 cmd)
7397d90da8SBoris Brezillon {
74f2abfeb2SBoris Brezillon 	if (nand_has_exec_op(chip)) {
758878b126SMiquel Raynal 		struct nand_op_instr instrs[] = {
768878b126SMiquel Raynal 			NAND_OP_CMD(cmd, 0),
778878b126SMiquel Raynal 		};
78ae2294b1SBoris Brezillon 		struct nand_operation op = NAND_OPERATION(chip->cur_cs, instrs);
798878b126SMiquel Raynal 
808878b126SMiquel Raynal 		return nand_exec_op(chip, &op);
818878b126SMiquel Raynal 	}
828878b126SMiquel Raynal 
83bf6065c6SBoris Brezillon 	chip->legacy.cmdfunc(chip, cmd, -1, -1);
8401389b6bSBoris Brezillon 
8597d90da8SBoris Brezillon 	return 0;
8697d90da8SBoris Brezillon }
8797d90da8SBoris Brezillon 
8897d90da8SBoris Brezillon static int hynix_nand_reg_write_op(struct nand_chip *chip, u8 addr, u8 val)
8997d90da8SBoris Brezillon {
9097d90da8SBoris Brezillon 	u16 column = ((u16)addr << 8) | addr;
9197d90da8SBoris Brezillon 
92f2abfeb2SBoris Brezillon 	if (nand_has_exec_op(chip)) {
9320366e19SBoris Brezillon 		struct nand_op_instr instrs[] = {
9420366e19SBoris Brezillon 			NAND_OP_ADDR(1, &addr, 0),
9520366e19SBoris Brezillon 			NAND_OP_8BIT_DATA_OUT(1, &val, 0),
9620366e19SBoris Brezillon 		};
97ae2294b1SBoris Brezillon 		struct nand_operation op = NAND_OPERATION(chip->cur_cs, instrs);
9820366e19SBoris Brezillon 
9920366e19SBoris Brezillon 		return nand_exec_op(chip, &op);
10020366e19SBoris Brezillon 	}
10120366e19SBoris Brezillon 
102bf6065c6SBoris Brezillon 	chip->legacy.cmdfunc(chip, NAND_CMD_NONE, column, -1);
103716bbbabSBoris Brezillon 	chip->legacy.write_byte(chip, val);
10497d90da8SBoris Brezillon 
10597d90da8SBoris Brezillon 	return 0;
10678f3482dSBoris Brezillon }
10701389b6bSBoris Brezillon 
1082e7f1cecSBoris Brezillon static int hynix_nand_setup_read_retry(struct nand_chip *chip, int retry_mode)
109626994e0SBoris Brezillon {
110626994e0SBoris Brezillon 	struct hynix_nand *hynix = nand_get_manufacturer_data(chip);
111626994e0SBoris Brezillon 	const u8 *values;
11297d90da8SBoris Brezillon 	int i, ret;
113626994e0SBoris Brezillon 
114626994e0SBoris Brezillon 	values = hynix->read_retry->values +
115626994e0SBoris Brezillon 		 (retry_mode * hynix->read_retry->nregs);
116626994e0SBoris Brezillon 
117626994e0SBoris Brezillon 	/* Enter 'Set Hynix Parameters' mode */
11897d90da8SBoris Brezillon 	ret = hynix_nand_cmd_op(chip, NAND_HYNIX_CMD_SET_PARAMS);
11997d90da8SBoris Brezillon 	if (ret)
12097d90da8SBoris Brezillon 		return ret;
121626994e0SBoris Brezillon 
122626994e0SBoris Brezillon 	/*
123626994e0SBoris Brezillon 	 * Configure the NAND in the requested read-retry mode.
124626994e0SBoris Brezillon 	 * This is done by setting pre-defined values in internal NAND
125626994e0SBoris Brezillon 	 * registers.
126626994e0SBoris Brezillon 	 *
127626994e0SBoris Brezillon 	 * The set of registers is NAND specific, and the values are either
128626994e0SBoris Brezillon 	 * predefined or extracted from an OTP area on the NAND (values are
129626994e0SBoris Brezillon 	 * probably tweaked at production in this case).
130626994e0SBoris Brezillon 	 */
131626994e0SBoris Brezillon 	for (i = 0; i < hynix->read_retry->nregs; i++) {
13297d90da8SBoris Brezillon 		ret = hynix_nand_reg_write_op(chip, hynix->read_retry->regs[i],
13397d90da8SBoris Brezillon 					      values[i]);
13497d90da8SBoris Brezillon 		if (ret)
13597d90da8SBoris Brezillon 			return ret;
136626994e0SBoris Brezillon 	}
137626994e0SBoris Brezillon 
138626994e0SBoris Brezillon 	/* Apply the new settings. */
13997d90da8SBoris Brezillon 	return hynix_nand_cmd_op(chip, NAND_HYNIX_CMD_APPLY_PARAMS);
140626994e0SBoris Brezillon }
141626994e0SBoris Brezillon 
142626994e0SBoris Brezillon /**
143626994e0SBoris Brezillon  * hynix_get_majority - get the value that is occurring the most in a given
144626994e0SBoris Brezillon  *			set of values
145626994e0SBoris Brezillon  * @in: the array of values to test
146626994e0SBoris Brezillon  * @repeat: the size of the in array
147626994e0SBoris Brezillon  * @out: pointer used to store the output value
148626994e0SBoris Brezillon  *
149626994e0SBoris Brezillon  * This function implements the 'majority check' logic that is supposed to
150626994e0SBoris Brezillon  * overcome the unreliability of MLC NANDs when reading the OTP area storing
151626994e0SBoris Brezillon  * the read-retry parameters.
152626994e0SBoris Brezillon  *
153626994e0SBoris Brezillon  * It's based on a pretty simple assumption: if we repeat the same value
154626994e0SBoris Brezillon  * several times and then take the one that is occurring the most, we should
155626994e0SBoris Brezillon  * find the correct value.
156626994e0SBoris Brezillon  * Let's hope this dummy algorithm prevents us from losing the read-retry
157626994e0SBoris Brezillon  * parameters.
158626994e0SBoris Brezillon  */
159626994e0SBoris Brezillon static int hynix_get_majority(const u8 *in, int repeat, u8 *out)
160626994e0SBoris Brezillon {
161626994e0SBoris Brezillon 	int i, j, half = repeat / 2;
162626994e0SBoris Brezillon 
163626994e0SBoris Brezillon 	/*
164626994e0SBoris Brezillon 	 * We only test the first half of the in array because we must ensure
165626994e0SBoris Brezillon 	 * that the value is at least occurring repeat / 2 times.
166626994e0SBoris Brezillon 	 *
167626994e0SBoris Brezillon 	 * This loop is suboptimal since we may count the occurrences of the
168626994e0SBoris Brezillon 	 * same value several time, but we are doing that on small sets, which
169626994e0SBoris Brezillon 	 * makes it acceptable.
170626994e0SBoris Brezillon 	 */
171626994e0SBoris Brezillon 	for (i = 0; i < half; i++) {
172626994e0SBoris Brezillon 		int cnt = 0;
173626994e0SBoris Brezillon 		u8 val = in[i];
174626994e0SBoris Brezillon 
175626994e0SBoris Brezillon 		/* Count all values that are matching the one at index i. */
176626994e0SBoris Brezillon 		for (j = i + 1; j < repeat; j++) {
177626994e0SBoris Brezillon 			if (in[j] == val)
178626994e0SBoris Brezillon 				cnt++;
179626994e0SBoris Brezillon 		}
180626994e0SBoris Brezillon 
181626994e0SBoris Brezillon 		/* We found a value occurring more than repeat / 2. */
182626994e0SBoris Brezillon 		if (cnt > half) {
183626994e0SBoris Brezillon 			*out = val;
184626994e0SBoris Brezillon 			return 0;
185626994e0SBoris Brezillon 		}
186626994e0SBoris Brezillon 	}
187626994e0SBoris Brezillon 
188626994e0SBoris Brezillon 	return -EIO;
189626994e0SBoris Brezillon }
190626994e0SBoris Brezillon 
191626994e0SBoris Brezillon static int hynix_read_rr_otp(struct nand_chip *chip,
192626994e0SBoris Brezillon 			     const struct hynix_read_retry_otp *info,
193626994e0SBoris Brezillon 			     void *buf)
194626994e0SBoris Brezillon {
19597d90da8SBoris Brezillon 	int i, ret;
196626994e0SBoris Brezillon 
19797d90da8SBoris Brezillon 	ret = nand_reset_op(chip);
19897d90da8SBoris Brezillon 	if (ret)
19997d90da8SBoris Brezillon 		return ret;
200626994e0SBoris Brezillon 
20197d90da8SBoris Brezillon 	ret = hynix_nand_cmd_op(chip, NAND_HYNIX_CMD_SET_PARAMS);
20297d90da8SBoris Brezillon 	if (ret)
20397d90da8SBoris Brezillon 		return ret;
204626994e0SBoris Brezillon 
205626994e0SBoris Brezillon 	for (i = 0; i < info->nregs; i++) {
20697d90da8SBoris Brezillon 		ret = hynix_nand_reg_write_op(chip, info->regs[i],
20797d90da8SBoris Brezillon 					      info->values[i]);
20897d90da8SBoris Brezillon 		if (ret)
20997d90da8SBoris Brezillon 			return ret;
210626994e0SBoris Brezillon 	}
211626994e0SBoris Brezillon 
21297d90da8SBoris Brezillon 	ret = hynix_nand_cmd_op(chip, NAND_HYNIX_CMD_APPLY_PARAMS);
21397d90da8SBoris Brezillon 	if (ret)
21497d90da8SBoris Brezillon 		return ret;
215626994e0SBoris Brezillon 
216626994e0SBoris Brezillon 	/* Sequence to enter OTP mode? */
21797d90da8SBoris Brezillon 	ret = hynix_nand_cmd_op(chip, 0x17);
21897d90da8SBoris Brezillon 	if (ret)
21997d90da8SBoris Brezillon 		return ret;
22097d90da8SBoris Brezillon 
22197d90da8SBoris Brezillon 	ret = hynix_nand_cmd_op(chip, 0x4);
22297d90da8SBoris Brezillon 	if (ret)
22397d90da8SBoris Brezillon 		return ret;
22497d90da8SBoris Brezillon 
22597d90da8SBoris Brezillon 	ret = hynix_nand_cmd_op(chip, 0x19);
22697d90da8SBoris Brezillon 	if (ret)
22797d90da8SBoris Brezillon 		return ret;
228626994e0SBoris Brezillon 
229626994e0SBoris Brezillon 	/* Now read the page */
23097d90da8SBoris Brezillon 	ret = nand_read_page_op(chip, info->page, 0, buf, info->size);
23197d90da8SBoris Brezillon 	if (ret)
23297d90da8SBoris Brezillon 		return ret;
233626994e0SBoris Brezillon 
234626994e0SBoris Brezillon 	/* Put everything back to normal */
23597d90da8SBoris Brezillon 	ret = nand_reset_op(chip);
23697d90da8SBoris Brezillon 	if (ret)
23797d90da8SBoris Brezillon 		return ret;
238626994e0SBoris Brezillon 
23997d90da8SBoris Brezillon 	ret = hynix_nand_cmd_op(chip, NAND_HYNIX_CMD_SET_PARAMS);
24097d90da8SBoris Brezillon 	if (ret)
24197d90da8SBoris Brezillon 		return ret;
24297d90da8SBoris Brezillon 
24397d90da8SBoris Brezillon 	ret = hynix_nand_reg_write_op(chip, 0x38, 0);
24497d90da8SBoris Brezillon 	if (ret)
24597d90da8SBoris Brezillon 		return ret;
24697d90da8SBoris Brezillon 
24797d90da8SBoris Brezillon 	ret = hynix_nand_cmd_op(chip, NAND_HYNIX_CMD_APPLY_PARAMS);
24897d90da8SBoris Brezillon 	if (ret)
24997d90da8SBoris Brezillon 		return ret;
25097d90da8SBoris Brezillon 
25197d90da8SBoris Brezillon 	return nand_read_page_op(chip, 0, 0, NULL, 0);
252626994e0SBoris Brezillon }
253626994e0SBoris Brezillon 
254626994e0SBoris Brezillon #define NAND_HYNIX_1XNM_RR_COUNT_OFFS				0
255626994e0SBoris Brezillon #define NAND_HYNIX_1XNM_RR_REG_COUNT_OFFS			8
256626994e0SBoris Brezillon #define NAND_HYNIX_1XNM_RR_SET_OFFS(x, setsize, inv)		\
257626994e0SBoris Brezillon 	(16 + ((((x) * 2) + ((inv) ? 1 : 0)) * (setsize)))
258626994e0SBoris Brezillon 
259626994e0SBoris Brezillon static int hynix_mlc_1xnm_rr_value(const u8 *buf, int nmodes, int nregs,
260626994e0SBoris Brezillon 				   int mode, int reg, bool inv, u8 *val)
261626994e0SBoris Brezillon {
262626994e0SBoris Brezillon 	u8 tmp[NAND_HYNIX_1XNM_RR_REPEAT];
263626994e0SBoris Brezillon 	int val_offs = (mode * nregs) + reg;
264626994e0SBoris Brezillon 	int set_size = nmodes * nregs;
265626994e0SBoris Brezillon 	int i, ret;
266626994e0SBoris Brezillon 
267626994e0SBoris Brezillon 	for (i = 0; i < NAND_HYNIX_1XNM_RR_REPEAT; i++) {
268626994e0SBoris Brezillon 		int set_offs = NAND_HYNIX_1XNM_RR_SET_OFFS(i, set_size, inv);
269626994e0SBoris Brezillon 
270626994e0SBoris Brezillon 		tmp[i] = buf[val_offs + set_offs];
271626994e0SBoris Brezillon 	}
272626994e0SBoris Brezillon 
273626994e0SBoris Brezillon 	ret = hynix_get_majority(tmp, NAND_HYNIX_1XNM_RR_REPEAT, val);
274626994e0SBoris Brezillon 	if (ret)
275626994e0SBoris Brezillon 		return ret;
276626994e0SBoris Brezillon 
277626994e0SBoris Brezillon 	if (inv)
278626994e0SBoris Brezillon 		*val = ~*val;
279626994e0SBoris Brezillon 
280626994e0SBoris Brezillon 	return 0;
281626994e0SBoris Brezillon }
282626994e0SBoris Brezillon 
283626994e0SBoris Brezillon static u8 hynix_1xnm_mlc_read_retry_regs[] = {
284626994e0SBoris Brezillon 	0xcc, 0xbf, 0xaa, 0xab, 0xcd, 0xad, 0xae, 0xaf
285626994e0SBoris Brezillon };
286626994e0SBoris Brezillon 
287626994e0SBoris Brezillon static int hynix_mlc_1xnm_rr_init(struct nand_chip *chip,
288626994e0SBoris Brezillon 				  const struct hynix_read_retry_otp *info)
289626994e0SBoris Brezillon {
290626994e0SBoris Brezillon 	struct hynix_nand *hynix = nand_get_manufacturer_data(chip);
291626994e0SBoris Brezillon 	struct hynix_read_retry *rr = NULL;
292626994e0SBoris Brezillon 	int ret, i, j;
293626994e0SBoris Brezillon 	u8 nregs, nmodes;
294626994e0SBoris Brezillon 	u8 *buf;
295626994e0SBoris Brezillon 
296626994e0SBoris Brezillon 	buf = kmalloc(info->size, GFP_KERNEL);
297626994e0SBoris Brezillon 	if (!buf)
298626994e0SBoris Brezillon 		return -ENOMEM;
299626994e0SBoris Brezillon 
300626994e0SBoris Brezillon 	ret = hynix_read_rr_otp(chip, info, buf);
301626994e0SBoris Brezillon 	if (ret)
302626994e0SBoris Brezillon 		goto out;
303626994e0SBoris Brezillon 
304626994e0SBoris Brezillon 	ret = hynix_get_majority(buf, NAND_HYNIX_1XNM_RR_REPEAT,
305626994e0SBoris Brezillon 				 &nmodes);
306626994e0SBoris Brezillon 	if (ret)
307626994e0SBoris Brezillon 		goto out;
308626994e0SBoris Brezillon 
309626994e0SBoris Brezillon 	ret = hynix_get_majority(buf + NAND_HYNIX_1XNM_RR_REPEAT,
310626994e0SBoris Brezillon 				 NAND_HYNIX_1XNM_RR_REPEAT,
311626994e0SBoris Brezillon 				 &nregs);
312626994e0SBoris Brezillon 	if (ret)
313626994e0SBoris Brezillon 		goto out;
314626994e0SBoris Brezillon 
315626994e0SBoris Brezillon 	rr = kzalloc(sizeof(*rr) + (nregs * nmodes), GFP_KERNEL);
3164ca8c1d4SDan Carpenter 	if (!rr) {
3174ca8c1d4SDan Carpenter 		ret = -ENOMEM;
318626994e0SBoris Brezillon 		goto out;
3194ca8c1d4SDan Carpenter 	}
320626994e0SBoris Brezillon 
321626994e0SBoris Brezillon 	for (i = 0; i < nmodes; i++) {
322626994e0SBoris Brezillon 		for (j = 0; j < nregs; j++) {
323626994e0SBoris Brezillon 			u8 *val = rr->values + (i * nregs);
324626994e0SBoris Brezillon 
325626994e0SBoris Brezillon 			ret = hynix_mlc_1xnm_rr_value(buf, nmodes, nregs, i, j,
326626994e0SBoris Brezillon 						      false, val);
327626994e0SBoris Brezillon 			if (!ret)
328626994e0SBoris Brezillon 				continue;
329626994e0SBoris Brezillon 
330626994e0SBoris Brezillon 			ret = hynix_mlc_1xnm_rr_value(buf, nmodes, nregs, i, j,
331626994e0SBoris Brezillon 						      true, val);
332626994e0SBoris Brezillon 			if (ret)
333626994e0SBoris Brezillon 				goto out;
334626994e0SBoris Brezillon 		}
335626994e0SBoris Brezillon 	}
336626994e0SBoris Brezillon 
337626994e0SBoris Brezillon 	rr->nregs = nregs;
338626994e0SBoris Brezillon 	rr->regs = hynix_1xnm_mlc_read_retry_regs;
339626994e0SBoris Brezillon 	hynix->read_retry = rr;
3408e8b2706SMiquel Raynal 	chip->ops.setup_read_retry = hynix_nand_setup_read_retry;
341626994e0SBoris Brezillon 	chip->read_retries = nmodes;
342626994e0SBoris Brezillon 
343626994e0SBoris Brezillon out:
344626994e0SBoris Brezillon 	kfree(buf);
345626994e0SBoris Brezillon 
346626994e0SBoris Brezillon 	if (ret)
347626994e0SBoris Brezillon 		kfree(rr);
348626994e0SBoris Brezillon 
349626994e0SBoris Brezillon 	return ret;
350626994e0SBoris Brezillon }
351626994e0SBoris Brezillon 
352626994e0SBoris Brezillon static const u8 hynix_mlc_1xnm_rr_otp_regs[] = { 0x38 };
353626994e0SBoris Brezillon static const u8 hynix_mlc_1xnm_rr_otp_values[] = { 0x52 };
354626994e0SBoris Brezillon 
355626994e0SBoris Brezillon static const struct hynix_read_retry_otp hynix_mlc_1xnm_rr_otps[] = {
356626994e0SBoris Brezillon 	{
357626994e0SBoris Brezillon 		.nregs = ARRAY_SIZE(hynix_mlc_1xnm_rr_otp_regs),
358626994e0SBoris Brezillon 		.regs = hynix_mlc_1xnm_rr_otp_regs,
359626994e0SBoris Brezillon 		.values = hynix_mlc_1xnm_rr_otp_values,
360626994e0SBoris Brezillon 		.page = 0x21f,
361626994e0SBoris Brezillon 		.size = 784
362626994e0SBoris Brezillon 	},
363626994e0SBoris Brezillon 	{
364626994e0SBoris Brezillon 		.nregs = ARRAY_SIZE(hynix_mlc_1xnm_rr_otp_regs),
365626994e0SBoris Brezillon 		.regs = hynix_mlc_1xnm_rr_otp_regs,
366626994e0SBoris Brezillon 		.values = hynix_mlc_1xnm_rr_otp_values,
367626994e0SBoris Brezillon 		.page = 0x200,
368626994e0SBoris Brezillon 		.size = 528,
369626994e0SBoris Brezillon 	},
370626994e0SBoris Brezillon };
371626994e0SBoris Brezillon 
372626994e0SBoris Brezillon static int hynix_nand_rr_init(struct nand_chip *chip)
373626994e0SBoris Brezillon {
374626994e0SBoris Brezillon 	int i, ret = 0;
375626994e0SBoris Brezillon 	bool valid_jedecid;
376626994e0SBoris Brezillon 
377626994e0SBoris Brezillon 	valid_jedecid = hynix_nand_has_valid_jedecid(chip);
378626994e0SBoris Brezillon 
379626994e0SBoris Brezillon 	/*
380626994e0SBoris Brezillon 	 * We only support read-retry for 1xnm NANDs, and those NANDs all
381626994e0SBoris Brezillon 	 * expose a valid JEDEC ID.
382626994e0SBoris Brezillon 	 */
383626994e0SBoris Brezillon 	if (valid_jedecid) {
384626994e0SBoris Brezillon 		u8 nand_tech = chip->id.data[5] >> 4;
385626994e0SBoris Brezillon 
386626994e0SBoris Brezillon 		/* 1xnm technology */
387626994e0SBoris Brezillon 		if (nand_tech == 4) {
388626994e0SBoris Brezillon 			for (i = 0; i < ARRAY_SIZE(hynix_mlc_1xnm_rr_otps);
389626994e0SBoris Brezillon 			     i++) {
390626994e0SBoris Brezillon 				/*
391626994e0SBoris Brezillon 				 * FIXME: Hynix recommend to copy the
392626994e0SBoris Brezillon 				 * read-retry OTP area into a normal page.
393626994e0SBoris Brezillon 				 */
394626994e0SBoris Brezillon 				ret = hynix_mlc_1xnm_rr_init(chip,
395626994e0SBoris Brezillon 						hynix_mlc_1xnm_rr_otps);
396626994e0SBoris Brezillon 				if (!ret)
397626994e0SBoris Brezillon 					break;
398626994e0SBoris Brezillon 			}
399626994e0SBoris Brezillon 		}
400626994e0SBoris Brezillon 	}
401626994e0SBoris Brezillon 
402626994e0SBoris Brezillon 	if (ret)
403626994e0SBoris Brezillon 		pr_warn("failed to initialize read-retry infrastructure");
404626994e0SBoris Brezillon 
405626994e0SBoris Brezillon 	return 0;
406626994e0SBoris Brezillon }
407626994e0SBoris Brezillon 
40878f3482dSBoris Brezillon static void hynix_nand_extract_oobsize(struct nand_chip *chip,
40978f3482dSBoris Brezillon 				       bool valid_jedecid)
41078f3482dSBoris Brezillon {
41178f3482dSBoris Brezillon 	struct mtd_info *mtd = nand_to_mtd(chip);
412629a442cSBoris Brezillon 	struct nand_memory_organization *memorg;
41378f3482dSBoris Brezillon 	u8 oobsize;
41478f3482dSBoris Brezillon 
415629a442cSBoris Brezillon 	memorg = nanddev_get_memorg(&chip->base);
416629a442cSBoris Brezillon 
41778f3482dSBoris Brezillon 	oobsize = ((chip->id.data[3] >> 2) & 0x3) |
41878f3482dSBoris Brezillon 		  ((chip->id.data[3] >> 4) & 0x4);
41978f3482dSBoris Brezillon 
42078f3482dSBoris Brezillon 	if (valid_jedecid) {
42178f3482dSBoris Brezillon 		switch (oobsize) {
42278f3482dSBoris Brezillon 		case 0:
423629a442cSBoris Brezillon 			memorg->oobsize = 2048;
42478f3482dSBoris Brezillon 			break;
42578f3482dSBoris Brezillon 		case 1:
426629a442cSBoris Brezillon 			memorg->oobsize = 1664;
42778f3482dSBoris Brezillon 			break;
42878f3482dSBoris Brezillon 		case 2:
429629a442cSBoris Brezillon 			memorg->oobsize = 1024;
43078f3482dSBoris Brezillon 			break;
43178f3482dSBoris Brezillon 		case 3:
432629a442cSBoris Brezillon 			memorg->oobsize = 640;
43378f3482dSBoris Brezillon 			break;
43478f3482dSBoris Brezillon 		default:
43578f3482dSBoris Brezillon 			/*
43678f3482dSBoris Brezillon 			 * We should never reach this case, but if that
43778f3482dSBoris Brezillon 			 * happens, this probably means Hynix decided to use
43878f3482dSBoris Brezillon 			 * a different extended ID format, and we should find
43978f3482dSBoris Brezillon 			 * a way to support it.
44078f3482dSBoris Brezillon 			 */
44178f3482dSBoris Brezillon 			WARN(1, "Invalid OOB size");
44278f3482dSBoris Brezillon 			break;
44378f3482dSBoris Brezillon 		}
44478f3482dSBoris Brezillon 	} else {
44578f3482dSBoris Brezillon 		switch (oobsize) {
44601389b6bSBoris Brezillon 		case 0:
447629a442cSBoris Brezillon 			memorg->oobsize = 128;
44801389b6bSBoris Brezillon 			break;
44901389b6bSBoris Brezillon 		case 1:
450629a442cSBoris Brezillon 			memorg->oobsize = 224;
45101389b6bSBoris Brezillon 			break;
45201389b6bSBoris Brezillon 		case 2:
453629a442cSBoris Brezillon 			memorg->oobsize = 448;
45401389b6bSBoris Brezillon 			break;
45501389b6bSBoris Brezillon 		case 3:
456629a442cSBoris Brezillon 			memorg->oobsize = 64;
45701389b6bSBoris Brezillon 			break;
45801389b6bSBoris Brezillon 		case 4:
459629a442cSBoris Brezillon 			memorg->oobsize = 32;
46001389b6bSBoris Brezillon 			break;
46101389b6bSBoris Brezillon 		case 5:
462629a442cSBoris Brezillon 			memorg->oobsize = 16;
46301389b6bSBoris Brezillon 			break;
46478f3482dSBoris Brezillon 		case 6:
465629a442cSBoris Brezillon 			memorg->oobsize = 640;
46601389b6bSBoris Brezillon 			break;
46778f3482dSBoris Brezillon 		default:
46878f3482dSBoris Brezillon 			/*
46978f3482dSBoris Brezillon 			 * We should never reach this case, but if that
47078f3482dSBoris Brezillon 			 * happens, this probably means Hynix decided to use
47178f3482dSBoris Brezillon 			 * a different extended ID format, and we should find
47278f3482dSBoris Brezillon 			 * a way to support it.
47378f3482dSBoris Brezillon 			 */
47478f3482dSBoris Brezillon 			WARN(1, "Invalid OOB size");
47578f3482dSBoris Brezillon 			break;
47678f3482dSBoris Brezillon 		}
47716c4fba0SMartin Blumenstingl 
47816c4fba0SMartin Blumenstingl 		/*
47916c4fba0SMartin Blumenstingl 		 * The datasheet of H27UCG8T2BTR mentions that the "Redundant
48016c4fba0SMartin Blumenstingl 		 * Area Size" is encoded "per 8KB" (page size). This chip uses
48116c4fba0SMartin Blumenstingl 		 * a page size of 16KiB. The datasheet mentions an OOB size of
48216c4fba0SMartin Blumenstingl 		 * 1.280 bytes, but the OOB size encoded in the ID bytes (using
48316c4fba0SMartin Blumenstingl 		 * the existing logic above) is 640 bytes.
48416c4fba0SMartin Blumenstingl 		 * Update the OOB size for this chip by taking the value
48516c4fba0SMartin Blumenstingl 		 * determined above and scaling it to the actual page size (so
48616c4fba0SMartin Blumenstingl 		 * the actual OOB size for this chip is: 640 * 16k / 8k).
48716c4fba0SMartin Blumenstingl 		 */
48816c4fba0SMartin Blumenstingl 		if (chip->id.data[1] == 0xde)
489629a442cSBoris Brezillon 			memorg->oobsize *= memorg->pagesize / SZ_8K;
49078f3482dSBoris Brezillon 	}
491629a442cSBoris Brezillon 
492629a442cSBoris Brezillon 	mtd->oobsize = memorg->oobsize;
49301389b6bSBoris Brezillon }
49401389b6bSBoris Brezillon 
49578f3482dSBoris Brezillon static void hynix_nand_extract_ecc_requirements(struct nand_chip *chip,
49678f3482dSBoris Brezillon 						bool valid_jedecid)
49778f3482dSBoris Brezillon {
498*53576c7bSMiquel Raynal 	struct nand_device *base = &chip->base;
499*53576c7bSMiquel Raynal 	struct nand_ecc_props requirements = {};
50078f3482dSBoris Brezillon 	u8 ecc_level = (chip->id.data[4] >> 4) & 0x7;
50178f3482dSBoris Brezillon 
50278f3482dSBoris Brezillon 	if (valid_jedecid) {
50378f3482dSBoris Brezillon 		/* Reference: H27UCG8T2E datasheet */
504*53576c7bSMiquel Raynal 		requirements.step_size = 1024;
50578f3482dSBoris Brezillon 
50678f3482dSBoris Brezillon 		switch (ecc_level) {
50778f3482dSBoris Brezillon 		case 0:
508*53576c7bSMiquel Raynal 			requirements.step_size = 0;
509*53576c7bSMiquel Raynal 			requirements.strength = 0;
51078f3482dSBoris Brezillon 			break;
51178f3482dSBoris Brezillon 		case 1:
512*53576c7bSMiquel Raynal 			requirements.strength = 4;
51378f3482dSBoris Brezillon 			break;
51478f3482dSBoris Brezillon 		case 2:
515*53576c7bSMiquel Raynal 			requirements.strength = 24;
51678f3482dSBoris Brezillon 			break;
51778f3482dSBoris Brezillon 		case 3:
518*53576c7bSMiquel Raynal 			requirements.strength = 32;
51978f3482dSBoris Brezillon 			break;
52078f3482dSBoris Brezillon 		case 4:
521*53576c7bSMiquel Raynal 			requirements.strength = 40;
52278f3482dSBoris Brezillon 			break;
52378f3482dSBoris Brezillon 		case 5:
524*53576c7bSMiquel Raynal 			requirements.strength = 50;
52578f3482dSBoris Brezillon 			break;
52678f3482dSBoris Brezillon 		case 6:
527*53576c7bSMiquel Raynal 			requirements.strength = 60;
52878f3482dSBoris Brezillon 			break;
52978f3482dSBoris Brezillon 		default:
53078f3482dSBoris Brezillon 			/*
53178f3482dSBoris Brezillon 			 * We should never reach this case, but if that
53278f3482dSBoris Brezillon 			 * happens, this probably means Hynix decided to use
53378f3482dSBoris Brezillon 			 * a different extended ID format, and we should find
53478f3482dSBoris Brezillon 			 * a way to support it.
53578f3482dSBoris Brezillon 			 */
53678f3482dSBoris Brezillon 			WARN(1, "Invalid ECC requirements");
53701389b6bSBoris Brezillon 		}
53878f3482dSBoris Brezillon 	} else {
53978f3482dSBoris Brezillon 		/*
54078f3482dSBoris Brezillon 		 * The ECC requirements field meaning depends on the
54178f3482dSBoris Brezillon 		 * NAND technology.
54278f3482dSBoris Brezillon 		 */
543fd213b5bSMartin Blumenstingl 		u8 nand_tech = chip->id.data[5] & 0x7;
54478f3482dSBoris Brezillon 
54578f3482dSBoris Brezillon 		if (nand_tech < 3) {
54678f3482dSBoris Brezillon 			/* > 26nm, reference: H27UBG8T2A datasheet */
54778f3482dSBoris Brezillon 			if (ecc_level < 5) {
548*53576c7bSMiquel Raynal 				requirements.step_size = 512;
549*53576c7bSMiquel Raynal 				requirements.strength = 1 << ecc_level;
55078f3482dSBoris Brezillon 			} else if (ecc_level < 7) {
55178f3482dSBoris Brezillon 				if (ecc_level == 5)
552*53576c7bSMiquel Raynal 					requirements.step_size = 2048;
55378f3482dSBoris Brezillon 				else
554*53576c7bSMiquel Raynal 					requirements.step_size = 1024;
555*53576c7bSMiquel Raynal 				requirements.strength = 24;
55678f3482dSBoris Brezillon 			} else {
55778f3482dSBoris Brezillon 				/*
55878f3482dSBoris Brezillon 				 * We should never reach this case, but if that
55978f3482dSBoris Brezillon 				 * happens, this probably means Hynix decided
56078f3482dSBoris Brezillon 				 * to use a different extended ID format, and
56178f3482dSBoris Brezillon 				 * we should find a way to support it.
56278f3482dSBoris Brezillon 				 */
56378f3482dSBoris Brezillon 				WARN(1, "Invalid ECC requirements");
56478f3482dSBoris Brezillon 			}
56578f3482dSBoris Brezillon 		} else {
56678f3482dSBoris Brezillon 			/* <= 26nm, reference: H27UBG8T2B datasheet */
56778f3482dSBoris Brezillon 			if (!ecc_level) {
568*53576c7bSMiquel Raynal 				requirements.step_size = 0;
569*53576c7bSMiquel Raynal 				requirements.strength = 0;
57078f3482dSBoris Brezillon 			} else if (ecc_level < 5) {
571*53576c7bSMiquel Raynal 				requirements.step_size = 512;
572*53576c7bSMiquel Raynal 				requirements.strength = 1 << (ecc_level - 1);
57378f3482dSBoris Brezillon 			} else {
574*53576c7bSMiquel Raynal 				requirements.step_size = 1024;
575*53576c7bSMiquel Raynal 				requirements.strength = 24 +
57678f3482dSBoris Brezillon 							(8 * (ecc_level - 5));
57778f3482dSBoris Brezillon 			}
57878f3482dSBoris Brezillon 		}
57978f3482dSBoris Brezillon 	}
580*53576c7bSMiquel Raynal 
581*53576c7bSMiquel Raynal 	nanddev_set_ecc_requirements(base, &requirements);
58278f3482dSBoris Brezillon }
58378f3482dSBoris Brezillon 
58478f3482dSBoris Brezillon static void hynix_nand_extract_scrambling_requirements(struct nand_chip *chip,
58578f3482dSBoris Brezillon 						       bool valid_jedecid)
58678f3482dSBoris Brezillon {
58778f3482dSBoris Brezillon 	u8 nand_tech;
58878f3482dSBoris Brezillon 
58978f3482dSBoris Brezillon 	/* We need scrambling on all TLC NANDs*/
59029815168SBoris Brezillon 	if (nanddev_bits_per_cell(&chip->base) > 2)
59178f3482dSBoris Brezillon 		chip->options |= NAND_NEED_SCRAMBLING;
59278f3482dSBoris Brezillon 
59378f3482dSBoris Brezillon 	/* And on MLC NANDs with sub-3xnm process */
59478f3482dSBoris Brezillon 	if (valid_jedecid) {
59578f3482dSBoris Brezillon 		nand_tech = chip->id.data[5] >> 4;
59678f3482dSBoris Brezillon 
59778f3482dSBoris Brezillon 		/* < 3xnm */
59878f3482dSBoris Brezillon 		if (nand_tech > 0)
59978f3482dSBoris Brezillon 			chip->options |= NAND_NEED_SCRAMBLING;
60078f3482dSBoris Brezillon 	} else {
601fd213b5bSMartin Blumenstingl 		nand_tech = chip->id.data[5] & 0x7;
60278f3482dSBoris Brezillon 
60378f3482dSBoris Brezillon 		/* < 32nm */
60478f3482dSBoris Brezillon 		if (nand_tech > 2)
60578f3482dSBoris Brezillon 			chip->options |= NAND_NEED_SCRAMBLING;
60678f3482dSBoris Brezillon 	}
60778f3482dSBoris Brezillon }
60878f3482dSBoris Brezillon 
60978f3482dSBoris Brezillon static void hynix_nand_decode_id(struct nand_chip *chip)
61078f3482dSBoris Brezillon {
61178f3482dSBoris Brezillon 	struct mtd_info *mtd = nand_to_mtd(chip);
612629a442cSBoris Brezillon 	struct nand_memory_organization *memorg;
61378f3482dSBoris Brezillon 	bool valid_jedecid;
61478f3482dSBoris Brezillon 	u8 tmp;
61578f3482dSBoris Brezillon 
616629a442cSBoris Brezillon 	memorg = nanddev_get_memorg(&chip->base);
617629a442cSBoris Brezillon 
61878f3482dSBoris Brezillon 	/*
61978f3482dSBoris Brezillon 	 * Exclude all SLC NANDs from this advanced detection scheme.
62078f3482dSBoris Brezillon 	 * According to the ranges defined in several datasheets, it might
62178f3482dSBoris Brezillon 	 * appear that even SLC NANDs could fall in this extended ID scheme.
62278f3482dSBoris Brezillon 	 * If that the case rework the test to let SLC NANDs go through the
62378f3482dSBoris Brezillon 	 * detection process.
62478f3482dSBoris Brezillon 	 */
62578f3482dSBoris Brezillon 	if (chip->id.len < 6 || nand_is_slc(chip)) {
62678f3482dSBoris Brezillon 		nand_decode_ext_id(chip);
62778f3482dSBoris Brezillon 		return;
62878f3482dSBoris Brezillon 	}
62978f3482dSBoris Brezillon 
63078f3482dSBoris Brezillon 	/* Extract pagesize */
631629a442cSBoris Brezillon 	memorg->pagesize = 2048 << (chip->id.data[3] & 0x03);
632629a442cSBoris Brezillon 	mtd->writesize = memorg->pagesize;
63378f3482dSBoris Brezillon 
63478f3482dSBoris Brezillon 	tmp = (chip->id.data[3] >> 4) & 0x3;
63578f3482dSBoris Brezillon 	/*
63678f3482dSBoris Brezillon 	 * When bit7 is set that means we start counting at 1MiB, otherwise
63778f3482dSBoris Brezillon 	 * we start counting at 128KiB and shift this value the content of
63878f3482dSBoris Brezillon 	 * ID[3][4:5].
63978f3482dSBoris Brezillon 	 * The only exception is when ID[3][4:5] == 3 and ID[3][7] == 0, in
64078f3482dSBoris Brezillon 	 * this case the erasesize is set to 768KiB.
64178f3482dSBoris Brezillon 	 */
642629a442cSBoris Brezillon 	if (chip->id.data[3] & 0x80) {
643629a442cSBoris Brezillon 		memorg->pages_per_eraseblock = (SZ_1M << tmp) /
644629a442cSBoris Brezillon 					       memorg->pagesize;
64578f3482dSBoris Brezillon 		mtd->erasesize = SZ_1M << tmp;
646629a442cSBoris Brezillon 	} else if (tmp == 3) {
647629a442cSBoris Brezillon 		memorg->pages_per_eraseblock = (SZ_512K + SZ_256K) /
648629a442cSBoris Brezillon 					       memorg->pagesize;
64978f3482dSBoris Brezillon 		mtd->erasesize = SZ_512K + SZ_256K;
650629a442cSBoris Brezillon 	} else {
651629a442cSBoris Brezillon 		memorg->pages_per_eraseblock = (SZ_128K << tmp) /
652629a442cSBoris Brezillon 					       memorg->pagesize;
65378f3482dSBoris Brezillon 		mtd->erasesize = SZ_128K << tmp;
654629a442cSBoris Brezillon 	}
65578f3482dSBoris Brezillon 
65678f3482dSBoris Brezillon 	/*
65778f3482dSBoris Brezillon 	 * Modern Toggle DDR NANDs have a valid JEDECID even though they are
65878f3482dSBoris Brezillon 	 * not exposing a valid JEDEC parameter table.
65978f3482dSBoris Brezillon 	 * These NANDs use a different NAND ID scheme.
66078f3482dSBoris Brezillon 	 */
66178f3482dSBoris Brezillon 	valid_jedecid = hynix_nand_has_valid_jedecid(chip);
66278f3482dSBoris Brezillon 
66378f3482dSBoris Brezillon 	hynix_nand_extract_oobsize(chip, valid_jedecid);
66478f3482dSBoris Brezillon 	hynix_nand_extract_ecc_requirements(chip, valid_jedecid);
66578f3482dSBoris Brezillon 	hynix_nand_extract_scrambling_requirements(chip, valid_jedecid);
66601389b6bSBoris Brezillon }
66701389b6bSBoris Brezillon 
668626994e0SBoris Brezillon static void hynix_nand_cleanup(struct nand_chip *chip)
669626994e0SBoris Brezillon {
670626994e0SBoris Brezillon 	struct hynix_nand *hynix = nand_get_manufacturer_data(chip);
671626994e0SBoris Brezillon 
672626994e0SBoris Brezillon 	if (!hynix)
673626994e0SBoris Brezillon 		return;
674626994e0SBoris Brezillon 
675626994e0SBoris Brezillon 	kfree(hynix->read_retry);
676626994e0SBoris Brezillon 	kfree(hynix);
677626994e0SBoris Brezillon 	nand_set_manufacturer_data(chip, NULL);
678626994e0SBoris Brezillon }
679626994e0SBoris Brezillon 
680246a06ffSMiquel Raynal static int
681246a06ffSMiquel Raynal h27ucg8t2atrbc_choose_interface_config(struct nand_chip *chip,
682246a06ffSMiquel Raynal 				       struct nand_interface_config *iface)
683246a06ffSMiquel Raynal {
684246a06ffSMiquel Raynal 	onfi_fill_interface_config(chip, iface, NAND_SDR_IFACE, 4);
685246a06ffSMiquel Raynal 
686246a06ffSMiquel Raynal 	return nand_choose_best_sdr_timings(chip, iface, NULL);
687246a06ffSMiquel Raynal }
688246a06ffSMiquel Raynal 
68901389b6bSBoris Brezillon static int hynix_nand_init(struct nand_chip *chip)
69001389b6bSBoris Brezillon {
691626994e0SBoris Brezillon 	struct hynix_nand *hynix;
692626994e0SBoris Brezillon 	int ret;
693626994e0SBoris Brezillon 
69401389b6bSBoris Brezillon 	if (!nand_is_slc(chip))
69504649ec1SFrieder Schrempf 		chip->options |= NAND_BBM_LASTPAGE;
69601389b6bSBoris Brezillon 	else
697bb592548SFrieder Schrempf 		chip->options |= NAND_BBM_FIRSTPAGE | NAND_BBM_SECONDPAGE;
69801389b6bSBoris Brezillon 
699626994e0SBoris Brezillon 	hynix = kzalloc(sizeof(*hynix), GFP_KERNEL);
700626994e0SBoris Brezillon 	if (!hynix)
701626994e0SBoris Brezillon 		return -ENOMEM;
702626994e0SBoris Brezillon 
703626994e0SBoris Brezillon 	nand_set_manufacturer_data(chip, hynix);
704626994e0SBoris Brezillon 
705246a06ffSMiquel Raynal 	if (!strncmp("H27UCG8T2ATR-BC", chip->parameters.model,
706246a06ffSMiquel Raynal 		     sizeof("H27UCG8T2ATR-BC") - 1))
707246a06ffSMiquel Raynal 		chip->ops.choose_interface_config =
708246a06ffSMiquel Raynal 			h27ucg8t2atrbc_choose_interface_config;
709246a06ffSMiquel Raynal 
710626994e0SBoris Brezillon 	ret = hynix_nand_rr_init(chip);
711626994e0SBoris Brezillon 	if (ret)
712626994e0SBoris Brezillon 		hynix_nand_cleanup(chip);
713626994e0SBoris Brezillon 
714626994e0SBoris Brezillon 	return ret;
71501389b6bSBoris Brezillon }
71601389b6bSBoris Brezillon 
71701389b6bSBoris Brezillon const struct nand_manufacturer_ops hynix_nand_manuf_ops = {
71801389b6bSBoris Brezillon 	.detect = hynix_nand_decode_id,
71901389b6bSBoris Brezillon 	.init = hynix_nand_init,
720626994e0SBoris Brezillon 	.cleanup = hynix_nand_cleanup,
72101389b6bSBoris Brezillon };
722