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 Inline Diff

drivers/mtd/nand/Makefile
1 # 1 #
2 # (C) Copyright 2006 2 # (C) Copyright 2006
3 # Wolfgang Denk, DENX Software Engineering, wd@denx.de. 3 # Wolfgang Denk, DENX Software Engineering, wd@denx.de.
4 # 4 #
5 # SPDX-License-Identifier: GPL-2.0+ 5 # SPDX-License-Identifier: GPL-2.0+
6 # 6 #
7 7
8 ifdef CONFIG_SPL_BUILD 8 ifdef CONFIG_SPL_BUILD
9 9
10 ifdef CONFIG_SPL_NAND_DRIVERS 10 ifdef CONFIG_SPL_NAND_DRIVERS
11 NORMAL_DRIVERS=y 11 NORMAL_DRIVERS=y
12 endif 12 endif
13 13
14 obj-$(CONFIG_SPL_NAND_AM33XX_BCH) += am335x_spl_bch.o 14 obj-$(CONFIG_SPL_NAND_AM33XX_BCH) += am335x_spl_bch.o
15 obj-$(CONFIG_SPL_NAND_DENALI) += denali_spl.o 15 obj-$(CONFIG_SPL_NAND_DENALI) += denali_spl.o
16 obj-$(CONFIG_SPL_NAND_SIMPLE) += nand_spl_simple.o 16 obj-$(CONFIG_SPL_NAND_SIMPLE) += nand_spl_simple.o
17 obj-$(CONFIG_SPL_NAND_LOAD) += nand_spl_load.o 17 obj-$(CONFIG_SPL_NAND_LOAD) += nand_spl_load.o
18 obj-$(CONFIG_SPL_NAND_ECC) += nand_ecc.o 18 obj-$(CONFIG_SPL_NAND_ECC) += nand_ecc.o
19 obj-$(CONFIG_SPL_NAND_BASE) += nand_base.o 19 obj-$(CONFIG_SPL_NAND_BASE) += nand_base.o
20 obj-$(CONFIG_SPL_NAND_INIT) += nand.o 20 obj-$(CONFIG_SPL_NAND_INIT) += nand.o
21 ifeq ($(CONFIG_SPL_ENV_SUPPORT),y) 21 ifeq ($(CONFIG_SPL_ENV_SUPPORT),y)
22 obj-$(CONFIG_ENV_IS_IN_NAND) += nand_util.o 22 obj-$(CONFIG_ENV_IS_IN_NAND) += nand_util.o
23 endif 23 endif
24 24
25 else # not spl 25 else # not spl
26 26
27 NORMAL_DRIVERS=y 27 NORMAL_DRIVERS=y
28 28
29 obj-y += nand.o 29 obj-y += nand.o
30 obj-y += nand_bbt.o 30 obj-y += nand_bbt.o
31 obj-y += nand_ids.o 31 obj-y += nand_ids.o
32 obj-y += nand_util.o 32 obj-y += nand_util.o
33 obj-y += nand_ecc.o 33 obj-y += nand_ecc.o
34 obj-y += nand_base.o 34 obj-y += nand_base.o
35 obj-y += nand_timings.o 35 obj-y += nand_timings.o
36 36
37 endif # not spl 37 endif # not spl
38 38
39 ifdef NORMAL_DRIVERS 39 ifdef NORMAL_DRIVERS
40 40
41 obj-$(CONFIG_NAND_ECC_BCH) += nand_bch.o 41 obj-$(CONFIG_NAND_ECC_BCH) += nand_bch.o
42 42
43 obj-$(CONFIG_NAND_ATMEL) += atmel_nand.o 43 obj-$(CONFIG_NAND_ATMEL) += atmel_nand.o
44 obj-$(CONFIG_NAND_ARASAN) += arasan_nfc.o 44 obj-$(CONFIG_NAND_ARASAN) += arasan_nfc.o
45 obj-$(CONFIG_NAND_DAVINCI) += davinci_nand.o 45 obj-$(CONFIG_NAND_DAVINCI) += davinci_nand.o
46 obj-$(CONFIG_NAND_DENALI) += denali.o 46 obj-$(CONFIG_NAND_DENALI) += denali.o
47 obj-$(CONFIG_NAND_DENALI_DT) += denali_dt.o 47 obj-$(CONFIG_NAND_DENALI_DT) += denali_dt.o
48 obj-$(CONFIG_NAND_FSL_ELBC) += fsl_elbc_nand.o 48 obj-$(CONFIG_NAND_FSL_ELBC) += fsl_elbc_nand.o
49 obj-$(CONFIG_NAND_FSL_IFC) += fsl_ifc_nand.o 49 obj-$(CONFIG_NAND_FSL_IFC) += fsl_ifc_nand.o
50 obj-$(CONFIG_NAND_FSL_UPM) += fsl_upm.o 50 obj-$(CONFIG_NAND_FSL_UPM) += fsl_upm.o
51 obj-$(CONFIG_NAND_FSMC) += fsmc_nand.o 51 obj-$(CONFIG_NAND_FSMC) += fsmc_nand.o
52 obj-$(CONFIG_NAND_KB9202) += kb9202_nand.o 52 obj-$(CONFIG_NAND_KB9202) += kb9202_nand.o
53 obj-$(CONFIG_NAND_KIRKWOOD) += kirkwood_nand.o 53 obj-$(CONFIG_NAND_KIRKWOOD) += kirkwood_nand.o
54 obj-$(CONFIG_NAND_KMETER1) += kmeter1_nand.o 54 obj-$(CONFIG_NAND_KMETER1) += kmeter1_nand.o
55 obj-$(CONFIG_NAND_LPC32XX_MLC) += lpc32xx_nand_mlc.o 55 obj-$(CONFIG_NAND_LPC32XX_MLC) += lpc32xx_nand_mlc.o
56 obj-$(CONFIG_NAND_LPC32XX_SLC) += lpc32xx_nand_slc.o 56 obj-$(CONFIG_NAND_LPC32XX_SLC) += lpc32xx_nand_slc.o
57 obj-$(CONFIG_NAND_VF610_NFC) += vf610_nfc.o 57 obj-$(CONFIG_NAND_VF610_NFC) += vf610_nfc.o
58 obj-$(CONFIG_NAND_MXC) += mxc_nand.o 58 obj-$(CONFIG_NAND_MXC) += mxc_nand.o
59 obj-$(CONFIG_NAND_MXS) += mxs_nand.o 59 obj-$(CONFIG_NAND_MXS) += mxs_nand.o
60 obj-$(CONFIG_NAND_NDFC) += ndfc.o 60 obj-$(CONFIG_NAND_NDFC) += ndfc.o
61 obj-$(CONFIG_NAND_PXA3XX) += pxa3xx_nand.o 61 obj-$(CONFIG_NAND_PXA3XX) += pxa3xx_nand.o
62 obj-$(CONFIG_NAND_SPEAR) += spr_nand.o 62 obj-$(CONFIG_NAND_SPEAR) += spr_nand.o
63 obj-$(CONFIG_TEGRA_NAND) += tegra_nand.o 63 obj-$(CONFIG_TEGRA_NAND) += tegra_nand.o
64 obj-$(CONFIG_NAND_OMAP_GPMC) += omap_gpmc.o 64 obj-$(CONFIG_NAND_OMAP_GPMC) += omap_gpmc.o
65 obj-$(CONFIG_NAND_OMAP_ELM) += omap_elm.o 65 obj-$(CONFIG_NAND_OMAP_ELM) += omap_elm.o
66 obj-$(CONFIG_NAND_PLAT) += nand_plat.o 66 obj-$(CONFIG_NAND_PLAT) += nand_plat.o
67 obj-$(CONFIG_NAND_SUNXI) += sunxi_nand.o 67 obj-$(CONFIG_NAND_SUNXI) += sunxi_nand.o
68 obj-$(CONFIG_NAND_ZYNQ) += zynq_nand.o 68 obj-$(CONFIG_NAND_ZYNQ) += zynq_nand.o
69 69
70 else # minimal SPL drivers 70 else # minimal SPL drivers
71 71
72 obj-$(CONFIG_NAND_FSL_ELBC) += fsl_elbc_spl.o 72 obj-$(CONFIG_NAND_FSL_ELBC) += fsl_elbc_spl.o
73 obj-$(CONFIG_NAND_FSL_IFC) += fsl_ifc_spl.o 73 obj-$(CONFIG_NAND_FSL_IFC) += fsl_ifc_spl.o
74 obj-$(CONFIG_NAND_MXC) += mxc_nand_spl.o 74 obj-$(CONFIG_NAND_MXC) += mxc_nand_spl.o
75 obj-y += nand_ids.o
75 obj-$(CONFIG_NAND_MXS) += mxs_nand_spl.o mxs_nand.o 76 obj-$(CONFIG_NAND_MXS) += mxs_nand_spl.o mxs_nand.o
76 obj-$(CONFIG_NAND_SUNXI) += sunxi_nand_spl.o 77 obj-$(CONFIG_NAND_SUNXI) += sunxi_nand_spl.o
77 78
78 endif # drivers 79 endif # drivers
79 80
drivers/mtd/nand/mxs_nand_spl.c
1 /* 1 /*
2 * Copyright (C) 2014 Gateworks Corporation 2 * Copyright (C) 2014 Gateworks Corporation
3 * Copyright 2019 NXP
3 * Author: Tim Harvey <tharvey@gateworks.com> 4 * Author: Tim Harvey <tharvey@gateworks.com>
4 * 5 *
5 * SPDX-License-Identifier: GPL-2.0+ 6 * SPDX-License-Identifier: GPL-2.0+
6 */ 7 */
7 #include <common.h> 8 #include <common.h>
8 #include <nand.h> 9 #include <nand.h>
9 #include <malloc.h> 10 #include <malloc.h>
11 #include <linux/mtd/rawnand.h>
10 12
11 static struct mtd_info *mtd; 13 static struct mtd_info *mtd;
12 static struct nand_chip nand_chip; 14 static struct nand_chip nand_chip;
13 15
14 static void mxs_nand_command(struct mtd_info *mtd, unsigned int command, 16 static void mxs_nand_command(struct mtd_info *mtd, unsigned int command,
15 int column, int page_addr) 17 int column, int page_addr)
16 { 18 {
17 register struct nand_chip *chip = mtd_to_nand(mtd); 19 register struct nand_chip *chip = mtd_to_nand(mtd);
18 u32 timeo, time_start; 20 u32 timeo, time_start;
19 21
20 /* write out the command to the device */ 22 /* write out the command to the device */
21 chip->cmd_ctrl(mtd, command, NAND_CLE); 23 chip->cmd_ctrl(mtd, command, NAND_CLE);
22 24
23 /* Serially input address */ 25 /* Serially input address */
24 if (column != -1) { 26 if (column != -1) {
25 chip->cmd_ctrl(mtd, column, NAND_ALE); 27 chip->cmd_ctrl(mtd, column, NAND_ALE);
26 chip->cmd_ctrl(mtd, column >> 8, NAND_ALE); 28 chip->cmd_ctrl(mtd, column >> 8, NAND_ALE);
27 } 29 }
28 if (page_addr != -1) { 30 if (page_addr != -1) {
29 chip->cmd_ctrl(mtd, page_addr, NAND_ALE); 31 chip->cmd_ctrl(mtd, page_addr, NAND_ALE);
30 chip->cmd_ctrl(mtd, page_addr >> 8, NAND_ALE); 32 chip->cmd_ctrl(mtd, page_addr >> 8, NAND_ALE);
31 /* One more address cycle for devices > 128MiB */ 33 /* One more address cycle for devices > 128MiB */
32 if (chip->chipsize > (128 << 20)) 34 if (chip->chipsize > (128 << 20))
33 chip->cmd_ctrl(mtd, page_addr >> 16, NAND_ALE); 35 chip->cmd_ctrl(mtd, page_addr >> 16, NAND_ALE);
34 } 36 }
35 chip->cmd_ctrl(mtd, NAND_CMD_NONE, 0); 37 chip->cmd_ctrl(mtd, NAND_CMD_NONE, 0);
36 38
37 if (command == NAND_CMD_READ0) { 39 if (command == NAND_CMD_READ0) {
38 chip->cmd_ctrl(mtd, NAND_CMD_READSTART, NAND_CLE); 40 chip->cmd_ctrl(mtd, NAND_CMD_READSTART, NAND_CLE);
39 chip->cmd_ctrl(mtd, NAND_CMD_NONE, 0); 41 chip->cmd_ctrl(mtd, NAND_CMD_NONE, 0);
40 } else if (command == NAND_CMD_RNDOUT) { 42 } else if (command == NAND_CMD_RNDOUT) {
41 /* No ready / busy check necessary */ 43 /* No ready / busy check necessary */
42 chip->cmd_ctrl(mtd, NAND_CMD_RNDOUTSTART, 44 chip->cmd_ctrl(mtd, NAND_CMD_RNDOUTSTART,
43 NAND_NCE | NAND_CLE); 45 NAND_NCE | NAND_CLE);
44 chip->cmd_ctrl(mtd, NAND_CMD_NONE, 46 chip->cmd_ctrl(mtd, NAND_CMD_NONE,
45 NAND_NCE); 47 NAND_NCE);
46 } 48 }
47 49
48 /* wait for nand ready */ 50 /* wait for nand ready */
49 ndelay(100); 51 ndelay(100);
50 timeo = (CONFIG_SYS_HZ * 20) / 1000; 52 timeo = (CONFIG_SYS_HZ * 20) / 1000;
51 time_start = get_timer(0); 53 time_start = get_timer(0);
52 while (get_timer(time_start) < timeo) { 54 while (get_timer(time_start) < timeo) {
53 if (chip->dev_ready(mtd)) 55 if (chip->dev_ready(mtd))
54 break; 56 break;
55 } 57 }
56 } 58 }
57 59
58 static u16 onfi_crc16(u16 crc, u8 const *p, size_t len) 60 static u16 onfi_crc16(u16 crc, u8 const *p, size_t len)
59 { 61 {
60 int i; 62 int i;
61 while (len--) { 63 while (len--) {
62 crc ^= *p++ << 8; 64 crc ^= *p++ << 8;
63 for (i = 0; i < 8; i++) 65 for (i = 0; i < 8; i++)
64 crc = (crc << 1) ^ ((crc & 0x8000) ? 0x8005 : 0); 66 crc = (crc << 1) ^ ((crc & 0x8000) ? 0x8005 : 0);
65 } 67 }
66 68
67 return crc; 69 return crc;
68 } 70 }
69 71
70 /* Parse the Extended Parameter Page. */ 72 /* Parse the Extended Parameter Page. */
71 static int nand_flash_detect_ext_param_page(struct mtd_info *mtd, 73 static int nand_flash_detect_ext_param_page(struct mtd_info *mtd,
72 struct nand_chip *chip, struct nand_onfi_params *p) 74 struct nand_chip *chip, struct nand_onfi_params *p)
73 { 75 {
74 struct onfi_ext_param_page *ep; 76 struct onfi_ext_param_page *ep;
75 struct onfi_ext_section *s; 77 struct onfi_ext_section *s;
76 struct onfi_ext_ecc_info *ecc; 78 struct onfi_ext_ecc_info *ecc;
77 uint8_t *cursor; 79 uint8_t *cursor;
78 int ret = -EINVAL; 80 int ret = -EINVAL;
79 int len; 81 int len;
80 int i; 82 int i;
81 83
82 len = le16_to_cpu(p->ext_param_page_length) * 16; 84 len = le16_to_cpu(p->ext_param_page_length) * 16;
83 ep = malloc(len); 85 ep = malloc(len);
84 if (!ep) { 86 if (!ep) {
85 printf("can't malloc memory 0x%x\n", len); 87 printf("can't malloc memory 0x%x\n", len);
86 return -ENOMEM; 88 return -ENOMEM;
87 } 89 }
88 90
89 /* Send our own NAND_CMD_PARAM. */ 91 /* Send our own NAND_CMD_PARAM. */
90 chip->cmdfunc(mtd, NAND_CMD_PARAM, 0, -1); 92 chip->cmdfunc(mtd, NAND_CMD_PARAM, 0, -1);
91 93
92 /* Use the Change Read Column command to skip the ONFI param pages. */ 94 /* Use the Change Read Column command to skip the ONFI param pages. */
93 chip->cmdfunc(mtd, NAND_CMD_RNDOUT, 95 chip->cmdfunc(mtd, NAND_CMD_RNDOUT,
94 sizeof(*p) * p->num_of_param_pages , -1); 96 sizeof(*p) * p->num_of_param_pages , -1);
95 97
96 /* Read out the Extended Parameter Page. */ 98 /* Read out the Extended Parameter Page. */
97 chip->read_buf(mtd, (uint8_t *)ep, len); 99 chip->read_buf(mtd, (uint8_t *)ep, len);
98 if ((onfi_crc16(ONFI_CRC_BASE, ((uint8_t *)ep) + 2, len - 2) 100 if ((onfi_crc16(ONFI_CRC_BASE, ((uint8_t *)ep) + 2, len - 2)
99 != le16_to_cpu(ep->crc))) { 101 != le16_to_cpu(ep->crc))) {
100 printf("fail in the CRC.\n"); 102 printf("fail in the CRC.\n");
101 goto ext_out; 103 goto ext_out;
102 } 104 }
103 105
104 /* 106 /*
105 * Check the signature. 107 * Check the signature.
106 * Do not strictly follow the ONFI spec, maybe changed in future. 108 * Do not strictly follow the ONFI spec, maybe changed in future.
107 */ 109 */
108 if (strncmp((char *)ep->sig, "EPPS", 4)) { 110 if (strncmp((char *)ep->sig, "EPPS", 4)) {
109 printf("The signature is invalid.\n"); 111 printf("The signature is invalid.\n");
110 goto ext_out; 112 goto ext_out;
111 } 113 }
112 114
113 /* find the ECC section. */ 115 /* find the ECC section. */
114 cursor = (uint8_t *)(ep + 1); 116 cursor = (uint8_t *)(ep + 1);
115 for (i = 0; i < ONFI_EXT_SECTION_MAX; i++) { 117 for (i = 0; i < ONFI_EXT_SECTION_MAX; i++) {
116 s = ep->sections + i; 118 s = ep->sections + i;
117 if (s->type == ONFI_SECTION_TYPE_2) 119 if (s->type == ONFI_SECTION_TYPE_2)
118 break; 120 break;
119 cursor += s->length * 16; 121 cursor += s->length * 16;
120 } 122 }
121 if (i == ONFI_EXT_SECTION_MAX) { 123 if (i == ONFI_EXT_SECTION_MAX) {
122 printf("We can not find the ECC section.\n"); 124 printf("We can not find the ECC section.\n");
123 goto ext_out; 125 goto ext_out;
124 } 126 }
125 127
126 /* get the info we want. */ 128 /* get the info we want. */
127 ecc = (struct onfi_ext_ecc_info *)cursor; 129 ecc = (struct onfi_ext_ecc_info *)cursor;
128 130
129 if (!ecc->codeword_size) { 131 if (!ecc->codeword_size) {
130 printf("Invalid codeword size\n"); 132 printf("Invalid codeword size\n");
131 goto ext_out; 133 goto ext_out;
132 } 134 }
133 135
134 chip->ecc_strength_ds = ecc->ecc_bits; 136 chip->ecc_strength_ds = ecc->ecc_bits;
135 chip->ecc_step_ds = 1 << ecc->codeword_size; 137 chip->ecc_step_ds = 1 << ecc->codeword_size;
136 ret = 0; 138 ret = 0;
137 139
138 ext_out: 140 ext_out:
139 free(ep); 141 free(ep);
140 return ret; 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 register struct nand_chip *chip = mtd_to_nand(mtd); 188 register struct nand_chip *chip = mtd_to_nand(mtd);
147 int i, val; 189 int i, val;
148 u8 mfg_id, dev_id; 190 u8 mfg_id, dev_id;
149 u8 id_data[8]; 191 u8 id_data[8];
150 struct nand_onfi_params *p = &chip->onfi_params; 192 struct nand_onfi_params *p = &chip->onfi_params;
193 int busw = 0;
151 194
152 /* Reset the chip */ 195 /* Reset the chip */
153 chip->cmdfunc(mtd, NAND_CMD_RESET, -1, -1); 196 chip->cmdfunc(mtd, NAND_CMD_RESET, -1, -1);
154 197
155 /* Send the command for reading device ID */ 198 /* Send the command for reading device ID */
156 chip->cmdfunc(mtd, NAND_CMD_READID, 0x00, -1); 199 chip->cmdfunc(mtd, NAND_CMD_READID, 0x00, -1);
157 200
158 /* Read manufacturer and device IDs */ 201 /* Read manufacturer and device IDs */
159 mfg_id = chip->read_byte(mtd); 202 mfg_id = chip->read_byte(mtd);
160 dev_id = chip->read_byte(mtd); 203 dev_id = chip->read_byte(mtd);
161 204
162 /* Try again to make sure */ 205 /* Try again to make sure */
163 chip->cmdfunc(mtd, NAND_CMD_READID, 0x00, -1); 206 chip->cmdfunc(mtd, NAND_CMD_READID, 0x00, -1);
164 for (i = 0; i < 8; i++) 207 for (i = 0; i < 8; i++)
165 id_data[i] = chip->read_byte(mtd); 208 id_data[i] = chip->read_byte(mtd);
166 if (id_data[0] != mfg_id || id_data[1] != dev_id) { 209 if (id_data[0] != mfg_id || id_data[1] != dev_id) {
167 printf("second ID read did not match"); 210 printf("second ID read did not match");
168 return -1; 211 return -1;
169 } 212 }
170 debug("0x%02x:0x%02x ", mfg_id, dev_id); 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 /* read ONFI */ 227 /* read ONFI */
173 chip->onfi_version = 0; 228 chip->onfi_version = 0;
174 chip->cmdfunc(mtd, NAND_CMD_READID, 0x20, -1); 229 chip->cmdfunc(mtd, NAND_CMD_READID, 0x20, -1);
175 if (chip->read_byte(mtd) != 'O' || chip->read_byte(mtd) != 'N' || 230 if (chip->read_byte(mtd) != 'O' || chip->read_byte(mtd) != 'N' ||
176 chip->read_byte(mtd) != 'F' || chip->read_byte(mtd) != 'I') { 231 chip->read_byte(mtd) != 'F' || chip->read_byte(mtd) != 'I') {
177 return -2; 232 return -2;
178 } 233 }
179 234
180 /* we have ONFI, probe it */ 235 /* we have ONFI, probe it */
181 chip->cmdfunc(mtd, NAND_CMD_PARAM, 0, -1); 236 chip->cmdfunc(mtd, NAND_CMD_PARAM, 0, -1);
182 chip->read_buf(mtd, (uint8_t *)p, sizeof(*p)); 237 chip->read_buf(mtd, (uint8_t *)p, sizeof(*p));
183 mtd->name = p->model; 238 mtd->name = p->model;
184 mtd->writesize = le32_to_cpu(p->byte_per_page); 239 mtd->writesize = le32_to_cpu(p->byte_per_page);
185 mtd->erasesize = le32_to_cpu(p->pages_per_block) * mtd->writesize; 240 mtd->erasesize = le32_to_cpu(p->pages_per_block) * mtd->writesize;
186 mtd->oobsize = le16_to_cpu(p->spare_bytes_per_page); 241 mtd->oobsize = le16_to_cpu(p->spare_bytes_per_page);
187 chip->chipsize = le32_to_cpu(p->blocks_per_lun); 242 chip->chipsize = le32_to_cpu(p->blocks_per_lun);
188 chip->chipsize *= (uint64_t)mtd->erasesize * p->lun_count; 243 chip->chipsize *= (uint64_t)mtd->erasesize * p->lun_count;
189 /* Calculate the address shift from the page size */ 244 /* Calculate the address shift from the page size */
190 chip->page_shift = ffs(mtd->writesize) - 1; 245 chip->page_shift = ffs(mtd->writesize) - 1;
191 chip->phys_erase_shift = ffs(mtd->erasesize) - 1; 246 chip->phys_erase_shift = ffs(mtd->erasesize) - 1;
192 /* Convert chipsize to number of pages per chip -1 */ 247 /* Convert chipsize to number of pages per chip -1 */
193 chip->pagemask = (chip->chipsize >> chip->page_shift) - 1; 248 chip->pagemask = (chip->chipsize >> chip->page_shift) - 1;
194 chip->badblockbits = 8; 249 chip->badblockbits = 8;
195 250
196 /* Check version */ 251 /* Check version */
197 val = le16_to_cpu(p->revision); 252 val = le16_to_cpu(p->revision);
198 if (val & (1 << 5)) 253 if (val & (1 << 5))
199 chip->onfi_version = 23; 254 chip->onfi_version = 23;
200 else if (val & (1 << 4)) 255 else if (val & (1 << 4))
201 chip->onfi_version = 22; 256 chip->onfi_version = 22;
202 else if (val & (1 << 3)) 257 else if (val & (1 << 3))
203 chip->onfi_version = 21; 258 chip->onfi_version = 21;
204 else if (val & (1 << 2)) 259 else if (val & (1 << 2))
205 chip->onfi_version = 20; 260 chip->onfi_version = 20;
206 else if (val & (1 << 1)) 261 else if (val & (1 << 1))
207 chip->onfi_version = 10; 262 chip->onfi_version = 10;
208 263
209 if (!chip->onfi_version) { 264 if (!chip->onfi_version) {
210 printf("unsupported ONFI version: %d\n", val); 265 printf("unsupported ONFI version: %d\n", val);
211 return 0; 266 return 0;
212 } 267 }
213 268
214 if (p->ecc_bits != 0xff) { 269 if (p->ecc_bits != 0xff) {
215 chip->ecc_strength_ds = p->ecc_bits; 270 chip->ecc_strength_ds = p->ecc_bits;
216 chip->ecc_step_ds = 512; 271 chip->ecc_step_ds = 512;
217 } else if (chip->onfi_version >= 21 && 272 } else if (chip->onfi_version >= 21 &&
218 (onfi_feature(chip) & ONFI_FEATURE_EXT_PARAM_PAGE)) { 273 (onfi_feature(chip) & ONFI_FEATURE_EXT_PARAM_PAGE)) {
219 274
220 if (nand_flash_detect_ext_param_page(mtd, chip, p)) 275 if (nand_flash_detect_ext_param_page(mtd, chip, p))
221 printf("Failed to detect ONFI extended param page\n"); 276 printf("Failed to detect ONFI extended param page\n");
222 } else { 277 } else {
223 printf("Could not retrieve ONFI ECC requirements\n"); 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 debug("ecc_strength_ds %u, ecc_step_ds %u\n", chip->ecc_strength_ds, chip->ecc_step_ds); 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); 285 debug("erasesize=%x (>>%d)\n", mtd->erasesize, chip->phys_erase_shift);
228 debug("writesize=%d (>>%d)\n", mtd->writesize, chip->page_shift); 286 debug("writesize=%x (>>%d)\n", mtd->writesize, chip->page_shift);
229 debug("oobsize=%d\n", mtd->oobsize); 287 debug("oobsize=%d\n", mtd->oobsize);
230 debug("chipsize=%lld\n", chip->chipsize); 288 debug("chipsize=%llx\n", chip->chipsize);
231 289
232 return 0; 290 return 0;
233 } 291 }
234 292
235 static int mxs_read_page_ecc(struct mtd_info *mtd, void *buf, unsigned int page) 293 static int mxs_read_page_ecc(struct mtd_info *mtd, void *buf, unsigned int page)
236 { 294 {
237 register struct nand_chip *chip = mtd_to_nand(mtd); 295 register struct nand_chip *chip = mtd_to_nand(mtd);
238 int ret; 296 int ret;
239 297
240 chip->cmdfunc(mtd, NAND_CMD_READ0, 0x0, page); 298 chip->cmdfunc(mtd, NAND_CMD_READ0, 0x0, page);
241 ret = nand_chip.ecc.read_page(mtd, chip, buf, 1, page); 299 ret = nand_chip.ecc.read_page(mtd, chip, buf, 1, page);
242 if (ret < 0) { 300 if (ret < 0) {
243 printf("read_page failed %d\n", ret); 301 printf("read_page failed %d\n", ret);
244 return -1; 302 return -1;
245 } 303 }
246 return 0; 304 return 0;
247 } 305 }
248 306
249 static int is_badblock(struct mtd_info *mtd, loff_t offs, int allowbbt) 307 static int is_badblock(struct mtd_info *mtd, loff_t offs, int allowbbt)
250 { 308 {
251 register struct nand_chip *chip = mtd_to_nand(mtd); 309 register struct nand_chip *chip = mtd_to_nand(mtd);
252 unsigned int block = offs >> chip->phys_erase_shift; 310 unsigned int block = offs >> chip->phys_erase_shift;
253 unsigned int page = offs >> chip->page_shift; 311 unsigned int page = offs >> chip->page_shift;
254 312
255 debug("%s offs=0x%08x block:%d page:%d\n", __func__, (int)offs, block, 313 debug("%s offs=0x%08x block:%d page:%d\n", __func__, (int)offs, block,
256 page); 314 page);
257 chip->cmdfunc(mtd, NAND_CMD_READ0, mtd->writesize, page); 315 chip->cmdfunc(mtd, NAND_CMD_READ0, mtd->writesize, page);
258 memset(chip->oob_poi, 0, mtd->oobsize); 316 memset(chip->oob_poi, 0, mtd->oobsize);
259 chip->read_buf(mtd, chip->oob_poi, mtd->oobsize); 317 chip->read_buf(mtd, chip->oob_poi, mtd->oobsize);
260 318
261 return chip->oob_poi[0] != 0xff; 319 return chip->oob_poi[0] != 0xff;
262 } 320 }
263 321
264 /* setup mtd and nand structs and init mxs_nand driver */ 322 /* setup mtd and nand structs and init mxs_nand driver */
265 static int mxs_nand_init(void) 323 static int mxs_nand_init(void)
266 { 324 {
267 /* return if already initalized */ 325 /* return if already initalized */
268 if (nand_chip.numchips) 326 if (nand_chip.numchips)
269 return 0; 327 return 0;
270 328
271 /* init mxs nand driver */ 329 /* init mxs nand driver */
272 board_nand_init(&nand_chip); 330 board_nand_init(&nand_chip);
273 mtd = nand_to_mtd(&nand_chip); 331 mtd = nand_to_mtd(&nand_chip);
274 /* set mtd functions */ 332 /* set mtd functions */
275 nand_chip.cmdfunc = mxs_nand_command; 333 nand_chip.cmdfunc = mxs_nand_command;
276 nand_chip.numchips = 1; 334 nand_chip.numchips = 1;
277 335
278 /* identify flash device */ 336 /* identify flash device */
279 if (mxs_flash_ident(mtd)) { 337 if (mxs_flash_ident(mtd, NULL)) {
280 printf("Failed to identify\n"); 338 printf("Failed to identify\n");
281 return -1; 339 return -1;
282 } 340 }
283 341
284 /* allocate and initialize buffers */ 342 /* allocate and initialize buffers */
285 nand_chip.buffers = memalign(ARCH_DMA_MINALIGN, 343 nand_chip.buffers = memalign(ARCH_DMA_MINALIGN,
286 sizeof(*nand_chip.buffers)); 344 sizeof(*nand_chip.buffers));
287 nand_chip.oob_poi = nand_chip.buffers->databuf + mtd->writesize; 345 nand_chip.oob_poi = nand_chip.buffers->databuf + mtd->writesize;
288 /* setup flash layout (does not scan as we override that) */ 346 /* setup flash layout (does not scan as we override that) */
289 mtd->size = nand_chip.chipsize; 347 mtd->size = nand_chip.chipsize;
290 nand_chip.scan_bbt(mtd); 348 nand_chip.scan_bbt(mtd);
291 349
292 return 0; 350 return 0;
293 } 351 }
294 352
295 int nand_spl_load_image(uint32_t offs, unsigned int size, void *buf) 353 int nand_spl_load_image(uint32_t offs, unsigned int size, void *buf)
296 { 354 {
297 struct nand_chip *chip; 355 struct nand_chip *chip;
298 unsigned int page; 356 unsigned int page;
299 unsigned int nand_page_per_block; 357 unsigned int nand_page_per_block;
300 unsigned int sz = 0; 358 unsigned int sz = 0;
301 uint8_t *page_buf = NULL; 359 uint8_t *page_buf = NULL;
302 uint32_t page_off; 360 uint32_t page_off;
303 361
304 if (mxs_nand_init()) 362 if (mxs_nand_init())
305 return -ENODEV; 363 return -ENODEV;
306 364
307 chip = mtd_to_nand(mtd); 365 chip = mtd_to_nand(mtd);
308 366
309 page_buf = malloc(mtd->writesize); 367 page_buf = malloc(mtd->writesize);
310 if (!page_buf) 368 if (!page_buf)
311 return -ENOMEM; 369 return -ENOMEM;
312 370
313 page = offs >> chip->page_shift; 371 page = offs >> chip->page_shift;
314 page_off = offs & (mtd->writesize - 1); 372 page_off = offs & (mtd->writesize - 1);
315 nand_page_per_block = mtd->erasesize / mtd->writesize; 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 while (size) { 377 while (size) {
320 if (mxs_read_page_ecc(mtd, page_buf, page) < 0) 378 if (mxs_read_page_ecc(mtd, page_buf, page) < 0)
321 return -1; 379 return -1;
322 380
323 if (size > (mtd->writesize - page_off)) 381 if (size > (mtd->writesize - page_off))
324 sz = (mtd->writesize - page_off); 382 sz = (mtd->writesize - page_off);
325 else 383 else
326 sz = size; 384 sz = size;
327 385
328 memcpy(buf, page_buf + page_off, sz); 386 memcpy(buf, page_buf + page_off, sz);
329 387
330 offs += mtd->writesize; 388 offs += mtd->writesize;
331 page++; 389 page++;
332 buf += (mtd->writesize - page_off); 390 buf += (mtd->writesize - page_off);
333 page_off = 0; 391 page_off = 0;
334 size -= sz; 392 size -= sz;
335 393
336 /* 394 /*
337 * Check if we have crossed a block boundary, and if so 395 * Check if we have crossed a block boundary, and if so
338 * check for bad block. 396 * check for bad block.
339 */ 397 */
340 if (!(page % nand_page_per_block)) { 398 if (!(page % nand_page_per_block)) {
341 /* 399 /*
342 * Yes, new block. See if this block is good. If not, 400 * Yes, new block. See if this block is good. If not,
343 * loop until we find a good block. 401 * loop until we find a good block.
344 */ 402 */
345 while (is_badblock(mtd, offs, 1)) { 403 while (is_badblock(mtd, offs, 1)) {
346 page = page + nand_page_per_block; 404 page = page + nand_page_per_block;
347 /* Check i we've reached the end of flash. */ 405 /* Check i we've reached the end of flash. */
348 if (page >= mtd->size >> chip->page_shift) { 406 if (page >= mtd->size >> chip->page_shift) {
349 free(page_buf); 407 free(page_buf);
350 return -ENOMEM; 408 return -ENOMEM;
351 } 409 }
352 } 410 }
353 } 411 }
354 } 412 }
355 413
356 free(page_buf); 414 free(page_buf);
357 415
358 return 0; 416 return 0;
359 } 417 }
360 418
361 int nand_default_bbt(struct mtd_info *mtd) 419 int nand_default_bbt(struct mtd_info *mtd)
362 { 420 {
363 return 0; 421 return 0;
364 } 422 }
365 423
366 void nand_init(void) 424 void nand_init(void)
367 { 425 {
368 } 426 }
369 427
370 void nand_deselect(void) 428 void nand_deselect(void)
371 { 429 {
372 } 430 }
373 431
374 432