Commit e4c09508 authored by Scott Wood's avatar Scott Wood
Browse files

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: default avatarScott Wood <scottwood@freescale.com>
parent acdab5c3
......@@ -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
......
ifndef NAND_SPL
sinclude $(OBJTREE)/board/$(BOARDDIR)/config.tmp
endif
ifndef TEXT_BASE
TEXT_BASE = 0xFE000000
endif
......@@ -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
......@@ -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;
}
......
/*
* 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++);
}
......@@ -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,88 +502,10 @@ init_e300_core: /* time t 10 */
SYNC
mtspr HID2, r3
/* clear all BAT's */
/*----------------------------------*/
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
/* invalidate all tlb's
*
* From the 603e User Manual: "The 603e provides the ability to
* invalidate a TLB entry. The TLB Invalidate Entry (tlbie)
* instruction invalidates the TLB entry indexed by the EA, and
* operates on both the instruction and data TLBs simultaneously
* invalidating four TLB entries (both sets in each TLB). The
* index corresponds to bits 15-19 of the EA. To invalidate all
* entries within both TLBs, 32 tlbie instructions should be
* issued, incrementing this field by one each time."
*
* "Note that the tlbia instruction is not implemented on the
* 603e."
*
* bits 15-19 correspond to addresses 0x00000000 to 0x0001F000
* incrementing by 0x1000 each time. The code below is sort of
* 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:
......@@ -590,7 +518,6 @@ setup_bats:
ori r3, r3, CFG_IBAT0U@l
mtspr IBAT0L, r4
mtspr IBAT0U, r3
isync
/* DBAT 0 */
addis r4, r0, CFG_DBAT0L@h
......@@ -599,7 +526,6 @@ setup_bats:
ori r3, r3, CFG_DBAT0U@l
mtspr DBAT0L, r4
mtspr DBAT0U, r3
isync
/* IBAT 1 */
addis r4, r0, CFG_IBAT1L@h
......@@ -608,7 +534,6 @@ setup_bats:
ori r3, r3, CFG_IBAT1U@l
mtspr IBAT1L, r4
mtspr IBAT1U, r3
isync
/* DBAT 1 */
addis r4, r0, CFG_DBAT1L@h
......@@ -617,7 +542,6 @@ setup_bats:
ori r3, r3, CFG_DBAT1U@l
mtspr DBAT1L, r4
mtspr DBAT1U, r3
isync
/* IBAT 2 */
addis r4, r0, CFG_IBAT2L@h
......@@ -626,7 +550,6 @@ setup_bats:
ori r3, r3, CFG_IBAT2U@l
mtspr IBAT2L, r4
mtspr IBAT2U, r3
isync
/* DBAT 2 */
addis r4, r0, CFG_DBAT2L@h
......@@ -635,7 +558,6 @@ setup_bats:
ori r3, r3, CFG_DBAT2U@l
mtspr DBAT2L, r4
mtspr DBAT2U, r3
isync
/* IBAT 3 */
addis r4, r0, CFG_IBAT3L@h
......@@ -644,7 +566,6 @@ setup_bats:
ori r3, r3, CFG_IBAT3U@l
mtspr IBAT3L, r4
mtspr IBAT3U, r3
isync
/* DBAT 3 */
addis r4, r0, CFG_DBAT3L@h
......@@ -653,7 +574,6 @@ setup_bats:
ori r3, r3, CFG_DBAT3U@l
mtspr DBAT3L, r4
mtspr DBAT3U, r3
isync
#ifdef CONFIG_HIGH_BATS
/* IBAT 4 */
......@@ -663,7 +583,6 @@ setup_bats:
ori r3, r3, CFG_IBAT4U@l
mtspr IBAT4L, r4
mtspr IBAT4U, r3
isync
/* DBAT 4 */
addis r4, r0, CFG_DBAT4L@h
......@@ -672,7 +591,6 @@ setup_bats:
ori r3, r3, CFG_DBAT4U@l
mtspr DBAT4L, r4
mtspr DBAT4U, r3
isync
/* IBAT 5 */
addis r4, r0, CFG_IBAT5L@h
......@@ -681,7 +599,6 @@ setup_bats:
ori r3, r3, CFG_IBAT5U@l
mtspr IBAT5L, r4
mtspr IBAT5U, r3
isync
/* DBAT 5 */
addis r4, r0, CFG_DBAT5L@h
......@@ -690,7 +607,6 @@ setup_bats:
ori r3, r3, CFG_DBAT5U@l
mtspr DBAT5L, r4
mtspr DBAT5U, r3
isync
/* IBAT 6 */
addis r4, r0, CFG_IBAT6L@h
......@@ -699,7 +615,6 @@ setup_bats:
ori r3, r3, CFG_IBAT6U@l
mtspr IBAT6L, r4
mtspr IBAT6U, r3
isync
/* DBAT 6 */
addis r4, r0, CFG_DBAT6L@h
......@@ -708,7 +623,6 @@ setup_bats:
ori r3, r3, CFG_DBAT6U@l
mtspr DBAT6L, r4
mtspr DBAT6U, r3
isync
/* IBAT 7 */
addis r4, r0, CFG_IBAT7L@h
......@@ -717,7 +631,6 @@ setup_bats:
ori r3, r3, CFG_IBAT7U@l
mtspr IBAT7L, r4
mtspr IBAT7U, r3
isync
/* DBAT 7 */
addis r4, r0, CFG_DBAT7L@h
......@@ -726,12 +639,28 @@ setup_bats:
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);
isync
/* invalidate all tlb's
*
* From the 603e User Manual: "The 603e provides the ability to
* invalidate a TLB entry. The TLB Invalidate Entry (tlbie)
* instruction invalidates the TLB entry indexed by the EA, and
* operates on both the instruction and data TLBs simultaneously
* invalidating four TLB entries (both sets in each TLB). The
* index corresponds to bits 15-19 of the EA. To invalidate all
* entries within both TLBs, 32 tlbie instructions should be
* issued, incrementing this field by one each time."
*
* "Note that the tlbia instruction is not implemented on the
* 603e."
*
* bits 15-19 correspond to addresses 0x00000000 to 0x0001F000
* incrementing by 0x1000 each time. The code below is sort of
* based on code in "flush_tlbs" from arch/ppc/kernel/head.S
*
*/
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 */
......@@ -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_NAND_U_BOOT_SIZE (512 << 10)
#define CFG_NAND_U_BOOT_DST 0x00100000