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 extern void board_nand_init(struct nand_chip
*nand
);
28 extern void ndfc_hwcontrol(struct mtd_info
*mtdinfo
, int cmd
);
29 extern void ndfc_write_byte(struct mtd_info
*mtdinfo
, u_char byte
);
30 extern u_char
ndfc_read_byte(struct mtd_info
*mtdinfo
);
31 extern int ndfc_dev_ready(struct mtd_info
*mtdinfo
);
32 extern int jump_to_ram(ulong delta
);
33 extern int jump_to_uboot(ulong addr
);
35 static int nand_is_bad_block(struct mtd_info
*mtd
, int block
)
37 struct nand_chip
*this = mtd
->priv
;
38 int page_addr
= block
* CFG_NAND_PAGE_COUNT
;
40 /* Begin command latch cycle */
41 this->hwcontrol(mtd
, NAND_CTL_SETCLE
);
42 this->write_byte(mtd
, NAND_CMD_READOOB
);
43 /* Set ALE and clear CLE to start address cycle */
44 this->hwcontrol(mtd
, NAND_CTL_CLRCLE
);
45 this->hwcontrol(mtd
, NAND_CTL_SETALE
);
47 this->write_byte(mtd
, CFG_NAND_BAD_BLOCK_POS
); /* A[7:0] */
48 this->write_byte(mtd
, (uchar
)(page_addr
& 0xff)); /* A[16:9] */
49 this->write_byte(mtd
, (uchar
)((page_addr
>> 8) & 0xff)); /* A[24:17] */
50 #ifdef CFG_NAND_4_ADDR_CYCLE
51 /* One more address cycle for devices > 32MiB */
52 this->write_byte(mtd
, (uchar
)((page_addr
>> 16) & 0x0f)); /* A[xx:25] */
54 /* Latch in address */
55 this->hwcontrol(mtd
, NAND_CTL_CLRALE
);
58 * Wait a while for the data to be ready
68 if (this->read_byte(mtd
) != 0xff)
74 static int nand_read_page(struct mtd_info
*mtd
, int block
, int page
, uchar
*dst
)
76 struct nand_chip
*this = mtd
->priv
;
77 int page_addr
= page
+ block
* CFG_NAND_PAGE_COUNT
;
80 /* Begin command latch cycle */
81 this->hwcontrol(mtd
, NAND_CTL_SETCLE
);
82 this->write_byte(mtd
, NAND_CMD_READ0
);
83 /* Set ALE and clear CLE to start address cycle */
84 this->hwcontrol(mtd
, NAND_CTL_CLRCLE
);
85 this->hwcontrol(mtd
, NAND_CTL_SETALE
);
87 this->write_byte(mtd
, 0); /* A[7:0] */
88 this->write_byte(mtd
, (uchar
)(page_addr
& 0xff)); /* A[16:9] */
89 this->write_byte(mtd
, (uchar
)((page_addr
>> 8) & 0xff)); /* A[24:17] */
90 #ifdef CFG_NAND_4_ADDR_CYCLE
91 /* One more address cycle for devices > 32MiB */
92 this->write_byte(mtd
, (uchar
)((page_addr
>> 16) & 0x0f)); /* A[xx:25] */
94 /* Latch in address */
95 this->hwcontrol(mtd
, NAND_CTL_CLRALE
);
98 * Wait a while for the data to be ready
101 this->dev_ready(mtd
);
106 * Read page into buffer
108 for (i
=0; i
<CFG_NAND_PAGE_SIZE
; i
++)
109 *dst
++ = this->read_byte(mtd
);
114 static int nand_load(struct mtd_info
*mtd
, int offs
, int uboot_size
, uchar
*dst
)
121 * offs has to be aligned to a block address!
123 block
= offs
/ CFG_NAND_BLOCK_SIZE
;
126 while (blockcopy_count
< (uboot_size
/ CFG_NAND_BLOCK_SIZE
)) {
127 if (!nand_is_bad_block(mtd
, block
)) {
131 for (page
= 0; page
< CFG_NAND_PAGE_COUNT
; page
++) {
132 nand_read_page(mtd
, block
, page
, dst
);
133 dst
+= CFG_NAND_PAGE_SIZE
;
148 struct nand_chip nand_chip
;
149 nand_info_t nand_info
;
154 * Init sdram, so we have access to memory
156 mem_size
= initdram(0);
159 * Init board specific nand support
161 nand_info
.priv
= &nand_chip
;
162 nand_chip
.IO_ADDR_R
= nand_chip
.IO_ADDR_W
= (void __iomem
*)CFG_NAND_BASE
;
163 nand_chip
.dev_ready
= NULL
; /* preset to NULL */
164 board_nand_init(&nand_chip
);
167 * Load U-Boot image from NAND into RAM
169 ret
= nand_load(&nand_info
, CFG_NAND_U_BOOT_OFFS
, CFG_NAND_U_BOOT_SIZE
,
170 (uchar
*)CFG_NAND_U_BOOT_DST
);
173 * Jump to U-Boot image
175 uboot
= (void (*)(void))CFG_NAND_U_BOOT_START
;