Commit f1b6c814f70431be638f99bef8404a51c9a87349

Authored by Han Xu
1 parent 55dbdd9d56

MLK-20962: Support legacy full id NAND in SPL

Current SPL code only support ONFI-compatible NAND, porting the code
from nand_base.c to support legacy full id NAND chips, such as Toshiba
TC58NVG2S0H.

Signed-off-by: Han Xu <han.xu@nxp.com>
(cherry picked from commit 4086c6b9556acbec2a8748578eb4a9e719ab4ae7)

Showing 2 changed files with 65 additions and 6 deletions Side-by-side Diff

drivers/mtd/nand/Makefile
... ... @@ -72,6 +72,7 @@
72 72 obj-$(CONFIG_NAND_FSL_ELBC) += fsl_elbc_spl.o
73 73 obj-$(CONFIG_NAND_FSL_IFC) += fsl_ifc_spl.o
74 74 obj-$(CONFIG_NAND_MXC) += mxc_nand_spl.o
  75 +obj-y += nand_ids.o
75 76 obj-$(CONFIG_NAND_MXS) += mxs_nand_spl.o mxs_nand.o
76 77 obj-$(CONFIG_NAND_SUNXI) += sunxi_nand_spl.o
77 78  
drivers/mtd/nand/mxs_nand_spl.c
1 1 /*
2 2 * Copyright (C) 2014 Gateworks Corporation
  3 + * Copyright 2019 NXP
3 4 * Author: Tim Harvey <tharvey@gateworks.com>
4 5 *
5 6 * SPDX-License-Identifier: GPL-2.0+
... ... @@ -7,6 +8,7 @@
7 8 #include <common.h>
8 9 #include <nand.h>
9 10 #include <malloc.h>
  11 +#include <linux/mtd/rawnand.h>
10 12  
11 13 static struct mtd_info *mtd;
12 14 static struct nand_chip nand_chip;
13 15  
14 16  
15 17  
... ... @@ -140,14 +142,55 @@
140 142 return ret;
141 143 }
142 144  
  145 +/* Extract the bits of per cell from the 3rd byte of the extended ID */
  146 +static int nand_get_bits_per_cell(u8 cellinfo)
  147 +{
  148 + int bits;
143 149  
144   -static int mxs_flash_ident(struct mtd_info *mtd)
  150 + bits = cellinfo & NAND_CI_CELLTYPE_MSK;
  151 + bits >>= NAND_CI_CELLTYPE_SHIFT;
  152 + return bits + 1;
  153 +}
  154 +
  155 +static inline bool is_full_id_nand(struct nand_flash_dev *type)
145 156 {
  157 + return type->id_len;
  158 +}
  159 +
  160 +static bool find_full_id_nand(struct mtd_info *mtd, struct nand_chip *chip,
  161 + struct nand_flash_dev *type, u8 *id_data, int *busw)
  162 +{
  163 + if (!strncmp((char *)type->id, (char *)id_data, type->id_len)) {
  164 + mtd->writesize = type->pagesize;
  165 + mtd->erasesize = type->erasesize;
  166 + mtd->oobsize = type->oobsize;
  167 +
  168 + chip->bits_per_cell = nand_get_bits_per_cell(id_data[2]);
  169 + chip->chipsize = (uint64_t)type->chipsize << 20;
  170 + chip->options |= type->options;
  171 + chip->ecc_strength_ds = NAND_ECC_STRENGTH(type);
  172 + chip->ecc_step_ds = NAND_ECC_STEP(type);
  173 + chip->onfi_timing_mode_default =
  174 + type->onfi_timing_mode_default;
  175 +
  176 + *busw = type->options & NAND_BUSWIDTH_16;
  177 +
  178 + if (!mtd->name)
  179 + mtd->name = type->name;
  180 +
  181 + return true;
  182 + }
  183 + return false;
  184 +}
  185 +
  186 +static int mxs_flash_ident(struct mtd_info *mtd, struct nand_flash_dev *type)
  187 +{
146 188 register struct nand_chip *chip = mtd_to_nand(mtd);
147 189 int i, val;
148 190 u8 mfg_id, dev_id;
149 191 u8 id_data[8];
150 192 struct nand_onfi_params *p = &chip->onfi_params;
  193 + int busw = 0;
151 194  
152 195 /* Reset the chip */
153 196 chip->cmdfunc(mtd, NAND_CMD_RESET, -1, -1);
... ... @@ -169,6 +212,18 @@
169 212 }
170 213 debug("0x%02x:0x%02x ", mfg_id, dev_id);
171 214  
  215 + if (!type)
  216 + type = nand_flash_ids;
  217 +
  218 + for (; type->name != NULL; type++) {
  219 + if (is_full_id_nand(type)) {
  220 + if (find_full_id_nand(mtd, chip, type, id_data, &busw))
  221 + goto ident_done;
  222 + } else if (dev_id == type->dev_id) {
  223 + break;
  224 + }
  225 + }
  226 +
172 227 /* read ONFI */
173 228 chip->onfi_version = 0;
174 229 chip->cmdfunc(mtd, NAND_CMD_READID, 0x20, -1);
175 230  
176 231  
... ... @@ -223,11 +278,14 @@
223 278 printf("Could not retrieve ONFI ECC requirements\n");
224 279 }
225 280  
  281 +ident_done:
  282 + chip->page_shift = ffs(mtd->writesize) - 1;
  283 + chip->phys_erase_shift = ffs(mtd->erasesize) - 1;
226 284 debug("ecc_strength_ds %u, ecc_step_ds %u\n", chip->ecc_strength_ds, chip->ecc_step_ds);
227   - debug("erasesize=%d (>>%d)\n", mtd->erasesize, chip->phys_erase_shift);
228   - debug("writesize=%d (>>%d)\n", mtd->writesize, chip->page_shift);
  285 + debug("erasesize=%x (>>%d)\n", mtd->erasesize, chip->phys_erase_shift);
  286 + debug("writesize=%x (>>%d)\n", mtd->writesize, chip->page_shift);
229 287 debug("oobsize=%d\n", mtd->oobsize);
230   - debug("chipsize=%lld\n", chip->chipsize);
  288 + debug("chipsize=%llx\n", chip->chipsize);
231 289  
232 290 return 0;
233 291 }
... ... @@ -276,7 +334,7 @@
276 334 nand_chip.numchips = 1;
277 335  
278 336 /* identify flash device */
279   - if (mxs_flash_ident(mtd)) {
  337 + if (mxs_flash_ident(mtd, NULL)) {
280 338 printf("Failed to identify\n");
281 339 return -1;
282 340 }
... ... @@ -314,7 +372,7 @@
314 372 page_off = offs & (mtd->writesize - 1);
315 373 nand_page_per_block = mtd->erasesize / mtd->writesize;
316 374  
317   - debug("%s offset:0x%08x len:%d page:%d\n", __func__, offs, size, page);
  375 + debug("%s offset:0x%08x len:%d page:%x\n", __func__, offs, size, page);
318 376  
319 377 while (size) {
320 378 if (mxs_read_page_ecc(mtd, page_buf, page) < 0)