1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * (C) Copyright 2006-2008 4 * Stefan Roese, DENX Software Engineering, sr@denx.de. 5 */ 6 7 #include <common.h> 8 #include <nand.h> 9 #include <asm/io.h> 10 #include <linux/mtd/nand_ecc.h> 11 12 static int nand_ecc_pos[] = CONFIG_SYS_NAND_ECCPOS; 13 static struct mtd_info *mtd; 14 static struct nand_chip nand_chip; 15 16 #define ECCSTEPS (CONFIG_SYS_NAND_PAGE_SIZE / \ 17 CONFIG_SYS_NAND_ECCSIZE) 18 #define ECCTOTAL (ECCSTEPS * CONFIG_SYS_NAND_ECCBYTES) 19 20 21 #if (CONFIG_SYS_NAND_PAGE_SIZE <= 512) 22 /* 23 * NAND command for small page NAND devices (512) 24 */ 25 static int nand_command(int block, int page, uint32_t offs, 26 u8 cmd) 27 { 28 struct nand_chip *this = mtd_to_nand(mtd); 29 int page_addr = page + block * CONFIG_SYS_NAND_PAGE_COUNT; 30 31 while (!this->dev_ready(mtd)) 32 ; 33 34 /* Begin command latch cycle */ 35 this->cmd_ctrl(mtd, cmd, NAND_CTRL_CLE | NAND_CTRL_CHANGE); 36 /* Set ALE and clear CLE to start address cycle */ 37 /* Column address */ 38 this->cmd_ctrl(mtd, offs, NAND_CTRL_ALE | NAND_CTRL_CHANGE); 39 this->cmd_ctrl(mtd, page_addr & 0xff, NAND_CTRL_ALE); /* A[16:9] */ 40 this->cmd_ctrl(mtd, (page_addr >> 8) & 0xff, 41 NAND_CTRL_ALE); /* A[24:17] */ 42 #ifdef CONFIG_SYS_NAND_4_ADDR_CYCLE 43 /* One more address cycle for devices > 32MiB */ 44 this->cmd_ctrl(mtd, (page_addr >> 16) & 0x0f, 45 NAND_CTRL_ALE); /* A[28:25] */ 46 #endif 47 /* Latch in address */ 48 this->cmd_ctrl(mtd, NAND_CMD_NONE, NAND_NCE | NAND_CTRL_CHANGE); 49 50 /* 51 * Wait a while for the data to be ready 52 */ 53 while (!this->dev_ready(mtd)) 54 ; 55 56 return 0; 57 } 58 #else 59 /* 60 * NAND command for large page NAND devices (2k) 61 */ 62 static int nand_command(int block, int page, uint32_t offs, 63 u8 cmd) 64 { 65 struct nand_chip *this = mtd_to_nand(mtd); 66 int page_addr = page + block * CONFIG_SYS_NAND_PAGE_COUNT; 67 void (*hwctrl)(struct mtd_info *mtd, int cmd, 68 unsigned int ctrl) = this->cmd_ctrl; 69 70 while (!this->dev_ready(mtd)) 71 ; 72 73 /* Emulate NAND_CMD_READOOB */ 74 if (cmd == NAND_CMD_READOOB) { 75 offs += CONFIG_SYS_NAND_PAGE_SIZE; 76 cmd = NAND_CMD_READ0; 77 } 78 79 /* Shift the offset from byte addressing to word addressing. */ 80 if ((this->options & NAND_BUSWIDTH_16) && !nand_opcode_8bits(cmd)) 81 offs >>= 1; 82 83 /* Begin command latch cycle */ 84 hwctrl(mtd, cmd, NAND_CTRL_CLE | NAND_CTRL_CHANGE); 85 /* Set ALE and clear CLE to start address cycle */ 86 /* Column address */ 87 hwctrl(mtd, offs & 0xff, 88 NAND_CTRL_ALE | NAND_CTRL_CHANGE); /* A[7:0] */ 89 hwctrl(mtd, (offs >> 8) & 0xff, NAND_CTRL_ALE); /* A[11:9] */ 90 /* Row address */ 91 hwctrl(mtd, (page_addr & 0xff), NAND_CTRL_ALE); /* A[19:12] */ 92 hwctrl(mtd, ((page_addr >> 8) & 0xff), 93 NAND_CTRL_ALE); /* A[27:20] */ 94 #ifdef CONFIG_SYS_NAND_5_ADDR_CYCLE 95 /* One more address cycle for devices > 128MiB */ 96 hwctrl(mtd, (page_addr >> 16) & 0x0f, 97 NAND_CTRL_ALE); /* A[31:28] */ 98 #endif 99 /* Latch in address */ 100 hwctrl(mtd, NAND_CMD_READSTART, 101 NAND_CTRL_CLE | NAND_CTRL_CHANGE); 102 hwctrl(mtd, NAND_CMD_NONE, NAND_NCE | NAND_CTRL_CHANGE); 103 104 /* 105 * Wait a while for the data to be ready 106 */ 107 while (!this->dev_ready(mtd)) 108 ; 109 110 return 0; 111 } 112 #endif 113 114 static int nand_is_bad_block(int block) 115 { 116 struct nand_chip *this = mtd_to_nand(mtd); 117 u_char bb_data[2]; 118 119 nand_command(block, 0, CONFIG_SYS_NAND_BAD_BLOCK_POS, 120 NAND_CMD_READOOB); 121 122 /* 123 * Read one byte (or two if it's a 16 bit chip). 124 */ 125 if (this->options & NAND_BUSWIDTH_16) { 126 this->read_buf(mtd, bb_data, 2); 127 if (bb_data[0] != 0xff || bb_data[1] != 0xff) 128 return 1; 129 } else { 130 this->read_buf(mtd, bb_data, 1); 131 if (bb_data[0] != 0xff) 132 return 1; 133 } 134 135 return 0; 136 } 137 138 #if defined(CONFIG_SYS_NAND_HW_ECC_OOBFIRST) 139 static int nand_read_page(int block, int page, uchar *dst) 140 { 141 struct nand_chip *this = mtd_to_nand(mtd); 142 u_char ecc_calc[ECCTOTAL]; 143 u_char ecc_code[ECCTOTAL]; 144 u_char oob_data[CONFIG_SYS_NAND_OOBSIZE]; 145 int i; 146 int eccsize = CONFIG_SYS_NAND_ECCSIZE; 147 int eccbytes = CONFIG_SYS_NAND_ECCBYTES; 148 int eccsteps = ECCSTEPS; 149 uint8_t *p = dst; 150 151 nand_command(block, page, 0, NAND_CMD_READOOB); 152 this->read_buf(mtd, oob_data, CONFIG_SYS_NAND_OOBSIZE); 153 nand_command(block, page, 0, NAND_CMD_READ0); 154 155 /* Pick the ECC bytes out of the oob data */ 156 for (i = 0; i < ECCTOTAL; i++) 157 ecc_code[i] = oob_data[nand_ecc_pos[i]]; 158 159 160 for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) { 161 this->ecc.hwctl(mtd, NAND_ECC_READ); 162 this->read_buf(mtd, p, eccsize); 163 this->ecc.calculate(mtd, p, &ecc_calc[i]); 164 this->ecc.correct(mtd, p, &ecc_code[i], &ecc_calc[i]); 165 } 166 167 return 0; 168 } 169 #else 170 static int nand_read_page(int block, int page, void *dst) 171 { 172 struct nand_chip *this = mtd_to_nand(mtd); 173 u_char ecc_calc[ECCTOTAL]; 174 u_char ecc_code[ECCTOTAL]; 175 u_char oob_data[CONFIG_SYS_NAND_OOBSIZE]; 176 int i; 177 int eccsize = CONFIG_SYS_NAND_ECCSIZE; 178 int eccbytes = CONFIG_SYS_NAND_ECCBYTES; 179 int eccsteps = ECCSTEPS; 180 uint8_t *p = dst; 181 182 nand_command(block, page, 0, NAND_CMD_READ0); 183 184 for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) { 185 if (this->ecc.mode != NAND_ECC_SOFT) 186 this->ecc.hwctl(mtd, NAND_ECC_READ); 187 this->read_buf(mtd, p, eccsize); 188 this->ecc.calculate(mtd, p, &ecc_calc[i]); 189 } 190 this->read_buf(mtd, oob_data, CONFIG_SYS_NAND_OOBSIZE); 191 192 /* Pick the ECC bytes out of the oob data */ 193 for (i = 0; i < ECCTOTAL; i++) 194 ecc_code[i] = oob_data[nand_ecc_pos[i]]; 195 196 eccsteps = ECCSTEPS; 197 p = dst; 198 199 for (i = 0 ; eccsteps; eccsteps--, i += eccbytes, p += eccsize) { 200 /* No chance to do something with the possible error message 201 * from correct_data(). We just hope that all possible errors 202 * are corrected by this routine. 203 */ 204 this->ecc.correct(mtd, p, &ecc_code[i], &ecc_calc[i]); 205 } 206 207 return 0; 208 } 209 #endif 210 211 /* nand_init() - initialize data to make nand usable by SPL */ 212 void nand_init(void) 213 { 214 /* 215 * Init board specific nand support 216 */ 217 mtd = nand_to_mtd(&nand_chip); 218 nand_chip.IO_ADDR_R = nand_chip.IO_ADDR_W = 219 (void __iomem *)CONFIG_SYS_NAND_BASE; 220 board_nand_init(&nand_chip); 221 222 #ifdef CONFIG_SPL_NAND_SOFTECC 223 if (nand_chip.ecc.mode == NAND_ECC_SOFT) { 224 nand_chip.ecc.calculate = nand_calculate_ecc; 225 nand_chip.ecc.correct = nand_correct_data; 226 } 227 #endif 228 229 if (nand_chip.select_chip) 230 nand_chip.select_chip(mtd, 0); 231 } 232 233 /* Unselect after operation */ 234 void nand_deselect(void) 235 { 236 if (nand_chip.select_chip) 237 nand_chip.select_chip(mtd, -1); 238 } 239 240 #include "nand_spl_loaders.c" 241