xref: /linux/drivers/mtd/nand/raw/nand_hynix.c (revision 16c4fba03a45ac8c6048a96e02abc933e1354852)
101389b6bSBoris Brezillon /*
201389b6bSBoris Brezillon  * Copyright (C) 2017 Free Electrons
301389b6bSBoris Brezillon  * Copyright (C) 2017 NextThing Co
401389b6bSBoris Brezillon  *
501389b6bSBoris Brezillon  * Author: Boris Brezillon <boris.brezillon@free-electrons.com>
601389b6bSBoris Brezillon  *
701389b6bSBoris Brezillon  * This program is free software; you can redistribute it and/or modify
801389b6bSBoris Brezillon  * it under the terms of the GNU General Public License as published by
901389b6bSBoris Brezillon  * the Free Software Foundation; either version 2 of the License, or
1001389b6bSBoris Brezillon  * (at your option) any later version.
1101389b6bSBoris Brezillon  *
1201389b6bSBoris Brezillon  * This program is distributed in the hope that it will be useful,
1301389b6bSBoris Brezillon  * but WITHOUT ANY WARRANTY; without even the implied warranty of
1401389b6bSBoris Brezillon  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1501389b6bSBoris Brezillon  * GNU General Public License for more details.
1601389b6bSBoris Brezillon  */
1701389b6bSBoris Brezillon 
18d4092d76SBoris Brezillon #include <linux/mtd/rawnand.h>
1978f3482dSBoris Brezillon #include <linux/sizes.h>
20626994e0SBoris Brezillon #include <linux/slab.h>
21626994e0SBoris Brezillon 
22626994e0SBoris Brezillon #define NAND_HYNIX_CMD_SET_PARAMS	0x36
23626994e0SBoris Brezillon #define NAND_HYNIX_CMD_APPLY_PARAMS	0x16
24626994e0SBoris Brezillon 
25626994e0SBoris Brezillon #define NAND_HYNIX_1XNM_RR_REPEAT	8
26626994e0SBoris Brezillon 
27626994e0SBoris Brezillon /**
28626994e0SBoris Brezillon  * struct hynix_read_retry - read-retry data
29626994e0SBoris Brezillon  * @nregs: number of register to set when applying a new read-retry mode
30626994e0SBoris Brezillon  * @regs: register offsets (NAND chip dependent)
31626994e0SBoris Brezillon  * @values: array of values to set in registers. The array size is equal to
32626994e0SBoris Brezillon  *	    (nregs * nmodes)
33626994e0SBoris Brezillon  */
34626994e0SBoris Brezillon struct hynix_read_retry {
35626994e0SBoris Brezillon 	int nregs;
36626994e0SBoris Brezillon 	const u8 *regs;
37626994e0SBoris Brezillon 	u8 values[0];
38626994e0SBoris Brezillon };
39626994e0SBoris Brezillon 
40626994e0SBoris Brezillon /**
41626994e0SBoris Brezillon  * struct hynix_nand - private Hynix NAND struct
42626994e0SBoris Brezillon  * @nand_technology: manufacturing process expressed in picometer
43626994e0SBoris Brezillon  * @read_retry: read-retry information
44626994e0SBoris Brezillon  */
45626994e0SBoris Brezillon struct hynix_nand {
46626994e0SBoris Brezillon 	const struct hynix_read_retry *read_retry;
47626994e0SBoris Brezillon };
48626994e0SBoris Brezillon 
49626994e0SBoris Brezillon /**
50626994e0SBoris Brezillon  * struct hynix_read_retry_otp - structure describing how the read-retry OTP
51626994e0SBoris Brezillon  *				 area
52626994e0SBoris Brezillon  * @nregs: number of hynix private registers to set before reading the reading
53626994e0SBoris Brezillon  *	   the OTP area
54626994e0SBoris Brezillon  * @regs: registers that should be configured
55626994e0SBoris Brezillon  * @values: values that should be set in regs
56626994e0SBoris Brezillon  * @page: the address to pass to the READ_PAGE command. Depends on the NAND
57626994e0SBoris Brezillon  *	  chip
58626994e0SBoris Brezillon  * @size: size of the read-retry OTP section
59626994e0SBoris Brezillon  */
60626994e0SBoris Brezillon struct hynix_read_retry_otp {
61626994e0SBoris Brezillon 	int nregs;
62626994e0SBoris Brezillon 	const u8 *regs;
63626994e0SBoris Brezillon 	const u8 *values;
64626994e0SBoris Brezillon 	int page;
65626994e0SBoris Brezillon 	int size;
66626994e0SBoris Brezillon };
6701389b6bSBoris Brezillon 
6878f3482dSBoris Brezillon static bool hynix_nand_has_valid_jedecid(struct nand_chip *chip)
6901389b6bSBoris Brezillon {
7097d90da8SBoris Brezillon 	u8 jedecid[5] = { };
7197d90da8SBoris Brezillon 	int ret;
7297d90da8SBoris Brezillon 
7397d90da8SBoris Brezillon 	ret = nand_readid_op(chip, 0x40, jedecid, sizeof(jedecid));
7497d90da8SBoris Brezillon 	if (ret)
7597d90da8SBoris Brezillon 		return false;
7697d90da8SBoris Brezillon 
7797d90da8SBoris Brezillon 	return !strncmp("JEDEC", jedecid, sizeof(jedecid));
7897d90da8SBoris Brezillon }
7997d90da8SBoris Brezillon 
8097d90da8SBoris Brezillon static int hynix_nand_cmd_op(struct nand_chip *chip, u8 cmd)
8197d90da8SBoris Brezillon {
8201389b6bSBoris Brezillon 	struct mtd_info *mtd = nand_to_mtd(chip);
8301389b6bSBoris Brezillon 
848878b126SMiquel Raynal 	if (chip->exec_op) {
858878b126SMiquel Raynal 		struct nand_op_instr instrs[] = {
868878b126SMiquel Raynal 			NAND_OP_CMD(cmd, 0),
878878b126SMiquel Raynal 		};
888878b126SMiquel Raynal 		struct nand_operation op = NAND_OPERATION(instrs);
898878b126SMiquel Raynal 
908878b126SMiquel Raynal 		return nand_exec_op(chip, &op);
918878b126SMiquel Raynal 	}
928878b126SMiquel Raynal 
9397d90da8SBoris Brezillon 	chip->cmdfunc(mtd, cmd, -1, -1);
9401389b6bSBoris Brezillon 
9597d90da8SBoris Brezillon 	return 0;
9697d90da8SBoris Brezillon }
9797d90da8SBoris Brezillon 
9897d90da8SBoris Brezillon static int hynix_nand_reg_write_op(struct nand_chip *chip, u8 addr, u8 val)
9997d90da8SBoris Brezillon {
10097d90da8SBoris Brezillon 	struct mtd_info *mtd = nand_to_mtd(chip);
10197d90da8SBoris Brezillon 	u16 column = ((u16)addr << 8) | addr;
10297d90da8SBoris Brezillon 
10397d90da8SBoris Brezillon 	chip->cmdfunc(mtd, NAND_CMD_NONE, column, -1);
10497d90da8SBoris Brezillon 	chip->write_byte(mtd, val);
10597d90da8SBoris Brezillon 
10697d90da8SBoris Brezillon 	return 0;
10778f3482dSBoris Brezillon }
10801389b6bSBoris Brezillon 
109626994e0SBoris Brezillon static int hynix_nand_setup_read_retry(struct mtd_info *mtd, int retry_mode)
110626994e0SBoris Brezillon {
111626994e0SBoris Brezillon 	struct nand_chip *chip = mtd_to_nand(mtd);
112626994e0SBoris Brezillon 	struct hynix_nand *hynix = nand_get_manufacturer_data(chip);
113626994e0SBoris Brezillon 	const u8 *values;
11497d90da8SBoris Brezillon 	int i, ret;
115626994e0SBoris Brezillon 
116626994e0SBoris Brezillon 	values = hynix->read_retry->values +
117626994e0SBoris Brezillon 		 (retry_mode * hynix->read_retry->nregs);
118626994e0SBoris Brezillon 
119626994e0SBoris Brezillon 	/* Enter 'Set Hynix Parameters' mode */
12097d90da8SBoris Brezillon 	ret = hynix_nand_cmd_op(chip, NAND_HYNIX_CMD_SET_PARAMS);
12197d90da8SBoris Brezillon 	if (ret)
12297d90da8SBoris Brezillon 		return ret;
123626994e0SBoris Brezillon 
124626994e0SBoris Brezillon 	/*
125626994e0SBoris Brezillon 	 * Configure the NAND in the requested read-retry mode.
126626994e0SBoris Brezillon 	 * This is done by setting pre-defined values in internal NAND
127626994e0SBoris Brezillon 	 * registers.
128626994e0SBoris Brezillon 	 *
129626994e0SBoris Brezillon 	 * The set of registers is NAND specific, and the values are either
130626994e0SBoris Brezillon 	 * predefined or extracted from an OTP area on the NAND (values are
131626994e0SBoris Brezillon 	 * probably tweaked at production in this case).
132626994e0SBoris Brezillon 	 */
133626994e0SBoris Brezillon 	for (i = 0; i < hynix->read_retry->nregs; i++) {
13497d90da8SBoris Brezillon 		ret = hynix_nand_reg_write_op(chip, hynix->read_retry->regs[i],
13597d90da8SBoris Brezillon 					      values[i]);
13697d90da8SBoris Brezillon 		if (ret)
13797d90da8SBoris Brezillon 			return ret;
138626994e0SBoris Brezillon 	}
139626994e0SBoris Brezillon 
140626994e0SBoris Brezillon 	/* Apply the new settings. */
14197d90da8SBoris Brezillon 	return hynix_nand_cmd_op(chip, NAND_HYNIX_CMD_APPLY_PARAMS);
142626994e0SBoris Brezillon }
143626994e0SBoris Brezillon 
144626994e0SBoris Brezillon /**
145626994e0SBoris Brezillon  * hynix_get_majority - get the value that is occurring the most in a given
146626994e0SBoris Brezillon  *			set of values
147626994e0SBoris Brezillon  * @in: the array of values to test
148626994e0SBoris Brezillon  * @repeat: the size of the in array
149626994e0SBoris Brezillon  * @out: pointer used to store the output value
150626994e0SBoris Brezillon  *
151626994e0SBoris Brezillon  * This function implements the 'majority check' logic that is supposed to
152626994e0SBoris Brezillon  * overcome the unreliability of MLC NANDs when reading the OTP area storing
153626994e0SBoris Brezillon  * the read-retry parameters.
154626994e0SBoris Brezillon  *
155626994e0SBoris Brezillon  * It's based on a pretty simple assumption: if we repeat the same value
156626994e0SBoris Brezillon  * several times and then take the one that is occurring the most, we should
157626994e0SBoris Brezillon  * find the correct value.
158626994e0SBoris Brezillon  * Let's hope this dummy algorithm prevents us from losing the read-retry
159626994e0SBoris Brezillon  * parameters.
160626994e0SBoris Brezillon  */
161626994e0SBoris Brezillon static int hynix_get_majority(const u8 *in, int repeat, u8 *out)
162626994e0SBoris Brezillon {
163626994e0SBoris Brezillon 	int i, j, half = repeat / 2;
164626994e0SBoris Brezillon 
165626994e0SBoris Brezillon 	/*
166626994e0SBoris Brezillon 	 * We only test the first half of the in array because we must ensure
167626994e0SBoris Brezillon 	 * that the value is at least occurring repeat / 2 times.
168626994e0SBoris Brezillon 	 *
169626994e0SBoris Brezillon 	 * This loop is suboptimal since we may count the occurrences of the
170626994e0SBoris Brezillon 	 * same value several time, but we are doing that on small sets, which
171626994e0SBoris Brezillon 	 * makes it acceptable.
172626994e0SBoris Brezillon 	 */
173626994e0SBoris Brezillon 	for (i = 0; i < half; i++) {
174626994e0SBoris Brezillon 		int cnt = 0;
175626994e0SBoris Brezillon 		u8 val = in[i];
176626994e0SBoris Brezillon 
177626994e0SBoris Brezillon 		/* Count all values that are matching the one at index i. */
178626994e0SBoris Brezillon 		for (j = i + 1; j < repeat; j++) {
179626994e0SBoris Brezillon 			if (in[j] == val)
180626994e0SBoris Brezillon 				cnt++;
181626994e0SBoris Brezillon 		}
182626994e0SBoris Brezillon 
183626994e0SBoris Brezillon 		/* We found a value occurring more than repeat / 2. */
184626994e0SBoris Brezillon 		if (cnt > half) {
185626994e0SBoris Brezillon 			*out = val;
186626994e0SBoris Brezillon 			return 0;
187626994e0SBoris Brezillon 		}
188626994e0SBoris Brezillon 	}
189626994e0SBoris Brezillon 
190626994e0SBoris Brezillon 	return -EIO;
191626994e0SBoris Brezillon }
192626994e0SBoris Brezillon 
193626994e0SBoris Brezillon static int hynix_read_rr_otp(struct nand_chip *chip,
194626994e0SBoris Brezillon 			     const struct hynix_read_retry_otp *info,
195626994e0SBoris Brezillon 			     void *buf)
196626994e0SBoris Brezillon {
19797d90da8SBoris Brezillon 	int i, ret;
198626994e0SBoris Brezillon 
19997d90da8SBoris Brezillon 	ret = nand_reset_op(chip);
20097d90da8SBoris Brezillon 	if (ret)
20197d90da8SBoris Brezillon 		return ret;
202626994e0SBoris Brezillon 
20397d90da8SBoris Brezillon 	ret = hynix_nand_cmd_op(chip, NAND_HYNIX_CMD_SET_PARAMS);
20497d90da8SBoris Brezillon 	if (ret)
20597d90da8SBoris Brezillon 		return ret;
206626994e0SBoris Brezillon 
207626994e0SBoris Brezillon 	for (i = 0; i < info->nregs; i++) {
20897d90da8SBoris Brezillon 		ret = hynix_nand_reg_write_op(chip, info->regs[i],
20997d90da8SBoris Brezillon 					      info->values[i]);
21097d90da8SBoris Brezillon 		if (ret)
21197d90da8SBoris Brezillon 			return ret;
212626994e0SBoris Brezillon 	}
213626994e0SBoris Brezillon 
21497d90da8SBoris Brezillon 	ret = hynix_nand_cmd_op(chip, NAND_HYNIX_CMD_APPLY_PARAMS);
21597d90da8SBoris Brezillon 	if (ret)
21697d90da8SBoris Brezillon 		return ret;
217626994e0SBoris Brezillon 
218626994e0SBoris Brezillon 	/* Sequence to enter OTP mode? */
21997d90da8SBoris Brezillon 	ret = hynix_nand_cmd_op(chip, 0x17);
22097d90da8SBoris Brezillon 	if (ret)
22197d90da8SBoris Brezillon 		return ret;
22297d90da8SBoris Brezillon 
22397d90da8SBoris Brezillon 	ret = hynix_nand_cmd_op(chip, 0x4);
22497d90da8SBoris Brezillon 	if (ret)
22597d90da8SBoris Brezillon 		return ret;
22697d90da8SBoris Brezillon 
22797d90da8SBoris Brezillon 	ret = hynix_nand_cmd_op(chip, 0x19);
22897d90da8SBoris Brezillon 	if (ret)
22997d90da8SBoris Brezillon 		return ret;
230626994e0SBoris Brezillon 
231626994e0SBoris Brezillon 	/* Now read the page */
23297d90da8SBoris Brezillon 	ret = nand_read_page_op(chip, info->page, 0, buf, info->size);
23397d90da8SBoris Brezillon 	if (ret)
23497d90da8SBoris Brezillon 		return ret;
235626994e0SBoris Brezillon 
236626994e0SBoris Brezillon 	/* Put everything back to normal */
23797d90da8SBoris Brezillon 	ret = nand_reset_op(chip);
23897d90da8SBoris Brezillon 	if (ret)
23997d90da8SBoris Brezillon 		return ret;
240626994e0SBoris Brezillon 
24197d90da8SBoris Brezillon 	ret = hynix_nand_cmd_op(chip, NAND_HYNIX_CMD_SET_PARAMS);
24297d90da8SBoris Brezillon 	if (ret)
24397d90da8SBoris Brezillon 		return ret;
24497d90da8SBoris Brezillon 
24597d90da8SBoris Brezillon 	ret = hynix_nand_reg_write_op(chip, 0x38, 0);
24697d90da8SBoris Brezillon 	if (ret)
24797d90da8SBoris Brezillon 		return ret;
24897d90da8SBoris Brezillon 
24997d90da8SBoris Brezillon 	ret = hynix_nand_cmd_op(chip, NAND_HYNIX_CMD_APPLY_PARAMS);
25097d90da8SBoris Brezillon 	if (ret)
25197d90da8SBoris Brezillon 		return ret;
25297d90da8SBoris Brezillon 
25397d90da8SBoris Brezillon 	return nand_read_page_op(chip, 0, 0, NULL, 0);
254626994e0SBoris Brezillon }
255626994e0SBoris Brezillon 
256626994e0SBoris Brezillon #define NAND_HYNIX_1XNM_RR_COUNT_OFFS				0
257626994e0SBoris Brezillon #define NAND_HYNIX_1XNM_RR_REG_COUNT_OFFS			8
258626994e0SBoris Brezillon #define NAND_HYNIX_1XNM_RR_SET_OFFS(x, setsize, inv)		\
259626994e0SBoris Brezillon 	(16 + ((((x) * 2) + ((inv) ? 1 : 0)) * (setsize)))
260626994e0SBoris Brezillon 
261626994e0SBoris Brezillon static int hynix_mlc_1xnm_rr_value(const u8 *buf, int nmodes, int nregs,
262626994e0SBoris Brezillon 				   int mode, int reg, bool inv, u8 *val)
263626994e0SBoris Brezillon {
264626994e0SBoris Brezillon 	u8 tmp[NAND_HYNIX_1XNM_RR_REPEAT];
265626994e0SBoris Brezillon 	int val_offs = (mode * nregs) + reg;
266626994e0SBoris Brezillon 	int set_size = nmodes * nregs;
267626994e0SBoris Brezillon 	int i, ret;
268626994e0SBoris Brezillon 
269626994e0SBoris Brezillon 	for (i = 0; i < NAND_HYNIX_1XNM_RR_REPEAT; i++) {
270626994e0SBoris Brezillon 		int set_offs = NAND_HYNIX_1XNM_RR_SET_OFFS(i, set_size, inv);
271626994e0SBoris Brezillon 
272626994e0SBoris Brezillon 		tmp[i] = buf[val_offs + set_offs];
273626994e0SBoris Brezillon 	}
274626994e0SBoris Brezillon 
275626994e0SBoris Brezillon 	ret = hynix_get_majority(tmp, NAND_HYNIX_1XNM_RR_REPEAT, val);
276626994e0SBoris Brezillon 	if (ret)
277626994e0SBoris Brezillon 		return ret;
278626994e0SBoris Brezillon 
279626994e0SBoris Brezillon 	if (inv)
280626994e0SBoris Brezillon 		*val = ~*val;
281626994e0SBoris Brezillon 
282626994e0SBoris Brezillon 	return 0;
283626994e0SBoris Brezillon }
284626994e0SBoris Brezillon 
285626994e0SBoris Brezillon static u8 hynix_1xnm_mlc_read_retry_regs[] = {
286626994e0SBoris Brezillon 	0xcc, 0xbf, 0xaa, 0xab, 0xcd, 0xad, 0xae, 0xaf
287626994e0SBoris Brezillon };
288626994e0SBoris Brezillon 
289626994e0SBoris Brezillon static int hynix_mlc_1xnm_rr_init(struct nand_chip *chip,
290626994e0SBoris Brezillon 				  const struct hynix_read_retry_otp *info)
291626994e0SBoris Brezillon {
292626994e0SBoris Brezillon 	struct hynix_nand *hynix = nand_get_manufacturer_data(chip);
293626994e0SBoris Brezillon 	struct hynix_read_retry *rr = NULL;
294626994e0SBoris Brezillon 	int ret, i, j;
295626994e0SBoris Brezillon 	u8 nregs, nmodes;
296626994e0SBoris Brezillon 	u8 *buf;
297626994e0SBoris Brezillon 
298626994e0SBoris Brezillon 	buf = kmalloc(info->size, GFP_KERNEL);
299626994e0SBoris Brezillon 	if (!buf)
300626994e0SBoris Brezillon 		return -ENOMEM;
301626994e0SBoris Brezillon 
302626994e0SBoris Brezillon 	ret = hynix_read_rr_otp(chip, info, buf);
303626994e0SBoris Brezillon 	if (ret)
304626994e0SBoris Brezillon 		goto out;
305626994e0SBoris Brezillon 
306626994e0SBoris Brezillon 	ret = hynix_get_majority(buf, NAND_HYNIX_1XNM_RR_REPEAT,
307626994e0SBoris Brezillon 				 &nmodes);
308626994e0SBoris Brezillon 	if (ret)
309626994e0SBoris Brezillon 		goto out;
310626994e0SBoris Brezillon 
311626994e0SBoris Brezillon 	ret = hynix_get_majority(buf + NAND_HYNIX_1XNM_RR_REPEAT,
312626994e0SBoris Brezillon 				 NAND_HYNIX_1XNM_RR_REPEAT,
313626994e0SBoris Brezillon 				 &nregs);
314626994e0SBoris Brezillon 	if (ret)
315626994e0SBoris Brezillon 		goto out;
316626994e0SBoris Brezillon 
317626994e0SBoris Brezillon 	rr = kzalloc(sizeof(*rr) + (nregs * nmodes), GFP_KERNEL);
3184ca8c1d4SDan Carpenter 	if (!rr) {
3194ca8c1d4SDan Carpenter 		ret = -ENOMEM;
320626994e0SBoris Brezillon 		goto out;
3214ca8c1d4SDan Carpenter 	}
322626994e0SBoris Brezillon 
323626994e0SBoris Brezillon 	for (i = 0; i < nmodes; i++) {
324626994e0SBoris Brezillon 		for (j = 0; j < nregs; j++) {
325626994e0SBoris Brezillon 			u8 *val = rr->values + (i * nregs);
326626994e0SBoris Brezillon 
327626994e0SBoris Brezillon 			ret = hynix_mlc_1xnm_rr_value(buf, nmodes, nregs, i, j,
328626994e0SBoris Brezillon 						      false, val);
329626994e0SBoris Brezillon 			if (!ret)
330626994e0SBoris Brezillon 				continue;
331626994e0SBoris Brezillon 
332626994e0SBoris Brezillon 			ret = hynix_mlc_1xnm_rr_value(buf, nmodes, nregs, i, j,
333626994e0SBoris Brezillon 						      true, val);
334626994e0SBoris Brezillon 			if (ret)
335626994e0SBoris Brezillon 				goto out;
336626994e0SBoris Brezillon 		}
337626994e0SBoris Brezillon 	}
338626994e0SBoris Brezillon 
339626994e0SBoris Brezillon 	rr->nregs = nregs;
340626994e0SBoris Brezillon 	rr->regs = hynix_1xnm_mlc_read_retry_regs;
341626994e0SBoris Brezillon 	hynix->read_retry = rr;
342626994e0SBoris Brezillon 	chip->setup_read_retry = hynix_nand_setup_read_retry;
343626994e0SBoris Brezillon 	chip->read_retries = nmodes;
344626994e0SBoris Brezillon 
345626994e0SBoris Brezillon out:
346626994e0SBoris Brezillon 	kfree(buf);
347626994e0SBoris Brezillon 
348626994e0SBoris Brezillon 	if (ret)
349626994e0SBoris Brezillon 		kfree(rr);
350626994e0SBoris Brezillon 
351626994e0SBoris Brezillon 	return ret;
352626994e0SBoris Brezillon }
353626994e0SBoris Brezillon 
354626994e0SBoris Brezillon static const u8 hynix_mlc_1xnm_rr_otp_regs[] = { 0x38 };
355626994e0SBoris Brezillon static const u8 hynix_mlc_1xnm_rr_otp_values[] = { 0x52 };
356626994e0SBoris Brezillon 
357626994e0SBoris Brezillon static const struct hynix_read_retry_otp hynix_mlc_1xnm_rr_otps[] = {
358626994e0SBoris Brezillon 	{
359626994e0SBoris Brezillon 		.nregs = ARRAY_SIZE(hynix_mlc_1xnm_rr_otp_regs),
360626994e0SBoris Brezillon 		.regs = hynix_mlc_1xnm_rr_otp_regs,
361626994e0SBoris Brezillon 		.values = hynix_mlc_1xnm_rr_otp_values,
362626994e0SBoris Brezillon 		.page = 0x21f,
363626994e0SBoris Brezillon 		.size = 784
364626994e0SBoris Brezillon 	},
365626994e0SBoris Brezillon 	{
366626994e0SBoris Brezillon 		.nregs = ARRAY_SIZE(hynix_mlc_1xnm_rr_otp_regs),
367626994e0SBoris Brezillon 		.regs = hynix_mlc_1xnm_rr_otp_regs,
368626994e0SBoris Brezillon 		.values = hynix_mlc_1xnm_rr_otp_values,
369626994e0SBoris Brezillon 		.page = 0x200,
370626994e0SBoris Brezillon 		.size = 528,
371626994e0SBoris Brezillon 	},
372626994e0SBoris Brezillon };
373626994e0SBoris Brezillon 
374626994e0SBoris Brezillon static int hynix_nand_rr_init(struct nand_chip *chip)
375626994e0SBoris Brezillon {
376626994e0SBoris Brezillon 	int i, ret = 0;
377626994e0SBoris Brezillon 	bool valid_jedecid;
378626994e0SBoris Brezillon 
379626994e0SBoris Brezillon 	valid_jedecid = hynix_nand_has_valid_jedecid(chip);
380626994e0SBoris Brezillon 
381626994e0SBoris Brezillon 	/*
382626994e0SBoris Brezillon 	 * We only support read-retry for 1xnm NANDs, and those NANDs all
383626994e0SBoris Brezillon 	 * expose a valid JEDEC ID.
384626994e0SBoris Brezillon 	 */
385626994e0SBoris Brezillon 	if (valid_jedecid) {
386626994e0SBoris Brezillon 		u8 nand_tech = chip->id.data[5] >> 4;
387626994e0SBoris Brezillon 
388626994e0SBoris Brezillon 		/* 1xnm technology */
389626994e0SBoris Brezillon 		if (nand_tech == 4) {
390626994e0SBoris Brezillon 			for (i = 0; i < ARRAY_SIZE(hynix_mlc_1xnm_rr_otps);
391626994e0SBoris Brezillon 			     i++) {
392626994e0SBoris Brezillon 				/*
393626994e0SBoris Brezillon 				 * FIXME: Hynix recommend to copy the
394626994e0SBoris Brezillon 				 * read-retry OTP area into a normal page.
395626994e0SBoris Brezillon 				 */
396626994e0SBoris Brezillon 				ret = hynix_mlc_1xnm_rr_init(chip,
397626994e0SBoris Brezillon 						hynix_mlc_1xnm_rr_otps);
398626994e0SBoris Brezillon 				if (!ret)
399626994e0SBoris Brezillon 					break;
400626994e0SBoris Brezillon 			}
401626994e0SBoris Brezillon 		}
402626994e0SBoris Brezillon 	}
403626994e0SBoris Brezillon 
404626994e0SBoris Brezillon 	if (ret)
405626994e0SBoris Brezillon 		pr_warn("failed to initialize read-retry infrastructure");
406626994e0SBoris Brezillon 
407626994e0SBoris Brezillon 	return 0;
408626994e0SBoris Brezillon }
409626994e0SBoris Brezillon 
41078f3482dSBoris Brezillon static void hynix_nand_extract_oobsize(struct nand_chip *chip,
41178f3482dSBoris Brezillon 				       bool valid_jedecid)
41278f3482dSBoris Brezillon {
41378f3482dSBoris Brezillon 	struct mtd_info *mtd = nand_to_mtd(chip);
41478f3482dSBoris Brezillon 	u8 oobsize;
41578f3482dSBoris Brezillon 
41678f3482dSBoris Brezillon 	oobsize = ((chip->id.data[3] >> 2) & 0x3) |
41778f3482dSBoris Brezillon 		  ((chip->id.data[3] >> 4) & 0x4);
41878f3482dSBoris Brezillon 
41978f3482dSBoris Brezillon 	if (valid_jedecid) {
42078f3482dSBoris Brezillon 		switch (oobsize) {
42178f3482dSBoris Brezillon 		case 0:
42278f3482dSBoris Brezillon 			mtd->oobsize = 2048;
42378f3482dSBoris Brezillon 			break;
42478f3482dSBoris Brezillon 		case 1:
42578f3482dSBoris Brezillon 			mtd->oobsize = 1664;
42678f3482dSBoris Brezillon 			break;
42778f3482dSBoris Brezillon 		case 2:
42878f3482dSBoris Brezillon 			mtd->oobsize = 1024;
42978f3482dSBoris Brezillon 			break;
43078f3482dSBoris Brezillon 		case 3:
43178f3482dSBoris Brezillon 			mtd->oobsize = 640;
43278f3482dSBoris Brezillon 			break;
43378f3482dSBoris Brezillon 		default:
43478f3482dSBoris Brezillon 			/*
43578f3482dSBoris Brezillon 			 * We should never reach this case, but if that
43678f3482dSBoris Brezillon 			 * happens, this probably means Hynix decided to use
43778f3482dSBoris Brezillon 			 * a different extended ID format, and we should find
43878f3482dSBoris Brezillon 			 * a way to support it.
43978f3482dSBoris Brezillon 			 */
44078f3482dSBoris Brezillon 			WARN(1, "Invalid OOB size");
44178f3482dSBoris Brezillon 			break;
44278f3482dSBoris Brezillon 		}
44378f3482dSBoris Brezillon 	} else {
44478f3482dSBoris Brezillon 		switch (oobsize) {
44501389b6bSBoris Brezillon 		case 0:
44601389b6bSBoris Brezillon 			mtd->oobsize = 128;
44701389b6bSBoris Brezillon 			break;
44801389b6bSBoris Brezillon 		case 1:
44901389b6bSBoris Brezillon 			mtd->oobsize = 224;
45001389b6bSBoris Brezillon 			break;
45101389b6bSBoris Brezillon 		case 2:
45201389b6bSBoris Brezillon 			mtd->oobsize = 448;
45301389b6bSBoris Brezillon 			break;
45401389b6bSBoris Brezillon 		case 3:
45501389b6bSBoris Brezillon 			mtd->oobsize = 64;
45601389b6bSBoris Brezillon 			break;
45701389b6bSBoris Brezillon 		case 4:
45801389b6bSBoris Brezillon 			mtd->oobsize = 32;
45901389b6bSBoris Brezillon 			break;
46001389b6bSBoris Brezillon 		case 5:
46101389b6bSBoris Brezillon 			mtd->oobsize = 16;
46201389b6bSBoris Brezillon 			break;
46378f3482dSBoris Brezillon 		case 6:
46401389b6bSBoris Brezillon 			mtd->oobsize = 640;
46501389b6bSBoris Brezillon 			break;
46678f3482dSBoris Brezillon 		default:
46778f3482dSBoris Brezillon 			/*
46878f3482dSBoris Brezillon 			 * We should never reach this case, but if that
46978f3482dSBoris Brezillon 			 * happens, this probably means Hynix decided to use
47078f3482dSBoris Brezillon 			 * a different extended ID format, and we should find
47178f3482dSBoris Brezillon 			 * a way to support it.
47278f3482dSBoris Brezillon 			 */
47378f3482dSBoris Brezillon 			WARN(1, "Invalid OOB size");
47478f3482dSBoris Brezillon 			break;
47578f3482dSBoris Brezillon 		}
476*16c4fba0SMartin Blumenstingl 
477*16c4fba0SMartin Blumenstingl 		/*
478*16c4fba0SMartin Blumenstingl 		 * The datasheet of H27UCG8T2BTR mentions that the "Redundant
479*16c4fba0SMartin Blumenstingl 		 * Area Size" is encoded "per 8KB" (page size). This chip uses
480*16c4fba0SMartin Blumenstingl 		 * a page size of 16KiB. The datasheet mentions an OOB size of
481*16c4fba0SMartin Blumenstingl 		 * 1.280 bytes, but the OOB size encoded in the ID bytes (using
482*16c4fba0SMartin Blumenstingl 		 * the existing logic above) is 640 bytes.
483*16c4fba0SMartin Blumenstingl 		 * Update the OOB size for this chip by taking the value
484*16c4fba0SMartin Blumenstingl 		 * determined above and scaling it to the actual page size (so
485*16c4fba0SMartin Blumenstingl 		 * the actual OOB size for this chip is: 640 * 16k / 8k).
486*16c4fba0SMartin Blumenstingl 		 */
487*16c4fba0SMartin Blumenstingl 		if (chip->id.data[1] == 0xde)
488*16c4fba0SMartin Blumenstingl 			mtd->oobsize *= mtd->writesize / SZ_8K;
48978f3482dSBoris Brezillon 	}
49001389b6bSBoris Brezillon }
49101389b6bSBoris Brezillon 
49278f3482dSBoris Brezillon static void hynix_nand_extract_ecc_requirements(struct nand_chip *chip,
49378f3482dSBoris Brezillon 						bool valid_jedecid)
49478f3482dSBoris Brezillon {
49578f3482dSBoris Brezillon 	u8 ecc_level = (chip->id.data[4] >> 4) & 0x7;
49678f3482dSBoris Brezillon 
49778f3482dSBoris Brezillon 	if (valid_jedecid) {
49878f3482dSBoris Brezillon 		/* Reference: H27UCG8T2E datasheet */
49978f3482dSBoris Brezillon 		chip->ecc_step_ds = 1024;
50078f3482dSBoris Brezillon 
50178f3482dSBoris Brezillon 		switch (ecc_level) {
50278f3482dSBoris Brezillon 		case 0:
50378f3482dSBoris Brezillon 			chip->ecc_step_ds = 0;
50478f3482dSBoris Brezillon 			chip->ecc_strength_ds = 0;
50578f3482dSBoris Brezillon 			break;
50678f3482dSBoris Brezillon 		case 1:
50778f3482dSBoris Brezillon 			chip->ecc_strength_ds = 4;
50878f3482dSBoris Brezillon 			break;
50978f3482dSBoris Brezillon 		case 2:
51078f3482dSBoris Brezillon 			chip->ecc_strength_ds = 24;
51178f3482dSBoris Brezillon 			break;
51278f3482dSBoris Brezillon 		case 3:
51378f3482dSBoris Brezillon 			chip->ecc_strength_ds = 32;
51478f3482dSBoris Brezillon 			break;
51578f3482dSBoris Brezillon 		case 4:
51678f3482dSBoris Brezillon 			chip->ecc_strength_ds = 40;
51778f3482dSBoris Brezillon 			break;
51878f3482dSBoris Brezillon 		case 5:
51978f3482dSBoris Brezillon 			chip->ecc_strength_ds = 50;
52078f3482dSBoris Brezillon 			break;
52178f3482dSBoris Brezillon 		case 6:
52278f3482dSBoris Brezillon 			chip->ecc_strength_ds = 60;
52378f3482dSBoris Brezillon 			break;
52478f3482dSBoris Brezillon 		default:
52578f3482dSBoris Brezillon 			/*
52678f3482dSBoris Brezillon 			 * We should never reach this case, but if that
52778f3482dSBoris Brezillon 			 * happens, this probably means Hynix decided to use
52878f3482dSBoris Brezillon 			 * a different extended ID format, and we should find
52978f3482dSBoris Brezillon 			 * a way to support it.
53078f3482dSBoris Brezillon 			 */
53178f3482dSBoris Brezillon 			WARN(1, "Invalid ECC requirements");
53201389b6bSBoris Brezillon 		}
53378f3482dSBoris Brezillon 	} else {
53478f3482dSBoris Brezillon 		/*
53578f3482dSBoris Brezillon 		 * The ECC requirements field meaning depends on the
53678f3482dSBoris Brezillon 		 * NAND technology.
53778f3482dSBoris Brezillon 		 */
538fd213b5bSMartin Blumenstingl 		u8 nand_tech = chip->id.data[5] & 0x7;
53978f3482dSBoris Brezillon 
54078f3482dSBoris Brezillon 		if (nand_tech < 3) {
54178f3482dSBoris Brezillon 			/* > 26nm, reference: H27UBG8T2A datasheet */
54278f3482dSBoris Brezillon 			if (ecc_level < 5) {
54378f3482dSBoris Brezillon 				chip->ecc_step_ds = 512;
54478f3482dSBoris Brezillon 				chip->ecc_strength_ds = 1 << ecc_level;
54578f3482dSBoris Brezillon 			} else if (ecc_level < 7) {
54678f3482dSBoris Brezillon 				if (ecc_level == 5)
54778f3482dSBoris Brezillon 					chip->ecc_step_ds = 2048;
54878f3482dSBoris Brezillon 				else
54978f3482dSBoris Brezillon 					chip->ecc_step_ds = 1024;
55078f3482dSBoris Brezillon 				chip->ecc_strength_ds = 24;
55178f3482dSBoris Brezillon 			} else {
55278f3482dSBoris Brezillon 				/*
55378f3482dSBoris Brezillon 				 * We should never reach this case, but if that
55478f3482dSBoris Brezillon 				 * happens, this probably means Hynix decided
55578f3482dSBoris Brezillon 				 * to use a different extended ID format, and
55678f3482dSBoris Brezillon 				 * we should find a way to support it.
55778f3482dSBoris Brezillon 				 */
55878f3482dSBoris Brezillon 				WARN(1, "Invalid ECC requirements");
55978f3482dSBoris Brezillon 			}
56078f3482dSBoris Brezillon 		} else {
56178f3482dSBoris Brezillon 			/* <= 26nm, reference: H27UBG8T2B datasheet */
56278f3482dSBoris Brezillon 			if (!ecc_level) {
56378f3482dSBoris Brezillon 				chip->ecc_step_ds = 0;
56478f3482dSBoris Brezillon 				chip->ecc_strength_ds = 0;
56578f3482dSBoris Brezillon 			} else if (ecc_level < 5) {
56678f3482dSBoris Brezillon 				chip->ecc_step_ds = 512;
56778f3482dSBoris Brezillon 				chip->ecc_strength_ds = 1 << (ecc_level - 1);
56878f3482dSBoris Brezillon 			} else {
56978f3482dSBoris Brezillon 				chip->ecc_step_ds = 1024;
57078f3482dSBoris Brezillon 				chip->ecc_strength_ds = 24 +
57178f3482dSBoris Brezillon 							(8 * (ecc_level - 5));
57278f3482dSBoris Brezillon 			}
57378f3482dSBoris Brezillon 		}
57478f3482dSBoris Brezillon 	}
57578f3482dSBoris Brezillon }
57678f3482dSBoris Brezillon 
57778f3482dSBoris Brezillon static void hynix_nand_extract_scrambling_requirements(struct nand_chip *chip,
57878f3482dSBoris Brezillon 						       bool valid_jedecid)
57978f3482dSBoris Brezillon {
58078f3482dSBoris Brezillon 	u8 nand_tech;
58178f3482dSBoris Brezillon 
58278f3482dSBoris Brezillon 	/* We need scrambling on all TLC NANDs*/
58378f3482dSBoris Brezillon 	if (chip->bits_per_cell > 2)
58478f3482dSBoris Brezillon 		chip->options |= NAND_NEED_SCRAMBLING;
58578f3482dSBoris Brezillon 
58678f3482dSBoris Brezillon 	/* And on MLC NANDs with sub-3xnm process */
58778f3482dSBoris Brezillon 	if (valid_jedecid) {
58878f3482dSBoris Brezillon 		nand_tech = chip->id.data[5] >> 4;
58978f3482dSBoris Brezillon 
59078f3482dSBoris Brezillon 		/* < 3xnm */
59178f3482dSBoris Brezillon 		if (nand_tech > 0)
59278f3482dSBoris Brezillon 			chip->options |= NAND_NEED_SCRAMBLING;
59378f3482dSBoris Brezillon 	} else {
594fd213b5bSMartin Blumenstingl 		nand_tech = chip->id.data[5] & 0x7;
59578f3482dSBoris Brezillon 
59678f3482dSBoris Brezillon 		/* < 32nm */
59778f3482dSBoris Brezillon 		if (nand_tech > 2)
59878f3482dSBoris Brezillon 			chip->options |= NAND_NEED_SCRAMBLING;
59978f3482dSBoris Brezillon 	}
60078f3482dSBoris Brezillon }
60178f3482dSBoris Brezillon 
60278f3482dSBoris Brezillon static void hynix_nand_decode_id(struct nand_chip *chip)
60378f3482dSBoris Brezillon {
60478f3482dSBoris Brezillon 	struct mtd_info *mtd = nand_to_mtd(chip);
60578f3482dSBoris Brezillon 	bool valid_jedecid;
60678f3482dSBoris Brezillon 	u8 tmp;
60778f3482dSBoris Brezillon 
60878f3482dSBoris Brezillon 	/*
60978f3482dSBoris Brezillon 	 * Exclude all SLC NANDs from this advanced detection scheme.
61078f3482dSBoris Brezillon 	 * According to the ranges defined in several datasheets, it might
61178f3482dSBoris Brezillon 	 * appear that even SLC NANDs could fall in this extended ID scheme.
61278f3482dSBoris Brezillon 	 * If that the case rework the test to let SLC NANDs go through the
61378f3482dSBoris Brezillon 	 * detection process.
61478f3482dSBoris Brezillon 	 */
61578f3482dSBoris Brezillon 	if (chip->id.len < 6 || nand_is_slc(chip)) {
61678f3482dSBoris Brezillon 		nand_decode_ext_id(chip);
61778f3482dSBoris Brezillon 		return;
61878f3482dSBoris Brezillon 	}
61978f3482dSBoris Brezillon 
62078f3482dSBoris Brezillon 	/* Extract pagesize */
62178f3482dSBoris Brezillon 	mtd->writesize = 2048 << (chip->id.data[3] & 0x03);
62278f3482dSBoris Brezillon 
62378f3482dSBoris Brezillon 	tmp = (chip->id.data[3] >> 4) & 0x3;
62478f3482dSBoris Brezillon 	/*
62578f3482dSBoris Brezillon 	 * When bit7 is set that means we start counting at 1MiB, otherwise
62678f3482dSBoris Brezillon 	 * we start counting at 128KiB and shift this value the content of
62778f3482dSBoris Brezillon 	 * ID[3][4:5].
62878f3482dSBoris Brezillon 	 * The only exception is when ID[3][4:5] == 3 and ID[3][7] == 0, in
62978f3482dSBoris Brezillon 	 * this case the erasesize is set to 768KiB.
63078f3482dSBoris Brezillon 	 */
63178f3482dSBoris Brezillon 	if (chip->id.data[3] & 0x80)
63278f3482dSBoris Brezillon 		mtd->erasesize = SZ_1M << tmp;
63378f3482dSBoris Brezillon 	else if (tmp == 3)
63478f3482dSBoris Brezillon 		mtd->erasesize = SZ_512K + SZ_256K;
63578f3482dSBoris Brezillon 	else
63678f3482dSBoris Brezillon 		mtd->erasesize = SZ_128K << tmp;
63778f3482dSBoris Brezillon 
63878f3482dSBoris Brezillon 	/*
63978f3482dSBoris Brezillon 	 * Modern Toggle DDR NANDs have a valid JEDECID even though they are
64078f3482dSBoris Brezillon 	 * not exposing a valid JEDEC parameter table.
64178f3482dSBoris Brezillon 	 * These NANDs use a different NAND ID scheme.
64278f3482dSBoris Brezillon 	 */
64378f3482dSBoris Brezillon 	valid_jedecid = hynix_nand_has_valid_jedecid(chip);
64478f3482dSBoris Brezillon 
64578f3482dSBoris Brezillon 	hynix_nand_extract_oobsize(chip, valid_jedecid);
64678f3482dSBoris Brezillon 	hynix_nand_extract_ecc_requirements(chip, valid_jedecid);
64778f3482dSBoris Brezillon 	hynix_nand_extract_scrambling_requirements(chip, valid_jedecid);
64801389b6bSBoris Brezillon }
64901389b6bSBoris Brezillon 
650626994e0SBoris Brezillon static void hynix_nand_cleanup(struct nand_chip *chip)
651626994e0SBoris Brezillon {
652626994e0SBoris Brezillon 	struct hynix_nand *hynix = nand_get_manufacturer_data(chip);
653626994e0SBoris Brezillon 
654626994e0SBoris Brezillon 	if (!hynix)
655626994e0SBoris Brezillon 		return;
656626994e0SBoris Brezillon 
657626994e0SBoris Brezillon 	kfree(hynix->read_retry);
658626994e0SBoris Brezillon 	kfree(hynix);
659626994e0SBoris Brezillon 	nand_set_manufacturer_data(chip, NULL);
660626994e0SBoris Brezillon }
661626994e0SBoris Brezillon 
66201389b6bSBoris Brezillon static int hynix_nand_init(struct nand_chip *chip)
66301389b6bSBoris Brezillon {
664626994e0SBoris Brezillon 	struct hynix_nand *hynix;
665626994e0SBoris Brezillon 	int ret;
666626994e0SBoris Brezillon 
66701389b6bSBoris Brezillon 	if (!nand_is_slc(chip))
66801389b6bSBoris Brezillon 		chip->bbt_options |= NAND_BBT_SCANLASTPAGE;
66901389b6bSBoris Brezillon 	else
67001389b6bSBoris Brezillon 		chip->bbt_options |= NAND_BBT_SCAN2NDPAGE;
67101389b6bSBoris Brezillon 
672626994e0SBoris Brezillon 	hynix = kzalloc(sizeof(*hynix), GFP_KERNEL);
673626994e0SBoris Brezillon 	if (!hynix)
674626994e0SBoris Brezillon 		return -ENOMEM;
675626994e0SBoris Brezillon 
676626994e0SBoris Brezillon 	nand_set_manufacturer_data(chip, hynix);
677626994e0SBoris Brezillon 
678626994e0SBoris Brezillon 	ret = hynix_nand_rr_init(chip);
679626994e0SBoris Brezillon 	if (ret)
680626994e0SBoris Brezillon 		hynix_nand_cleanup(chip);
681626994e0SBoris Brezillon 
682626994e0SBoris Brezillon 	return ret;
68301389b6bSBoris Brezillon }
68401389b6bSBoris Brezillon 
68501389b6bSBoris Brezillon const struct nand_manufacturer_ops hynix_nand_manuf_ops = {
68601389b6bSBoris Brezillon 	.detect = hynix_nand_decode_id,
68701389b6bSBoris Brezillon 	.init = hynix_nand_init,
688626994e0SBoris Brezillon 	.cleanup = hynix_nand_cleanup,
68901389b6bSBoris Brezillon };
690