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