NAND boot: MPC8313ERDB support

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>
This commit is contained in:
Scott Wood 2008-06-30 14:13:28 -05:00
parent acdab5c33f
commit e4c0950854
14 changed files with 704 additions and 248 deletions

View File

@ -1997,8 +1997,11 @@ TASREG_config : unconfig
#########################################################################
MPC8313ERDB_33_config \
MPC8313ERDB_66_config: unconfig
MPC8313ERDB_66_config \
MPC8313ERDB_NAND_33_config \
MPC8313ERDB_NAND_66_config: unconfig
@mkdir -p $(obj)include
@mkdir -p $(obj)board/freescale/mpc8313erdb
@if [ "$(findstring _33_,$@)" ] ; then \
$(XECHO) -n "...33M ..." ; \
echo "#define CFG_33MHZ" >>$(obj)include/config.h ; \
@ -2006,6 +2009,11 @@ MPC8313ERDB_66_config: unconfig
if [ "$(findstring _66_,$@)" ] ; then \
$(XECHO) -n "...66M..." ; \
echo "#define CFG_66MHZ" >>$(obj)include/config.h ; \
fi ; \
if [ "$(findstring _NAND_,$@)" ] ; then \
$(XECHO) -n "...NAND..." ; \
echo "TEXT_BASE = 0x00100000" > $(obj)/board/freescale/mpc8313erdb/config.tmp ; \
echo "#define CONFIG_NAND_U_BOOT" >>$(obj)include/config.h ; \
fi ;
@$(MKCONFIG) -a MPC8313ERDB ppc mpc83xx mpc8313erdb freescale

View File

@ -1 +1,7 @@
ifndef NAND_SPL
sinclude $(OBJTREE)/board/$(BOARDDIR)/config.tmp
endif
ifndef TEXT_BASE
TEXT_BASE = 0xFE000000
endif

View File

@ -29,6 +29,8 @@
#include <pci.h>
#include <mpc83xx.h>
#include <vsc7385.h>
#include <ns16550.h>
#include <nand.h>
DECLARE_GLOBAL_DATA_PTR;
@ -50,6 +52,7 @@ int checkboard(void)
return 0;
}
#ifndef CONFIG_NAND_SPL
static struct pci_region pci_regions[] = {
{
bus_start: CFG_PCI1_MEM_BASE,
@ -128,3 +131,32 @@ void ft_board_setup(void *blob, bd_t *bd)
#endif
}
#endif
#else /* CONFIG_NAND_SPL */
void board_init_f(ulong bootflag)
{
board_early_init_f();
NS16550_init((NS16550_t)(CFG_IMMR + 0x4500),
CFG_NS16550_CLK / 16 / CONFIG_BAUDRATE);
puts("NAND boot... ");
init_timebase();
initdram(0);
relocate_code(CFG_NAND_U_BOOT_RELOC + 0x10000, (gd_t *)gd,
CFG_NAND_U_BOOT_RELOC);
}
void board_init_r(gd_t *gd, ulong dest_addr)
{
nand_boot();
}
void putc(char c)
{
if (gd->flags & GD_FLG_SILENT)
return;
if (c == '\n')
NS16550_putc((NS16550_t)(CFG_IMMR + 0x4500), '\r');
NS16550_putc((NS16550_t)(CFG_IMMR + 0x4500), c);
}
#endif

View File

@ -58,8 +58,10 @@ static void resume_from_sleep(void)
*/
static long fixed_sdram(void)
{
volatile immap_t *im = (volatile immap_t *)CFG_IMMR;
u32 msize = CFG_DDR_SIZE * 1024 * 1024;
#ifndef CFG_RAMBOOT
volatile immap_t *im = (volatile immap_t *)CFG_IMMR;
u32 msize_log2 = __ilog2(msize);
im->sysconf.ddrlaw[0].bar = CFG_DDR_SDRAM_BASE >> 12;
@ -100,6 +102,7 @@ static long fixed_sdram(void)
/* enable DDR controller */
im->ddr.sdram_cfg |= SDRAM_CFG_MEM_EN;
#endif
return msize;
}

112
cpu/mpc83xx/nand_init.c Normal file
View File

@ -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++);
}

