#########################################################################
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 ; \
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
#include <pci.h>
#include <mpc83xx.h>
#include <vsc7385.h>
+#include <ns16550.h>
+#include <nand.h>
DECLARE_GLOBAL_DATA_PTR;
return 0;
}
+#ifndef CONFIG_NAND_SPL
static struct pci_region pci_regions[] = {
{
bus_start: CFG_PCI1_MEM_BASE,
#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
*/
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;
/* enable DDR controller */
im->ddr.sdram_cfg |= SDRAM_CFG_MEM_EN;
+#endif
return msize;
}
--- /dev/null
+/*
+ * 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++);
+}
* 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.
#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
*
*/
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
/*
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 */
#if 1 /* Remapping flash with LAW0. */
bl remap_flash_by_law0
#endif
-#endif /* CFG_RAMBOOT */
+#endif /* CFG_FLASHBOOT */
/* setup the bats */
bl setup_bats
/* run 1st part of board init code (in Flash)*/
bl board_init_f
+#ifndef CONFIG_NAND_SPL
/*
* Vector Table
*/
lwz r1,GPR1(r1)
SYNC
rfi
+#endif /* !CONFIG_NAND_SPL */
/*
* This code initialises the E300 processor core
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:
ori r3, r3, CFG_IBAT0U@l
mtspr IBAT0L, r4
mtspr IBAT0U, r3
- isync
/* DBAT 0 */
addis r4, r0, CFG_DBAT0L@h
ori r3, r3, CFG_DBAT0U@l
mtspr DBAT0L, r4
mtspr DBAT0U, r3
- isync
/* IBAT 1 */
addis r4, r0, CFG_IBAT1L@h
ori r3, r3, CFG_IBAT1U@l
mtspr IBAT1L, r4
mtspr IBAT1U, r3
- isync
/* DBAT 1 */
addis r4, r0, CFG_DBAT1L@h
ori r3, r3, CFG_DBAT1U@l
mtspr DBAT1L, r4
mtspr DBAT1U, r3
- isync
/* IBAT 2 */
addis r4, r0, CFG_IBAT2L@h
ori r3, r3, CFG_IBAT2U@l
mtspr IBAT2L, r4
mtspr IBAT2U, r3
- isync
/* DBAT 2 */
addis r4, r0, CFG_DBAT2L@h
ori r3, r3, CFG_DBAT2U@l
mtspr DBAT2L, r4
mtspr DBAT2U, r3
- isync
/* IBAT 3 */
addis r4, r0, CFG_IBAT3L@h
ori r3, r3, CFG_IBAT3U@l
mtspr IBAT3L, r4
mtspr IBAT3U, r3
- isync
/* DBAT 3 */
addis r4, r0, CFG_DBAT3L@h
ori r3, r3, CFG_DBAT3U@l
mtspr DBAT3L, r4
mtspr DBAT3U, r3
- isync
#ifdef CONFIG_HIGH_BATS
/* IBAT 4 */
ori r3, r3, CFG_IBAT4U@l
mtspr IBAT4L, r4
mtspr IBAT4U, r3
- isync
/* DBAT 4 */
addis r4, r0, CFG_DBAT4L@h
ori r3, r3, CFG_DBAT4U@l
mtspr DBAT4L, r4
mtspr DBAT4U, r3
- isync
/* IBAT 5 */
addis r4, r0, CFG_IBAT5L@h
ori r3, r3, CFG_IBAT5U@l
mtspr IBAT5L, r4
mtspr IBAT5U, r3
- isync
/* DBAT 5 */
addis r4, r0, CFG_DBAT5L@h
ori r3, r3, CFG_DBAT5U@l
mtspr DBAT5L, r4
mtspr DBAT5U, r3
- isync
/* IBAT 6 */
addis r4, r0, CFG_IBAT6L@h
ori r3, r3, CFG_IBAT6U@l
mtspr IBAT6L, r4
mtspr IBAT6U, r3
- isync
/* DBAT 6 */
addis r4, r0, CFG_DBAT6L@h
ori r3, r3, CFG_DBAT6U@l
mtspr DBAT6L, r4
mtspr DBAT6U, r3
- isync
/* IBAT 7 */
addis r4, r0, CFG_IBAT7L@h
ori r3, r3, CFG_IBAT7U@l
mtspr IBAT7L, r4
mtspr IBAT7U, r3
- isync
/* DBAT 7 */
addis r4, r0, CFG_DBAT7L@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);
+ 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
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 */
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.
stw r0,0(r4)
bdnz 3b
4:
+#endif
+
clear_bss:
/*
* Now clear BSS segment
mr r4, r10 /* Destination Address */
bl board_init_r
+#ifndef CONFIG_NAND_SPL
/*
* Copy exception vector code to low memory
*
stw r0, 4(r7)
blr
+#endif /* !CONFIG_NAND_SPL */
#ifdef CFG_INIT_RAM_LOCK
lock_ram_in_cache:
sync
blr
+#ifndef CONFIG_NAND_SPL
.globl unlock_ram_in_cache
unlock_ram_in_cache:
/* invalidate the INIT_RAM section */
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 */
stw r4, LBLAWBAR1(r3)
stw r4, LBLAWAR1(r3) /* Off LBIU LAW1 */
blr
+#endif /* CFG_FLASHBOOT */
#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
#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 \
#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
#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
+#define CFG_NAND_U_BOOT_START 0x00100100
+#define CFG_NAND_U_BOOT_OFFS 16384
+#define CFG_NAND_U_BOOT_RELOC 0x00010000
-#define CFG_BR1_PRELIM ( CFG_NAND_BASE \
+#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 \
| 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 */
#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}
/*
* 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 */
#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
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 */
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 */
/* 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)
void board_nand_select_device(struct nand_chip *nand, int chip);
#endif
+__attribute__((noreturn)) void nand_boot(void);
+
#endif /* !CFG_NAND_LEGACY */
#endif
}
/* ------------------------------------------------------------------------- */
-
+#ifndef CONFIG_NAND_SPL
unsigned long ticks2usec(unsigned long ticks)
{
ulong tbclk = get_tbclk();
return ((ulong)ticks);
}
-
+#endif
/* ------------------------------------------------------------------------- */
int init_timebase (void)
--- /dev/null
+#
+# (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
+
+#########################################################################
--- /dev/null
+/*
+ * (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");
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
/*
* Jump to U-Boot image
*/
- uboot = (void (*)(void))CFG_NAND_U_BOOT_START;
+ uboot = (void *)CFG_NAND_U_BOOT_START;
(*uboot)();
}
--- /dev/null
+/*
+ * 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();
+}