summaryrefslogtreecommitdiffstats
path: root/nand_spl
diff options
context:
space:
mode:
Diffstat (limited to 'nand_spl')
-rw-r--r--nand_spl/board/freescale/mpc8569mds/Makefile133
-rw-r--r--nand_spl/board/freescale/mpc8569mds/nand_boot.c75
-rw-r--r--nand_spl/nand_boot_fsl_nfc.c72
3 files changed, 265 insertions, 15 deletions
diff --git a/nand_spl/board/freescale/mpc8569mds/Makefile b/nand_spl/board/freescale/mpc8569mds/Makefile
new file mode 100644
index 0000000000..7ed9d619dc
--- /dev/null
+++ b/nand_spl/board/freescale/mpc8569mds/Makefile
@@ -0,0 +1,133 @@
+#
+# (C) Copyright 2007
+# Stefan Roese, DENX Software Engineering, sr@denx.de.
+#
+# Copyright 2009 Freescale Semiconductor, Inc.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# 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
+#
+
+NAND_SPL := y
+TEXT_BASE := 0xfff00000
+PAD_TO := 0xfff01000
+
+include $(TOPDIR)/config.mk
+
+LDSCRIPT= $(TOPDIR)/cpu/$(CPU)/u-boot-nand_spl.lds
+LDFLAGS = -Bstatic -T $(LDSCRIPT) -Ttext $(TEXT_BASE) $(PLATFORM_LDFLAGS)
+AFLAGS += -DCONFIG_NAND_SPL
+CFLAGS += -DCONFIG_NAND_SPL
+
+SOBJS = start.o resetvec.o
+COBJS = cache.o cpu_init_early.o cpu_init_nand.o fsl_law.o law.o \
+ nand_boot.o nand_boot_fsl_elbc.o ns16550.o tlb.o tlb_table.o
+
+SRCS := $(addprefix $(obj),$(SOBJS:.o=.S) $(COBJS:.o=.c))
+OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
+__OBJS := $(SOBJS) $(COBJS)
+LNDIR := $(OBJTREE)/nand_spl/board/$(BOARDDIR)
+
+nandobj := $(OBJTREE)/nand_spl/
+
+ALL = $(nandobj)u-boot-spl $(nandobj)u-boot-spl.bin $(nandobj)u-boot-spl-16k.bin
+
+all: $(obj).depend $(ALL)
+
+$(nandobj)u-boot-spl-16k.bin: $(nandobj)u-boot-spl
+ $(OBJCOPY) ${OBJCFLAGS} --pad-to=$(PAD_TO) -O binary $< $@
+
+$(nandobj)u-boot-spl.bin: $(nandobj)u-boot-spl
+ $(OBJCOPY) ${OBJCFLAGS} -O binary $< $@
+
+$(nandobj)u-boot-spl: $(OBJS)
+ cd $(LNDIR) && $(LD) $(LDFLAGS) $(__OBJS) $(PLATFORM_LIBS) \
+ -Map $(nandobj)u-boot-spl.map \
+ -o $(nandobj)u-boot-spl
+
+# create symbolic links for common files
+
+$(obj)cache.c:
+ @rm -f $(obj)cache.c
+ ln -sf $(SRCTREE)/lib_ppc/cache.c $(obj)cache.c
+
+$(obj)cpu_init_early.c:
+ @rm -f $(obj)cpu_init_early.c
+ ln -sf $(SRCTREE)/cpu/mpc85xx/cpu_init_early.c $(obj)cpu_init_early.c
+
+$(obj)cpu_init_nand.c:
+ @rm -f $(obj)cpu_init_nand.c
+ ln -sf $(SRCTREE)/cpu/mpc85xx/cpu_init_nand.c $(obj)cpu_init_nand.c
+
+$(obj)fsl_law.c:
+ @rm -f $(obj)fsl_law.c
+ ln -sf $(SRCTREE)/drivers/misc/fsl_law.c $(obj)fsl_law.c
+
+$(obj)law.c:
+ @rm -f $(obj)law.c
+ ln -sf $(SRCTREE)/board/$(BOARDDIR)/law.c $(obj)law.c
+
+$(obj)nand_boot_fsl_elbc.c:
+ @rm -f $(obj)nand_boot_fsl_elbc.c
+ ln -sf $(SRCTREE)/nand_spl/nand_boot_fsl_elbc.c \
+ $(obj)nand_boot_fsl_elbc.c
+
+$(obj)ns16550.c:
+ @rm -f $(obj)ns16550.c
+ ln -sf $(SRCTREE)/drivers/serial/ns16550.c $(obj)ns16550.c
+
+$(obj)resetvec.S:
+ @rm -f $(obj)resetvec.S
+ ln -s $(SRCTREE)/cpu/$(CPU)/resetvec.S $(obj)resetvec.S
+
+$(obj)fixed_ivor.S:
+ @rm -f $(obj)fixed_ivor.S
+ ln -sf $(SRCTREE)/cpu/mpc85xx/fixed_ivor.S $(obj)fixed_ivor.S
+
+$(obj)start.S: $(obj)fixed_ivor.S
+ @rm -f $(obj)start.S
+ ln -sf $(SRCTREE)/cpu/mpc85xx/start.S $(obj)start.S
+
+$(obj)tlb.c:
+ @rm -f $(obj)tlb.c
+ ln -sf $(SRCTREE)/cpu/mpc85xx/tlb.c $(obj)tlb.c
+
+$(obj)tlb_table.c:
+ @rm -f $(obj)tlb_table.c
+ ln -sf $(SRCTREE)/board/$(BOARDDIR)/tlb.c $(obj)tlb_table.c
+
+ifneq ($(OBJTREE), $(SRCTREE))
+$(obj)nand_boot.c:
+ @rm -f $(obj)nand_boot.c
+ ln -s $(SRCTREE)/nand_spl/board/$(BOARDDIR)/nand_boot.c $(obj)nand_boot.c
+endif
+
+#########################################################################
+
+$(obj)%.o: $(obj)%.S
+ $(CC) $(AFLAGS) -c -o $@ $<
+
+$(obj)%.o: $(obj)%.c
+ $(CC) $(CFLAGS) -c -o $@ $<
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/nand_spl/board/freescale/mpc8569mds/nand_boot.c b/nand_spl/board/freescale/mpc8569mds/nand_boot.c
new file mode 100644
index 0000000000..e03065699c
--- /dev/null
+++ b/nand_spl/board/freescale/mpc8569mds/nand_boot.c
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2009 Freescale Semiconductor, Inc.
+ *
+ * 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 <mpc85xx.h>
+#include <asm-ppc/io.h>
+#include <ns16550.h>
+#include <nand.h>
+#include <asm/mmu.h>
+#include <asm/immap_85xx.h>
+#include <asm/fsl_ddr_sdram.h>
+#include <asm/fsl_law.h>
+
+#define SYSCLK_66 66666666
+
+DECLARE_GLOBAL_DATA_PTR;
+
+void board_init_f(ulong bootflag)
+{
+ uint plat_ratio, bus_clk, sys_clk;
+ volatile ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
+
+ sys_clk = SYSCLK_66;
+
+ plat_ratio = gur->porpllsr & 0x0000003e;
+ plat_ratio >>= 1;
+ bus_clk = plat_ratio * sys_clk;
+ NS16550_init((NS16550_t)CONFIG_SYS_NS16550_COM1,
+ bus_clk / 16 / CONFIG_BAUDRATE);
+
+ puts("\nNAND boot... ");
+
+ /* copy code to DDR and jump to it - this should not return */
+ /* NOTE - code has to be copied out of NAND buffer before
+ * other blocks can be read.
+ */
+ relocate_code(CONFIG_SYS_NAND_U_BOOT_RELOC_SP, 0,
+ CONFIG_SYS_NAND_U_BOOT_RELOC);
+}
+
+void board_init_r(gd_t *gd, ulong dest_addr)
+{
+ nand_boot();
+}
+
+void putc(char c)
+{
+ if (c == '\n')
+ NS16550_putc((NS16550_t)CONFIG_SYS_NS16550_COM1, '\r');
+
+ NS16550_putc((NS16550_t)CONFIG_SYS_NS16550_COM1, c);
+}
+
+void puts(const char *str)
+{
+ while (*str)
+ putc(*str++);
+}
diff --git a/nand_spl/nand_boot_fsl_nfc.c b/nand_spl/nand_boot_fsl_nfc.c
index a9df2a8273..f4040a7cf9 100644
--- a/nand_spl/nand_boot_fsl_nfc.c
+++ b/nand_spl/nand_boot_fsl_nfc.c
@@ -26,11 +26,15 @@
#include <common.h>
#include <nand.h>
+#ifdef CONFIG_MX31
#include <asm-arm/arch/mx31-regs.h>
+#else
+#include <asm-arm/arch/imx-regs.h>
+#endif
#include <asm/io.h>
#include <fsl_nfc.h>
-static struct fsl_nfc_regs *nfc;
+struct fsl_nfc_regs *nfc;
static void nfc_wait_ready(void)
{
@@ -45,13 +49,35 @@ static void nfc_wait_ready(void)
writew(tmp, &nfc->nand_flash_config2);
}
-static void nfc_nand_init(void)
+void nfc_nand_init(void)
{
+#if defined(MXC_NFC_V1_1)
+ int ecc_per_page = CONFIG_SYS_NAND_PAGE_SIZE / 512;
+ int config1;
+
+ writew(CONFIG_SYS_NAND_SPARE_SIZE / 2, &nfc->spare_area_size);
+
+ /* unlocking RAM Buff */
+ writew(0x2, &nfc->configuration);
+
+ /* hardware ECC checking and correct */
+ config1 = readw(&nfc->nand_flash_config1) | NFC_ECC_EN | 0x800;
+ /*
+ * if spare size is larger that 16 bytes per 512 byte hunk
+ * then use 8 symbol correction instead of 4
+ */
+ if ((CONFIG_SYS_NAND_SPARE_SIZE / ecc_per_page) > 16)
+ config1 &= ~NFC_4_8N_ECC;
+ else
+ config1 |= NFC_4_8N_ECC;
+ writew(config1, &nfc->nand_flash_config1);
+#elif defined(MXC_NFC_V1)
/* unlocking RAM Buff */
writew(0x2, &nfc->configuration);
/* hardware ECC checking and correct */
writew(NFC_ECC_EN, &nfc->nand_flash_config1);
+#endif
}
static void nfc_nand_command(unsigned short command)
@@ -65,12 +91,12 @@ static void nfc_nand_page_address(unsigned int page_address)
{
unsigned int page_count;
- writew(0x00, &nfc->flash_cmd);
+ writew(0x00, &nfc->flash_add);
writew(NFC_ADDR, &nfc->nand_flash_config2);
nfc_wait_ready();
- /* code only for 2kb flash */
- if (CONFIG_SYS_NAND_PAGE_SIZE == 0x800) {
+ /* code only for large page flash */
+ if (CONFIG_SYS_NAND_PAGE_SIZE > 512) {
writew(0x00, &nfc->flash_add);
writew(NFC_ADDR, &nfc->nand_flash_config2);
nfc_wait_ready();
@@ -88,22 +114,38 @@ static void nfc_nand_page_address(unsigned int page_address)
page_count = page_count >> 8;
} while (page_count);
}
+
+ writew(0x00, &nfc->flash_add);
+ writew(NFC_ADDR, &nfc->nand_flash_config2);
+ nfc_wait_ready();
}
static void nfc_nand_data_output(void)
{
+ int config1 = readw(&nfc->nand_flash_config1);
+#ifdef NAND_MXC_2K_MULTI_CYCLE
int i;
+#endif
+ config1 |= NFC_ECC_EN | NFC_INT_MSK;
+ writew(config1, &nfc->nand_flash_config1);
+ writew(0, &nfc->buffer_address);
+ writew(NFC_OUTPUT, &nfc->nand_flash_config2);
+ nfc_wait_ready();
+#ifdef NAND_MXC_2K_MULTI_CYCLE
/*
- * The NAND controller requires four output commands for
- * large page devices.
+ * This NAND controller requires multiple input commands
+ * for pages larger than 512 bytes.
*/
- for (i = 0; i < (CONFIG_SYS_NAND_PAGE_SIZE / 512); i++) {
- writew(NFC_ECC_EN, &nfc->nand_flash_config1);
- writew(i, &nfc->buffer_address); /* read in i:th buffer */
+ for (i = 1; i < (CONFIG_SYS_NAND_PAGE_SIZE / 512); i++) {
+ config1 = readw(&nfc->nand_flash_config1);
+ config1 |= NFC_ECC_EN | NFC_INT_MSK;
+ writew(config1, &nfc->nand_flash_config1);
+ writew(i, &nfc->buffer_address);
writew(NFC_OUTPUT, &nfc->nand_flash_config2);
nfc_wait_ready();
}
+#endif
}
static int nfc_nand_check_ecc(void)
@@ -121,7 +163,7 @@ static int nfc_read_page(unsigned int page_address, unsigned char *buf)
nfc_nand_command(NAND_CMD_READ0);
nfc_nand_page_address(page_address);
- if (CONFIG_SYS_NAND_PAGE_SIZE == 0x800)
+ if (CONFIG_SYS_NAND_PAGE_SIZE > 512)
nfc_nand_command(NAND_CMD_READSTART);
nfc_nand_data_output(); /* fill the main buffer 0 */
@@ -129,7 +171,7 @@ static int nfc_read_page(unsigned int page_address, unsigned char *buf)
if (nfc_nand_check_ecc())
return -1;
- src = &nfc->main_area0[0];
+ src = &nfc->main_area[0][0];
dst = (u32 *)buf;
/* main copy loop from NAND-buffer to SDRAM memory */
@@ -154,12 +196,12 @@ static int is_badblock(int pagenumber)
nfc_nand_command(NAND_CMD_READ0);
nfc_nand_page_address(page);
- if (CONFIG_SYS_NAND_PAGE_SIZE == 0x800)
+ if (CONFIG_SYS_NAND_PAGE_SIZE > 512)
nfc_nand_command(NAND_CMD_READSTART);
nfc_nand_data_output(); /* fill the main buffer 0 */
- src = &nfc->spare_area0[0];
+ src = &nfc->spare_area[0][0];
/*
* IMPORTANT NOTE: The nand flash controller uses a non-
@@ -209,7 +251,7 @@ static int nand_load(unsigned int from, unsigned int size, unsigned char *buf)
if (!(page % CONFIG_SYS_NAND_PAGE_COUNT)) {
/*
* Yes, new block. See if this block is good. If not,
- * loop until we find i good block.
+ * loop until we find a good block.
*/
while (is_badblock(page)) {
page = page + CONFIG_SYS_NAND_PAGE_COUNT;
OpenPOWER on IntegriCloud