View File

@ -2,7 +2,7 @@
* Copyright (C) 1998 Dan Malek <dmalek@jlc.net>
* Copyright (C) 1999 Magnus Damm <kieraypc01.p.y.kie.era.ericsson.se>
* Copyright (C) 2000, 2001,2002 Wolfgang Denk <wd@denx.de>
* Copyright Freescale Semiconductor, Inc. 2004, 2006. All rights reserved.
* Copyright Freescale Semiconductor, Inc. 2004, 2006, 2008.
*
* See file CREDITS for list of people who contributed to this
* project.
@ -57,6 +57,10 @@
#define MSR_KERNEL (MSR_FP|MSR_ME|MSR_RI)
#endif
#if !defined(CONFIG_NAND_SPL) && !defined(CFG_RAMBOOT)
#define CFG_FLASHBOOT
#endif
/*
* Set up GOT: Global Offset Table
*
@ -64,16 +68,16 @@
*/
START_GOT
GOT_ENTRY(_GOT2_TABLE_)
GOT_ENTRY(_FIXUP_TABLE_)
GOT_ENTRY(__bss_start)
GOT_ENTRY(_end)
#ifndef CONFIG_NAND_SPL
GOT_ENTRY(_FIXUP_TABLE_)
GOT_ENTRY(_start)
GOT_ENTRY(_start_of_vectors)
GOT_ENTRY(_end_of_vectors)
GOT_ENTRY(transfer_to_handler)
GOT_ENTRY(__init_end)
GOT_ENTRY(_end)
GOT_ENTRY(__bss_start)
#endif
END_GOT
/*
@ -165,7 +169,7 @@ boot_warm: /* time t 5 */
bl init_e300_core
#ifndef CFG_RAMBOOT
#ifdef CFG_FLASHBOOT
/* Inflate flash location so it appears everywhere, calculate */
/* the absolute address in final location of the FLASH, jump */
@ -181,7 +185,7 @@ in_flash:
#if 1 /* Remapping flash with LAW0. */
bl remap_flash_by_law0
#endif
#endif /* CFG_RAMBOOT */
#endif /* CFG_FLASHBOOT */
/* setup the bats */
bl setup_bats
@ -239,6 +243,7 @@ in_flash:
/* run 1st part of board init code (in Flash)*/
bl board_init_f
#ifndef CONFIG_NAND_SPL
/*
* Vector Table
*/
@ -428,6 +433,7 @@ int_return:
lwz r1,GPR1(r1)
SYNC
rfi
#endif /* !CONFIG_NAND_SPL */
/*
* This code initialises the E300 processor core
@ -496,27 +502,146 @@ init_e300_core: /* time t 10 */
SYNC
mtspr HID2, r3
/* clear all BAT's */
/*----------------------------------*/
/* Done! */
/*------------------------------*/
blr
xor r0, r0, r0
mtspr DBAT0U, r0
mtspr DBAT0L, r0
mtspr DBAT1U, r0
mtspr DBAT1L, r0
mtspr DBAT2U, r0
mtspr DBAT2L, r0
mtspr DBAT3U, r0
mtspr DBAT3L, r0
mtspr IBAT0U, r0
mtspr IBAT0L, r0
mtspr IBAT1U, r0
mtspr IBAT1L, r0
mtspr IBAT2U, r0
mtspr IBAT2L, r0
mtspr IBAT3U, r0
mtspr IBAT3L, r0
SYNC
/* setup_bats - set them up to some initial state */
.globl setup_bats
setup_bats:
addis r0, r0, 0x0000
/* IBAT 0 */
addis r4, r0, CFG_IBAT0L@h
ori r4, r4, CFG_IBAT0L@l
addis r3, r0, CFG_IBAT0U@h
ori r3, r3, CFG_IBAT0U@l
mtspr IBAT0L, r4
mtspr IBAT0U, r3
/* DBAT 0 */
addis r4, r0, CFG_DBAT0L@h
ori r4, r4, CFG_DBAT0L@l
addis r3, r0, CFG_DBAT0U@h
ori r3, r3, CFG_DBAT0U@l
mtspr DBAT0L, r4
mtspr DBAT0U, r3
/* IBAT 1 */
addis r4, r0, CFG_IBAT1L@h
ori r4, r4, CFG_IBAT1L@l
addis r3, r0, CFG_IBAT1U@h
ori r3, r3, CFG_IBAT1U@l
mtspr IBAT1L, r4
mtspr IBAT1U, r3
/* DBAT 1 */
addis r4, r0, CFG_DBAT1L@h
ori r4, r4, CFG_DBAT1L@l
addis r3, r0, CFG_DBAT1U@h
ori r3, r3, CFG_DBAT1U@l
mtspr DBAT1L, r4
mtspr DBAT1U, r3
/* IBAT 2 */
addis r4, r0, CFG_IBAT2L@h
ori r4, r4, CFG_IBAT2L@l
addis r3, r0, CFG_IBAT2U@h
ori r3, r3, CFG_IBAT2U@l
mtspr IBAT2L, r4
mtspr IBAT2U, r3
/* DBAT 2 */
addis r4, r0, CFG_DBAT2L@h
ori r4, r4, CFG_DBAT2L@l
addis r3, r0, CFG_DBAT2U@h
ori r3, r3, CFG_DBAT2U@l
mtspr DBAT2L, r4
mtspr DBAT2U, r3
/* IBAT 3 */
addis r4, r0, CFG_IBAT3L@h
ori r4, r4, CFG_IBAT3L@l
addis r3, r0, CFG_IBAT3U@h
ori r3, r3, CFG_IBAT3U@l
mtspr IBAT3L, r4
mtspr IBAT3U, r3
/* DBAT 3 */
addis r4, r0, CFG_DBAT3L@h
ori r4, r4, CFG_DBAT3L@l
addis r3, r0, CFG_DBAT3U@h
ori r3, r3, CFG_DBAT3U@l
mtspr DBAT3L, r4
mtspr DBAT3U, r3
#ifdef CONFIG_HIGH_BATS
/* IBAT 4 */
addis r4, r0, CFG_IBAT4L@h
ori r4, r4, CFG_IBAT4L@l
addis r3, r0, CFG_IBAT4U@h
ori r3, r3, CFG_IBAT4U@l
mtspr IBAT4L, r4
mtspr IBAT4U, r3
/* DBAT 4 */
addis r4, r0, CFG_DBAT4L@h
ori r4, r4, CFG_DBAT4L@l
addis r3, r0, CFG_DBAT4U@h
ori r3, r3, CFG_DBAT4U@l
mtspr DBAT4L, r4
mtspr DBAT4U, r3
/* IBAT 5 */
addis r4, r0, CFG_IBAT5L@h
ori r4, r4, CFG_IBAT5L@l
addis r3, r0, CFG_IBAT5U@h
ori r3, r3, CFG_IBAT5U@l
mtspr IBAT5L, r4
mtspr IBAT5U, r3
/* DBAT 5 */
addis r4, r0, CFG_DBAT5L@h
ori r4, r4, CFG_DBAT5L@l
addis r3, r0, CFG_DBAT5U@h
ori r3, r3, CFG_DBAT5U@l
mtspr DBAT5L, r4
mtspr DBAT5U, r3
/* IBAT 6 */
addis r4, r0, CFG_IBAT6L@h
ori r4, r4, CFG_IBAT6L@l
addis r3, r0, CFG_IBAT6U@h
ori r3, r3, CFG_IBAT6U@l
mtspr IBAT6L, r4
mtspr IBAT6U, r3
/* DBAT 6 */
addis r4, r0, CFG_DBAT6L@h
ori r4, r4, CFG_DBAT6L@l
addis r3, r0, CFG_DBAT6U@h
ori r3, r3, CFG_DBAT6U@l
mtspr DBAT6L, r4
mtspr DBAT6U, r3
/* IBAT 7 */
addis r4, r0, CFG_IBAT7L@h
ori r4, r4, CFG_IBAT7L@l
addis r3, r0, CFG_IBAT7U@h
ori r3, r3, CFG_IBAT7U@l
mtspr IBAT7L, r4
mtspr IBAT7U, r3
/* DBAT 7 */
addis r4, r0, CFG_DBAT7L@h
ori r4, r4, CFG_DBAT7L@l
addis r3, r0, CFG_DBAT7U@h
ori r3, r3, CFG_DBAT7U@l
mtspr DBAT7L, r4
mtspr DBAT7U, r3
#endif
isync
/* invalidate all tlb's
*
@ -537,202 +662,6 @@ init_e300_core: /* time t 10 */
* based on code in "flush_tlbs" from arch/ppc/kernel/head.S
*
*/
li r3, 32
mtctr r3
li r3, 0
1: tlbie r3
addi r3, r3, 0x1000
bdnz 1b
SYNC
/* Done! */
/*------------------------------*/
blr
.globl invalidate_bats
invalidate_bats:
/* invalidate BATs */
mtspr IBAT0U, r0
mtspr IBAT1U, r0
mtspr IBAT2U, r0
mtspr IBAT3U, r0
#ifdef CONFIG_HIGH_BATS
mtspr IBAT4U, r0
mtspr IBAT5U, r0
mtspr IBAT6U, r0
mtspr IBAT7U, r0
#endif
isync
mtspr DBAT0U, r0
mtspr DBAT1U, r0
mtspr DBAT2U, r0
mtspr DBAT3U, r0
#ifdef CONFIG_HIGH_BATS
mtspr DBAT4U, r0
mtspr DBAT5U, r0
mtspr DBAT6U, r0
mtspr DBAT7U, r0
#endif
isync
sync
blr
/* setup_bats - set them up to some initial state */
.globl setup_bats
setup_bats:
addis r0, r0, 0x0000
/* IBAT 0 */
addis r4, r0, CFG_IBAT0L@h
ori r4, r4, CFG_IBAT0L@l
addis r3, r0, CFG_IBAT0U@h
ori r3, r3, CFG_IBAT0U@l
mtspr IBAT0L, r4
mtspr IBAT0U, r3
isync
/* DBAT 0 */
addis r4, r0, CFG_DBAT0L@h
ori r4, r4, CFG_DBAT0L@l
addis r3, r0, CFG_DBAT0U@h
ori r3, r3, CFG_DBAT0U@l
mtspr DBAT0L, r4
mtspr DBAT0U, r3
isync
/* IBAT 1 */
addis r4, r0, CFG_IBAT1L@h
ori r4, r4, CFG_IBAT1L@l
addis r3, r0, CFG_IBAT1U@h
ori r3, r3, CFG_IBAT1U@l
mtspr IBAT1L, r4
mtspr IBAT1U, r3
isync
/* DBAT 1 */
addis r4, r0, CFG_DBAT1L@h
ori r4, r4, CFG_DBAT1L@l
addis r3, r0, CFG_DBAT1U@h
ori r3, r3, CFG_DBAT1U@l
mtspr DBAT1L, r4
mtspr DBAT1U, r3
isync
/* IBAT 2 */
addis r4, r0, CFG_IBAT2L@h
ori r4, r4, CFG_IBAT2L@l
addis r3, r0, CFG_IBAT2U@h
ori r3, r3, CFG_IBAT2U@l
mtspr IBAT2L, r4
mtspr IBAT2U, r3
isync
/* DBAT 2 */
addis r4, r0, CFG_DBAT2L@h
ori r4, r4, CFG_DBAT2L@l
addis r3, r0, CFG_DBAT2U@h
ori r3, r3, CFG_DBAT2U@l
mtspr DBAT2L, r4
mtspr DBAT2U, r3
isync
/* IBAT 3 */
addis r4, r0, CFG_IBAT3L@h
ori r4, r4, CFG_IBAT3L@l
addis r3, r0, CFG_IBAT3U@h
ori r3, r3, CFG_IBAT3U@l
mtspr IBAT3L, r4
mtspr IBAT3U, r3
isync
/* DBAT 3 */
addis r4, r0, CFG_DBAT3L@h
ori r4, r4, CFG_DBAT3L@l
addis r3, r0, CFG_DBAT3U@h
ori r3, r3, CFG_DBAT3U@l
mtspr DBAT3L, r4
mtspr DBAT3U, r3
isync
#ifdef CONFIG_HIGH_BATS
/* IBAT 4 */
addis r4, r0, CFG_IBAT4L@h
ori r4, r4, CFG_IBAT4L@l
addis r3, r0, CFG_IBAT4U@h
ori r3, r3, CFG_IBAT4U@l
mtspr IBAT4L, r4
mtspr IBAT4U, r3
isync
/* DBAT 4 */
addis r4, r0, CFG_DBAT4L@h
ori r4, r4, CFG_DBAT4L@l
addis r3, r0, CFG_DBAT4U@h
ori r3, r3, CFG_DBAT4U@l
mtspr DBAT4L, r4
mtspr DBAT4U, r3
isync
/* IBAT 5 */
addis r4, r0, CFG_IBAT5L@h
ori r4, r4, CFG_IBAT5L@l
addis r3, r0, CFG_IBAT5U@h
ori r3, r3, CFG_IBAT5U@l
mtspr IBAT5L, r4
mtspr IBAT5U, r3
isync
/* DBAT 5 */
addis r4, r0, CFG_DBAT5L@h
ori r4, r4, CFG_DBAT5L@l
addis r3, r0, CFG_DBAT5U@h
ori r3, r3, CFG_DBAT5U@l
mtspr DBAT5L, r4
mtspr DBAT5U, r3
isync
/* IBAT 6 */
addis r4, r0, CFG_IBAT6L@h
ori r4, r4, CFG_IBAT6L@l
addis r3, r0, CFG_IBAT6U@h
ori r3, r3, CFG_IBAT6U@l
mtspr IBAT6L, r4
mtspr IBAT6U, r3
isync
/* DBAT 6 */
addis r4, r0, CFG_DBAT6L@h
ori r4, r4, CFG_DBAT6L@l
addis r3, r0, CFG_DBAT6U@h
ori r3, r3, CFG_DBAT6U@l
mtspr DBAT6L, r4
mtspr DBAT6U, r3
isync
/* IBAT 7 */
addis r4, r0, CFG_IBAT7L@h
ori r4, r4, CFG_IBAT7L@l
addis r3, r0, CFG_IBAT7U@h
ori r3, r3, CFG_IBAT7U@l
mtspr IBAT7L, r4
mtspr IBAT7U, r3
isync
/* DBAT 7 */
addis r4, r0, CFG_DBAT7L@h
ori r4, r4, CFG_DBAT7L@l
addis r3, r0, CFG_DBAT7U@h
ori r3, r3, CFG_DBAT7U@l
mtspr DBAT7L, r4
mtspr DBAT7U, r3
isync
#endif
/* Invalidate TLBs.
* -> for (val = 0; val < 0x20000; val+=0x1000)
* -> tlbie(val);
*/
lis r3, 0
lis r5, 2
@ -874,7 +803,7 @@ relocate_code:
mr r3, r5 /* Destination Address */
lis r4, CFG_MONITOR_BASE@h /* Source Address */
ori r4, r4, CFG_MONITOR_BASE@l
lwz r5, GOT(__init_end)
lwz r5, GOT(__bss_start)
sub r5, r5, r4
li r6, CFG_CACHELINE_SIZE /* Cache Line Size */
@ -987,6 +916,7 @@ in_ram:
stw r0,0(r3)
bdnz 1b
#ifndef CONFIG_NAND_SPL
/*
* Now adjust the fixups and the pointers to the fixups
* in case we need to move ourselves again.
@ -1004,6 +934,8 @@ in_ram:
stw r0,0(r4)
bdnz 3b
4:
#endif
clear_bss:
/*
* Now clear BSS segment
@ -1037,6 +969,7 @@ clear_bss:
mr r4, r10 /* Destination Address */
bl board_init_r
#ifndef CONFIG_NAND_SPL
/*
* Copy exception vector code to low memory
*
@ -1119,6 +1052,7 @@ trap_reloc:
stw r0, 4(r7)
blr
#endif /* !CONFIG_NAND_SPL */
#ifdef CFG_INIT_RAM_LOCK
lock_ram_in_cache:
@ -1142,6 +1076,7 @@ lock_ram_in_cache:
sync
blr
#ifndef CONFIG_NAND_SPL
.globl unlock_ram_in_cache
unlock_ram_in_cache:
/* invalidate the INIT_RAM section */
@ -1165,8 +1100,10 @@ unlock_ram_in_cache:
mtspr HID0, r3 /* no invalidate, unlock */
sync
blr
#endif
#endif /* !CONFIG_NAND_SPL */
#endif /* CFG_INIT_RAM_LOCK */
#ifdef CFG_FLASHBOOT
map_flash_by_law1:
/* When booting from ROM (Flash or EPROM), clear the */
/* Address Mask in OR0 so ROM appears everywhere */
@ -1245,3 +1182,4 @@ remap_flash_by_law0:
stw r4, LBLAWBAR1(r3)
stw r4, LBLAWAR1(r3) /* Off LBIU LAW1 */
blr
#endif /* CFG_FLASHBOOT */

