1 diff -urN u-boot-1.3.1.orig/board/freescale/mpc8313erdb/Makefile u-boot-1.3.1/board/freescale/mpc8313erdb/Makefile
2 --- u-boot-1.3.1.orig/board/freescale/mpc8313erdb/Makefile 2007-12-06 10:21:19.000000000 +0100
3 +++ u-boot-1.3.1/board/freescale/mpc8313erdb/Makefile 2008-01-31 17:35:43.000000000 +0100
6 LIB = $(obj)lib$(BOARD).a
8 -COBJS := $(BOARD).o sdram.o
9 +COBJS := $(BOARD).o sdram.o nand.o
11 SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
12 OBJS := $(addprefix $(obj),$(COBJS))
13 diff -urN u-boot-1.3.1.orig/board/freescale/mpc8313erdb/nand.c u-boot-1.3.1/board/freescale/mpc8313erdb/nand.c
14 --- u-boot-1.3.1.orig/board/freescale/mpc8313erdb/nand.c 1970-01-01 01:00:00.000000000 +0100
15 +++ u-boot-1.3.1/board/freescale/mpc8313erdb/nand.c 2008-01-31 17:35:26.000000000 +0100
18 + * Copyright (C) Freescale Semiconductor, Inc. 2006.
20 + * Initialized by Nick.Spence@freescale.com
21 + * Wilson.Lo@freescale.com
23 + * See file CREDITS for list of people who contributed to this
26 + * This program is free software; you can redistribute it and/or
27 + * modify it under the terms of the GNU General Public License as
28 + * published by the Free Software Foundation; either version 2 of
29 + * the License, or (at your option) any later version.
31 + * This program is distributed in the hope that it will be useful,
32 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
33 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
34 + * GNU General Public License for more details.
36 + * You should have received a copy of the GNU General Public License
37 + * along with this program; if not, write to the Free Software
38 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
44 +#if defined(CONFIG_CMD_NAND)
45 +#if defined(CFG_NAND_LEGACY)
46 + #error "U-Boot legacy NAND commands not supported."
50 +#include <asm/errno.h>
54 +#define CFG_FCM_DEBUG_LVL 1
56 +#define FCM_DEBUG(n, args...) \
58 + if (n <= (CFG_FCM_DEBUG_LVL + 0)) \
61 +#else /* CONFIG_FCM_DEBUG */
62 +#define FCM_DEBUG(n, args...) do { } while(0)
65 +#define MIN(x, y) ((x < y) ? x : y)
67 +#define ERR_BYTE 0xFF /* Value returned for read bytes when read failed */
69 +#define FCM_TIMEOUT_USECS 100000 /* Maximum number of uSecs to wait for FCM */
71 +/* Private structure holding NAND Flash device specific information */
73 + int bank; /* Chip select bank number */
74 + unsigned int base; /* Chip select base address */
75 + int pgs; /* NAND page size */
76 + int oobbuf; /* Pointer to OOB block */
77 + unsigned int page; /* Last page written to / read from */
78 + unsigned int fmr; /* FCM Flash Mode Register value */
79 + unsigned int mdr; /* UPM/FCM Data Register value */
80 + unsigned int use_mdr; /* Non zero if the MDR is to be set */
81 + u_char *addr; /* Address of assigned FCM buffer */
82 + unsigned int read_bytes; /* Number of bytes read during command */
83 + unsigned int index; /* Pointer to next byte to 'read' */
84 + unsigned int req_bytes; /* Number of bytes read if command ok */
85 + unsigned int req_index; /* New read index if command ok */
86 + unsigned int status; /* status read from LTESR after last op*/
90 +/* These map to the positions used by the FCM hardware ECC generator */
92 +/* Small Page FLASH with FMR[ECCM] = 0 */
93 +static struct nand_oobinfo fcm_oob_sp_eccm0 = { /* TODO */
94 + .useecc = MTD_NANDECC_AUTOPL_USR, /* MTD_NANDECC_PLACEONLY, */
96 + .eccpos = {6, 7, 8},
97 + .oobfree = { {0, 5}, {9, 7} }
100 +/* Small Page FLASH with FMR[ECCM] = 1 */
101 +static struct nand_oobinfo fcm_oob_sp_eccm1 = { /* TODO */
102 + .useecc = MTD_NANDECC_AUTOPL_USR, /* MTD_NANDECC_PLACEONLY, */
104 + .eccpos = {8, 9, 10},
105 + .oobfree = { {0, 5}, {6, 2}, {11, 5} }
108 +/* Large Page FLASH with FMR[ECCM] = 0 */
109 +static struct nand_oobinfo fcm_oob_lp_eccm0 = {
110 + .useecc = MTD_NANDECC_AUTOPL_USR, /* MTD_NANDECC_PLACEONLY, */
112 + .eccpos = {6, 7, 8, 22, 23, 24, 38, 39, 40, 54, 55, 56},
113 + .oobfree = { {1, 5}, {9, 13}, {25, 13}, {41, 13}, {57, 7} }
116 +/* Large Page FLASH with FMR[ECCM] = 1 */
117 +static struct nand_oobinfo fcm_oob_lp_eccm1 = {
118 + .useecc = MTD_NANDECC_AUTOPL_USR, /* MTD_NANDECC_PLACEONLY, */
120 + .eccpos = {8, 9, 10, 24, 25, 26, 40, 41, 42, 56, 57, 58},
121 + .oobfree = { {1, 7}, {11, 13}, {27, 13}, {43, 13}, {59, 5} }
125 + * execute FCM command and wait for it to complete
127 +static int fcm_run_command(struct mtd_info *mtd)
129 + volatile immap_t *im = (immap_t *) CFG_IMMR;
130 + volatile lbus83xx_t *lbc= &im->lbus;
131 + register struct nand_chip *this = mtd->priv;
132 + struct fcm_nand *fcm = this->priv;
133 + long long end_tick;
135 + /* Setup the FMR[OP] to execute without write protection */
136 + lbc->fmr = fcm->fmr | 3;
138 + lbc->mdr = fcm->mdr;
140 + FCM_DEBUG(5,"fcm_run_command: fmr= %08X fir= %08X fcr= %08X\n",
141 + lbc->fmr, lbc->fir, lbc->fcr);
142 + FCM_DEBUG(5,"fcm_run_command: fbar=%08X fpar=%08X fbcr=%08X bank=%d\n",
143 + lbc->fbar, lbc->fpar, lbc->fbcr, fcm->bank);
145 + /* clear event registers */
147 + lbc->ltesr |= (LTESR_FCT | LTESR_PAR | LTESR_CC);
149 + /* execute special operation */
150 + lbc->lsor = fcm->bank;
152 + /* wait for FCM complete flag or timeout */
154 + end_tick = usec2ticks(FCM_TIMEOUT_USECS) + get_ticks();
156 + while (end_tick > get_ticks()) {
157 + if (lbc->ltesr & LTESR_CC) {
158 + fcm->status = lbc->ltesr &
159 + (LTESR_FCT | LTESR_PAR | LTESR_CC);
164 + /* store mdr value in case it was needed */
166 + fcm->mdr = lbc->mdr;
170 + FCM_DEBUG(5,"fcm_run_command: stat=%08X mdr= %08X fmr= %08X\n",
171 + fcm->status, fcm->mdr, lbc->fmr);
173 + /* if the operation completed ok then set the read buffer pointers */
174 + if (fcm->status == LTESR_CC) {
175 + fcm->read_bytes = fcm->req_bytes;
176 + fcm->index = fcm->req_index;
184 + * Set up the FCM hardware block and page address fields, and the fcm
185 + * structure addr field to point to the correct FCM buffer in memory
187 +static void set_addr(struct mtd_info *mtd, int column, int page_addr, int oob)
189 + volatile immap_t *im = (immap_t *) CFG_IMMR;
190 + volatile lbus83xx_t *lbc= &im->lbus;
191 + register struct nand_chip *this = mtd->priv;
192 + struct fcm_nand *fcm = this->priv;
195 + fcm->page = page_addr;
197 + lbc->fbar = page_addr >> (this->phys_erase_shift - this->page_shift);
199 + lbc->fpar = ((page_addr << FPAR_LP_PI_SHIFT) & FPAR_LP_PI) |
200 + ( oob ? FPAR_LP_MS : 0) |
202 + buf_num = (page_addr & 1) << 2;
204 + lbc->fpar = ((page_addr << FPAR_SP_PI_SHIFT) & FPAR_SP_PI) |
205 + ( oob ? FPAR_SP_MS : 0) |
207 + buf_num = page_addr & 7;
209 + fcm->addr = (unsigned char*)(fcm->base + (buf_num * 1024));
211 + /* for OOB data point to the second half of the buffer */
213 + fcm->addr += (fcm->pgs ? 2048 : 512);
217 +/* not required for FCM */
218 +static void fcm_hwcontrol(struct mtd_info *mtdinfo, int cmd)
225 + * FCM does not support 16 bit data busses
227 +static u16 fcm_read_word(struct mtd_info *mtd)
229 + printf("fcm_read_word: UNIMPLEMENTED.\n");
232 +static void fcm_write_word(struct mtd_info *mtd, u16 word)
234 + printf("fcm_write_word: UNIMPLEMENTED.\n");
238 + * Write buf to the FCM Controller Data Buffer
240 +static void fcm_write_buf(struct mtd_info *mtd, const u_char *buf, int len)
242 + register struct nand_chip *this = mtd->priv;
243 + struct fcm_nand *fcm = this->priv;
245 + FCM_DEBUG(3,"fcm_write_buf: writing %d bytes starting with 0x%x"
246 + " at %d.\n", len, *((unsigned long*) buf), fcm->index);
248 + /* If armed catch the address of the OOB buffer so that it can be */
249 + /* updated with the real signature after the program comletes */
251 + fcm->oobbuf = (int) buf;
253 + /* copy the data into the FCM hardware buffer and update the index */
254 + memcpy(&(fcm->addr[fcm->index]), buf, len);
261 + * FCM does not support individual writes. Instead these are either commands
262 + * or data being written, both of which are handled through the cmdfunc
265 +static void fcm_write_byte(struct mtd_info *mtd, u_char byte)
267 + printf("fcm_write_byte: UNIMPLEMENTED.\n");
271 + * read a byte from either the FCM hardware buffer if it has any data left
272 + * otherwise issue a command to read a single byte.
274 +static u_char fcm_read_byte(struct mtd_info *mtd)
276 + volatile immap_t *im = (immap_t *) CFG_IMMR;
277 + volatile lbus83xx_t *lbc= &im->lbus;
278 + register struct nand_chip *this = mtd->priv;
279 + struct fcm_nand *fcm = this->priv;
280 + unsigned char byte;
282 + /* If there are still bytes in the FCM then use the next byte */
283 + if(fcm->index < fcm->read_bytes) {
284 + byte = fcm->addr[(fcm->index)++];
285 + FCM_DEBUG(4,"fcm_read_byte: byte %u (%02X): %d of %d.\n",
286 + byte, byte, fcm->index-1, fcm->read_bytes);
288 + /* otherwise issue a command to read 1 byte */
289 + lbc->fir = (FIR_OP_RSW << FIR_OP0_SHIFT);
291 + fcm->read_bytes = 0;
293 + fcm->req_bytes = 0;
294 + fcm->req_index = 0;
295 + byte = fcm_run_command(mtd) ? ERR_BYTE : fcm->mdr & 0xff;
296 + FCM_DEBUG(4,"fcm_read_byte: byte %u (%02X) from bus.\n",
305 + * Read from the FCM Controller Data Buffer
307 +static void fcm_read_buf(struct mtd_info *mtd, u_char* buf, int len)
309 + volatile immap_t *im = (immap_t *) CFG_IMMR;
310 + volatile lbus83xx_t *lbc= &im->lbus;
311 + register struct nand_chip *this = mtd->priv;
312 + struct fcm_nand *fcm = this->priv;
316 + FCM_DEBUG(3,"fcm_read_buf: reading %d bytes.\n", len);
318 + /* If last read failed then return error bytes */
319 + if (fcm->status != LTESR_CC) {
320 + /* just keep copying bytes so that the oob works */
321 + memcpy(buf, &(fcm->addr[(fcm->index)]), len);
326 + /* see how much is still in the FCM buffer */
327 + i = min(len, (fcm->read_bytes - fcm->index));
331 + memcpy(buf, &(fcm->addr[(fcm->index)]), len);
334 + /* If more data is needed then issue another block read */
336 + FCM_DEBUG(3,"fcm_read_buf: getting %d more bytes.\n",
339 + lbc->fir = (FIR_OP_RBW << FIR_OP0_SHIFT);
340 + set_addr(mtd, 0, 0, 0);
342 + fcm->req_bytes = lbc->fbcr;
343 + fcm->req_index = 0;
345 + if (!fcm_run_command(mtd))
346 + fcm_read_buf(mtd, buf, rest);
348 + memcpy(buf, fcm->addr, rest);
356 + * Verify buffer against the FCM Controller Data Buffer
358 +static int fcm_verify_buf(struct mtd_info *mtd, const u_char *buf, int len)
360 + volatile immap_t *im = (immap_t *) CFG_IMMR;
361 + volatile lbus83xx_t *lbc= &im->lbus;
362 + register struct nand_chip *this = mtd->priv;
363 + struct fcm_nand *fcm = this->priv;
367 + FCM_DEBUG(3,"fcm_verify_buf: checking %d bytes starting with 0x%02x.\n",
368 + len, *((unsigned long*) buf));
369 + /* If last read failed then return error bytes */
370 + if (fcm->status != LTESR_CC) {
374 + /* see how much is still in the FCM buffer */
375 + i = min(len, (fcm->read_bytes - fcm->index));
379 + if (memcmp(buf, &(fcm->addr[(fcm->index)]), len)) {
385 + FCM_DEBUG(3,"fcm_verify_buf: getting %d more bytes.\n", rest);
387 + lbc->fir = (FIR_OP_RBW << FIR_OP0_SHIFT);
388 + set_addr(mtd, 0, 0, 0);
390 + fcm->req_bytes = lbc->fbcr;
391 + fcm->req_index = 0;
393 + if (fcm_run_command(mtd))
395 + return fcm_verify_buf(mtd, buf, rest);
401 +/* this function is called after Program and Erase Operations to
402 + * check for success or failure */
403 +static int fcm_wait(struct mtd_info *mtd, struct nand_chip *this, int state)
405 + volatile immap_t *im = (immap_t *) CFG_IMMR;
406 + volatile lbus83xx_t *lbc= &im->lbus;
407 + struct fcm_nand *fcm = this->priv;
409 + if (fcm->status != LTESR_CC) {
410 + return(0x1); /* Status Read error */
413 + /* Use READ_STATUS command, but wait for the device to be ready */
415 + fcm->req_index = 0;
416 + fcm->read_bytes = 0;
419 + lbc->fir = (FIR_OP_CW0 << FIR_OP0_SHIFT) |
420 + (FIR_OP_RBW << FIR_OP1_SHIFT);
421 + lbc->fcr = (NAND_CMD_STATUS << FCR_CMD0_SHIFT);
422 + set_addr(mtd, 0, 0, 0);
424 + fcm->req_bytes = lbc->fbcr;
425 + fcm_run_command(mtd);
426 + if (fcm->status != LTESR_CC) {
427 + return(0x1); /* Status Read error */
429 + return this->read_byte(mtd);
433 +/* cmdfunc send commands to the FCM */
434 +static void fcm_cmdfunc(struct mtd_info *mtd, unsigned command,
435 + int column, int page_addr)
437 + volatile immap_t *im = (immap_t *) CFG_IMMR;
438 + volatile lbus83xx_t *lbc= &im->lbus;
439 + register struct nand_chip *this = mtd->priv;
440 + struct fcm_nand *fcm = this->priv;
443 + fcm->req_index = 0;
445 + /* clear the read buffer */
446 + fcm->read_bytes = 0;
447 + if (command != NAND_CMD_PAGEPROG) {
453 + /* READ0 and READ1 read the entire buffer to use hardware ECC */
454 + case NAND_CMD_READ1:
455 + FCM_DEBUG(2,"fcm_cmdfunc: NAND_CMD_READ1, page_addr:"
456 + " 0x%x, column: 0x%x.\n", page_addr, column);
457 + fcm->req_index = column + 256;
459 + case NAND_CMD_READ0:
460 + FCM_DEBUG(2,"fcm_cmdfunc: NAND_CMD_READ0, page_addr:"
461 + " 0x%x, column: 0x%x.\n", page_addr, column);
462 + fcm->req_index = column;
465 + lbc->fir = (FIR_OP_CW0 << FIR_OP0_SHIFT) |
466 + (FIR_OP_CA << FIR_OP1_SHIFT) |
467 + (FIR_OP_PA << FIR_OP2_SHIFT) |
468 + (FIR_OP_CW1 << FIR_OP3_SHIFT) |
469 + (FIR_OP_RBW << FIR_OP4_SHIFT);
471 + lbc->fir = (FIR_OP_CW0 << FIR_OP0_SHIFT) |
472 + (FIR_OP_CA << FIR_OP1_SHIFT) |
473 + (FIR_OP_PA << FIR_OP2_SHIFT) |
474 + (FIR_OP_RBW << FIR_OP3_SHIFT);
476 + lbc->fcr = (NAND_CMD_READ0 << FCR_CMD0_SHIFT) |
477 + (NAND_CMD_READSTART << FCR_CMD1_SHIFT);
478 + lbc->fbcr = 0; /* read entire page to enable ECC */
479 + set_addr(mtd, 0, page_addr, 0);
480 + fcm->req_bytes = mtd->oobblock + mtd->oobsize;
482 + /* READOOB read only the OOB becasue no ECC is performed */
483 + case NAND_CMD_READOOB:
484 + FCM_DEBUG(2,"fcm_cmdfunc: NAND_CMD_READOOB, page_addr:"
485 + " 0x%x, column: 0x%x.\n", page_addr, column);
487 + lbc->fir = (FIR_OP_CW0 << FIR_OP0_SHIFT) |
488 + (FIR_OP_CA << FIR_OP1_SHIFT) |
489 + (FIR_OP_PA << FIR_OP2_SHIFT) |
490 + (FIR_OP_CW1 << FIR_OP3_SHIFT) |
491 + (FIR_OP_RBW << FIR_OP4_SHIFT);
492 + lbc->fcr = (NAND_CMD_READ0 << FCR_CMD0_SHIFT) |
493 + (NAND_CMD_READSTART << FCR_CMD1_SHIFT);
495 + lbc->fir = (FIR_OP_CW0 << FIR_OP0_SHIFT) |
496 + (FIR_OP_CA << FIR_OP1_SHIFT) |
497 + (FIR_OP_PA << FIR_OP2_SHIFT) |
498 + (FIR_OP_RBW << FIR_OP3_SHIFT);
499 + lbc->fcr = (NAND_CMD_READOOB << FCR_CMD0_SHIFT);
501 + lbc->fbcr = mtd->oobsize - column;
502 + set_addr(mtd, column, page_addr, 1);
504 + /* READID must read all 5 possible bytes while CEB is active */
505 + case NAND_CMD_READID:
506 + FCM_DEBUG(2,"fcm_cmdfunc: NAND_CMD_READID.\n");
507 + lbc->fir = (FIR_OP_CW0 << FIR_OP0_SHIFT) |
508 + (FIR_OP_UA << FIR_OP1_SHIFT) |
509 + (FIR_OP_RBW << FIR_OP2_SHIFT);
510 + lbc->fcr = (NAND_CMD_READID << FCR_CMD0_SHIFT);
511 + lbc->fbcr = 5; /* 5 bytes for manuf, device and exts */
515 + /* ERASE1 stores the block and page address */
516 + case NAND_CMD_ERASE1:
517 + FCM_DEBUG(2,"fcm_cmdfunc: NAND_CMD_ERASE1, page_addr:"
518 + " 0x%x.\n", page_addr);
519 + set_addr(mtd, 0, page_addr, 0);
521 + /* ERASE2 uses the block and page address from ERASE1 */
522 + case NAND_CMD_ERASE2:
523 + FCM_DEBUG(2,"fcm_cmdfunc: NAND_CMD_ERASE2.\n");
524 + lbc->fir = (FIR_OP_CW0 << FIR_OP0_SHIFT) |
525 + (FIR_OP_PA << FIR_OP1_SHIFT) |
526 + (FIR_OP_CM1 << FIR_OP2_SHIFT);
527 + lbc->fcr = (NAND_CMD_ERASE1 << FCR_CMD0_SHIFT) |
528 + (NAND_CMD_ERASE2 << FCR_CMD1_SHIFT);
531 + /* SEQIN sets up the addr buffer and all registers except the length */
532 + case NAND_CMD_SEQIN:
533 + FCM_DEBUG(2,"fcm_cmdfunc: NAND_CMD_SEQIN/PAGE_PROG, page_addr:"
534 + " 0x%x, column: 0x%x.\n", page_addr, column);
536 + lbc->fbcr = 0; /* write entire page to enable ECC */
538 + lbc->fbcr = 1; /* mark as partial page so no HW ECC */
541 + /* always use READ0 for large page devices */
542 + lbc->fir = (FIR_OP_CW0 << FIR_OP0_SHIFT) |
543 + (FIR_OP_CA << FIR_OP1_SHIFT) |
544 + (FIR_OP_PA << FIR_OP2_SHIFT) |
545 + (FIR_OP_WB << FIR_OP3_SHIFT) |
546 + (FIR_OP_CW1 << FIR_OP4_SHIFT);
547 + lbc->fcr = (NAND_CMD_SEQIN << FCR_CMD0_SHIFT) |
548 + (NAND_CMD_PAGEPROG << FCR_CMD1_SHIFT);
549 + set_addr(mtd, column, page_addr, 0);
551 + lbc->fir = (FIR_OP_CW0 << FIR_OP0_SHIFT) |
552 + (FIR_OP_CM2 << FIR_OP1_SHIFT) |
553 + (FIR_OP_CA << FIR_OP2_SHIFT) |
554 + (FIR_OP_PA << FIR_OP3_SHIFT) |
555 + (FIR_OP_WB << FIR_OP4_SHIFT) |
556 + (FIR_OP_CW1 << FIR_OP5_SHIFT);
557 + if (column >= mtd->oobblock) {
558 + /* OOB area --> READOOB */
559 + column -= mtd->oobblock;
560 + lbc->fcr = (NAND_CMD_READOOB << FCR_CMD0_SHIFT)
561 + | (NAND_CMD_PAGEPROG<< FCR_CMD1_SHIFT)
562 + | (NAND_CMD_SEQIN << FCR_CMD2_SHIFT);
563 + set_addr(mtd, column, page_addr, 1);
564 + } else if (column < 256) {
565 + /* First 256 bytes --> READ0 */
566 + lbc->fcr = (NAND_CMD_READ0 << FCR_CMD0_SHIFT)
567 + | (NAND_CMD_PAGEPROG<< FCR_CMD1_SHIFT)
568 + | (NAND_CMD_SEQIN << FCR_CMD2_SHIFT);
569 + set_addr(mtd, column, page_addr, 0);
571 + /* Second 256 bytes --> READ1 */
573 + lbc->fcr = (NAND_CMD_READ1 << FCR_CMD0_SHIFT)
574 + | (NAND_CMD_PAGEPROG<< FCR_CMD1_SHIFT)
575 + | (NAND_CMD_SEQIN << FCR_CMD2_SHIFT);
576 + set_addr(mtd, column, page_addr, 0);
580 + /* PAGEPROG reuses all of the setup from SEQIN and adds the length */
581 + case NAND_CMD_PAGEPROG:
582 + FCM_DEBUG(2,"fcm_cmdfunc: NAND_CMD_PAGEPROG"
583 + " writing %d bytes.\n",fcm->index);
584 + /* if the write did not start at 0 or is not a full page */
585 + /* then set the exact length, otherwise use a full page */
586 + /* write so the HW generates the ECC. */
588 + (fcm->index != (mtd->oobblock + mtd->oobsize)))
589 + lbc->fbcr = fcm->index;
590 + fcm->req_bytes = 0;
592 + /* CMD_STATUS must read the status byte while CEB is active */
593 + /* Note - it does not wait for the ready line */
594 + case NAND_CMD_STATUS:
595 + FCM_DEBUG(2,"fcm_cmdfunc: NAND_CMD_STATUS.\n");
596 + lbc->fir = (FIR_OP_CM0 << FIR_OP0_SHIFT) |
597 + (FIR_OP_RBW << FIR_OP1_SHIFT);
598 + lbc->fcr = (NAND_CMD_STATUS << FCR_CMD0_SHIFT);
601 + /* RESET without waiting for the ready line */
602 + case NAND_CMD_RESET:
603 + FCM_DEBUG(2,"fcm_cmdfunc: NAND_CMD_RESET.\n");
604 + lbc->fir = (FIR_OP_CM0 << FIR_OP0_SHIFT);
605 + lbc->fcr = (NAND_CMD_RESET << FCR_CMD0_SHIFT);
609 + printk("fcm_cmdfunc: error, unsupported command.\n");
613 + /* Short cuts fall through to save code */
615 + set_addr(mtd, 0, 0, 0);
617 + fcm->req_bytes = lbc->fbcr;
619 + fcm_run_command(mtd);
621 +#ifdef CONFIG_MTD_NAND_VERIFY_WRITE
622 + /* if we wrote a page then read back the oob to get the ECC */
623 + if ((command == NAND_CMD_PAGEPROG) &&
624 + (this->eccmode > NAND_ECC_SOFT) &&
625 + (lbc->fbcr == 0) &&
626 + (fcm->oobbuf != 0) &&
627 + (fcm->oobbuf != -1)) {
630 + unsigned char *oob_buf;
633 + oob_buf = (unsigned char*) fcm->oobbuf;
634 + oob_config = this->autooob->eccpos;
636 + /* wait for the write to complete and check it passed */
637 + if (!(this->waitfunc(mtd, this, FL_WRITING) & 0x01)) {
638 + /* read back the OOB */
639 + fcm_cmdfunc(mtd, NAND_CMD_READOOB, 0, i);
640 + /* if it succeeded then copy the ECC bytes */
641 + if (fcm->status == LTESR_CC) {
642 + for (i = 0; i < this->eccbytes; i++) {
643 + oob_buf[oob_config[i]] =
644 + fcm->addr[oob_config[i]];
656 + * fcm_enable_hwecc - start ECC generation
658 +static void fcm_enable_hwecc(struct mtd_info *mtd, int mode)
664 + * fcm_calculate_ecc - Calculate the ECC bytes
665 + * This is done by hardware during the write process, so we use this
666 + * to arm the oob buf capture on the next write_buf() call. The ECC bytes
667 + * only need to be captured if CONFIG_MTD_NAND_VERIFY_WRITE is defined which
668 + * reads back the pages and checks they match the data and oob buffers.
670 +static int fcm_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code)
672 + register struct nand_chip *this = mtd->priv;
673 + struct fcm_nand *fcm = this->priv;
675 +#ifdef CONFIG_MTD_NAND_VERIFY_WRITE
676 + /* arm capture of oob buf ptr on next write_buf */
683 + * fcm_correct_data - Detect and correct bit error(s)
684 + * The detection and correction is done automatically by the hardware,
685 + * if the complete page was read. If the status code is okay then there
686 + * was no error, otherwise we return an error code indicating an uncorrectable
689 +static int fcm_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_char *calc_ecc)
691 + register struct nand_chip *this = mtd->priv;
692 + struct fcm_nand *fcm = this->priv;
695 + if (fcm->status == LTESR_CC)
698 + return -1; /* uncorrectable error */
704 + * Dummy scan_bbt to complete setup of the FMR based on NAND size
706 +static int fcm_scan_bbt (struct mtd_info *mtd)
708 + volatile immap_t *im = (immap_t *) CFG_IMMR;
709 + volatile lbus83xx_t *lbc= &im->lbus;
710 + register struct nand_chip *this = mtd->priv;
711 + struct fcm_nand *fcm = this->priv;
716 + printk (KERN_ERR "fcm_scan_bbt():" \
717 + " Failed to allocate chip specific data structure\n");
721 + /* calculate FMR Address Length field */
723 + for (i = this->pagemask >> 16; i ; i >>= 8) {
727 + /* add to ECCM mode set in fcm_init */
728 + fcm->fmr |= 12 << FMR_CWTO_SHIFT | /* Timeout > 12 mSecs */
729 + al << FMR_AL_SHIFT;
731 + FCM_DEBUG(1,"fcm_init: nand->options = %08X\n", this->options);
732 + FCM_DEBUG(1,"fcm_init: nand->numchips = %10d\n", this->numchips);
733 + FCM_DEBUG(1,"fcm_init: nand->chipsize = %10d\n", this->chipsize);
734 + FCM_DEBUG(1,"fcm_init: nand->pagemask = %10X\n", this->pagemask);
735 + FCM_DEBUG(1,"fcm_init: nand->eccmode = %10d\n", this->eccmode );
736 + FCM_DEBUG(1,"fcm_init: nand->eccsize = %10d\n", this->eccsize );
737 + FCM_DEBUG(1,"fcm_init: nand->eccbytes = %10d\n", this->eccbytes);
738 + FCM_DEBUG(1,"fcm_init: nand->eccsteps = %10d\n", this->eccsteps);
739 + FCM_DEBUG(1,"fcm_init: nand->chip_delay = %8d\n", this->chip_delay);
740 + FCM_DEBUG(1,"fcm_init: nand->badblockpos = %7d\n", this->badblockpos);
741 + FCM_DEBUG(1,"fcm_init: nand->chip_shift = %8d\n", this->chip_shift);
742 + FCM_DEBUG(1,"fcm_init: nand->page_shift = %8d\n", this->page_shift);
743 + FCM_DEBUG(1,"fcm_init: nand->phys_erase_shift = %2d\n",
744 + this->phys_erase_shift);
745 + FCM_DEBUG(1,"fcm_init: mtd->flags = %08X\n", mtd->flags);
746 + FCM_DEBUG(1,"fcm_init: mtd->size = %10d\n", mtd->size);
747 + FCM_DEBUG(1,"fcm_init: mtd->erasesize = %10d\n", mtd->erasesize);
748 + FCM_DEBUG(1,"fcm_init: mtd->oobblock = %10d\n", mtd->oobblock);
749 + FCM_DEBUG(1,"fcm_init: mtd->oobsize = %10d\n", mtd->oobsize);
750 + FCM_DEBUG(1,"fcm_init: mtd->oobavail = %10d\n", mtd->oobavail);
751 + FCM_DEBUG(1,"fcm_init: mtd->ecctype = %10d\n", mtd->ecctype);
752 + FCM_DEBUG(1,"fcm_init: mtd->eccsize = %10d\n", mtd->eccsize);
754 + /* adjust Option Register and ECC to match Flash page size */
755 + if (mtd->oobblock == 512)
756 + lbc->bank[fcm->bank].or &= ~(OR_FCM_PGS);
757 + else if (mtd->oobblock == 2048) {
758 + lbc->bank[fcm->bank].or |= OR_FCM_PGS;
759 + /* adjust ecc setup if needed */
760 + if ( (lbc->bank[fcm->bank].br & BR_DECC) == BR_DECC_CHK_GEN) {
761 + mtd->eccsize = 2048;
762 + mtd->oobavail -= 9;
763 + this->eccmode = NAND_ECC_HW12_2048;
764 + this->eccsize = 2048;
765 + this->eccbytes += 9;
766 + this->eccsteps = 1;
767 + this->autooob = (fcm->fmr & FMR_ECCM) ?
768 + &fcm_oob_lp_eccm1 : &fcm_oob_lp_eccm0;
769 + memcpy(&mtd->oobinfo, this->autooob,
770 + sizeof(mtd->oobinfo));
774 + printf("fcm_init: page size %d is not supported\n",
778 + fcm->pgs = (lbc->bank[fcm->bank].or>>OR_FCM_PGS_SHIFT) & 1;
781 + printf("fcm_init: %d address bytes is not supported\n", al+2);
785 + /* restore default scan_bbt function and call it */
786 + this->scan_bbt = nand_default_bbt;
787 + return nand_default_bbt(mtd);
791 + * Board-specific NAND initialization. The following members of the
792 + * argument are board-specific (per include/linux/mtd/nand_new.h):
793 + * - IO_ADDR_R?: address to read the 8 I/O lines of the flash device
794 + * - IO_ADDR_W?: address to write the 8 I/O lines of the flash device
795 + * - hwcontrol: hardwarespecific function for accesing control-lines
796 + * - dev_ready: hardwarespecific function for accesing device ready/busy line
797 + * - enable_hwecc: function to enable (reset) hardware ecc generator. Must
798 + * only be provided if a hardware ECC is available
799 + * - eccmode: mode of ecc, see defines
800 + * - chip_delay: chip dependent delay for transfering data from array to
802 + * - options: various chip options. They can partly be set to inform
803 + * nand_scan about special functionality. See the defines for further
805 + * Members with a "?" were not set in the merged testing-NAND branch,
806 + * so they are not set here either.
808 +int board_nand_init(struct nand_chip *nand)
810 + volatile immap_t *im = (immap_t *) CFG_IMMR;
811 + volatile lbus83xx_t *lbc= &im->lbus;
812 + struct fcm_nand *fcm;
815 + /* Enable FCM detection of timeouts, ECC errors and completion */
816 + lbc->ltedr &= ~(LTESR_FCT | LTESR_PAR | LTESR_CC);
818 + fcm = kmalloc (sizeof(struct fcm_nand), GFP_KERNEL);
820 + printk (KERN_ERR "board_nand_init():" \
821 + " Cannot allocate read buffer data structure\n");
825 + /* Find which chip select bank is being used for this device */
826 + for (bank=0; bank<8; bank++) {
827 + if ( (lbc->bank[bank].br & BR_V) &&
828 + ( (lbc->bank[bank].br & BR_MSEL) == BR_MS_FCM ) &&
829 + ( (lbc->bank[bank].br & BR_BA) ==
830 + (lbc->bank[bank].or & OR_FCM_AM &
831 + (unsigned int)(nand->IO_ADDR_R) ) ) ) {
833 +// TODO fcm->fmr = FMR_ECCM; /* rest filled in later */
834 + fcm->fmr = 0; /* rest filled in later */
835 + fcm->read_bytes = 0;
837 + fcm->pgs = (lbc->bank[bank].or>>OR_FCM_PGS_SHIFT) & 1;
838 + fcm->base = lbc->bank[bank].br & BR_BA;
839 + fcm->addr = (unsigned char*) (fcm->base);
847 + printk (KERN_ERR "board_nand_init():" \
848 + " Could not find matching Chip Select\n");
852 + /* set up nand options */
854 + /* set up function call table */
855 + nand->hwcontrol = fcm_hwcontrol;
856 + nand->waitfunc = fcm_wait;
857 + nand->read_byte = fcm_read_byte;
858 + nand->write_byte = fcm_write_byte;
859 + nand->read_word = fcm_read_word;
860 + nand->write_word = fcm_write_word;
861 + nand->read_buf = fcm_read_buf;
862 + nand->verify_buf = fcm_verify_buf;
863 + nand->write_buf = fcm_write_buf;
864 + nand->cmdfunc = fcm_cmdfunc;
865 + nand->scan_bbt = fcm_scan_bbt;
867 + /* If CS Base Register selects full hardware ECC then use it */
868 + if ( ( (lbc->bank[bank].br & BR_DECC) >> BR_DECC_SHIFT) == 2) {
869 + /* put in small page settings and adjust later if needed */
870 + nand->eccmode = NAND_ECC_HW3_512;
871 + nand->autooob = (fcm->fmr & FMR_ECCM) ?
872 + &fcm_oob_sp_eccm1 : &fcm_oob_sp_eccm0;
873 + nand->calculate_ecc = fcm_calculate_ecc;
874 + nand->correct_data = fcm_correct_data;
875 + nand->enable_hwecc = fcm_enable_hwecc;
877 + /* otherwise fall back to default software ECC */
878 + nand->eccmode = NAND_ECC_SOFT;
885 diff -urN u-boot-1.3.1.orig/include/configs/MPC8313ERDB.h u-boot-1.3.1/include/configs/MPC8313ERDB.h
886 --- u-boot-1.3.1.orig/include/configs/MPC8313ERDB.h 2007-12-06 10:21:19.000000000 +0100
887 +++ u-boot-1.3.1/include/configs/MPC8313ERDB.h 2008-01-31 17:36:18.000000000 +0100
889 #define CONFIG_CMD_MII
890 #define CONFIG_CMD_DATE
891 #define CONFIG_CMD_PCI
892 +#define CONFIG_CMD_NAND
894 #if defined(CFG_RAMBOOT)
895 #undef CONFIG_CMD_ENV