1 // SPDX-License-Identifier: GPL-2.0+
3 * NAND boot for Freescale Integrated Flash Controller, NAND FCM
5 * Copyright 2011 Freescale Semiconductor, Inc.
6 * Author: Dipen Dudhat <dipen.dudhat@freescale.com>
14 #include <linux/mtd/rawnand.h>
15 #ifdef CONFIG_CHAIN_OF_TRUST
16 #include <fsl_validate.h>
19 static inline int is_blank(uchar
*addr
, int page_size
)
23 for (i
= 0; i
< page_size
; i
++) {
24 if (__raw_readb(&addr
[i
]) != 0xff)
29 * For the SPL, don't worry about uncorrectable errors
30 * where the main area is all FFs but shouldn't be.
35 /* returns nonzero if entire page is blank */
36 static inline int check_read_ecc(uchar
*buf
, u32
*eccstat
,
37 unsigned int bufnum
, int page_size
)
39 u32 reg
= eccstat
[bufnum
/ 4];
40 int errors
= (reg
>> ((3 - bufnum
% 4) * 8)) & 0xf;
42 if (errors
== 0xf) { /* uncorrectable */
43 /* Blank pages fail hw ECC checks */
44 if (is_blank(buf
, page_size
))
55 static inline struct fsl_ifc_runtime
*runtime_regs_address(void)
57 struct fsl_ifc regs
= {(void *)CFG_SYS_IFC_ADDR
, NULL
};
60 ver
= ifc_in32(®s
.gregs
->ifc_rev
);
61 if (ver
>= FSL_IFC_V2_0_0
)
62 regs
.rregs
= (void *)CFG_SYS_IFC_ADDR
+ IFC_RREGS_64KOFFSET
;
64 regs
.rregs
= (void *)CFG_SYS_IFC_ADDR
+ IFC_RREGS_4KOFFSET
;
69 static inline void nand_wait(uchar
*buf
, int bufnum
, int page_size
)
71 struct fsl_ifc_runtime
*ifc
= runtime_regs_address();
74 int bufperpage
= page_size
/ 512;
78 bufnum_end
= bufnum
+ bufperpage
- 1;
81 status
= ifc_in32(&ifc
->ifc_nand
.nand_evter_stat
);
82 } while (!(status
& IFC_NAND_EVTER_STAT_OPC
));
84 if (status
& IFC_NAND_EVTER_STAT_FTOER
) {
85 puts("flash time out error\n");
90 for (i
= bufnum
/ 4; i
<= bufnum_end
/ 4; i
++)
91 eccstat
[i
] = ifc_in32(&ifc
->ifc_nand
.nand_eccstat
[i
]);
93 for (i
= bufnum
; i
<= bufnum_end
; i
++) {
94 if (check_read_ecc(buf
, eccstat
, i
, page_size
))
98 ifc_out32(&ifc
->ifc_nand
.nand_evter_stat
, status
);
101 static inline int bad_block(uchar
*marker
, int port_size
)
104 return __raw_readb(marker
) != 0xff;
106 return __raw_readw((u16
*)marker
) != 0xffff;
109 int nand_spl_load_image(uint32_t offs
, unsigned int uboot_size
, void *vdst
)
111 struct fsl_ifc_fcm
*gregs
= (void *)CFG_SYS_IFC_ADDR
;
112 struct fsl_ifc_runtime
*ifc
= NULL
;
113 uchar
*buf
= (uchar
*)CFG_SYS_NAND_BASE
;
119 int bufnum_mask
, bufnum
, ver
= 0;
129 ifc
= runtime_regs_address();
131 /* Get NAND Flash configuration */
132 csor
= CFG_SYS_NAND_CSOR
;
133 cspr
= CFG_SYS_NAND_CSPR
;
135 port_size
= (cspr
& CSPR_PORT_SIZE_16
) ? 16 : 8;
137 if ((csor
& CSOR_NAND_PGS_MASK
) == CSOR_NAND_PGS_8K
) {
140 } else if ((csor
& CSOR_NAND_PGS_MASK
) == CSOR_NAND_PGS_4K
) {
143 } else if ((csor
& CSOR_NAND_PGS_MASK
) == CSOR_NAND_PGS_2K
) {
154 ver
= ifc_in32(&gregs
->ifc_rev
);
155 if (ver
>= FSL_IFC_V2_0_0
)
156 bufnum_mask
= (bufnum_mask
* 2) + 1;
159 32 << ((csor
& CSOR_NAND_PB_MASK
) >> CSOR_NAND_PB_SHIFT
);
161 blk_size
= pages_per_blk
* page_size
;
163 /* Open Full SRAM mapping for spare are access */
164 ifc_out32(&ifc
->ifc_nand
.ncfgr
, 0x0);
166 /* Clear Boot events */
167 ifc_out32(&ifc
->ifc_nand
.nand_evter_stat
, 0xffffffff);
169 /* Program FIR/FCR for Large/Small page */
170 if (page_size
> 512) {
171 ifc_out32(&ifc
->ifc_nand
.nand_fir0
,
172 (IFC_FIR_OP_CW0
<< IFC_NAND_FIR0_OP0_SHIFT
) |
173 (IFC_FIR_OP_CA0
<< IFC_NAND_FIR0_OP1_SHIFT
) |
174 (IFC_FIR_OP_RA0
<< IFC_NAND_FIR0_OP2_SHIFT
) |
175 (IFC_FIR_OP_CMD1
<< IFC_NAND_FIR0_OP3_SHIFT
) |
176 (IFC_FIR_OP_BTRD
<< IFC_NAND_FIR0_OP4_SHIFT
));
177 ifc_out32(&ifc
->ifc_nand
.nand_fir1
, 0x0);
179 ifc_out32(&ifc
->ifc_nand
.nand_fcr0
,
180 (NAND_CMD_READ0
<< IFC_NAND_FCR0_CMD0_SHIFT
) |
181 (NAND_CMD_READSTART
<< IFC_NAND_FCR0_CMD1_SHIFT
));
183 ifc_out32(&ifc
->ifc_nand
.nand_fir0
,
184 (IFC_FIR_OP_CW0
<< IFC_NAND_FIR0_OP0_SHIFT
) |
185 (IFC_FIR_OP_CA0
<< IFC_NAND_FIR0_OP1_SHIFT
) |
186 (IFC_FIR_OP_RA0
<< IFC_NAND_FIR0_OP2_SHIFT
) |
187 (IFC_FIR_OP_BTRD
<< IFC_NAND_FIR0_OP3_SHIFT
));
188 ifc_out32(&ifc
->ifc_nand
.nand_fir1
, 0x0);
190 ifc_out32(&ifc
->ifc_nand
.nand_fcr0
,
191 NAND_CMD_READ0
<< IFC_NAND_FCR0_CMD0_SHIFT
);
194 /* Program FBCR = 0 for full page read */
195 ifc_out32(&ifc
->ifc_nand
.nand_fbcr
, 0);
197 /* Read and copy u-boot on SDRAM from NAND device, In parallel
198 * check for Bad block if found skip it and read continue to
201 while (pos
< uboot_size
) {
204 pg_no
= offs
/ page_size
;
205 bufnum
= pg_no
& bufnum_mask
;
206 sram_addr
= bufnum
* page_size
* 2;
208 ifc_out32(&ifc
->ifc_nand
.row0
, pg_no
);
209 ifc_out32(&ifc
->ifc_nand
.col0
, 0);
211 ifc_out32(&ifc
->ifc_nand
.nandseq_strt
,
212 IFC_NAND_SEQ_STRT_FIR_STRT
);
214 /* wait for read to complete */
215 nand_wait(&buf
[sram_addr
], bufnum
, page_size
);
218 * If either of the first two pages are marked bad,
219 * continue to the next block.
222 bad_block(&buf
[sram_addr
+ page_size
+ bad_marker
],
225 offs
= (offs
+ blk_size
) & ~(blk_size
- 1);
226 pos
&= ~(blk_size
- 1);
230 for (j
= 0; j
< page_size
; j
++)
231 dst
[pos
+ j
] = __raw_readb(&buf
[sram_addr
+ j
]);
235 } while ((offs
& (blk_size
- 1)) && (pos
< uboot_size
));
242 * Main entrypoint for NAND Boot. It's necessary that SDRAM is already
243 * configured and available since this code loads the main U-Boot image
244 * from NAND into SDRAM and starts from there.
248 __attribute__((noreturn
)) void (*uboot
)(void);
250 * Load U-Boot image from NAND into RAM
252 nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS
,
253 CFG_SYS_NAND_U_BOOT_SIZE
,
254 (uchar
*)CFG_SYS_NAND_U_BOOT_DST
);
256 #ifdef CONFIG_NAND_ENV_DST
257 nand_spl_load_image(CONFIG_ENV_OFFSET
, CONFIG_ENV_SIZE
,
258 (uchar
*)CONFIG_NAND_ENV_DST
);
260 #ifdef CONFIG_ENV_OFFSET_REDUND
261 nand_spl_load_image(CONFIG_ENV_OFFSET_REDUND
, CONFIG_ENV_SIZE
,
262 (uchar
*)CONFIG_NAND_ENV_DST
+ CONFIG_ENV_SIZE
);
266 * Jump to U-Boot image
268 #ifdef CONFIG_SPL_FLUSH_IMAGE
270 * Clean d-cache and invalidate i-cache, to
271 * make sure that no stale data is executed.
273 flush_cache(CFG_SYS_NAND_U_BOOT_DST
, CFG_SYS_NAND_U_BOOT_SIZE
);
276 #ifdef CONFIG_CHAIN_OF_TRUST
278 * U-Boot header is appended at end of U-Boot image, so
279 * calculate U-Boot header address using U-Boot header size.
281 #define FSL_U_BOOT_HDR_ADDR \
282 ((CFG_SYS_NAND_U_BOOT_START + \
283 CFG_SYS_NAND_U_BOOT_SIZE) - \
285 spl_validate_uboot(FSL_U_BOOT_HDR_ADDR
,
286 CFG_SYS_NAND_U_BOOT_START
);
288 * In case of failure in validation, spl_validate_uboot would
289 * not return back in case of Production environment with ITS=1.
290 * Thus U-Boot will not start.
291 * In Development environment (ITS=0 and SB_EN=1), the function
292 * may return back in case of non-fatal failures.
296 uboot
= (void *)CFG_SYS_NAND_U_BOOT_START
;
300 #ifndef CONFIG_TPL_NAND_INIT
305 void nand_deselect(void)