View File

@ -63,6 +63,10 @@
#define CFG_IMMR 0xE0000000
#if defined(CONFIG_NAND_U_BOOT) && !defined(CONFIG_NAND_SPL)
#define CONFIG_DEFAULT_IMMR CFG_IMMR
#endif
#define CFG_MEMTEST_START 0x00001000
#define CFG_MEMTEST_END 0x07f00000
@ -173,10 +177,10 @@
#define CFG_FLASH_EMPTY_INFO /* display empty sectors */
#define CFG_FLASH_USE_BUFFER_WRITE /* buffer up multiple bytes */
#define CFG_BR0_PRELIM (CFG_FLASH_BASE | /* flash Base address */ \
#define CFG_NOR_BR_PRELIM (CFG_FLASH_BASE | /* flash Base address */ \
(2 << BR_PS_SHIFT) | /* 16 bit port size */ \
BR_V) /* valid */
#define CFG_OR0_PRELIM ( 0xFF000000 /* 16 MByte */ \
#define CFG_NOR_OR_PRELIM ( 0xFF800000 /* 8 MByte */ \
| OR_GPCM_XACS \
| OR_GPCM_SCY_9 \
| OR_GPCM_EHTR \
@ -193,7 +197,7 @@
#define CFG_MONITOR_BASE TEXT_BASE /* start of monitor */
#if (CFG_MONITOR_BASE < CFG_FLASH_BASE)
#if (CFG_MONITOR_BASE < CFG_FLASH_BASE) && !defined(CONFIG_NAND_SPL)
#define CFG_RAMBOOT
#endif
@ -220,19 +224,31 @@
#define CFG_LBC_MRTPR 0x20000000 /*TODO */ /* LB refresh timer prescal, 266MHz/32 */
/* drivers/mtd/nand/nand.c */
#define CFG_NAND_BASE 0xE2800000 /* 0xF0000000 */
#ifdef CONFIG_NAND_SPL
#define CFG_NAND_BASE 0xFFF00000
#else
#define CFG_NAND_BASE 0xE2800000
#endif
#define CFG_MAX_NAND_DEVICE 1
#define NAND_MAX_CHIPS 1
#define CONFIG_MTD_NAND_VERIFY_WRITE
#define CONFIG_CMD_NAND 1
#define CONFIG_NAND_FSL_ELBC 1
#define CFG_NAND_BLOCK_SIZE 16384
#define CFG_BR1_PRELIM ( CFG_NAND_BASE \
#define CFG_NAND_U_BOOT_SIZE (512 << 10)
#define CFG_NAND_U_BOOT_DST 0x00100000
#define CFG_NAND_U_BOOT_START 0x00100100
#define CFG_NAND_U_BOOT_OFFS 16384
#define CFG_NAND_U_BOOT_RELOC 0x00010000
#define CFG_NAND_BR_PRELIM ( CFG_NAND_BASE \
| (2<<BR_DECC_SHIFT) /* Use HW ECC */ \
| BR_PS_8 /* Port Size = 8 bit */ \
| BR_MS_FCM /* MSEL = FCM */ \
| BR_V ) /* valid */
#define CFG_OR1_PRELIM ( 0xFFFF8000 /* length 32K */ \
#define CFG_NAND_OR_PRELIM ( 0xFFFF8000 /* length 32K */ \
| OR_FCM_CSCT \
| OR_FCM_CST \
| OR_FCM_CHT \
@ -240,9 +256,25 @@
| OR_FCM_TRLX \
| OR_FCM_EHTR )
/* 0xFFFF8396 */
#ifdef CONFIG_NAND_U_BOOT
#define CFG_BR0_PRELIM CFG_NAND_BR_PRELIM
#define CFG_OR0_PRELIM CFG_NAND_OR_PRELIM
#define CFG_BR1_PRELIM CFG_NOR_BR_PRELIM
#define CFG_OR1_PRELIM CFG_NOR_OR_PRELIM
#else
#define CFG_BR0_PRELIM CFG_NOR_BR_PRELIM
#define CFG_OR0_PRELIM CFG_NOR_OR_PRELIM
#define CFG_BR1_PRELIM CFG_NAND_BR_PRELIM
#define CFG_OR1_PRELIM CFG_NAND_OR_PRELIM
#endif
#define CFG_LBLAWBAR1_PRELIM CFG_NAND_BASE
#define CFG_LBLAWAR1_PRELIM 0x8000000E /* 32KB */
#define CFG_NAND_LBLAWBAR_PRELIM CFG_LBLAWBAR1_PRELIM
#define CFG_NAND_LBLAWAR_PRELIM CFG_LBLAWAR1_PRELIM
/* local bus read write buffer mapping */
#define CFG_BR3_PRELIM 0xFA000801 /* map at 0xFA000000 */
#define CFG_OR3_PRELIM 0xFFFF8FF7 /* 32kB */
@ -274,7 +306,6 @@
#define CFG_NS16550
#define CFG_NS16550_SERIAL
#define CFG_NS16550_REG_SIZE 1
#define CFG_NS16550_CLK get_bus_freq(0)
#define CFG_BAUDRATE_TABLE \
{300, 600, 1200, 2400, 4800, 9600, 19200, 38400, 115200}
@ -353,7 +384,15 @@
/*
* Environment
*/
#ifndef CFG_RAMBOOT
#if defined(CONFIG_NAND_U_BOOT)
#define CFG_ENV_IS_IN_NAND 1
#define CFG_ENV_OFFSET (512 * 1024)
#define CFG_ENV_SECT_SIZE CFG_NAND_BLOCK_SIZE
#define CFG_ENV_SIZE CFG_ENV_SECT_SIZE
#define CFG_ENV_SIZE_REDUND CFG_ENV_SIZE
#define CFG_ENV_RANGE (CFG_ENV_SECT_SIZE * 4)
#define CFG_ENV_OFFSET_REDUND (CFG_ENV_OFFSET + CFG_ENV_RANGE)
#elif !defined(CFG_RAMBOOT)
#define CFG_ENV_IS_IN_FLASH 1
#define CFG_ENV_ADDR (CFG_MONITOR_BASE + CFG_MONITOR_LEN)
#define CFG_ENV_SECT_SIZE 0x10000 /* 64K(one sector) for env */
@ -390,7 +429,7 @@
#define CONFIG_CMD_DATE
#define CONFIG_CMD_PCI
#if defined(CFG_RAMBOOT)
#if defined(CFG_RAMBOOT) && !defined(CONFIG_NAND_U_BOOT)
#undef CONFIG_CMD_ENV
#undef CONFIG_CMD_LOADS
#endif
@ -432,6 +471,8 @@
HRCWL_CSB_TO_CLKIN_2X1 |\
HRCWL_CORE_TO_CSB_2X1)
#define CFG_NS16550_CLK (CONFIG_83XX_CLKIN * 2)
#elif defined(CFG_33MHZ)
/* 33MHz IN, 165MHz CSB, 330 DDR, 330 CORE */
@ -444,22 +485,31 @@
HRCWL_CSB_TO_CLKIN_5X1 |\
HRCWL_CORE_TO_CSB_2X1)
#define CFG_NS16550_CLK (CONFIG_83XX_CLKIN * 5)
#endif
/* 0xa0606c00 */
#define CFG_HRCW_HIGH (\
#define CFG_HRCW_HIGH_BASE (\
HRCWH_PCI_HOST |\
HRCWH_PCI1_ARBITER_ENABLE |\
HRCWH_CORE_ENABLE |\
HRCWH_FROM_0X00000100 |\
HRCWH_BOOTSEQ_DISABLE |\
HRCWH_SW_WATCHDOG_DISABLE |\
HRCWH_ROM_LOC_LOCAL_16BIT |\
HRCWH_RL_EXT_LEGACY |\
HRCWH_TSEC1M_IN_RGMII |\
HRCWH_TSEC2M_IN_RGMII |\
HRCWH_BIG_ENDIAN |\
HRCWH_LALE_NORMAL)
HRCWH_BIG_ENDIAN)
#ifdef CONFIG_NAND_SPL
#define CFG_HRCW_HIGH (CFG_HRCW_HIGH_BASE |\
HRCWH_FROM_0XFFF00100 |\
HRCWH_ROM_LOC_NAND_SP_8BIT |\
HRCWH_RL_EXT_NAND)
#else
#define CFG_HRCW_HIGH (CFG_HRCW_HIGH_BASE |\
HRCWH_FROM_0X00000100 |\
HRCWH_ROM_LOC_LOCAL_16BIT |\
HRCWH_RL_EXT_LEGACY)
#endif
/* System IO Config */
#define CFG_SICRH (SICRH_TSOBI1 | SICRH_TSOBI2) /* RGMII */

