2 * (C) Copyright 2006-2007
3 * Stefan Roese, DENX Software Engineering, sr@denx.de.
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation; either version 2 of
8 * the License, or (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
24 #define CFG_NAND_READ_DELAY \
25 { volatile int dummy; int i; for (i=0; i<10000; i++) dummy = i; }
27 static int nand_ecc_pos
[] = CFG_NAND_ECCPOS
;
29 extern void board_nand_init(struct nand_chip
*nand
);
31 static int nand_command(struct mtd_info
*mtd
, int block
, int page
, int offs
, u8 cmd
)
33 struct nand_chip
*this = mtd
->priv
;
34 int page_addr
= page
+ block
* CFG_NAND_PAGE_COUNT
;
41 /* Begin command latch cycle */
42 this->hwcontrol(mtd
, NAND_CTL_SETCLE
);
43 this->write_byte(mtd
, cmd
);
44 /* Set ALE and clear CLE to start address cycle */
45 this->hwcontrol(mtd
, NAND_CTL_CLRCLE
);
46 this->hwcontrol(mtd
, NAND_CTL_SETALE
);
48 this->write_byte(mtd
, offs
); /* A[7:0] */
49 this->write_byte(mtd
, (uchar
)(page_addr
& 0xff)); /* A[16:9] */
50 this->write_byte(mtd
, (uchar
)((page_addr
>> 8) & 0xff)); /* A[24:17] */
51 #ifdef CFG_NAND_4_ADDR_CYCLE
52 /* One more address cycle for devices > 32MiB */
53 this->write_byte(mtd
, (uchar
)((page_addr
>> 16) & 0x0f)); /* A[xx:25] */
55 /* Latch in address */
56 this->hwcontrol(mtd
, NAND_CTL_CLRALE
);
59 * Wait a while for the data to be ready
69 static int nand_is_bad_block(struct mtd_info
*mtd
, int block
)
71 struct nand_chip
*this = mtd
->priv
;
73 nand_command(mtd
, block
, 0, CFG_NAND_BAD_BLOCK_POS
, NAND_CMD_READOOB
);
78 if (this->read_byte(mtd
) != 0xff)
84 static int nand_read_page(struct mtd_info
*mtd
, int block
, int page
, uchar
*dst
)
86 struct nand_chip
*this = mtd
->priv
;
91 int eccsize
= CFG_NAND_ECCSIZE
;
92 int eccbytes
= CFG_NAND_ECCBYTES
;
93 int eccsteps
= CFG_NAND_ECCSTEPS
;
97 nand_command(mtd
, block
, page
, 0, NAND_CMD_READ0
);
99 /* No malloc available for now, just use some temporary locations
102 ecc_calc
= (u_char
*)(CFG_SDRAM_BASE
+ 0x10000);
103 ecc_code
= ecc_calc
+ 0x100;
104 oob_data
= ecc_calc
+ 0x200;
106 for (i
= 0; eccsteps
; eccsteps
--, i
+= eccbytes
, p
+= eccsize
) {
107 this->enable_hwecc(mtd
, NAND_ECC_READ
);
108 this->read_buf(mtd
, p
, eccsize
);
109 this->calculate_ecc(mtd
, p
, &ecc_calc
[i
]);
111 this->read_buf(mtd
, oob_data
, CFG_NAND_OOBSIZE
);
113 /* Pick the ECC bytes out of the oob data */
114 for (i
= 0; i
< CFG_NAND_ECCTOTAL
; i
++)
115 ecc_code
[i
] = oob_data
[nand_ecc_pos
[i
]];
117 eccsteps
= CFG_NAND_ECCSTEPS
;
120 for (i
= 0 ; eccsteps
; eccsteps
--, i
+= eccbytes
, p
+= eccsize
) {
121 /* No chance to do something with the possible error message
122 * from correct_data(). We just hope that all possible errors
123 * are corrected by this routine.
125 stat
= this->correct_data(mtd
, p
, &ecc_code
[i
], &ecc_calc
[i
]);
131 static int nand_load(struct mtd_info
*mtd
, int offs
, int uboot_size
, uchar
*dst
)
138 * offs has to be aligned to a block address!
140 block
= offs
/ CFG_NAND_BLOCK_SIZE
;
143 while (blockcopy_count
< (uboot_size
/ CFG_NAND_BLOCK_SIZE
)) {
144 if (!nand_is_bad_block(mtd
, block
)) {
148 for (page
= 0; page
< CFG_NAND_PAGE_COUNT
; page
++) {
149 nand_read_page(mtd
, block
, page
, dst
);
150 dst
+= CFG_NAND_PAGE_SIZE
;
165 struct nand_chip nand_chip
;
166 nand_info_t nand_info
;
171 * Init sdram, so we have access to memory
173 mem_size
= initdram(0);
176 * Init board specific nand support
178 nand_info
.priv
= &nand_chip
;
179 nand_chip
.IO_ADDR_R
= nand_chip
.IO_ADDR_W
= (void __iomem
*)CFG_NAND_BASE
;
180 nand_chip
.dev_ready
= NULL
; /* preset to NULL */
181 board_nand_init(&nand_chip
);
184 * Load U-Boot image from NAND into RAM
186 ret
= nand_load(&nand_info
, CFG_NAND_U_BOOT_OFFS
, CFG_NAND_U_BOOT_SIZE
,
187 (uchar
*)CFG_NAND_U_BOOT_DST
);
190 * Jump to U-Boot image
192 uboot
= (void (*)(void))CFG_NAND_U_BOOT_START
;