]>
Commit | Line | Data |
---|---|---|
312693c3 JL |
1 | /* |
2 | * Copyright (c) 2011 The Chromium OS Authors. | |
3 | * (C) Copyright 2011 NVIDIA Corporation <www.nvidia.com> | |
4 | * (C) Copyright 2006 Detlev Zundel, dzu@denx.de | |
5 | * (C) Copyright 2006 DENX Software Engineering | |
6 | * | |
1a459660 | 7 | * SPDX-License-Identifier: GPL-2.0+ |
312693c3 JL |
8 | */ |
9 | ||
10 | #include <common.h> | |
11 | #include <asm/io.h> | |
cf92e05c | 12 | #include <memalign.h> |
312693c3 | 13 | #include <nand.h> |
312693c3 JL |
14 | #include <asm/arch/clock.h> |
15 | #include <asm/arch/funcmux.h> | |
150c2493 | 16 | #include <asm/arch-tegra/clk_rst.h> |
312693c3 | 17 | #include <asm/errno.h> |
150c2493 | 18 | #include <asm/gpio.h> |
312693c3 | 19 | #include <fdtdec.h> |
adf4800d | 20 | #include <bouncebuf.h> |
312693c3 JL |
21 | #include "tegra_nand.h" |
22 | ||
23 | DECLARE_GLOBAL_DATA_PTR; | |
24 | ||
25 | #define NAND_CMD_TIMEOUT_MS 10 | |
26 | ||
27 | #define SKIPPED_SPARE_BYTES 4 | |
28 | ||
29 | /* ECC bytes to be generated for tag data */ | |
30 | #define TAG_ECC_BYTES 4 | |
31 | ||
32 | /* 64 byte oob block info for large page (== 2KB) device | |
33 | * | |
34 | * OOB flash layout for Tegra with Reed-Solomon 4 symbol correct ECC: | |
35 | * Skipped bytes(4) | |
36 | * Main area Ecc(36) | |
37 | * Tag data(20) | |
38 | * Tag data Ecc(4) | |
39 | * | |
40 | * Yaffs2 will use 16 tag bytes. | |
41 | */ | |
42 | static struct nand_ecclayout eccoob = { | |
43 | .eccbytes = 36, | |
44 | .eccpos = { | |
45 | 4, 5, 6, 7, 8, 9, 10, 11, 12, | |
46 | 13, 14, 15, 16, 17, 18, 19, 20, 21, | |
47 | 22, 23, 24, 25, 26, 27, 28, 29, 30, | |
48 | 31, 32, 33, 34, 35, 36, 37, 38, 39, | |
49 | }, | |
50 | .oobavail = 20, | |
51 | .oobfree = { | |
52 | { | |
53 | .offset = 40, | |
54 | .length = 20, | |
55 | }, | |
56 | } | |
57 | }; | |
58 | ||
59 | enum { | |
60 | ECC_OK, | |
61 | ECC_TAG_ERROR = 1 << 0, | |
62 | ECC_DATA_ERROR = 1 << 1 | |
63 | }; | |
64 | ||
65 | /* Timing parameters */ | |
66 | enum { | |
67 | FDT_NAND_MAX_TRP_TREA, | |
68 | FDT_NAND_TWB, | |
69 | FDT_NAND_MAX_TCR_TAR_TRR, | |
70 | FDT_NAND_TWHR, | |
71 | FDT_NAND_MAX_TCS_TCH_TALS_TALH, | |
72 | FDT_NAND_TWH, | |
73 | FDT_NAND_TWP, | |
74 | FDT_NAND_TRH, | |
75 | FDT_NAND_TADL, | |
76 | ||
77 | FDT_NAND_TIMING_COUNT | |
78 | }; | |
79 | ||
80 | /* Information about an attached NAND chip */ | |
81 | struct fdt_nand { | |
82 | struct nand_ctlr *reg; | |
83 | int enabled; /* 1 to enable, 0 to disable */ | |
b0265d56 | 84 | struct gpio_desc wp_gpio; /* write-protect GPIO */ |
312693c3 JL |
85 | s32 width; /* bit width, normally 8 */ |
86 | u32 timing[FDT_NAND_TIMING_COUNT]; | |
87 | }; | |
88 | ||
89 | struct nand_drv { | |
90 | struct nand_ctlr *reg; | |
312693c3 JL |
91 | struct fdt_nand config; |
92 | }; | |
93 | ||
94 | static struct nand_drv nand_ctrl; | |
95 | static struct mtd_info *our_mtd; | |
96 | static struct nand_chip nand_chip[CONFIG_SYS_MAX_NAND_DEVICE]; | |
97 | ||
312693c3 JL |
98 | /** |
99 | * Wait for command completion | |
100 | * | |
101 | * @param reg nand_ctlr structure | |
102 | * @return | |
103 | * 1 - Command completed | |
104 | * 0 - Timeout | |
105 | */ | |
106 | static int nand_waitfor_cmd_completion(struct nand_ctlr *reg) | |
107 | { | |
108 | u32 reg_val; | |
109 | int running; | |
110 | int i; | |
111 | ||
112 | for (i = 0; i < NAND_CMD_TIMEOUT_MS * 1000; i++) { | |
113 | if ((readl(®->command) & CMD_GO) || | |
114 | !(readl(®->status) & STATUS_RBSY0) || | |
115 | !(readl(®->isr) & ISR_IS_CMD_DONE)) { | |
116 | udelay(1); | |
117 | continue; | |
118 | } | |
119 | reg_val = readl(®->dma_mst_ctrl); | |
120 | /* | |
121 | * If DMA_MST_CTRL_EN_A_ENABLE or DMA_MST_CTRL_EN_B_ENABLE | |
122 | * is set, that means DMA engine is running. | |
123 | * | |
124 | * Then we have to wait until DMA_MST_CTRL_IS_DMA_DONE | |
125 | * is cleared, indicating DMA transfer completion. | |
126 | */ | |
127 | running = reg_val & (DMA_MST_CTRL_EN_A_ENABLE | | |
128 | DMA_MST_CTRL_EN_B_ENABLE); | |
129 | if (!running || (reg_val & DMA_MST_CTRL_IS_DMA_DONE)) | |
130 | return 1; | |
131 | udelay(1); | |
132 | } | |
133 | return 0; | |
134 | } | |
135 | ||
136 | /** | |
137 | * Read one byte from the chip | |
138 | * | |
139 | * @param mtd MTD device structure | |
140 | * @return data byte | |
141 | * | |
142 | * Read function for 8bit bus-width | |
143 | */ | |
144 | static uint8_t read_byte(struct mtd_info *mtd) | |
145 | { | |
17cb4b8f | 146 | struct nand_chip *chip = mtd_to_nand(mtd); |
312693c3 JL |
147 | struct nand_drv *info; |
148 | ||
17cb4b8f | 149 | info = (struct nand_drv *)nand_get_controller_data(chip); |
312693c3 | 150 | |
1bc66a57 MZ |
151 | writel(CMD_GO | CMD_PIO | CMD_RX | CMD_CE0 | CMD_A_VALID, |
152 | &info->reg->command); | |
153 | if (!nand_waitfor_cmd_completion(info->reg)) | |
154 | printf("Command timeout\n"); | |
312693c3 | 155 | |
1bc66a57 | 156 | return (uint8_t)readl(&info->reg->resp); |
312693c3 JL |
157 | } |
158 | ||
a833b950 LS |
159 | /** |
160 | * Read len bytes from the chip into a buffer | |
161 | * | |
162 | * @param mtd MTD device structure | |
163 | * @param buf buffer to store data to | |
164 | * @param len number of bytes to read | |
165 | * | |
166 | * Read function for 8bit bus-width | |
167 | */ | |
168 | static void read_buf(struct mtd_info *mtd, uint8_t *buf, int len) | |
169 | { | |
170 | int i, s; | |
171 | unsigned int reg; | |
17cb4b8f SW |
172 | struct nand_chip *chip = mtd_to_nand(mtd); |
173 | struct nand_drv *info = (struct nand_drv *)nand_get_controller_data(chip); | |
a833b950 LS |
174 | |
175 | for (i = 0; i < len; i += 4) { | |
176 | s = (len - i) > 4 ? 4 : len - i; | |
177 | writel(CMD_PIO | CMD_RX | CMD_A_VALID | CMD_CE0 | | |
178 | ((s - 1) << CMD_TRANS_SIZE_SHIFT) | CMD_GO, | |
179 | &info->reg->command); | |
180 | if (!nand_waitfor_cmd_completion(info->reg)) | |
181 | puts("Command timeout during read_buf\n"); | |
182 | reg = readl(&info->reg->resp); | |
183 | memcpy(buf + i, ®, s); | |
184 | } | |
185 | } | |
186 | ||
312693c3 JL |
187 | /** |
188 | * Check NAND status to see if it is ready or not | |
189 | * | |
190 | * @param mtd MTD device structure | |
191 | * @return | |
192 | * 1 - ready | |
193 | * 0 - not ready | |
194 | */ | |
195 | static int nand_dev_ready(struct mtd_info *mtd) | |
196 | { | |
17cb4b8f | 197 | struct nand_chip *chip = mtd_to_nand(mtd); |
312693c3 JL |
198 | int reg_val; |
199 | struct nand_drv *info; | |
200 | ||
17cb4b8f | 201 | info = (struct nand_drv *)nand_get_controller_data(chip); |
312693c3 JL |
202 | |
203 | reg_val = readl(&info->reg->status); | |
204 | if (reg_val & STATUS_RBSY0) | |
205 | return 1; | |
206 | else | |
207 | return 0; | |
208 | } | |
209 | ||
210 | /* Dummy implementation: we don't support multiple chips */ | |
211 | static void nand_select_chip(struct mtd_info *mtd, int chipnr) | |
212 | { | |
213 | switch (chipnr) { | |
214 | case -1: | |
215 | case 0: | |
216 | break; | |
217 | ||
218 | default: | |
219 | BUG(); | |
220 | } | |
221 | } | |
222 | ||
223 | /** | |
224 | * Clear all interrupt status bits | |
225 | * | |
226 | * @param reg nand_ctlr structure | |
227 | */ | |
228 | static void nand_clear_interrupt_status(struct nand_ctlr *reg) | |
229 | { | |
230 | u32 reg_val; | |
231 | ||
232 | /* Clear interrupt status */ | |
233 | reg_val = readl(®->isr); | |
234 | writel(reg_val, ®->isr); | |
235 | } | |
236 | ||
237 | /** | |
238 | * Send command to NAND device | |
239 | * | |
240 | * @param mtd MTD device structure | |
241 | * @param command the command to be sent | |
242 | * @param column the column address for this command, -1 if none | |
243 | * @param page_addr the page address for this command, -1 if none | |
244 | */ | |
245 | static void nand_command(struct mtd_info *mtd, unsigned int command, | |
246 | int column, int page_addr) | |
247 | { | |
17cb4b8f | 248 | struct nand_chip *chip = mtd_to_nand(mtd); |
312693c3 JL |
249 | struct nand_drv *info; |
250 | ||
17cb4b8f | 251 | info = (struct nand_drv *)nand_get_controller_data(chip); |
312693c3 JL |
252 | |
253 | /* | |
254 | * Write out the command to the device. | |
255 | * | |
256 | * Only command NAND_CMD_RESET or NAND_CMD_READID will come | |
257 | * here before mtd->writesize is initialized. | |
258 | */ | |
259 | ||
260 | /* Emulate NAND_CMD_READOOB */ | |
261 | if (command == NAND_CMD_READOOB) { | |
262 | assert(mtd->writesize != 0); | |
263 | column += mtd->writesize; | |
264 | command = NAND_CMD_READ0; | |
265 | } | |
266 | ||
267 | /* Adjust columns for 16 bit bus-width */ | |
268 | if (column != -1 && (chip->options & NAND_BUSWIDTH_16)) | |
269 | column >>= 1; | |
270 | ||
271 | nand_clear_interrupt_status(info->reg); | |
272 | ||
273 | /* Stop DMA engine, clear DMA completion status */ | |
274 | writel(DMA_MST_CTRL_EN_A_DISABLE | |
275 | | DMA_MST_CTRL_EN_B_DISABLE | |
276 | | DMA_MST_CTRL_IS_DMA_DONE, | |
277 | &info->reg->dma_mst_ctrl); | |
278 | ||
279 | /* | |
280 | * Program and erase have their own busy handlers | |
281 | * status and sequential in needs no delay | |
282 | */ | |
283 | switch (command) { | |
284 | case NAND_CMD_READID: | |
285 | writel(NAND_CMD_READID, &info->reg->cmd_reg1); | |
a833b950 | 286 | writel(column & 0xFF, &info->reg->addr_reg1); |
1bc66a57 MZ |
287 | writel(CMD_GO | CMD_CLE | CMD_ALE | CMD_CE0, |
288 | &info->reg->command); | |
312693c3 | 289 | break; |
a833b950 LS |
290 | case NAND_CMD_PARAM: |
291 | writel(NAND_CMD_PARAM, &info->reg->cmd_reg1); | |
292 | writel(column & 0xFF, &info->reg->addr_reg1); | |
293 | writel(CMD_GO | CMD_CLE | CMD_ALE | CMD_CE0, | |
294 | &info->reg->command); | |
295 | break; | |
312693c3 JL |
296 | case NAND_CMD_READ0: |
297 | writel(NAND_CMD_READ0, &info->reg->cmd_reg1); | |
298 | writel(NAND_CMD_READSTART, &info->reg->cmd_reg2); | |
299 | writel((page_addr << 16) | (column & 0xFFFF), | |
300 | &info->reg->addr_reg1); | |
301 | writel(page_addr >> 16, &info->reg->addr_reg2); | |
302 | return; | |
303 | case NAND_CMD_SEQIN: | |
304 | writel(NAND_CMD_SEQIN, &info->reg->cmd_reg1); | |
305 | writel(NAND_CMD_PAGEPROG, &info->reg->cmd_reg2); | |
306 | writel((page_addr << 16) | (column & 0xFFFF), | |
307 | &info->reg->addr_reg1); | |
308 | writel(page_addr >> 16, | |
309 | &info->reg->addr_reg2); | |
310 | return; | |
311 | case NAND_CMD_PAGEPROG: | |
312 | return; | |
313 | case NAND_CMD_ERASE1: | |
314 | writel(NAND_CMD_ERASE1, &info->reg->cmd_reg1); | |
315 | writel(NAND_CMD_ERASE2, &info->reg->cmd_reg2); | |
316 | writel(page_addr, &info->reg->addr_reg1); | |
317 | writel(CMD_GO | CMD_CLE | CMD_ALE | | |
318 | CMD_SEC_CMD | CMD_CE0 | CMD_ALE_BYTES3, | |
319 | &info->reg->command); | |
320 | break; | |
321 | case NAND_CMD_ERASE2: | |
322 | return; | |
323 | case NAND_CMD_STATUS: | |
324 | writel(NAND_CMD_STATUS, &info->reg->cmd_reg1); | |
325 | writel(CMD_GO | CMD_CLE | CMD_PIO | CMD_RX | |
326 | | ((1 - 0) << CMD_TRANS_SIZE_SHIFT) | |
327 | | CMD_CE0, | |
328 | &info->reg->command); | |
312693c3 JL |
329 | break; |
330 | case NAND_CMD_RESET: | |
331 | writel(NAND_CMD_RESET, &info->reg->cmd_reg1); | |
332 | writel(CMD_GO | CMD_CLE | CMD_CE0, | |
333 | &info->reg->command); | |
334 | break; | |
335 | case NAND_CMD_RNDOUT: | |
336 | default: | |
337 | printf("%s: Unsupported command %d\n", __func__, command); | |
338 | return; | |
339 | } | |
340 | if (!nand_waitfor_cmd_completion(info->reg)) | |
341 | printf("Command 0x%02X timeout\n", command); | |
342 | } | |
343 | ||
344 | /** | |
345 | * Check whether the pointed buffer are all 0xff (blank). | |
346 | * | |
347 | * @param buf data buffer for blank check | |
348 | * @param len length of the buffer in byte | |
349 | * @return | |
350 | * 1 - blank | |
351 | * 0 - non-blank | |
352 | */ | |
353 | static int blank_check(u8 *buf, int len) | |
354 | { | |
355 | int i; | |
356 | ||
357 | for (i = 0; i < len; i++) | |
358 | if (buf[i] != 0xFF) | |
359 | return 0; | |
360 | return 1; | |
361 | } | |
362 | ||
363 | /** | |
364 | * After a DMA transfer for read, we call this function to see whether there | |
365 | * is any uncorrectable error on the pointed data buffer or oob buffer. | |
366 | * | |
367 | * @param reg nand_ctlr structure | |
368 | * @param databuf data buffer | |
369 | * @param a_len data buffer length | |
370 | * @param oobbuf oob buffer | |
371 | * @param b_len oob buffer length | |
372 | * @return | |
373 | * ECC_OK - no ECC error or correctable ECC error | |
374 | * ECC_TAG_ERROR - uncorrectable tag ECC error | |
375 | * ECC_DATA_ERROR - uncorrectable data ECC error | |
376 | * ECC_DATA_ERROR + ECC_TAG_ERROR - uncorrectable data+tag ECC error | |
377 | */ | |
378 | static int check_ecc_error(struct nand_ctlr *reg, u8 *databuf, | |
379 | int a_len, u8 *oobbuf, int b_len) | |
380 | { | |
381 | int return_val = ECC_OK; | |
382 | u32 reg_val; | |
383 | ||
384 | if (!(readl(®->isr) & ISR_IS_ECC_ERR)) | |
385 | return ECC_OK; | |
386 | ||
387 | /* | |
388 | * Area A is used for the data block (databuf). Area B is used for | |
389 | * the spare block (oobbuf) | |
390 | */ | |
391 | reg_val = readl(®->dec_status); | |
392 | if ((reg_val & DEC_STATUS_A_ECC_FAIL) && databuf) { | |
393 | reg_val = readl(®->bch_dec_status_buf); | |
394 | /* | |
395 | * If uncorrectable error occurs on data area, then see whether | |
396 | * they are all FF. If all are FF, it's a blank page. | |
397 | * Not error. | |
398 | */ | |
399 | if ((reg_val & BCH_DEC_STATUS_FAIL_SEC_FLAG_MASK) && | |
400 | !blank_check(databuf, a_len)) | |
401 | return_val |= ECC_DATA_ERROR; | |
402 | } | |
403 | ||
404 | if ((reg_val & DEC_STATUS_B_ECC_FAIL) && oobbuf) { | |
405 | reg_val = readl(®->bch_dec_status_buf); | |
406 | /* | |
407 | * If uncorrectable error occurs on tag area, then see whether | |
408 | * they are all FF. If all are FF, it's a blank page. | |
409 | * Not error. | |
410 | */ | |
411 | if ((reg_val & BCH_DEC_STATUS_FAIL_TAG_MASK) && | |
412 | !blank_check(oobbuf, b_len)) | |
413 | return_val |= ECC_TAG_ERROR; | |
414 | } | |
415 | ||
416 | return return_val; | |
417 | } | |
418 | ||
419 | /** | |
420 | * Set GO bit to send command to device | |
421 | * | |
422 | * @param reg nand_ctlr structure | |
423 | */ | |
424 | static void start_command(struct nand_ctlr *reg) | |
425 | { | |
426 | u32 reg_val; | |
427 | ||
428 | reg_val = readl(®->command); | |
429 | reg_val |= CMD_GO; | |
430 | writel(reg_val, ®->command); | |
431 | } | |
432 | ||
433 | /** | |
434 | * Clear command GO bit, DMA GO bit, and DMA completion status | |
435 | * | |
436 | * @param reg nand_ctlr structure | |
437 | */ | |
438 | static void stop_command(struct nand_ctlr *reg) | |
439 | { | |
440 | /* Stop command */ | |
441 | writel(0, ®->command); | |
442 | ||
443 | /* Stop DMA engine and clear DMA completion status */ | |
444 | writel(DMA_MST_CTRL_GO_DISABLE | |
445 | | DMA_MST_CTRL_IS_DMA_DONE, | |
446 | ®->dma_mst_ctrl); | |
447 | } | |
448 | ||
449 | /** | |
450 | * Set up NAND bus width and page size | |
451 | * | |
452 | * @param info nand_info structure | |
453 | * @param *reg_val address of reg_val | |
454 | * @return 0 if ok, -1 on error | |
455 | */ | |
456 | static int set_bus_width_page_size(struct fdt_nand *config, | |
457 | u32 *reg_val) | |
458 | { | |
459 | if (config->width == 8) | |
460 | *reg_val = CFG_BUS_WIDTH_8BIT; | |
461 | else if (config->width == 16) | |
462 | *reg_val = CFG_BUS_WIDTH_16BIT; | |
463 | else { | |
464 | debug("%s: Unsupported bus width %d\n", __func__, | |
465 | config->width); | |
466 | return -1; | |
467 | } | |
468 | ||
469 | if (our_mtd->writesize == 512) | |
470 | *reg_val |= CFG_PAGE_SIZE_512; | |
471 | else if (our_mtd->writesize == 2048) | |
472 | *reg_val |= CFG_PAGE_SIZE_2048; | |
473 | else if (our_mtd->writesize == 4096) | |
474 | *reg_val |= CFG_PAGE_SIZE_4096; | |
475 | else { | |
476 | debug("%s: Unsupported page size %d\n", __func__, | |
477 | our_mtd->writesize); | |
478 | return -1; | |
479 | } | |
480 | ||
481 | return 0; | |
482 | } | |
483 | ||
484 | /** | |
485 | * Page read/write function | |
486 | * | |
487 | * @param mtd mtd info structure | |
488 | * @param chip nand chip info structure | |
489 | * @param buf data buffer | |
490 | * @param page page number | |
491 | * @param with_ecc 1 to enable ECC, 0 to disable ECC | |
492 | * @param is_writing 0 for read, 1 for write | |
493 | * @return 0 when successfully completed | |
494 | * -EIO when command timeout | |
495 | */ | |
496 | static int nand_rw_page(struct mtd_info *mtd, struct nand_chip *chip, | |
497 | uint8_t *buf, int page, int with_ecc, int is_writing) | |
498 | { | |
499 | u32 reg_val; | |
500 | int tag_size; | |
501 | struct nand_oobfree *free = chip->ecc.layout->oobfree; | |
502 | /* 4*128=512 (byte) is the value that our HW can support. */ | |
503 | ALLOC_CACHE_ALIGN_BUFFER(u32, tag_buf, 128); | |
504 | char *tag_ptr; | |
505 | struct nand_drv *info; | |
506 | struct fdt_nand *config; | |
adf4800d MZ |
507 | unsigned int bbflags; |
508 | struct bounce_buffer bbstate, bbstate_oob; | |
312693c3 JL |
509 | |
510 | if ((uintptr_t)buf & 0x03) { | |
511 | printf("buf %p has to be 4-byte aligned\n", buf); | |
512 | return -EINVAL; | |
513 | } | |
514 | ||
17cb4b8f | 515 | info = (struct nand_drv *)nand_get_controller_data(chip); |
312693c3 JL |
516 | config = &info->config; |
517 | if (set_bus_width_page_size(config, ®_val)) | |
518 | return -EINVAL; | |
519 | ||
520 | /* Need to be 4-byte aligned */ | |
521 | tag_ptr = (char *)tag_buf; | |
522 | ||
523 | stop_command(info->reg); | |
524 | ||
adf4800d MZ |
525 | if (is_writing) |
526 | bbflags = GEN_BB_READ; | |
527 | else | |
528 | bbflags = GEN_BB_WRITE; | |
529 | ||
530 | bounce_buffer_start(&bbstate, (void *)buf, 1 << chip->page_shift, | |
531 | bbflags); | |
312693c3 | 532 | writel((1 << chip->page_shift) - 1, &info->reg->dma_cfg_a); |
adf4800d | 533 | writel(virt_to_phys(bbstate.bounce_buffer), &info->reg->data_block_ptr); |
312693c3 | 534 | |
adf4800d | 535 | /* Set ECC selection, configure ECC settings */ |
312693c3 | 536 | if (with_ecc) { |
312693c3 JL |
537 | if (is_writing) |
538 | memcpy(tag_ptr, chip->oob_poi + free->offset, | |
adf4800d | 539 | chip->ecc.layout->oobavail + TAG_ECC_BYTES); |
312693c3 JL |
540 | tag_size = chip->ecc.layout->oobavail + TAG_ECC_BYTES; |
541 | reg_val |= (CFG_SKIP_SPARE_SEL_4 | |
542 | | CFG_SKIP_SPARE_ENABLE | |
543 | | CFG_HW_ECC_CORRECTION_ENABLE | |
544 | | CFG_ECC_EN_TAG_DISABLE | |
545 | | CFG_HW_ECC_SEL_RS | |
546 | | CFG_HW_ECC_ENABLE | |
547 | | CFG_TVAL4 | |
548 | | (tag_size - 1)); | |
549 | ||
550 | if (!is_writing) | |
551 | tag_size += SKIPPED_SPARE_BYTES; | |
adf4800d MZ |
552 | bounce_buffer_start(&bbstate_oob, (void *)tag_ptr, tag_size, |
553 | bbflags); | |
312693c3 JL |
554 | } else { |
555 | tag_size = mtd->oobsize; | |
556 | reg_val |= (CFG_SKIP_SPARE_DISABLE | |
557 | | CFG_HW_ECC_CORRECTION_DISABLE | |
558 | | CFG_ECC_EN_TAG_DISABLE | |
559 | | CFG_HW_ECC_DISABLE | |
560 | | (tag_size - 1)); | |
adf4800d MZ |
561 | bounce_buffer_start(&bbstate_oob, (void *)chip->oob_poi, |
562 | tag_size, bbflags); | |
312693c3 JL |
563 | } |
564 | writel(reg_val, &info->reg->config); | |
adf4800d | 565 | writel(virt_to_phys(bbstate_oob.bounce_buffer), &info->reg->tag_ptr); |
312693c3 | 566 | writel(BCH_CONFIG_BCH_ECC_DISABLE, &info->reg->bch_config); |
312693c3 JL |
567 | writel(tag_size - 1, &info->reg->dma_cfg_b); |
568 | ||
569 | nand_clear_interrupt_status(info->reg); | |
570 | ||
571 | reg_val = CMD_CLE | CMD_ALE | |
572 | | CMD_SEC_CMD | |
573 | | (CMD_ALE_BYTES5 << CMD_ALE_BYTE_SIZE_SHIFT) | |
574 | | CMD_A_VALID | |
575 | | CMD_B_VALID | |
576 | | (CMD_TRANS_SIZE_PAGE << CMD_TRANS_SIZE_SHIFT) | |
577 | | CMD_CE0; | |
578 | if (!is_writing) | |
579 | reg_val |= (CMD_AFT_DAT_DISABLE | CMD_RX); | |
580 | else | |
581 | reg_val |= (CMD_AFT_DAT_ENABLE | CMD_TX); | |
582 | writel(reg_val, &info->reg->command); | |
583 | ||
584 | /* Setup DMA engine */ | |
585 | reg_val = DMA_MST_CTRL_GO_ENABLE | |
586 | | DMA_MST_CTRL_BURST_8WORDS | |
587 | | DMA_MST_CTRL_EN_A_ENABLE | |
588 | | DMA_MST_CTRL_EN_B_ENABLE; | |
589 | ||
590 | if (!is_writing) | |
591 | reg_val |= DMA_MST_CTRL_DIR_READ; | |
592 | else | |
593 | reg_val |= DMA_MST_CTRL_DIR_WRITE; | |
594 | ||
595 | writel(reg_val, &info->reg->dma_mst_ctrl); | |
596 | ||
597 | start_command(info->reg); | |
598 | ||
599 | if (!nand_waitfor_cmd_completion(info->reg)) { | |
600 | if (!is_writing) | |
601 | printf("Read Page 0x%X timeout ", page); | |
602 | else | |
603 | printf("Write Page 0x%X timeout ", page); | |
604 | if (with_ecc) | |
605 | printf("with ECC"); | |
606 | else | |
607 | printf("without ECC"); | |
608 | printf("\n"); | |
609 | return -EIO; | |
610 | } | |
611 | ||
adf4800d MZ |
612 | bounce_buffer_stop(&bbstate_oob); |
613 | bounce_buffer_stop(&bbstate); | |
614 | ||
312693c3 JL |
615 | if (with_ecc && !is_writing) { |
616 | memcpy(chip->oob_poi, tag_ptr, | |
617 | SKIPPED_SPARE_BYTES); | |
618 | memcpy(chip->oob_poi + free->offset, | |
619 | tag_ptr + SKIPPED_SPARE_BYTES, | |
620 | chip->ecc.layout->oobavail); | |
621 | reg_val = (u32)check_ecc_error(info->reg, (u8 *)buf, | |
622 | 1 << chip->page_shift, | |
623 | (u8 *)(tag_ptr + SKIPPED_SPARE_BYTES), | |
624 | chip->ecc.layout->oobavail); | |
625 | if (reg_val & ECC_TAG_ERROR) | |
626 | printf("Read Page 0x%X tag ECC error\n", page); | |
627 | if (reg_val & ECC_DATA_ERROR) | |
628 | printf("Read Page 0x%X data ECC error\n", | |
629 | page); | |
630 | if (reg_val & (ECC_DATA_ERROR | ECC_TAG_ERROR)) | |
631 | return -EIO; | |
632 | } | |
633 | return 0; | |
634 | } | |
635 | ||
636 | /** | |
637 | * Hardware ecc based page read function | |
638 | * | |
639 | * @param mtd mtd info structure | |
640 | * @param chip nand chip info structure | |
641 | * @param buf buffer to store read data | |
642 | * @param page page number to read | |
643 | * @return 0 when successfully completed | |
644 | * -EIO when command timeout | |
645 | */ | |
646 | static int nand_read_page_hwecc(struct mtd_info *mtd, | |
dfe64e2c | 647 | struct nand_chip *chip, uint8_t *buf, int oob_required, int page) |
312693c3 JL |
648 | { |
649 | return nand_rw_page(mtd, chip, buf, page, 1, 0); | |
650 | } | |
651 | ||
652 | /** | |
653 | * Hardware ecc based page write function | |
654 | * | |
655 | * @param mtd mtd info structure | |
656 | * @param chip nand chip info structure | |
657 | * @param buf data buffer | |
658 | */ | |
dfe64e2c | 659 | static int nand_write_page_hwecc(struct mtd_info *mtd, |
81c77252 SW |
660 | struct nand_chip *chip, const uint8_t *buf, int oob_required, |
661 | int page) | |
312693c3 | 662 | { |
312693c3 | 663 | nand_rw_page(mtd, chip, (uint8_t *)buf, page, 1, 1); |
dfe64e2c | 664 | return 0; |
312693c3 JL |
665 | } |
666 | ||
667 | ||
668 | /** | |
669 | * Read raw page data without ecc | |
670 | * | |
671 | * @param mtd mtd info structure | |
672 | * @param chip nand chip info structure | |
673 | * @param buf buffer to store read data | |
674 | * @param page page number to read | |
675 | * @return 0 when successfully completed | |
676 | * -EINVAL when chip->oob_poi is not double-word aligned | |
677 | * -EIO when command timeout | |
678 | */ | |
679 | static int nand_read_page_raw(struct mtd_info *mtd, | |
dfe64e2c | 680 | struct nand_chip *chip, uint8_t *buf, int oob_required, int page) |
312693c3 JL |
681 | { |
682 | return nand_rw_page(mtd, chip, buf, page, 0, 0); | |
683 | } | |
684 | ||
685 | /** | |
686 | * Raw page write function | |
687 | * | |
688 | * @param mtd mtd info structure | |
689 | * @param chip nand chip info structure | |
690 | * @param buf data buffer | |
691 | */ | |
dfe64e2c | 692 | static int nand_write_page_raw(struct mtd_info *mtd, |
81c77252 SW |
693 | struct nand_chip *chip, const uint8_t *buf, |
694 | int oob_required, int page) | |
312693c3 | 695 | { |
312693c3 | 696 | nand_rw_page(mtd, chip, (uint8_t *)buf, page, 0, 1); |
dfe64e2c | 697 | return 0; |
312693c3 JL |
698 | } |
699 | ||
700 | /** | |
701 | * OOB data read/write function | |
702 | * | |
703 | * @param mtd mtd info structure | |
704 | * @param chip nand chip info structure | |
705 | * @param page page number to read | |
706 | * @param with_ecc 1 to enable ECC, 0 to disable ECC | |
707 | * @param is_writing 0 for read, 1 for write | |
708 | * @return 0 when successfully completed | |
709 | * -EINVAL when chip->oob_poi is not double-word aligned | |
710 | * -EIO when command timeout | |
711 | */ | |
712 | static int nand_rw_oob(struct mtd_info *mtd, struct nand_chip *chip, | |
713 | int page, int with_ecc, int is_writing) | |
714 | { | |
715 | u32 reg_val; | |
716 | int tag_size; | |
717 | struct nand_oobfree *free = chip->ecc.layout->oobfree; | |
718 | struct nand_drv *info; | |
adf4800d MZ |
719 | unsigned int bbflags; |
720 | struct bounce_buffer bbstate_oob; | |
312693c3 JL |
721 | |
722 | if (((int)chip->oob_poi) & 0x03) | |
723 | return -EINVAL; | |
17cb4b8f | 724 | info = (struct nand_drv *)nand_get_controller_data(chip); |
312693c3 JL |
725 | if (set_bus_width_page_size(&info->config, ®_val)) |
726 | return -EINVAL; | |
727 | ||
728 | stop_command(info->reg); | |
729 | ||
312693c3 JL |
730 | /* Set ECC selection */ |
731 | tag_size = mtd->oobsize; | |
732 | if (with_ecc) | |
733 | reg_val |= CFG_ECC_EN_TAG_ENABLE; | |
734 | else | |
735 | reg_val |= (CFG_ECC_EN_TAG_DISABLE); | |
736 | ||
737 | reg_val |= ((tag_size - 1) | | |
738 | CFG_SKIP_SPARE_DISABLE | | |
739 | CFG_HW_ECC_CORRECTION_DISABLE | | |
740 | CFG_HW_ECC_DISABLE); | |
741 | writel(reg_val, &info->reg->config); | |
742 | ||
312693c3 JL |
743 | if (is_writing && with_ecc) |
744 | tag_size -= TAG_ECC_BYTES; | |
745 | ||
adf4800d MZ |
746 | if (is_writing) |
747 | bbflags = GEN_BB_READ; | |
748 | else | |
749 | bbflags = GEN_BB_WRITE; | |
750 | ||
751 | bounce_buffer_start(&bbstate_oob, (void *)chip->oob_poi, tag_size, | |
752 | bbflags); | |
753 | writel(virt_to_phys(bbstate_oob.bounce_buffer), &info->reg->tag_ptr); | |
754 | ||
755 | writel(BCH_CONFIG_BCH_ECC_DISABLE, &info->reg->bch_config); | |
756 | ||
312693c3 JL |
757 | writel(tag_size - 1, &info->reg->dma_cfg_b); |
758 | ||
759 | nand_clear_interrupt_status(info->reg); | |
760 | ||
761 | reg_val = CMD_CLE | CMD_ALE | |
762 | | CMD_SEC_CMD | |
763 | | (CMD_ALE_BYTES5 << CMD_ALE_BYTE_SIZE_SHIFT) | |
764 | | CMD_B_VALID | |
765 | | CMD_CE0; | |
766 | if (!is_writing) | |
767 | reg_val |= (CMD_AFT_DAT_DISABLE | CMD_RX); | |
768 | else | |
769 | reg_val |= (CMD_AFT_DAT_ENABLE | CMD_TX); | |
770 | writel(reg_val, &info->reg->command); | |
771 | ||
772 | /* Setup DMA engine */ | |
773 | reg_val = DMA_MST_CTRL_GO_ENABLE | |
774 | | DMA_MST_CTRL_BURST_8WORDS | |
775 | | DMA_MST_CTRL_EN_B_ENABLE; | |
776 | if (!is_writing) | |
777 | reg_val |= DMA_MST_CTRL_DIR_READ; | |
778 | else | |
779 | reg_val |= DMA_MST_CTRL_DIR_WRITE; | |
780 | ||
781 | writel(reg_val, &info->reg->dma_mst_ctrl); | |
782 | ||
783 | start_command(info->reg); | |
784 | ||
785 | if (!nand_waitfor_cmd_completion(info->reg)) { | |
786 | if (!is_writing) | |
787 | printf("Read OOB of Page 0x%X timeout\n", page); | |
788 | else | |
789 | printf("Write OOB of Page 0x%X timeout\n", page); | |
790 | return -EIO; | |
791 | } | |
792 | ||
adf4800d MZ |
793 | bounce_buffer_stop(&bbstate_oob); |
794 | ||
312693c3 JL |
795 | if (with_ecc && !is_writing) { |
796 | reg_val = (u32)check_ecc_error(info->reg, 0, 0, | |
797 | (u8 *)(chip->oob_poi + free->offset), | |
798 | chip->ecc.layout->oobavail); | |
799 | if (reg_val & ECC_TAG_ERROR) | |
800 | printf("Read OOB of Page 0x%X tag ECC error\n", page); | |
801 | } | |
802 | return 0; | |
803 | } | |
804 | ||
805 | /** | |
806 | * OOB data read function | |
807 | * | |
808 | * @param mtd mtd info structure | |
809 | * @param chip nand chip info structure | |
810 | * @param page page number to read | |
312693c3 JL |
811 | */ |
812 | static int nand_read_oob(struct mtd_info *mtd, struct nand_chip *chip, | |
dfe64e2c | 813 | int page) |
312693c3 | 814 | { |
dfe64e2c | 815 | chip->cmdfunc(mtd, NAND_CMD_READOOB, 0, page); |
312693c3 | 816 | nand_rw_oob(mtd, chip, page, 0, 0); |
dfe64e2c | 817 | return 0; |
312693c3 JL |
818 | } |
819 | ||
820 | /** | |
821 | * OOB data write function | |
822 | * | |
823 | * @param mtd mtd info structure | |
824 | * @param chip nand chip info structure | |
825 | * @param page page number to write | |
826 | * @return 0 when successfully completed | |
827 | * -EINVAL when chip->oob_poi is not double-word aligned | |
828 | * -EIO when command timeout | |
829 | */ | |
830 | static int nand_write_oob(struct mtd_info *mtd, struct nand_chip *chip, | |
831 | int page) | |
832 | { | |
833 | chip->cmdfunc(mtd, NAND_CMD_SEQIN, mtd->writesize, page); | |
834 | ||
835 | return nand_rw_oob(mtd, chip, page, 0, 1); | |
836 | } | |
837 | ||
838 | /** | |
839 | * Set up NAND memory timings according to the provided parameters | |
840 | * | |
841 | * @param timing Timing parameters | |
842 | * @param reg NAND controller register address | |
843 | */ | |
844 | static void setup_timing(unsigned timing[FDT_NAND_TIMING_COUNT], | |
845 | struct nand_ctlr *reg) | |
846 | { | |
847 | u32 reg_val, clk_rate, clk_period, time_val; | |
848 | ||
849 | clk_rate = (u32)clock_get_periph_rate(PERIPH_ID_NDFLASH, | |
850 | CLOCK_ID_PERIPH) / 1000000; | |
851 | clk_period = 1000 / clk_rate; | |
852 | reg_val = ((timing[FDT_NAND_MAX_TRP_TREA] / clk_period) << | |
853 | TIMING_TRP_RESP_CNT_SHIFT) & TIMING_TRP_RESP_CNT_MASK; | |
854 | reg_val |= ((timing[FDT_NAND_TWB] / clk_period) << | |
855 | TIMING_TWB_CNT_SHIFT) & TIMING_TWB_CNT_MASK; | |
856 | time_val = timing[FDT_NAND_MAX_TCR_TAR_TRR] / clk_period; | |
857 | if (time_val > 2) | |
858 | reg_val |= ((time_val - 2) << TIMING_TCR_TAR_TRR_CNT_SHIFT) & | |
859 | TIMING_TCR_TAR_TRR_CNT_MASK; | |
860 | reg_val |= ((timing[FDT_NAND_TWHR] / clk_period) << | |
861 | TIMING_TWHR_CNT_SHIFT) & TIMING_TWHR_CNT_MASK; | |
862 | time_val = timing[FDT_NAND_MAX_TCS_TCH_TALS_TALH] / clk_period; | |
863 | if (time_val > 1) | |
864 | reg_val |= ((time_val - 1) << TIMING_TCS_CNT_SHIFT) & | |
865 | TIMING_TCS_CNT_MASK; | |
866 | reg_val |= ((timing[FDT_NAND_TWH] / clk_period) << | |
867 | TIMING_TWH_CNT_SHIFT) & TIMING_TWH_CNT_MASK; | |
868 | reg_val |= ((timing[FDT_NAND_TWP] / clk_period) << | |
869 | TIMING_TWP_CNT_SHIFT) & TIMING_TWP_CNT_MASK; | |
870 | reg_val |= ((timing[FDT_NAND_TRH] / clk_period) << | |
871 | TIMING_TRH_CNT_SHIFT) & TIMING_TRH_CNT_MASK; | |
872 | reg_val |= ((timing[FDT_NAND_MAX_TRP_TREA] / clk_period) << | |
873 | TIMING_TRP_CNT_SHIFT) & TIMING_TRP_CNT_MASK; | |
874 | writel(reg_val, ®->timing); | |
875 | ||
876 | reg_val = 0; | |
877 | time_val = timing[FDT_NAND_TADL] / clk_period; | |
878 | if (time_val > 2) | |
879 | reg_val = (time_val - 2) & TIMING2_TADL_CNT_MASK; | |
880 | writel(reg_val, ®->timing2); | |
881 | } | |
882 | ||
883 | /** | |
884 | * Decode NAND parameters from the device tree | |
885 | * | |
886 | * @param blob Device tree blob | |
887 | * @param node Node containing "nand-flash" compatble node | |
888 | * @return 0 if ok, -ve on error (FDT_ERR_...) | |
889 | */ | |
890 | static int fdt_decode_nand(const void *blob, int node, struct fdt_nand *config) | |
891 | { | |
892 | int err; | |
893 | ||
894 | config->reg = (struct nand_ctlr *)fdtdec_get_addr(blob, node, "reg"); | |
895 | config->enabled = fdtdec_get_is_enabled(blob, node); | |
896 | config->width = fdtdec_get_int(blob, node, "nvidia,nand-width", 8); | |
b0265d56 SG |
897 | err = gpio_request_by_name_nodev(blob, node, "nvidia,wp-gpios", 0, |
898 | &config->wp_gpio, GPIOD_IS_OUT); | |
312693c3 JL |
899 | if (err) |
900 | return err; | |
901 | err = fdtdec_get_int_array(blob, node, "nvidia,timing", | |
902 | config->timing, FDT_NAND_TIMING_COUNT); | |
903 | if (err < 0) | |
904 | return err; | |
905 | ||
906 | /* Now look up the controller and decode that */ | |
907 | node = fdt_next_node(blob, node, NULL); | |
908 | if (node < 0) | |
909 | return node; | |
910 | ||
911 | return 0; | |
912 | } | |
913 | ||
914 | /** | |
915 | * Board-specific NAND initialization | |
916 | * | |
917 | * @param nand nand chip info structure | |
918 | * @return 0, after initialized, -1 on error | |
919 | */ | |
920 | int tegra_nand_init(struct nand_chip *nand, int devnum) | |
921 | { | |
922 | struct nand_drv *info = &nand_ctrl; | |
923 | struct fdt_nand *config = &info->config; | |
924 | int node, ret; | |
925 | ||
926 | node = fdtdec_next_compatible(gd->fdt_blob, 0, | |
927 | COMPAT_NVIDIA_TEGRA20_NAND); | |
928 | if (node < 0) | |
929 | return -1; | |
930 | if (fdt_decode_nand(gd->fdt_blob, node, config)) { | |
931 | printf("Could not decode nand-flash in device tree\n"); | |
932 | return -1; | |
933 | } | |
934 | if (!config->enabled) | |
935 | return -1; | |
936 | info->reg = config->reg; | |
937 | nand->ecc.mode = NAND_ECC_HW; | |
938 | nand->ecc.layout = &eccoob; | |
939 | ||
940 | nand->options = LP_OPTIONS; | |
941 | nand->cmdfunc = nand_command; | |
942 | nand->read_byte = read_byte; | |
a833b950 | 943 | nand->read_buf = read_buf; |
312693c3 JL |
944 | nand->ecc.read_page = nand_read_page_hwecc; |
945 | nand->ecc.write_page = nand_write_page_hwecc; | |
946 | nand->ecc.read_page_raw = nand_read_page_raw; | |
947 | nand->ecc.write_page_raw = nand_write_page_raw; | |
948 | nand->ecc.read_oob = nand_read_oob; | |
949 | nand->ecc.write_oob = nand_write_oob; | |
dfe64e2c | 950 | nand->ecc.strength = 1; |
312693c3 JL |
951 | nand->select_chip = nand_select_chip; |
952 | nand->dev_ready = nand_dev_ready; | |
17cb4b8f | 953 | nand_set_controller_data(nand, &nand_ctrl); |
312693c3 | 954 | |
6eeedc19 MZ |
955 | /* Disable subpage writes as we do not provide ecc->hwctl */ |
956 | nand->options |= NAND_NO_SUBPAGE_WRITE; | |
957 | ||
312693c3 JL |
958 | /* Adjust controller clock rate */ |
959 | clock_start_periph_pll(PERIPH_ID_NDFLASH, CLOCK_ID_PERIPH, 52000000); | |
960 | ||
961 | /* Adjust timing for NAND device */ | |
962 | setup_timing(config->timing, info->reg); | |
963 | ||
b0265d56 | 964 | dm_gpio_set_value(&config->wp_gpio, 1); |
312693c3 | 965 | |
17cb4b8f | 966 | our_mtd = nand_to_mtd(nand); |
312693c3 JL |
967 | ret = nand_scan_ident(our_mtd, CONFIG_SYS_NAND_MAX_CHIPS, NULL); |
968 | if (ret) | |
969 | return ret; | |
970 | ||
971 | nand->ecc.size = our_mtd->writesize; | |
972 | nand->ecc.bytes = our_mtd->oobsize; | |
973 | ||
974 | ret = nand_scan_tail(our_mtd); | |
975 | if (ret) | |
976 | return ret; | |
977 | ||
b616d9b0 | 978 | ret = nand_register(devnum, our_mtd); |
312693c3 JL |
979 | if (ret) |
980 | return ret; | |
981 | ||
982 | return 0; | |
983 | } | |
984 | ||
985 | void board_nand_init(void) | |
986 | { | |
987 | struct nand_chip *nand = &nand_chip[0]; | |
988 | ||
989 | if (tegra_nand_init(nand, 0)) | |
990 | puts("Tegra NAND init failed\n"); | |
991 | } |