View File

@ -30,7 +30,9 @@
/* IMMRBAR - Internal Memory Register Base Address
*/
#ifndef CONFIG_DEFAULT_IMMR
#define CONFIG_DEFAULT_IMMR 0xFF400000 /* Default IMMR base address */
#endif
#define IMMRBAR 0x0000 /* Register offset to immr */
#define IMMRBAR_BASE_ADDR 0xFFF00000 /* Base address mask */
#define IMMRBAR_RES ~(IMMRBAR_BASE_ADDR)

View File

@ -126,5 +126,7 @@ int nand_get_lock_status(nand_info_t *meminfo, ulong offset);
void board_nand_select_device(struct nand_chip *nand, int chip);
#endif
__attribute__((noreturn)) void nand_boot(void);
#endif /* !CFG_NAND_LEGACY */
#endif

View File

@ -67,7 +67,7 @@ void udelay(unsigned long usec)
}
/* ------------------------------------------------------------------------- */
#ifndef CONFIG_NAND_SPL
unsigned long ticks2usec(unsigned long ticks)
{
ulong tbclk = get_tbclk();
@ -83,7 +83,7 @@ unsigned long ticks2usec(unsigned long ticks)
return ((ulong)ticks);
}
#endif
/* ------------------------------------------------------------------------- */
int init_timebase (void)

