diff options
author | Miquel Raynal <miquel.raynal@bootlin.com> | 2018-08-16 17:30:07 +0200 |
---|---|---|
committer | Jagan Teki <jagan@amarulasolutions.com> | 2018-09-20 20:10:49 +0530 |
commit | a430fa06a4ac50e785fdbfb7f43c3cb14b35619c (patch) | |
tree | 08c848b10a9dc1bc865096f0bdce248218512e4d /drivers/mtd/nand/fsl_ifc_spl.c | |
parent | ce9bdc87436ef91129876c9b16fcf5111eea69aa (diff) | |
download | u-boot-a430fa06a4ac50e785fdbfb7f43c3cb14b35619c.tar.gz u-boot-a430fa06a4ac50e785fdbfb7f43c3cb14b35619c.tar.xz u-boot-a430fa06a4ac50e785fdbfb7f43c3cb14b35619c.zip |
mtd: move NAND files into a raw/ subdirectory
NAND flavors, like serial and parallel, have a lot in common and would
benefit to share code. Let's move raw (parallel) NAND specific code in a
raw/ subdirectory, to ease the addition of a core file in nand/ and the
introduction of a spi/ subdirectory specific to SPI NANDs.
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Diffstat (limited to 'drivers/mtd/nand/fsl_ifc_spl.c')
-rw-r--r-- | drivers/mtd/nand/fsl_ifc_spl.c | 306 |
1 files changed, 0 insertions, 306 deletions
diff --git a/drivers/mtd/nand/fsl_ifc_spl.c b/drivers/mtd/nand/fsl_ifc_spl.c deleted file mode 100644 index 7137eb4108..0000000000 --- a/drivers/mtd/nand/fsl_ifc_spl.c +++ /dev/null @@ -1,306 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * NAND boot for Freescale Integrated Flash Controller, NAND FCM - * - * Copyright 2011 Freescale Semiconductor, Inc. - * Author: Dipen Dudhat <dipen.dudhat@freescale.com> - */ - -#include <common.h> -#include <asm/io.h> -#include <fsl_ifc.h> -#include <linux/mtd/rawnand.h> -#ifdef CONFIG_CHAIN_OF_TRUST -#include <fsl_validate.h> -#endif - -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)) & 0xf; - - if (errors == 0xf) { /* uncorrectable */ - /* Blank pages fail hw ECC checks */ - if (is_blank(buf, page_size)) - return 1; - - puts("ecc error\n"); - for (;;) - ; - } - - return 0; -} - -static inline struct fsl_ifc_runtime *runtime_regs_address(void) -{ - struct fsl_ifc regs = {(void *)CONFIG_SYS_IFC_ADDR, NULL}; - int ver = 0; - - ver = ifc_in32(®s.gregs->ifc_rev); - if (ver >= FSL_IFC_V2_0_0) - regs.rregs = (void *)CONFIG_SYS_IFC_ADDR + IFC_RREGS_64KOFFSET; - else - regs.rregs = (void *)CONFIG_SYS_IFC_ADDR + IFC_RREGS_4KOFFSET; - - return regs.rregs; -} - -static inline void nand_wait(uchar *buf, int bufnum, int page_size) -{ - struct fsl_ifc_runtime *ifc = runtime_regs_address(); - u32 status; - u32 eccstat[8]; - int bufperpage = page_size / 512; - int bufnum_end, i; - - bufnum *= bufperpage; - bufnum_end = bufnum + bufperpage - 1; - - do { - status = ifc_in32(&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] = ifc_in32(&ifc->ifc_nand.nand_eccstat[i]); - - for (i = bufnum; i <= bufnum_end; i++) { - if (check_read_ecc(buf, eccstat, i, page_size)) - break; - } - - ifc_out32(&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; -} - -int nand_spl_load_image(uint32_t offs, unsigned int uboot_size, void *vdst) -{ - struct fsl_ifc_fcm *gregs = (void *)CONFIG_SYS_IFC_ADDR; - struct fsl_ifc_runtime *ifc = NULL; - 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, ver = 0; - - int csor, cspr; - int pos = 0; - int j = 0; - - int sram_addr; - int pg_no; - uchar *dst = vdst; - - ifc = runtime_regs_address(); - - /* Get NAND Flash configuration */ - csor = CONFIG_SYS_NAND_CSOR; - cspr = CONFIG_SYS_NAND_CSPR; - - port_size = (cspr & CSPR_PORT_SIZE_16) ? 16 : 8; - - if ((csor & CSOR_NAND_PGS_MASK) == CSOR_NAND_PGS_8K) { - page_size = 8192; - bufnum_mask = 0x0; - } else if ((csor & CSOR_NAND_PGS_MASK) == CSOR_NAND_PGS_4K) { - page_size = 4096; - bufnum_mask = 0x1; - } else if ((csor & CSOR_NAND_PGS_MASK) == CSOR_NAND_PGS_2K) { - page_size = 2048; - bufnum_mask = 0x3; - } else { - page_size = 512; - bufnum_mask = 0xf; - - if (port_size == 8) - bad_marker = 5; - } - - ver = ifc_in32(&gregs->ifc_rev); - if (ver >= FSL_IFC_V2_0_0) - bufnum_mask = (bufnum_mask * 2) + 1; - - 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 */ - ifc_out32(&ifc->ifc_nand.ncfgr, 0x0); - - /* Clear Boot events */ - ifc_out32(&ifc->ifc_nand.nand_evter_stat, 0xffffffff); - - /* Program FIR/FCR for Large/Small page */ - if (page_size > 512) { - ifc_out32(&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)); - ifc_out32(&ifc->ifc_nand.nand_fir1, 0x0); - - ifc_out32(&ifc->ifc_nand.nand_fcr0, - (NAND_CMD_READ0 << IFC_NAND_FCR0_CMD0_SHIFT) | - (NAND_CMD_READSTART << IFC_NAND_FCR0_CMD1_SHIFT)); - } else { - ifc_out32(&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)); - ifc_out32(&ifc->ifc_nand.nand_fir1, 0x0); - - ifc_out32(&ifc->ifc_nand.nand_fcr0, - NAND_CMD_READ0 << IFC_NAND_FCR0_CMD0_SHIFT); - } - - /* Program FBCR = 0 for full page read */ - ifc_out32(&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; - - ifc_out32(&ifc->ifc_nand.row0, pg_no); - ifc_out32(&ifc->ifc_nand.col0, 0); - /* start read */ - ifc_out32(&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)); - } - - return 0; -} - -/* - * 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_spl_load_image(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_spl_load_image(CONFIG_ENV_OFFSET, CONFIG_ENV_SIZE, - (uchar *)CONFIG_NAND_ENV_DST); - -#ifdef CONFIG_ENV_OFFSET_REDUND - nand_spl_load_image(CONFIG_ENV_OFFSET_REDUND, CONFIG_ENV_SIZE, - (uchar *)CONFIG_NAND_ENV_DST + CONFIG_ENV_SIZE); -#endif -#endif - /* - * Jump to U-Boot image - */ -#ifdef CONFIG_SPL_FLUSH_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); -#endif - -#ifdef CONFIG_CHAIN_OF_TRUST - /* - * U-Boot header is appended at end of U-boot image, so - * calculate U-boot header address using U-boot header size. - */ -#define CONFIG_U_BOOT_HDR_ADDR \ - ((CONFIG_SYS_NAND_U_BOOT_START + \ - CONFIG_SYS_NAND_U_BOOT_SIZE) - \ - CONFIG_U_BOOT_HDR_SIZE) - spl_validate_uboot(CONFIG_U_BOOT_HDR_ADDR, - CONFIG_SYS_NAND_U_BOOT_START); - /* - * In case of failure in validation, spl_validate_uboot would - * not return back in case of Production environment with ITS=1. - * Thus U-Boot will not start. - * In Development environment (ITS=0 and SB_EN=1), the function - * may return back in case of non-fatal failures. - */ -#endif - - uboot = (void *)CONFIG_SYS_NAND_U_BOOT_START; - uboot(); -} - -#ifndef CONFIG_SPL_NAND_INIT -void nand_init(void) -{ -} - -void nand_deselect(void) -{ -} -#endif |