1*c942fddfSThomas 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; 29626994e0SBoris Brezillon u8 values[0]; 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; 340626994e0SBoris Brezillon chip->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 { 49878f3482dSBoris Brezillon u8 ecc_level = (chip->id.data[4] >> 4) & 0x7; 49978f3482dSBoris Brezillon 50078f3482dSBoris Brezillon if (valid_jedecid) { 50178f3482dSBoris Brezillon /* Reference: H27UCG8T2E datasheet */ 5026a1b66d6SBoris Brezillon chip->base.eccreq.step_size = 1024; 50378f3482dSBoris Brezillon 50478f3482dSBoris Brezillon switch (ecc_level) { 50578f3482dSBoris Brezillon case 0: 5066a1b66d6SBoris Brezillon chip->base.eccreq.step_size = 0; 5076a1b66d6SBoris Brezillon chip->base.eccreq.strength = 0; 50878f3482dSBoris Brezillon break; 50978f3482dSBoris Brezillon case 1: 5106a1b66d6SBoris Brezillon chip->base.eccreq.strength = 4; 51178f3482dSBoris Brezillon break; 51278f3482dSBoris Brezillon case 2: 5136a1b66d6SBoris Brezillon chip->base.eccreq.strength = 24; 51478f3482dSBoris Brezillon break; 51578f3482dSBoris Brezillon case 3: 5166a1b66d6SBoris Brezillon chip->base.eccreq.strength = 32; 51778f3482dSBoris Brezillon break; 51878f3482dSBoris Brezillon case 4: 5196a1b66d6SBoris Brezillon chip->base.eccreq.strength = 40; 52078f3482dSBoris Brezillon break; 52178f3482dSBoris Brezillon case 5: 5226a1b66d6SBoris Brezillon chip->base.eccreq.strength = 50; 52378f3482dSBoris Brezillon break; 52478f3482dSBoris Brezillon case 6: 5256a1b66d6SBoris Brezillon chip->base.eccreq.strength = 60; 52678f3482dSBoris Brezillon break; 52778f3482dSBoris Brezillon default: 52878f3482dSBoris Brezillon /* 52978f3482dSBoris Brezillon * We should never reach this case, but if that 53078f3482dSBoris Brezillon * happens, this probably means Hynix decided to use 53178f3482dSBoris Brezillon * a different extended ID format, and we should find 53278f3482dSBoris Brezillon * a way to support it. 53378f3482dSBoris Brezillon */ 53478f3482dSBoris Brezillon WARN(1, "Invalid ECC requirements"); 53501389b6bSBoris Brezillon } 53678f3482dSBoris Brezillon } else { 53778f3482dSBoris Brezillon /* 53878f3482dSBoris Brezillon * The ECC requirements field meaning depends on the 53978f3482dSBoris Brezillon * NAND technology. 54078f3482dSBoris Brezillon */ 541fd213b5bSMartin Blumenstingl u8 nand_tech = chip->id.data[5] & 0x7; 54278f3482dSBoris Brezillon 54378f3482dSBoris Brezillon if (nand_tech < 3) { 54478f3482dSBoris Brezillon /* > 26nm, reference: H27UBG8T2A datasheet */ 54578f3482dSBoris Brezillon if (ecc_level < 5) { 5466a1b66d6SBoris Brezillon chip->base.eccreq.step_size = 512; 5476a1b66d6SBoris Brezillon chip->base.eccreq.strength = 1 << ecc_level; 54878f3482dSBoris Brezillon } else if (ecc_level < 7) { 54978f3482dSBoris Brezillon if (ecc_level == 5) 5506a1b66d6SBoris Brezillon chip->base.eccreq.step_size = 2048; 55178f3482dSBoris Brezillon else 5526a1b66d6SBoris Brezillon chip->base.eccreq.step_size = 1024; 5536a1b66d6SBoris Brezillon chip->base.eccreq.strength = 24; 55478f3482dSBoris Brezillon } else { 55578f3482dSBoris Brezillon /* 55678f3482dSBoris Brezillon * We should never reach this case, but if that 55778f3482dSBoris Brezillon * happens, this probably means Hynix decided 55878f3482dSBoris Brezillon * to use a different extended ID format, and 55978f3482dSBoris Brezillon * we should find a way to support it. 56078f3482dSBoris Brezillon */ 56178f3482dSBoris Brezillon WARN(1, "Invalid ECC requirements"); 56278f3482dSBoris Brezillon } 56378f3482dSBoris Brezillon } else { 56478f3482dSBoris Brezillon /* <= 26nm, reference: H27UBG8T2B datasheet */ 56578f3482dSBoris Brezillon if (!ecc_level) { 5666a1b66d6SBoris Brezillon chip->base.eccreq.step_size = 0; 5676a1b66d6SBoris Brezillon chip->base.eccreq.strength = 0; 56878f3482dSBoris Brezillon } else if (ecc_level < 5) { 5696a1b66d6SBoris Brezillon chip->base.eccreq.step_size = 512; 5706a1b66d6SBoris Brezillon chip->base.eccreq.strength = 1 << (ecc_level - 1); 57178f3482dSBoris Brezillon } else { 5726a1b66d6SBoris Brezillon chip->base.eccreq.step_size = 1024; 5736a1b66d6SBoris Brezillon chip->base.eccreq.strength = 24 + 57478f3482dSBoris Brezillon (8 * (ecc_level - 5)); 57578f3482dSBoris Brezillon } 57678f3482dSBoris Brezillon } 57778f3482dSBoris Brezillon } 57878f3482dSBoris Brezillon } 57978f3482dSBoris Brezillon 58078f3482dSBoris Brezillon static void hynix_nand_extract_scrambling_requirements(struct nand_chip *chip, 58178f3482dSBoris Brezillon bool valid_jedecid) 58278f3482dSBoris Brezillon { 58378f3482dSBoris Brezillon u8 nand_tech; 58478f3482dSBoris Brezillon 58578f3482dSBoris Brezillon /* We need scrambling on all TLC NANDs*/ 58629815168SBoris Brezillon if (nanddev_bits_per_cell(&chip->base) > 2) 58778f3482dSBoris Brezillon chip->options |= NAND_NEED_SCRAMBLING; 58878f3482dSBoris Brezillon 58978f3482dSBoris Brezillon /* And on MLC NANDs with sub-3xnm process */ 59078f3482dSBoris Brezillon if (valid_jedecid) { 59178f3482dSBoris Brezillon nand_tech = chip->id.data[5] >> 4; 59278f3482dSBoris Brezillon 59378f3482dSBoris Brezillon /* < 3xnm */ 59478f3482dSBoris Brezillon if (nand_tech > 0) 59578f3482dSBoris Brezillon chip->options |= NAND_NEED_SCRAMBLING; 59678f3482dSBoris Brezillon } else { 597fd213b5bSMartin Blumenstingl nand_tech = chip->id.data[5] & 0x7; 59878f3482dSBoris Brezillon 59978f3482dSBoris Brezillon /* < 32nm */ 60078f3482dSBoris Brezillon if (nand_tech > 2) 60178f3482dSBoris Brezillon chip->options |= NAND_NEED_SCRAMBLING; 60278f3482dSBoris Brezillon } 60378f3482dSBoris Brezillon } 60478f3482dSBoris Brezillon 60578f3482dSBoris Brezillon static void hynix_nand_decode_id(struct nand_chip *chip) 60678f3482dSBoris Brezillon { 60778f3482dSBoris Brezillon struct mtd_info *mtd = nand_to_mtd(chip); 608629a442cSBoris Brezillon struct nand_memory_organization *memorg; 60978f3482dSBoris Brezillon bool valid_jedecid; 61078f3482dSBoris Brezillon u8 tmp; 61178f3482dSBoris Brezillon 612629a442cSBoris Brezillon memorg = nanddev_get_memorg(&chip->base); 613629a442cSBoris Brezillon 61478f3482dSBoris Brezillon /* 61578f3482dSBoris Brezillon * Exclude all SLC NANDs from this advanced detection scheme. 61678f3482dSBoris Brezillon * According to the ranges defined in several datasheets, it might 61778f3482dSBoris Brezillon * appear that even SLC NANDs could fall in this extended ID scheme. 61878f3482dSBoris Brezillon * If that the case rework the test to let SLC NANDs go through the 61978f3482dSBoris Brezillon * detection process. 62078f3482dSBoris Brezillon */ 62178f3482dSBoris Brezillon if (chip->id.len < 6 || nand_is_slc(chip)) { 62278f3482dSBoris Brezillon nand_decode_ext_id(chip); 62378f3482dSBoris Brezillon return; 62478f3482dSBoris Brezillon } 62578f3482dSBoris Brezillon 62678f3482dSBoris Brezillon /* Extract pagesize */ 627629a442cSBoris Brezillon memorg->pagesize = 2048 << (chip->id.data[3] & 0x03); 628629a442cSBoris Brezillon mtd->writesize = memorg->pagesize; 62978f3482dSBoris Brezillon 63078f3482dSBoris Brezillon tmp = (chip->id.data[3] >> 4) & 0x3; 63178f3482dSBoris Brezillon /* 63278f3482dSBoris Brezillon * When bit7 is set that means we start counting at 1MiB, otherwise 63378f3482dSBoris Brezillon * we start counting at 128KiB and shift this value the content of 63478f3482dSBoris Brezillon * ID[3][4:5]. 63578f3482dSBoris Brezillon * The only exception is when ID[3][4:5] == 3 and ID[3][7] == 0, in 63678f3482dSBoris Brezillon * this case the erasesize is set to 768KiB. 63778f3482dSBoris Brezillon */ 638629a442cSBoris Brezillon if (chip->id.data[3] & 0x80) { 639629a442cSBoris Brezillon memorg->pages_per_eraseblock = (SZ_1M << tmp) / 640629a442cSBoris Brezillon memorg->pagesize; 64178f3482dSBoris Brezillon mtd->erasesize = SZ_1M << tmp; 642629a442cSBoris Brezillon } else if (tmp == 3) { 643629a442cSBoris Brezillon memorg->pages_per_eraseblock = (SZ_512K + SZ_256K) / 644629a442cSBoris Brezillon memorg->pagesize; 64578f3482dSBoris Brezillon mtd->erasesize = SZ_512K + SZ_256K; 646629a442cSBoris Brezillon } else { 647629a442cSBoris Brezillon memorg->pages_per_eraseblock = (SZ_128K << tmp) / 648629a442cSBoris Brezillon memorg->pagesize; 64978f3482dSBoris Brezillon mtd->erasesize = SZ_128K << tmp; 650629a442cSBoris Brezillon } 65178f3482dSBoris Brezillon 65278f3482dSBoris Brezillon /* 65378f3482dSBoris Brezillon * Modern Toggle DDR NANDs have a valid JEDECID even though they are 65478f3482dSBoris Brezillon * not exposing a valid JEDEC parameter table. 65578f3482dSBoris Brezillon * These NANDs use a different NAND ID scheme. 65678f3482dSBoris Brezillon */ 65778f3482dSBoris Brezillon valid_jedecid = hynix_nand_has_valid_jedecid(chip); 65878f3482dSBoris Brezillon 65978f3482dSBoris Brezillon hynix_nand_extract_oobsize(chip, valid_jedecid); 66078f3482dSBoris Brezillon hynix_nand_extract_ecc_requirements(chip, valid_jedecid); 66178f3482dSBoris Brezillon hynix_nand_extract_scrambling_requirements(chip, valid_jedecid); 66201389b6bSBoris Brezillon } 66301389b6bSBoris Brezillon 664626994e0SBoris Brezillon static void hynix_nand_cleanup(struct nand_chip *chip) 665626994e0SBoris Brezillon { 666626994e0SBoris Brezillon struct hynix_nand *hynix = nand_get_manufacturer_data(chip); 667626994e0SBoris Brezillon 668626994e0SBoris Brezillon if (!hynix) 669626994e0SBoris Brezillon return; 670626994e0SBoris Brezillon 671626994e0SBoris Brezillon kfree(hynix->read_retry); 672626994e0SBoris Brezillon kfree(hynix); 673626994e0SBoris Brezillon nand_set_manufacturer_data(chip, NULL); 674626994e0SBoris Brezillon } 675626994e0SBoris Brezillon 67601389b6bSBoris Brezillon static int hynix_nand_init(struct nand_chip *chip) 67701389b6bSBoris Brezillon { 678626994e0SBoris Brezillon struct hynix_nand *hynix; 679626994e0SBoris Brezillon int ret; 680626994e0SBoris Brezillon 68101389b6bSBoris Brezillon if (!nand_is_slc(chip)) 68204649ec1SFrieder Schrempf chip->options |= NAND_BBM_LASTPAGE; 68301389b6bSBoris Brezillon else 684bb592548SFrieder Schrempf chip->options |= NAND_BBM_FIRSTPAGE | NAND_BBM_SECONDPAGE; 68501389b6bSBoris Brezillon 686626994e0SBoris Brezillon hynix = kzalloc(sizeof(*hynix), GFP_KERNEL); 687626994e0SBoris Brezillon if (!hynix) 688626994e0SBoris Brezillon return -ENOMEM; 689626994e0SBoris Brezillon 690626994e0SBoris Brezillon nand_set_manufacturer_data(chip, hynix); 691626994e0SBoris Brezillon 692626994e0SBoris Brezillon ret = hynix_nand_rr_init(chip); 693626994e0SBoris Brezillon if (ret) 694626994e0SBoris Brezillon hynix_nand_cleanup(chip); 695626994e0SBoris Brezillon 696626994e0SBoris Brezillon return ret; 69701389b6bSBoris Brezillon } 69801389b6bSBoris Brezillon 69901389b6bSBoris Brezillon const struct nand_manufacturer_ops hynix_nand_manuf_ops = { 70001389b6bSBoris Brezillon .detect = hynix_nand_decode_id, 70101389b6bSBoris Brezillon .init = hynix_nand_init, 702626994e0SBoris Brezillon .cleanup = hynix_nand_cleanup, 70301389b6bSBoris Brezillon }; 704