View File

@ -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
#########################################################################

View File

@ -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");

View File

@ -235,7 +235,7 @@ void nand_boot(void)
struct nand_chip nand_chip;
nand_info_t nand_info;
int ret;
void (*uboot)(void);
__attribute__((noreturn)) void (*uboot)(void);
/*
* Init board specific nand support
@ -254,6 +254,6 @@ void nand_boot(void)
/*
* Jump to U-Boot image
*/
uboot = (void (*)(void))CFG_NAND_U_BOOT_START;
uboot = (void *)CFG_NAND_U_BOOT_START;
(*uboot)();
}

View File

@ -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(&regs->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(&regs->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(&regs->fcr, (NAND_CMD_READ0 << FCR_CMD0_SHIFT) |
(NAND_CMD_READSTART << FCR_CMD1_SHIFT));
out_be32(&regs->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(&regs->fcr, NAND_CMD_READ0 << FCR_CMD0_SHIFT);
out_be32(&regs->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(&regs->fbcr, 0);
clrsetbits_be32(&regs->bank[0].br, BR_DECC, BR_DECC_CHK_GEN);
while (pos < uboot_size) {
int i = 0;
out_be32(&regs->fbar, offs >> block_shift);
do {
int j;
unsigned int page_offs = (offs & (block_size - 1)) << 1;
out_be32(&regs->ltesr, ~0);
out_be32(&regs->lteatr, 0);
out_be32(&regs->fpar, page_offs);
out_be32(&regs->fmr, fmr);
out_be32(&regs->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();
}