Note that with older board revisions, NAND boot may only work after a power-on reset, and not after a warm reset. I don't have a newer board to test on; if you have a board with a 33MHz crystal, please let me know if it works after a warm reset. Signed-off-by: Scott Wood <scottwood@freescale.com>master
parent
acdab5c33f
commit
e4c0950854
@ -1 +1,7 @@ |
||||
ifndef NAND_SPL |
||||
sinclude $(OBJTREE)/board/$(BOARDDIR)/config.tmp |
||||
endif |
||||
|
||||
ifndef TEXT_BASE |
||||
TEXT_BASE = 0xFE000000
|
||||
endif |
||||
|
@ -0,0 +1,112 @@ |
||||
/*
|
||||
* Copyright (C) 2004-2008 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 |
||||
*/ |
||||
|
||||
#include <common.h> |
||||
#include <mpc83xx.h> |
||||
|
||||
DECLARE_GLOBAL_DATA_PTR; |
||||
|
||||
/*
|
||||
* Breathe some life into the CPU... |
||||
* |
||||
* Set up the memory map, |
||||
* initialize a bunch of registers, |
||||
* initialize the UPM's |
||||
*/ |
||||
void cpu_init_f (volatile immap_t * im) |
||||
{ |
||||
int i; |
||||
|
||||
/* Pointer is writable since we allocated a register for it */ |
||||
gd = (gd_t *) (CFG_INIT_RAM_ADDR + CFG_GBL_DATA_OFFSET); |
||||
|
||||
/* Clear initial global data */ |
||||
for (i = 0; i < sizeof(gd_t); i++) |
||||
((char *)gd)[i] = 0; |
||||
|
||||
/* system performance tweaking */ |
||||
|
||||
#ifdef CFG_ACR_PIPE_DEP |
||||
/* Arbiter pipeline depth */ |
||||
im->arbiter.acr = (im->arbiter.acr & ~ACR_PIPE_DEP) | |
||||
(CFG_ACR_PIPE_DEP << ACR_PIPE_DEP_SHIFT); |
||||
#endif |
||||
|
||||
#ifdef CFG_ACR_RPTCNT |
||||
/* Arbiter repeat count */ |
||||
im->arbiter.acr = (im->arbiter.acr & ~(ACR_RPTCNT)) | |
||||
(CFG_ACR_RPTCNT << ACR_RPTCNT_SHIFT); |
||||
#endif |
||||
|
||||
#ifdef CFG_SPCR_OPT |
||||
/* Optimize transactions between CSB and other devices */ |
||||
im->sysconf.spcr = (im->sysconf.spcr & ~SPCR_OPT) | |
||||
(CFG_SPCR_OPT << SPCR_OPT_SHIFT); |
||||
#endif |
||||
|
||||
/* Enable Time Base & Decrimenter (so we will have udelay()) */ |
||||
im->sysconf.spcr |= SPCR_TBEN; |
||||
|
||||
/* DDR control driver register */ |
||||
#ifdef CFG_DDRCDR |
||||
im->sysconf.ddrcdr = CFG_DDRCDR; |
||||
#endif |
||||
/* Output buffer impedance register */ |
||||
#ifdef CFG_OBIR |
||||
im->sysconf.obir = CFG_OBIR; |
||||
#endif |
||||
|
||||
/*
|
||||
* Memory Controller: |
||||
*/ |
||||
|
||||
/* Map banks 0 and 1 to the FLASH banks 0 and 1 at preliminary
|
||||
* addresses - these have to be modified later when FLASH size |
||||
* has been determined |
||||
*/ |
||||
|
||||
#if defined(CFG_NAND_BR_PRELIM) \ |
||||
&& defined(CFG_NAND_OR_PRELIM) \
|
||||
&& defined(CFG_NAND_LBLAWBAR_PRELIM) \
|
||||
&& defined(CFG_NAND_LBLAWAR_PRELIM) |
||||
im->lbus.bank[0].br = CFG_NAND_BR_PRELIM; |
||||
im->lbus.bank[0].or = CFG_NAND_OR_PRELIM; |
||||
im->sysconf.lblaw[0].bar = CFG_NAND_LBLAWBAR_PRELIM; |
||||
im->sysconf.lblaw[0].ar = CFG_NAND_LBLAWAR_PRELIM; |
||||
#else |
||||
#error CFG_NAND_BR_PRELIM, CFG_NAND_OR_PRELIM, CFG_NAND_LBLAWBAR_PRELIM & CFG_NAND_LBLAWAR_PRELIM must be defined |
||||
#endif |
||||
} |
||||
|
||||
/*
|
||||
* Get timebase clock frequency (like cpu_clk in Hz) |
||||
*/ |
||||
unsigned long get_tbclk(void) |
||||
{ |
||||
return (gd->bus_clk + 3L) / 4L; |
||||
} |
||||
|
||||
void puts(const char *str) |
||||
{ |
||||
while (*str) |
||||
putc(*str++); |
||||
} |
@ -0,0 +1,101 @@ |
||||
#
|
||||
# (C) Copyright 2007
|
||||
# Stefan Roese, DENX Software Engineering, sr@denx.de.
|
||||
# (C) Copyright 2008 Freescale Semiconductor
|
||||
#
|
||||
# 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 := 0xfff04000
|
||||
|
||||
include $(TOPDIR)/config.mk |
||||
|
||||
LDSCRIPT= $(TOPDIR)/nand_spl/board/$(BOARDDIR)/u-boot.lds
|
||||
LDFLAGS = -Bstatic -T $(LDSCRIPT) -Ttext $(TEXT_BASE) $(PLATFORM_LDFLAGS)
|
||||
AFLAGS += -DCONFIG_NAND_SPL
|
||||
CFLAGS += -DCONFIG_NAND_SPL
|
||||
|
||||
SOBJS = start.o ticks.o
|
||||
COBJS = nand_boot_fsl_elbc.o $(BOARD).o sdram.o ns16550.o nand_init.o time.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) \
|
||||
-Map $(nandobj)u-boot-spl.map \
|
||||
-o $(nandobj)u-boot-spl
|
||||
|
||||
# create symbolic links for common files
|
||||
|
||||
$(obj)start.S: |
||||
ln -sf $(SRCTREE)/cpu/mpc83xx/start.S $(obj)start.S
|
||||
|
||||
$(obj)nand_boot_fsl_elbc.c: |
||||
ln -sf $(SRCTREE)/nand_spl/nand_boot_fsl_elbc.c \
|
||||
$(obj)nand_boot_fsl_elbc.c
|
||||
|
||||
$(obj)sdram.c: |
||||
ln -sf $(SRCTREE)/board/$(BOARDDIR)/sdram.c $(obj)sdram.c
|
||||
|
||||
$(obj)$(BOARD).c: |
||||
ln -sf $(SRCTREE)/board/$(BOARDDIR)/$(BOARD).c $(obj)$(BOARD).c
|
||||
|
||||
$(obj)ns16550.c: |
||||
ln -sf $(SRCTREE)/drivers/serial/ns16550.c $(obj)ns16550.c
|
||||
|
||||
$(obj)nand_init.c: |
||||
ln -sf $(SRCTREE)/cpu/mpc83xx/nand_init.c $(obj)nand_init.c
|
||||
|
||||
$(obj)time.c: |
||||
ln -sf $(SRCTREE)/lib_ppc/time.c $(obj)time.c
|
||||
|
||||
$(obj)ticks.S: |
||||
ln -sf $(SRCTREE)/lib_ppc/ticks.S $(obj)ticks.S
|
||||
|
||||
#########################################################################
|
||||
|
||||
$(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 |
||||
|
||||
#########################################################################
|
@ -0,0 +1,52 @@ |
||||
/* |
||||
* (C) Copyright 2006 |
||||
* Wolfgang Denk, DENX Software Engineering, wd@denx.de. |
||||
* |
||||
* Copyright 2008 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 |
||||
*/ |
||||
|
||||
OUTPUT_ARCH(powerpc) |
||||
SECTIONS |
||||
{ |
||||
. = 0xfff00000; |
||||
.text : { |
||||
*(.text*) |
||||
. = ALIGN(16); |
||||
*(.rodata*) |
||||
*(.eh_frame) |
||||
} |
||||
|
||||
. = ALIGN(8); |
||||
.data : { |
||||
*(.data*) |
||||
*(.sdata*) |
||||
_GOT2_TABLE_ = .; |
||||
*(.got2) |
||||
__got2_entries = (. - _GOT2_TABLE_) >> 2; |
||||
} |
||||
|
||||
. = ALIGN(8); |
||||
__bss_start = .; |
||||
.bss (NOLOAD) : { *(.*bss) } |
||||
_end = .; |
||||
} |
||||
ENTRY(_start) |
||||
ASSERT(_end <= 0xfff01000, "NAND bootstrap too big"); |
@ -0,0 +1,150 @@ |
||||
/*
|
||||
* NAND boot for Freescale Enhanced Local Bus Controller, Flash Control Machine |
||||
* |
||||
* (C) Copyright 2006-2008 |
||||
* Stefan Roese, DENX Software Engineering, sr@denx.de. |
||||
* |
||||
* Copyright (c) 2008 Freescale Semiconductor, Inc. |
||||
* Author: Scott Wood <scottwood@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/immap_83xx.h> |
||||
#include <asm/fsl_lbc.h> |
||||
#include <linux/mtd/nand.h> |
||||
|
||||
#define WINDOW_SIZE 8192 |
||||
|
||||
static void nand_wait(void) |
||||
{ |
||||
lbus83xx_t *regs = (lbus83xx_t *)(CFG_IMMR + 0x5000); |
||||
|
||||
for (;;) { |
||||
uint32_t status = in_be32(®s->ltesr); |
||||
|
||||
if (status == 1) |
||||
return; |
||||
|
||||
if (status & 1) { |
||||
puts("read failed (ltesr)\n"); |
||||
for (;;); |
||||
} |
||||
} |
||||
} |
||||
|
||||
static void nand_load(unsigned int offs, int uboot_size, uchar *dst) |
||||
{ |
||||
lbus83xx_t *regs = (lbus83xx_t *)(CFG_IMMR + 0x5000); |
||||
uchar *buf = (uchar *)CFG_NAND_BASE; |
||||
int large = in_be32(®s->bank[0].or) & OR_FCM_PGS; |
||||
int block_shift = large ? 17 : 14; |
||||
int block_size = 1 << block_shift; |
||||
int page_size = large ? 2048 : 512; |
||||
int bad_marker = large ? page_size + 0 : page_size + 5; |
||||
int fmr = (15 << FMR_CWTO_SHIFT) | (2 << FMR_AL_SHIFT) | 2; |
||||
int pos = 0; |
||||
|
||||
if (offs & (block_size - 1)) { |
||||
puts("bad offset\n"); |
||||
for (;;); |
||||
} |
||||
|
||||
if (large) { |
||||
fmr |= FMR_ECCM; |
||||
out_be32(®s->fcr, (NAND_CMD_READ0 << FCR_CMD0_SHIFT) | |
||||
(NAND_CMD_READSTART << FCR_CMD1_SHIFT)); |
||||
out_be32(®s->fir, |
||||
(FIR_OP_CW0 << FIR_OP0_SHIFT) | |
||||
(FIR_OP_CA << FIR_OP1_SHIFT) | |
||||
(FIR_OP_PA << FIR_OP2_SHIFT) | |
||||
(FIR_OP_CW1 << FIR_OP3_SHIFT) | |
||||
(FIR_OP_RBW << FIR_OP4_SHIFT)); |
||||
} else { |
||||
out_be32(®s->fcr, NAND_CMD_READ0 << FCR_CMD0_SHIFT); |
||||
out_be32(®s->fir, |
||||
(FIR_OP_CW0 << FIR_OP0_SHIFT) | |
||||
(FIR_OP_CA << FIR_OP1_SHIFT) | |
||||
(FIR_OP_PA << FIR_OP2_SHIFT) | |
||||
(FIR_OP_RBW << FIR_OP3_SHIFT)); |
||||
} |
||||
|
||||
out_be32(®s->fbcr, 0); |
||||
clrsetbits_be32(®s->bank[0].br, BR_DECC, BR_DECC_CHK_GEN); |
||||
|
||||
while (pos < uboot_size) { |
||||
int i = 0; |
||||
out_be32(®s->fbar, offs >> block_shift); |
||||
|
||||
do { |
||||
int j; |
||||
unsigned int page_offs = (offs & (block_size - 1)) << 1; |
||||
|
||||
out_be32(®s->ltesr, ~0); |
||||
out_be32(®s->lteatr, 0); |
||||
out_be32(®s->fpar, page_offs); |
||||
out_be32(®s->fmr, fmr); |
||||
out_be32(®s->lsor, 0); |
||||
nand_wait(); |
||||
|
||||
page_offs %= WINDOW_SIZE; |
||||
|
||||
/*
|
||||
* If either of the first two pages are marked bad, |
||||
* continue to the next block. |
||||
*/ |
||||
if (i++ < 2 && buf[page_offs + bad_marker] != 0xff) { |
||||
puts("skipping\n"); |
||||
offs = (offs + block_size) & ~(block_size - 1); |
||||
pos &= ~(block_size - 1); |
||||
break; |
||||
} |
||||
|
||||
for (j = 0; j < page_size; j++) |
||||
dst[pos + j] = buf[page_offs + j]; |
||||
|
||||
pos += page_size; |
||||
offs += page_size; |
||||
} while (offs & (block_size - 1)); |
||||
} |
||||
} |
||||
|
||||
/*
|
||||
* The main entry for NAND booting. 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 it from there. |
||||
*/ |
||||
void nand_boot(void) |
||||
{ |
||||
__attribute__((noreturn)) void (*uboot)(void); |
||||
|
||||
udelay(1000000); |
||||
|
||||
/*
|
||||
* Load U-Boot image from NAND into RAM |
||||
*/ |
||||
nand_load(CFG_NAND_U_BOOT_OFFS, CFG_NAND_U_BOOT_SIZE, |
||||
(uchar *)CFG_NAND_U_BOOT_DST); |
||||
|
||||
/*
|
||||
* Jump to U-Boot image |
||||
*/ |
||||
puts("transfering control\n"); |
||||
uboot = (void *)CFG_NAND_U_BOOT_START; |
||||
uboot(); |
||||
} |
Loading…
Reference in new issue