diff options
| -rw-r--r-- | Makefile | 10 | ||||
| -rw-r--r-- | board/freescale/mpc8313erdb/config.mk | 6 | ||||
| -rw-r--r-- | board/freescale/mpc8313erdb/mpc8313erdb.c | 32 | ||||
| -rw-r--r-- | board/freescale/mpc8313erdb/sdram.c | 5 | ||||
| -rw-r--r-- | cpu/mpc83xx/nand_init.c | 112 | ||||
| -rw-r--r-- | cpu/mpc83xx/start.S | 152 | ||||
| -rw-r--r-- | include/configs/MPC8313ERDB.h | 82 | ||||
| -rw-r--r-- | include/mpc83xx.h | 2 | ||||
| -rw-r--r-- | include/nand.h | 2 | ||||
| -rw-r--r-- | lib_ppc/time.c | 4 | ||||
| -rw-r--r-- | nand_spl/board/freescale/mpc8313erdb/Makefile | 101 | ||||
| -rw-r--r-- | nand_spl/board/freescale/mpc8313erdb/u-boot.lds | 52 | ||||
| -rw-r--r-- | nand_spl/nand_boot.c | 4 | ||||
| -rw-r--r-- | nand_spl/nand_boot_fsl_elbc.c | 150 | 
14 files changed, 585 insertions, 129 deletions
| @@ -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 diff --git a/board/freescale/mpc8313erdb/config.mk b/board/freescale/mpc8313erdb/config.mk index f76826495..fd72a1402 100644 --- a/board/freescale/mpc8313erdb/config.mk +++ b/board/freescale/mpc8313erdb/config.mk @@ -1 +1,7 @@ +ifndef NAND_SPL +sinclude $(OBJTREE)/board/$(BOARDDIR)/config.tmp +endif + +ifndef TEXT_BASE  TEXT_BASE = 0xFE000000 +endif diff --git a/board/freescale/mpc8313erdb/mpc8313erdb.c b/board/freescale/mpc8313erdb/mpc8313erdb.c index 7cbdb7bf3..ebb703d3e 100644 --- a/board/freescale/mpc8313erdb/mpc8313erdb.c +++ b/board/freescale/mpc8313erdb/mpc8313erdb.c @@ -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 diff --git a/board/freescale/mpc8313erdb/sdram.c b/board/freescale/mpc8313erdb/sdram.c index afd8b9d5e..3a6347fe1 100644 --- a/board/freescale/mpc8313erdb/sdram.c +++ b/board/freescale/mpc8313erdb/sdram.c @@ -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;  } diff --git a/cpu/mpc83xx/nand_init.c b/cpu/mpc83xx/nand_init.c new file mode 100644 index 000000000..e92f23023 --- /dev/null +++ b/cpu/mpc83xx/nand_init.c @@ -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++); +} diff --git a/cpu/mpc83xx/start.S b/cpu/mpc83xx/start.S index c18217479..16ed494f8 100644 --- a/cpu/mpc83xx/start.S +++ b/cpu/mpc83xx/start.S @@ -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 */ diff --git a/include/configs/MPC8313ERDB.h b/include/configs/MPC8313ERDB.h index 3a644d348..37f8cffd3 100644 --- a/include/configs/MPC8313ERDB.h +++ b/include/configs/MPC8313ERDB.h @@ -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 +#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 \ @@ -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 */ diff --git a/include/mpc83xx.h b/include/mpc83xx.h index 897ecd6bc..70a4de70d 100644 --- a/include/mpc83xx.h +++ b/include/mpc83xx.h @@ -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) diff --git a/include/nand.h b/include/nand.h index d5af4324c..764e9f972 100644 --- a/include/nand.h +++ b/include/nand.h @@ -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 diff --git a/lib_ppc/time.c b/lib_ppc/time.c index 2649d5ffd..f093a5785 100644 --- a/lib_ppc/time.c +++ b/lib_ppc/time.c @@ -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) diff --git a/nand_spl/board/freescale/mpc8313erdb/Makefile b/nand_spl/board/freescale/mpc8313erdb/Makefile new file mode 100644 index 000000000..3da1b1fff --- /dev/null +++ b/nand_spl/board/freescale/mpc8313erdb/Makefile @@ -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 + +######################################################################### diff --git a/nand_spl/board/freescale/mpc8313erdb/u-boot.lds b/nand_spl/board/freescale/mpc8313erdb/u-boot.lds new file mode 100644 index 000000000..40c414549 --- /dev/null +++ b/nand_spl/board/freescale/mpc8313erdb/u-boot.lds @@ -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"); diff --git a/nand_spl/nand_boot.c b/nand_spl/nand_boot.c index 5914d0403..0f56ba520 100644 --- a/nand_spl/nand_boot.c +++ b/nand_spl/nand_boot.c @@ -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)();  } diff --git a/nand_spl/nand_boot_fsl_elbc.c b/nand_spl/nand_boot_fsl_elbc.c new file mode 100644 index 000000000..0d2378ee8 --- /dev/null +++ b/nand_spl/nand_boot_fsl_elbc.c @@ -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(); +} |