diff options
author | Prabhakar Kushwaha <prabhakar@freescale.com> | 2013-04-16 13:28:12 +0530 |
---|---|---|
committer | Andy Fleming <afleming@freescale.com> | 2013-06-20 16:09:07 -0500 |
commit | 0fa934d235c282e8efd119fc14a18315a8666930 (patch) | |
tree | f5ba5143a55d85340127fcf34b6789c140628a89 /nand_spl/nand_boot_fsl_ifc.c | |
parent | 3a88179d03dfc41154e5bf12826c800dee864b7c (diff) | |
download | talos-obmc-uboot-0fa934d235c282e8efd119fc14a18315a8666930.tar.gz talos-obmc-uboot-0fa934d235c282e8efd119fc14a18315a8666930.zip |
board/p1010rdb:Add NAND boot support using new SPL format
- defines constants
- Add spl_minimal.c to initialise DDR
- update TLB entries as per NAND boot
- remove nand_spl support for P1010RDB
Signed-off-by: Prabhakar Kushwaha <prabhakar@freescale.com>
Signed-off-by: Andy Fleming <afleming@freescale.com>
Diffstat (limited to 'nand_spl/nand_boot_fsl_ifc.c')
-rw-r--r-- | nand_spl/nand_boot_fsl_ifc.c | 271 |
1 files changed, 0 insertions, 271 deletions
diff --git a/nand_spl/nand_boot_fsl_ifc.c b/nand_spl/nand_boot_fsl_ifc.c deleted file mode 100644 index 44972c5c09..0000000000 --- a/nand_spl/nand_boot_fsl_ifc.c +++ /dev/null @@ -1,271 +0,0 @@ -/* - * NAND boot for FSL Integrated Flash Controller, NAND Flash Control Machine - * - * Copyright 2011 Freescale Semiconductor, Inc. - * Author: Dipen Dudhat <dipen.dudhat@freescale.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include <common.h> -#include <asm/io.h> -#include <asm/fsl_ifc.h> -#include <linux/mtd/nand.h> - -static inline int is_blank(uchar *addr, int page_size) -{ - int i; - - for (i = 0; i < page_size; i++) { - if (__raw_readb(&addr[i]) != 0xff) - return 0; - } - - /* - * For the SPL, don't worry about uncorrectable errors - * where the main area is all FFs but shouldn't be. - */ - return 1; -} - -/* returns nonzero if entire page is blank */ -static inline int check_read_ecc(uchar *buf, u32 *eccstat, - unsigned int bufnum, int page_size) -{ - u32 reg = eccstat[bufnum / 4]; - int errors = (reg >> ((3 - bufnum % 4) * 8)) & 15; - - if (errors == 15) { /* uncorrectable */ - /* Blank pages fail hw ECC checks */ - if (is_blank(buf, page_size)) - return 1; - - puts("ecc error\n"); - for (;;) - ; - } - - return 0; -} - -static inline void nand_wait(uchar *buf, int bufnum, int page_size) -{ - struct fsl_ifc *ifc = IFC_BASE_ADDR; - u32 status; - u32 eccstat[4]; - int bufperpage = page_size / 512; - int bufnum_end, i; - - bufnum *= bufperpage; - bufnum_end = bufnum + bufperpage - 1; - - do { - status = in_be32(&ifc->ifc_nand.nand_evter_stat); - } while (!(status & IFC_NAND_EVTER_STAT_OPC)); - - if (status & IFC_NAND_EVTER_STAT_FTOER) { - puts("flash time out error\n"); - for (;;) - ; - } - - for (i = bufnum / 4; i <= bufnum_end / 4; i++) - eccstat[i] = in_be32(&ifc->ifc_nand.nand_eccstat[i]); - - for (i = bufnum; i <= bufnum_end; i++) { - if (check_read_ecc(buf, eccstat, i, page_size)) - break; - } - - out_be32(&ifc->ifc_nand.nand_evter_stat, status); -} - -static inline int bad_block(uchar *marker, int port_size) -{ - if (port_size == 8) - return __raw_readb(marker) != 0xff; - else - return __raw_readw((u16 *)marker) != 0xffff; -} - -static void nand_load(unsigned int offs, int uboot_size, uchar *dst) -{ - struct fsl_ifc *ifc = IFC_BASE_ADDR; - uchar *buf = (uchar *)CONFIG_SYS_NAND_BASE; - int page_size; - int port_size; - int pages_per_blk; - int blk_size; - int bad_marker = 0; - int bufnum_mask, bufnum; - - int csor, cspr; - int pos = 0; - int j = 0; - - int sram_addr; - int pg_no; - - /* Get NAND Flash configuration */ - csor = CONFIG_SYS_NAND_CSOR; - cspr = CONFIG_SYS_NAND_CSPR; - - if (!(csor & CSOR_NAND_ECC_DEC_EN)) { - /* soft ECC in SPL is unimplemented */ - puts("WARNING: soft ECC not checked in SPL\n"); - } else { - u32 hwcsor; - - /* make sure board is configured with ECC on boot */ - hwcsor = in_be32(&ifc->csor_cs[0].csor); - if (!(hwcsor & CSOR_NAND_ECC_DEC_EN)) - puts("WARNING: ECC not checked in SPL, " - "check board cfg\n"); - } - - port_size = (cspr & CSPR_PORT_SIZE_16) ? 16 : 8; - - if (csor & CSOR_NAND_PGS_4K) { - page_size = 4096; - bufnum_mask = 1; - } else if (csor & CSOR_NAND_PGS_2K) { - page_size = 2048; - bufnum_mask = 3; - } else { - page_size = 512; - bufnum_mask = 15; - - if (port_size == 8) - bad_marker = 5; - } - - pages_per_blk = - 32 << ((csor & CSOR_NAND_PB_MASK) >> CSOR_NAND_PB_SHIFT); - - blk_size = pages_per_blk * page_size; - - /* Open Full SRAM mapping for spare are access */ - out_be32(&ifc->ifc_nand.ncfgr, 0x0); - - /* Clear Boot events */ - out_be32(&ifc->ifc_nand.nand_evter_stat, 0xffffffff); - - /* Program FIR/FCR for Large/Small page */ - if (page_size > 512) { - out_be32(&ifc->ifc_nand.nand_fir0, - (IFC_FIR_OP_CW0 << IFC_NAND_FIR0_OP0_SHIFT) | - (IFC_FIR_OP_CA0 << IFC_NAND_FIR0_OP1_SHIFT) | - (IFC_FIR_OP_RA0 << IFC_NAND_FIR0_OP2_SHIFT) | - (IFC_FIR_OP_CMD1 << IFC_NAND_FIR0_OP3_SHIFT) | - (IFC_FIR_OP_BTRD << IFC_NAND_FIR0_OP4_SHIFT)); - out_be32(&ifc->ifc_nand.nand_fir1, 0x0); - - out_be32(&ifc->ifc_nand.nand_fcr0, - (NAND_CMD_READ0 << IFC_NAND_FCR0_CMD0_SHIFT) | - (NAND_CMD_READSTART << IFC_NAND_FCR0_CMD1_SHIFT)); - } else { - out_be32(&ifc->ifc_nand.nand_fir0, - (IFC_FIR_OP_CW0 << IFC_NAND_FIR0_OP0_SHIFT) | - (IFC_FIR_OP_CA0 << IFC_NAND_FIR0_OP1_SHIFT) | - (IFC_FIR_OP_RA0 << IFC_NAND_FIR0_OP2_SHIFT) | - (IFC_FIR_OP_BTRD << IFC_NAND_FIR0_OP3_SHIFT)); - out_be32(&ifc->ifc_nand.nand_fir1, 0x0); - - out_be32(&ifc->ifc_nand.nand_fcr0, - NAND_CMD_READ0 << IFC_NAND_FCR0_CMD0_SHIFT); - } - - /* Program FBCR = 0 for full page read */ - out_be32(&ifc->ifc_nand.nand_fbcr, 0); - - /* Read and copy u-boot on SDRAM from NAND device, In parallel - * check for Bad block if found skip it and read continue to - * next Block - */ - while (pos < uboot_size) { - int i = 0; - do { - pg_no = offs / page_size; - bufnum = pg_no & bufnum_mask; - sram_addr = bufnum * page_size * 2; - - out_be32(&ifc->ifc_nand.row0, pg_no); - out_be32(&ifc->ifc_nand.col0, 0); - /* start read */ - out_be32(&ifc->ifc_nand.nandseq_strt, - IFC_NAND_SEQ_STRT_FIR_STRT); - - /* wait for read to complete */ - nand_wait(&buf[sram_addr], bufnum, page_size); - - /* - * If either of the first two pages are marked bad, - * continue to the next block. - */ - if (i++ < 2 && - bad_block(&buf[sram_addr + page_size + bad_marker], - port_size)) { - puts("skipping\n"); - offs = (offs + blk_size) & ~(blk_size - 1); - pos &= ~(blk_size - 1); - break; - } - - for (j = 0; j < page_size; j++) - dst[pos + j] = __raw_readb(&buf[sram_addr + j]); - - pos += page_size; - offs += page_size; - } while ((offs & (blk_size - 1)) && (pos < uboot_size)); - } -} - -/* - * Main entrypoint for NAND Boot. It's necessary that SDRAM is already - * configured and available since this code loads the main U-boot image - * from NAND into SDRAM and starts from there. - */ -void nand_boot(void) -{ - __attribute__((noreturn)) void (*uboot)(void); - - /* - * Load U-Boot image from NAND into RAM - */ - nand_load(CONFIG_SYS_NAND_U_BOOT_OFFS, CONFIG_SYS_NAND_U_BOOT_SIZE, - (uchar *)CONFIG_SYS_NAND_U_BOOT_DST); - -#ifdef CONFIG_NAND_ENV_DST - nand_load(CONFIG_ENV_OFFSET, CONFIG_ENV_SIZE, - (uchar *)CONFIG_NAND_ENV_DST); - -#ifdef CONFIG_ENV_OFFSET_REDUND - nand_load(CONFIG_ENV_OFFSET_REDUND, CONFIG_ENV_SIZE, - (uchar *)CONFIG_NAND_ENV_DST + CONFIG_ENV_SIZE); -#endif -#endif - - /* - * Jump to U-Boot image - */ - /* - * Clean d-cache and invalidate i-cache, to - * make sure that no stale data is executed. - */ - flush_cache(CONFIG_SYS_NAND_U_BOOT_DST, CONFIG_SYS_NAND_U_BOOT_SIZE); - uboot = (void *)CONFIG_SYS_NAND_U_BOOT_START; - uboot(); -} |