浏览代码

Merge branch 'u-boot-pxa/master' into 'u-boot-arm/master'

Albert ARIBAUD 12 年之前
父节点
当前提交
e825b100d2
共有 100 个文件被更改,包括 3169 次插入746 次删除
  1. 22 0
      Makefile
  2. 16 0
      README
  3. 0 7
      arch/arm/cpu/arm926ejs/mxs/spl_boot.c
  4. 0 7
      arch/arm/cpu/arm926ejs/spear/spl.c
  5. 1 1
      arch/arm/cpu/pxa/pxa2xx.c
  6. 0 11
      arch/arm/include/asm/arch-pxa/hardware.h
  7. 0 6
      arch/arm/lib/board.c
  8. 0 5
      arch/avr32/lib/board.c
  9. 0 14
      arch/blackfin/lib/board.c
  10. 0 7
      arch/m68k/lib/board.c
  11. 4 0
      arch/microblaze/include/asm/processor.h
  12. 30 35
      arch/microblaze/lib/board.c
  13. 0 7
      arch/mips/lib/board.c
  14. 0 7
      arch/nds32/lib/board.c
  15. 17 29
      arch/nios2/lib/board.c
  16. 0 12
      arch/openrisc/lib/board.c
  17. 0 6
      arch/powerpc/cpu/mpc512x/speed.c
  18. 3 0
      arch/powerpc/cpu/mpc85xx/cmd_errata.c
  19. 10 8
      arch/powerpc/cpu/mpc85xx/cpu.c
  20. 14 0
      arch/powerpc/cpu/mpc85xx/cpu_init.c
  21. 7 0
      arch/powerpc/cpu/mpc85xx/fdt.c
  22. 4 0
      arch/powerpc/cpu/mpc85xx/fsl_corenet_serdes.c
  23. 10 10
      arch/powerpc/cpu/mpc85xx/p2041_ids.c
  24. 10 10
      arch/powerpc/cpu/mpc85xx/p3041_ids.c
  25. 10 10
      arch/powerpc/cpu/mpc85xx/p5020_ids.c
  26. 17 3
      arch/powerpc/cpu/mpc85xx/portals.c
  27. 4 0
      arch/powerpc/cpu/ppc4xx/Makefile
  28. 72 0
      arch/powerpc/cpu/ppc4xx/spl_boot.c
  29. 33 4
      arch/powerpc/cpu/ppc4xx/start.S
  30. 74 0
      arch/powerpc/cpu/ppc4xx/u-boot-spl.lds
  31. 2 0
      arch/powerpc/cpu/ppc4xx/u-boot.lds
  32. 9 3
      arch/powerpc/include/asm/config_mpc85xx.h
  33. 4 0
      arch/powerpc/include/asm/fsl_memac.h
  34. 11 1
      arch/powerpc/include/asm/immap_85xx.h
  35. 0 9
      arch/powerpc/lib/board.c
  36. 4 1
      arch/sandbox/config.mk
  37. 5 0
      arch/sandbox/cpu/cpu.c
  38. 8 1
      arch/sandbox/cpu/start.c
  39. 8 0
      arch/sandbox/include/asm/io.h
  40. 1 0
      arch/sandbox/include/asm/state.h
  41. 2 20
      arch/sandbox/include/asm/u-boot.h
  42. 0 1
      arch/sandbox/lib/Makefile
  43. 0 285
      arch/sandbox/lib/board.c
  44. 0 9
      arch/sh/lib/board.c
  45. 0 9
      arch/sparc/lib/board.c
  46. 0 7
      arch/x86/lib/board.c
  47. 20 6
      board/a3m071/a3m071.c
  48. 17 2
      board/freescale/b4860qds/tlb.c
  49. 6 0
      board/freescale/common/Makefile
  50. 23 3
      board/freescale/common/cds_pci_ft.c
  51. 1 1
      board/freescale/common/sdhc_boot.c
  52. 1 1
      board/freescale/p1010rdb/p1010rdb.c
  53. 14 0
      board/freescale/p1022ds/Makefile
  54. 1 0
      board/freescale/p1022ds/law.c
  55. 129 0
      board/freescale/p1022ds/spl_minimal.c
  56. 14 6
      board/freescale/p1022ds/tlb.c
  57. 65 1
      board/freescale/p1_p2_rdb_pc/p1_p2_rdb_pc.c
  58. 15 0
      board/freescale/p1_p2_rdb_pc/spl_minimal.c
  59. 9 0
      board/h2200/h2200.c
  60. 73 2
      board/lwmon5/lwmon5.c
  61. 3 1
      board/lwmon5/sdram.c
  62. 1 1
      board/sandbox/sandbox/sandbox.c
  63. 8 3
      board/xilinx/microblaze-generic/microblaze-generic.c
  64. 4 0
      board/xilinx/microblaze-generic/xparameters.h
  65. 3 0
      boards.cfg
  66. 93 15
      common/board_f.c
  67. 6 2
      common/board_r.c
  68. 57 30
      common/cmd_fdt.c
  69. 5 0
      common/cmd_ide.c
  70. 80 22
      common/cmd_nvedit.c
  71. 14 4
      common/cmd_sandbox.c
  72. 1 0
      common/cmd_sata.c
  73. 4 0
      common/cmd_scsi.c
  74. 287 9
      common/cmd_setexpr.c
  75. 7 4
      common/cmd_source.c
  76. 123 9
      common/env_mmc.c
  77. 11 0
      common/flash.c
  78. 0 8
      common/main.c
  79. 0 7
      common/spl/spl.c
  80. 1 0
      common/usb_storage.c
  81. 6 2
      config.mk
  82. 16 3
      disk/part_dos.c
  83. 22 16
      disk/part_efi.c
  84. 3 0
      disk/part_iso.c
  85. 5 1
      doc/README.fdt-control
  86. 199 0
      doc/README.p1010rdb
  87. 102 0
      doc/README.ramboot-ppc85xx
  88. 3 0
      doc/README.watchdog
  89. 7 12
      doc/feature-removal-schedule.txt
  90. 2 1
      doc/git-mailrc
  91. 1 0
      drivers/block/ata_piix.c
  92. 2 0
      drivers/block/pata_bfin.c
  93. 1 0
      drivers/block/systemace.c
  94. 14 12
      drivers/mmc/mmc.c
  95. 9 8
      drivers/mmc/spl_mmc.c
  96. 2 0
      drivers/mtd/nand/Makefile
  97. 1028 0
      drivers/mtd/nand/docg4.c
  98. 222 0
      drivers/mtd/nand/docg4_spl.c
  99. 0 9
      drivers/mtd/nand/mxc_nand_spl.c
  100. 17 0
      drivers/net/fm/memac.c

+ 22 - 0
Makefile

@@ -183,6 +183,16 @@ endif
 # load other configuration
 # load other configuration
 include $(TOPDIR)/config.mk
 include $(TOPDIR)/config.mk
 
 
+# Targets which don't build the source code
+NON_BUILD_TARGETS = backup clean clobber distclean mkproper tidy unconfig
+
+# Only do the generic board check when actually building, not configuring
+ifeq ($(filter $(NON_BUILD_TARGETS),$(MAKECMDGOALS)),)
+ifeq ($(findstring _config,$(MAKECMDGOALS)),)
+$(CHECK_GENERIC_BOARD)
+endif
+endif
+
 # If board code explicitly specified LDSCRIPT or CONFIG_SYS_LDSCRIPT, use
 # If board code explicitly specified LDSCRIPT or CONFIG_SYS_LDSCRIPT, use
 # that (or fail if absent).  Otherwise, search for a linker script in a
 # that (or fail if absent).  Otherwise, search for a linker script in a
 # standard location.
 # standard location.
@@ -554,6 +564,18 @@ endif
 $(obj)u-boot-img.bin: $(obj)spl/u-boot-spl.bin $(obj)u-boot.img
 $(obj)u-boot-img.bin: $(obj)spl/u-boot-spl.bin $(obj)u-boot.img
 		cat $(obj)spl/u-boot-spl.bin $(obj)u-boot.img > $@
 		cat $(obj)spl/u-boot-spl.bin $(obj)u-boot.img > $@
 
 
+# PPC4xx needs the SPL at the end of the image, since the reset vector
+# is located at 0xfffffffc. So we can't use the "u-boot-img.bin" target
+# and need to introduce a new build target with the full blown U-Boot
+# at the start padded up to the start of the SPL image. And then concat
+# the SPL image to the end.
+$(obj)u-boot-img-spl-at-end.bin: $(obj)spl/u-boot-spl.bin $(obj)u-boot.img
+		tr "\000" "\377" < /dev/zero | dd ibs=1 count=$(CONFIG_UBOOT_PAD_TO) \
+			of=$(obj)u-boot-pad.img 2>/dev/null
+		dd if=$(obj)u-boot.img of=$(obj)u-boot-pad.img \
+			conv=notrunc 2>/dev/null
+		cat $(obj)u-boot-pad.img $(obj)spl/u-boot-spl.bin > $@
+
 ifeq ($(CONFIG_SANDBOX),y)
 ifeq ($(CONFIG_SANDBOX),y)
 GEN_UBOOT = \
 GEN_UBOOT = \
 		cd $(LNDIR) && $(CC) $(SYMS) -T $(obj)u-boot.lds \
 		cd $(LNDIR) && $(CC) $(SYMS) -T $(obj)u-boot.lds \

+ 16 - 0
README

@@ -930,6 +930,13 @@ The following options need to be configured:
 
 
 		XXX - this list needs to get updated!
 		XXX - this list needs to get updated!
 
 
+- Regular expression support:
+		CONFIG_REGEX
+                If this variable is defined, U-Boot is linked against
+                the SLRE (Super Light Regular Expression) library,
+                which adds regex support to some commands, as for
+                example "env grep" and "setexpr".
+
 - Device tree:
 - Device tree:
 		CONFIG_OF_CONTROL
 		CONFIG_OF_CONTROL
 		If this variable is defined, U-Boot will use a device tree
 		If this variable is defined, U-Boot will use a device tree
@@ -3248,6 +3255,15 @@ Configuration Settings:
 		digits and dots.  Recommended value: 45 (9..1) for 80
 		digits and dots.  Recommended value: 45 (9..1) for 80
 		column displays, 15 (3..1) for 40 column displays.
 		column displays, 15 (3..1) for 40 column displays.
 
 
+- CONFIG_FLASH_VERIFY
+		If defined, the content of the flash (destination) is compared
+		against the source after the write operation. An error message
+		will be printed when the contents are not identical.
+		Please note that this option is useless in nearly all cases,
+		since such flash programming errors usually are detected earlier
+		while unprotecting/erasing/programming. Please only enable
+		this option if you really know what you are doing.
+
 - CONFIG_SYS_RX_ETH_BUFFER:
 - CONFIG_SYS_RX_ETH_BUFFER:
 		Defines the number of Ethernet receive buffers. On some
 		Defines the number of Ethernet receive buffers. On some
 		Ethernet controllers it is recommended to set this value
 		Ethernet controllers it is recommended to set this value

+ 0 - 7
arch/arm/cpu/arm926ejs/mxs/spl_boot.c

@@ -148,10 +148,3 @@ inline void board_init_r(gd_t *id, ulong dest_addr)
 	for (;;)
 	for (;;)
 		;
 		;
 }
 }
-
-void hang(void) __attribute__ ((noreturn));
-void hang(void)
-{
-	for (;;)
-		;
-}

+ 0 - 7
arch/arm/cpu/arm926ejs/spear/spl.c

@@ -31,13 +31,6 @@
 #include <asm/arch/spr_misc.h>
 #include <asm/arch/spr_misc.h>
 #include <asm/arch/spr_syscntl.h>
 #include <asm/arch/spr_syscntl.h>
 
 
-inline void hang(void)
-{
-	serial_puts("### ERROR ### Please RESET the board ###\n");
-	for (;;)
-		;
-}
-
 static void ddr_clock_init(void)
 static void ddr_clock_init(void)
 {
 {
 	struct misc_regs *misc_p = (struct misc_regs *)CONFIG_SPEAR_MISCBASE;
 	struct misc_regs *misc_p = (struct misc_regs *)CONFIG_SPEAR_MISCBASE;

+ 1 - 1
arch/arm/cpu/pxa/pxa2xx.c

@@ -284,7 +284,7 @@ void i2c_clk_enable(void)
 	writel(readl(CKEN) | CKEN14_I2C, CKEN);
 	writel(readl(CKEN) | CKEN14_I2C, CKEN);
 }
 }
 
 
-void reset_cpu(ulong ignored) __attribute__((noreturn));
+void __attribute__((weak)) reset_cpu(ulong ignored) __attribute__((noreturn));
 
 
 void reset_cpu(ulong ignored)
 void reset_cpu(ulong ignored)
 {
 {

+ 0 - 11
arch/arm/include/asm/arch-pxa/hardware.h

@@ -77,17 +77,6 @@
 #define GPIO_FALLING_EDGE	1
 #define GPIO_FALLING_EDGE	1
 #define GPIO_RISING_EDGE	2
 #define GPIO_RISING_EDGE	2
 #define GPIO_BOTH_EDGES		3
 #define GPIO_BOTH_EDGES		3
-extern void set_GPIO_IRQ_edge( int gpio_nr, int edge_mask );
-
-/*
- * Handy routine to set GPIO alternate functions
- */
-extern void set_GPIO_mode( int gpio_mode );
-
-/*
- * return current lclk frequency in units of 10kHz
- */
-extern unsigned int get_lclk_frequency_10khz(void);
 
 
 #endif
 #endif
 
 

+ 0 - 6
arch/arm/lib/board.c

@@ -706,9 +706,3 @@ void board_init_r(gd_t *id, ulong dest_addr)
 
 
 	/* NOTREACHED - no way out of command loop except booting */
 	/* NOTREACHED - no way out of command loop except booting */
 }
 }
-
-void hang(void)
-{
-	puts("### ERROR ### Please RESET the board ###\n");
-	for (;;);
-}

+ 0 - 5
arch/avr32/lib/board.c

@@ -120,11 +120,6 @@ static int display_banner (void)
 	return 0;
 	return 0;
 }
 }
 
 
-void hang(void)
-{
-	for (;;) ;
-}
-
 static int display_dram_config (void)
 static int display_dram_config (void)
 {
 {
 	int i;
 	int i;

+ 0 - 14
arch/blackfin/lib/board.c

@@ -432,17 +432,3 @@ void board_init_r(gd_t * id, ulong dest_addr)
 	for (;;)
 	for (;;)
 		main_loop();
 		main_loop();
 }
 }
-
-void hang(void)
-{
-#ifdef CONFIG_STATUS_LED
-	status_led_set(STATUS_LED_BOOT, STATUS_LED_OFF);
-	status_led_set(STATUS_LED_CRASH, STATUS_LED_BLINKING);
-#endif
-	puts("### ERROR ### Please RESET the board ###\n");
-	while (1)
-		/* If a JTAG emulator is hooked up, we'll automatically trigger
-		 * a breakpoint in it.  If one isn't, this is just a NOP.
-		 */
-		asm("emuexcpt;");
-}

+ 0 - 7
arch/m68k/lib/board.c

@@ -663,10 +663,3 @@ void board_init_r (gd_t *id, ulong dest_addr)
 
 
 	/* NOTREACHED - no way out of command loop except booting */
 	/* NOTREACHED - no way out of command loop except booting */
 }
 }
-
-
-void hang(void)
-{
-	puts ("### ERROR ### Please RESET the board ###\n");
-	for (;;);
-}

+ 4 - 0
arch/microblaze/include/asm/processor.h

@@ -31,4 +31,8 @@ extern char __text_start[];
 /* Microblaze board initialization function */
 /* Microblaze board initialization function */
 void board_init(void);
 void board_init(void);
 
 
+/* Watchdog functions */
+extern int hw_watchdog_init(void);
+extern void hw_watchdog_disable(void);
+
 #endif /* __ASM_MICROBLAZE_PROCESSOR_H */
 #endif /* __ASM_MICROBLAZE_PROCESSOR_H */

+ 30 - 35
arch/microblaze/lib/board.c

@@ -61,6 +61,9 @@ init_fnc_t *init_sequence[] = {
 	serial_init,
 	serial_init,
 	console_init_f,
 	console_init_f,
 	interrupts_init,
 	interrupts_init,
+#ifdef CONFIG_XILINX_TB_WATCHDOG
+	hw_watchdog_init,
+#endif
 	timer_init,
 	timer_init,
 	NULL,
 	NULL,
 };
 };
@@ -71,15 +74,15 @@ void board_init_f(ulong not_used)
 {
 {
 	bd_t *bd;
 	bd_t *bd;
 	init_fnc_t **init_fnc_ptr;
 	init_fnc_t **init_fnc_ptr;
-	gd = (gd_t *) (CONFIG_SYS_SDRAM_BASE + CONFIG_SYS_GBL_DATA_OFFSET);
-	bd = (bd_t *) (CONFIG_SYS_SDRAM_BASE + CONFIG_SYS_GBL_DATA_OFFSET \
+	gd = (gd_t *)(CONFIG_SYS_SDRAM_BASE + CONFIG_SYS_GBL_DATA_OFFSET);
+	bd = (bd_t *)(CONFIG_SYS_SDRAM_BASE + CONFIG_SYS_GBL_DATA_OFFSET
 						- GENERATED_BD_INFO_SIZE);
 						- GENERATED_BD_INFO_SIZE);
 #if defined(CONFIG_CMD_FLASH)
 #if defined(CONFIG_CMD_FLASH)
 	ulong flash_size = 0;
 	ulong flash_size = 0;
 #endif
 #endif
 	asm ("nop");	/* FIXME gd is not initialize - wait */
 	asm ("nop");	/* FIXME gd is not initialize - wait */
-	memset ((void *)gd, 0, GENERATED_GBL_DATA_SIZE);
-	memset ((void *)bd, 0, GENERATED_BD_INFO_SIZE);
+	memset((void *)gd, 0, GENERATED_GBL_DATA_SIZE);
+	memset((void *)bd, 0, GENERATED_BD_INFO_SIZE);
 	gd->bd = bd;
 	gd->bd = bd;
 	gd->baudrate = CONFIG_BAUDRATE;
 	gd->baudrate = CONFIG_BAUDRATE;
 	bd->bi_baudrate = CONFIG_BAUDRATE;
 	bd->bi_baudrate = CONFIG_BAUDRATE;
@@ -105,57 +108,55 @@ void board_init_f(ulong not_used)
 	 * aka CONFIG_SYS_MONITOR_BASE - Note there is no need for reloc_off
 	 * aka CONFIG_SYS_MONITOR_BASE - Note there is no need for reloc_off
 	 * as our monitory code is run from SDRAM
 	 * as our monitory code is run from SDRAM
 	 */
 	 */
-	mem_malloc_init (CONFIG_SYS_MALLOC_BASE, CONFIG_SYS_MALLOC_LEN);
+	mem_malloc_init(CONFIG_SYS_MALLOC_BASE, CONFIG_SYS_MALLOC_LEN);
 
 
 	serial_initialize();
 	serial_initialize();
 
 
 	for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {
 	for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {
-		WATCHDOG_RESET ();
-		if ((*init_fnc_ptr) () != 0) {
-			hang ();
-		}
+		WATCHDOG_RESET();
+		if ((*init_fnc_ptr) () != 0)
+			hang();
 	}
 	}
 
 
 #ifdef CONFIG_OF_CONTROL
 #ifdef CONFIG_OF_CONTROL
 	/* For now, put this check after the console is ready */
 	/* For now, put this check after the console is ready */
-	if (fdtdec_prepare_fdt()) {
-		panic("** CONFIG_OF_CONTROL defined but no FDT - please see "
-			"doc/README.fdt-control");
-	} else
+	if (fdtdec_prepare_fdt())
+		panic("** No FDT - please see doc/README.fdt-control");
+	else
 		printf("DTB: 0x%x\n", (u32)gd->fdt_blob);
 		printf("DTB: 0x%x\n", (u32)gd->fdt_blob);
 #endif
 #endif
 
 
-	puts ("SDRAM :\n");
-	printf ("\t\tIcache:%s\n", icache_status() ? "ON" : "OFF");
-	printf ("\t\tDcache:%s\n", dcache_status() ? "ON" : "OFF");
-	printf ("\tU-Boot Start:0x%08x\n", CONFIG_SYS_TEXT_BASE);
+	puts("SDRAM :\n");
+	printf("\t\tIcache:%s\n", icache_status() ? "ON" : "OFF");
+	printf("\t\tDcache:%s\n", dcache_status() ? "ON" : "OFF");
+	printf("\tU-Boot Start:0x%08x\n", CONFIG_SYS_TEXT_BASE);
 
 
 #if defined(CONFIG_CMD_FLASH)
 #if defined(CONFIG_CMD_FLASH)
-	puts ("Flash: ");
+	puts("Flash: ");
 	bd->bi_flashstart = CONFIG_SYS_FLASH_BASE;
 	bd->bi_flashstart = CONFIG_SYS_FLASH_BASE;
 	flash_size = flash_init();
 	flash_size = flash_init();
 	if (bd->bi_flashstart && flash_size > 0) {
 	if (bd->bi_flashstart && flash_size > 0) {
 # ifdef CONFIG_SYS_FLASH_CHECKSUM
 # ifdef CONFIG_SYS_FLASH_CHECKSUM
-		print_size (flash_size, "");
+		print_size(flash_size, "");
 		/*
 		/*
 		 * Compute and print flash CRC if flashchecksum is set to 'y'
 		 * Compute and print flash CRC if flashchecksum is set to 'y'
 		 *
 		 *
 		 * NOTE: Maybe we should add some WATCHDOG_RESET()? XXX
 		 * NOTE: Maybe we should add some WATCHDOG_RESET()? XXX
 		 */
 		 */
 		if (getenv_yesno("flashchecksum") == 1) {
 		if (getenv_yesno("flashchecksum") == 1) {
-			printf ("  CRC: %08X",
-				crc32(0, (const u8 *)bd->bi_flashstart,
-							flash_size)
+			printf("  CRC: %08X",
+			       crc32(0, (const u8 *)bd->bi_flashstart,
+				     flash_size)
 			);
 			);
 		}
 		}
-		putc ('\n');
+		putc('\n');
 # else	/* !CONFIG_SYS_FLASH_CHECKSUM */
 # else	/* !CONFIG_SYS_FLASH_CHECKSUM */
-		print_size (flash_size, "\n");
+		print_size(flash_size, "\n");
 # endif /* CONFIG_SYS_FLASH_CHECKSUM */
 # endif /* CONFIG_SYS_FLASH_CHECKSUM */
 		bd->bi_flashsize = flash_size;
 		bd->bi_flashsize = flash_size;
 		bd->bi_flashoffset = bd->bi_flashstart + flash_size;
 		bd->bi_flashoffset = bd->bi_flashstart + flash_size;
 	} else {
 	} else {
-		puts ("Flash init FAILED");
+		puts("Flash init FAILED");
 		bd->bi_flashstart = 0;
 		bd->bi_flashstart = 0;
 		bd->bi_flashsize = 0;
 		bd->bi_flashsize = 0;
 		bd->bi_flashoffset = 0;
 		bd->bi_flashoffset = 0;
@@ -163,10 +164,10 @@ void board_init_f(ulong not_used)
 #endif
 #endif
 
 
 	/* relocate environment function pointers etc. */
 	/* relocate environment function pointers etc. */
-	env_relocate ();
+	env_relocate();
 
 
 	/* Initialize stdio devices */
 	/* Initialize stdio devices */
-	stdio_init ();
+	stdio_init();
 
 
 	/* Initialize the jump table for applications */
 	/* Initialize the jump table for applications */
 	jumptable_init();
 	jumptable_init();
@@ -190,13 +191,7 @@ void board_init_f(ulong not_used)
 
 
 	/* main_loop */
 	/* main_loop */
 	for (;;) {
 	for (;;) {
-		WATCHDOG_RESET ();
-		main_loop ();
+		WATCHDOG_RESET();
+		main_loop();
 	}
 	}
 }
 }
-
-void hang (void)
-{
-	puts ("### ERROR ### Please RESET the board ###\n");
-	for (;;) ;
-}

+ 0 - 7
arch/mips/lib/board.c

@@ -344,10 +344,3 @@ void board_init_r(gd_t *id, ulong dest_addr)
 
 
 	/* NOTREACHED - no way out of command loop except booting */
 	/* NOTREACHED - no way out of command loop except booting */
 }
 }
-
-void hang(void)
-{
-	puts("### ERROR ### Please RESET the board ###\n");
-	for (;;)
-		;
-}

+ 0 - 7
arch/nds32/lib/board.c

@@ -404,10 +404,3 @@ void board_init_r(gd_t *id, ulong dest_addr)
 
 
 	/* NOTREACHED - no way out of command loop except booting */
 	/* NOTREACHED - no way out of command loop except booting */
 }
 }
-
-void hang(void)
-{
-	puts("### ERROR ### Please RESET the board ###\n");
-	for (;;)
-		;
-}

+ 17 - 29
arch/nios2/lib/board.c

@@ -64,7 +64,6 @@ typedef int (init_fnc_t) (void);
  ***********************************************************************/
  ***********************************************************************/
 
 
 init_fnc_t *init_sequence[] = {
 init_fnc_t *init_sequence[] = {
-
 #if defined(CONFIG_BOARD_EARLY_INIT_F)
 #if defined(CONFIG_BOARD_EARLY_INIT_F)
 	board_early_init_f,	/* Call board-specific init code early.*/
 	board_early_init_f,	/* Call board-specific init code early.*/
 #endif
 #endif
@@ -83,7 +82,7 @@ init_fnc_t *init_sequence[] = {
 
 
 
 
 /***********************************************************************/
 /***********************************************************************/
-void board_init (void)
+void board_init(void)
 {
 {
 	bd_t *bd;
 	bd_t *bd;
 	init_fnc_t **init_fnc_ptr;
 	init_fnc_t **init_fnc_ptr;
@@ -93,7 +92,7 @@ void board_init (void)
 	/* Pointer is writable since we allocated a register for it. */
 	/* Pointer is writable since we allocated a register for it. */
 	gd = &gd_data;
 	gd = &gd_data;
 	/* compiler optimization barrier needed for GCC >= 3.4 */
 	/* compiler optimization barrier needed for GCC >= 3.4 */
-	__asm__ __volatile__("": : :"memory");
+	__asm__ __volatile__("" : : : "memory");
 
 
 	gd->bd = &bd_data;
 	gd->bd = &bd_data;
 	gd->baudrate = CONFIG_BAUDRATE;
 	gd->baudrate = CONFIG_BAUDRATE;
@@ -106,25 +105,24 @@ void board_init (void)
 	bd->bi_flashstart = CONFIG_SYS_FLASH_BASE;
 	bd->bi_flashstart = CONFIG_SYS_FLASH_BASE;
 #endif
 #endif
 #if	defined(CONFIG_SYS_SRAM_BASE) && defined(CONFIG_SYS_SRAM_SIZE)
 #if	defined(CONFIG_SYS_SRAM_BASE) && defined(CONFIG_SYS_SRAM_SIZE)
-	bd->bi_sramstart= CONFIG_SYS_SRAM_BASE;
+	bd->bi_sramstart = CONFIG_SYS_SRAM_BASE;
 	bd->bi_sramsize	= CONFIG_SYS_SRAM_SIZE;
 	bd->bi_sramsize	= CONFIG_SYS_SRAM_SIZE;
 #endif
 #endif
 	bd->bi_baudrate	= CONFIG_BAUDRATE;
 	bd->bi_baudrate	= CONFIG_BAUDRATE;
 
 
 	for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {
 	for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {
-		WATCHDOG_RESET ();
-		if ((*init_fnc_ptr) () != 0) {
-			hang ();
-		}
+		WATCHDOG_RESET();
+		if ((*init_fnc_ptr) () != 0)
+			hang();
 	}
 	}
 
 
-	WATCHDOG_RESET ();
+	WATCHDOG_RESET();
 
 
 	/* The Malloc area is immediately below the monitor copy in RAM */
 	/* The Malloc area is immediately below the monitor copy in RAM */
 	mem_malloc_init(CONFIG_SYS_MALLOC_BASE, CONFIG_SYS_MALLOC_LEN);
 	mem_malloc_init(CONFIG_SYS_MALLOC_BASE, CONFIG_SYS_MALLOC_LEN);
 
 
 #ifndef CONFIG_SYS_NO_FLASH
 #ifndef CONFIG_SYS_NO_FLASH
-	WATCHDOG_RESET ();
+	WATCHDOG_RESET();
 	bd->bi_flashsize = flash_init();
 	bd->bi_flashsize = flash_init();
 #endif
 #endif
 
 
@@ -138,39 +136,29 @@ void board_init (void)
 	mmc_initialize(bd);
 	mmc_initialize(bd);
 #endif
 #endif
 
 
-	WATCHDOG_RESET ();
+	WATCHDOG_RESET();
 	env_relocate();
 	env_relocate();
 
 
-	WATCHDOG_RESET ();
+	WATCHDOG_RESET();
 	stdio_init();
 	stdio_init();
 	jumptable_init();
 	jumptable_init();
 	console_init_r();
 	console_init_r();
 
 
-	WATCHDOG_RESET ();
-	interrupt_init ();
+	WATCHDOG_RESET();
+	interrupt_init();
 
 
 #if defined(CONFIG_BOARD_LATE_INIT)
 #if defined(CONFIG_BOARD_LATE_INIT)
-	board_late_init ();
+	board_late_init();
 #endif
 #endif
 
 
 #if defined(CONFIG_CMD_NET)
 #if defined(CONFIG_CMD_NET)
-	puts ("Net:   ");
-	eth_initialize (bd);
+	puts("Net:   ");
+	eth_initialize(bd);
 #endif
 #endif
 
 
 	/* main_loop */
 	/* main_loop */
 	for (;;) {
 	for (;;) {
-		WATCHDOG_RESET ();
-		main_loop ();
+		WATCHDOG_RESET();
+		main_loop();
 	}
 	}
 }
 }
-
-
-/***********************************************************************/
-
-void hang (void)
-{
-	disable_interrupts ();
-	puts("### ERROR ### Please reset board ###\n");
-	for (;;);
-}

+ 0 - 12
arch/openrisc/lib/board.c

@@ -154,15 +154,3 @@ void board_init(void)
 		main_loop();
 		main_loop();
 	}
 	}
 }
 }
-
-
-/***********************************************************************/
-
-void hang(void)
-{
-	disable_interrupts();
-	puts("### ERROR ### Please reset board ###\n");
-
-	for (;;)
-		;
-}

+ 0 - 6
arch/powerpc/cpu/mpc512x/speed.c

@@ -151,9 +151,3 @@ U_BOOT_CMD(clocks, 1, 0, do_clocks,
 	"print clock configuration",
 	"print clock configuration",
 	"    clocks"
 	"    clocks"
 );
 );
-
-int prt_mpc512x_clks (void)
-{
-	do_clocks (NULL, 0, 0, NULL);
-	return (0);
-}

+ 3 - 0
arch/powerpc/cpu/mpc85xx/cmd_errata.c

@@ -254,6 +254,9 @@ static int do_errata(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 #endif
 #endif
 #ifdef CONFIG_SYS_P4080_ERRATUM_PCIE_A003
 #ifdef CONFIG_SYS_P4080_ERRATUM_PCIE_A003
 	puts("Work-around for Erratum PCIe-A003 enabled\n");
 	puts("Work-around for Erratum PCIe-A003 enabled\n");
+#endif
+#ifdef CONFIG_SYS_FSL_ERRATUM_USB14
+	puts("Work-around for Erratum USB14 enabled\n");
 #endif
 #endif
 	return 0;
 	return 0;
 }
 }

+ 10 - 8
arch/powerpc/cpu/mpc85xx/cpu.c

@@ -281,14 +281,6 @@ unsigned long get_tbclk (void)
 
 
 
 
 #if defined(CONFIG_WATCHDOG)
 #if defined(CONFIG_WATCHDOG)
-void
-watchdog_reset(void)
-{
-	int re_enable = disable_interrupts();
-	reset_85xx_watchdog();
-	if (re_enable) enable_interrupts();
-}
-
 void
 void
 reset_85xx_watchdog(void)
 reset_85xx_watchdog(void)
 {
 {
@@ -297,6 +289,16 @@ reset_85xx_watchdog(void)
 	 */
 	 */
 	mtspr(SPRN_TSR, TSR_WIS);
 	mtspr(SPRN_TSR, TSR_WIS);
 }
 }
+
+void
+watchdog_reset(void)
+{
+	int re_enable = disable_interrupts();
+
+	reset_85xx_watchdog();
+	if (re_enable)
+		enable_interrupts();
+}
 #endif	/* CONFIG_WATCHDOG */
 #endif	/* CONFIG_WATCHDOG */
 
 
 /*
 /*

+ 14 - 0
arch/powerpc/cpu/mpc85xx/cpu_init.c

@@ -623,6 +623,20 @@ skip_l2:
 	}
 	}
 #endif
 #endif
 
 
+#ifdef CONFIG_SYS_FSL_ERRATUM_USB14
+	/* On P204x/P304x/P50x0 Rev1.0, USB transmit will result internal
+	 * multi-bit ECC errors which has impact on performance, so software
+	 * should disable all ECC reporting from USB1 and USB2.
+	 */
+	if (IS_SVR_REV(get_svr(), 1, 0)) {
+		struct dcsr_dcfg_regs *dcfg = (struct dcsr_dcfg_regs *)
+			(CONFIG_SYS_DCSRBAR + CONFIG_SYS_DCSR_DCFG_OFFSET);
+		setbits_be32(&dcfg->ecccr1,
+				(DCSR_DCFG_ECC_DISABLE_USB1 |
+				 DCSR_DCFG_ECC_DISABLE_USB2));
+	}
+#endif
+
 #ifdef CONFIG_FMAN_ENET
 #ifdef CONFIG_FMAN_ENET
 	fman_enet_init();
 	fman_enet_init();
 #endif
 #endif

+ 7 - 0
arch/powerpc/cpu/mpc85xx/fdt.c

@@ -663,6 +663,13 @@ void ft_cpu_setup(void *blob, bd_t *bd)
 #ifdef CONFIG_FSL_CORENET
 #ifdef CONFIG_FSL_CORENET
 	do_fixup_by_compat_u32(blob, "fsl,qoriq-clockgen-1.0",
 	do_fixup_by_compat_u32(blob, "fsl,qoriq-clockgen-1.0",
 		"clock-frequency", CONFIG_SYS_CLK_FREQ, 1);
 		"clock-frequency", CONFIG_SYS_CLK_FREQ, 1);
+	do_fixup_by_compat_u32(blob, "fsl,qoriq-clockgen-2",
+		"clock-frequency", CONFIG_SYS_CLK_FREQ, 1);
+	do_fixup_by_compat_u32(blob, "fsl,mpic",
+		"clock-frequency", get_bus_freq(0)/2, 1);
+#else
+	do_fixup_by_compat_u32(blob, "fsl,mpic",
+		"clock-frequency", get_bus_freq(0), 1);
 #endif
 #endif
 
 
 	fdt_fixup_memory(blob, (u64)bd->bi_memstart, (u64)bd->bi_memsize);
 	fdt_fixup_memory(blob, (u64)bd->bi_memstart, (u64)bd->bi_memsize);

+ 4 - 0
arch/powerpc/cpu/mpc85xx/fsl_corenet_serdes.c

@@ -103,6 +103,10 @@ static const struct {
 	{ 22, 168, FSL_SRDS_BANK_3 },
 	{ 22, 168, FSL_SRDS_BANK_3 },
 	{ 23, 169, FSL_SRDS_BANK_3 },
 	{ 23, 169, FSL_SRDS_BANK_3 },
 #endif
 #endif
+#if SRDS_MAX_BANK > 3
+	{ 24, 175, FSL_SRDS_BANK_4 },
+	{ 25, 176, FSL_SRDS_BANK_4 },
+#endif
 };
 };
 
 
 int serdes_get_lane_idx(int lane)
 int serdes_get_lane_idx(int lane)

+ 10 - 10
arch/powerpc/cpu/mpc85xx/p2041_ids.c

@@ -27,16 +27,16 @@
 #ifdef CONFIG_SYS_DPAA_QBMAN
 #ifdef CONFIG_SYS_DPAA_QBMAN
 struct qportal_info qp_info[CONFIG_SYS_QMAN_NUM_PORTALS] = {
 struct qportal_info qp_info[CONFIG_SYS_QMAN_NUM_PORTALS] = {
 	/* dqrr liodn, frame data liodn, liodn off, sdest */
 	/* dqrr liodn, frame data liodn, liodn off, sdest */
-	SET_QP_INFO(1, 2, 1, 0),
-	SET_QP_INFO(3, 4, 2, 1),
-	SET_QP_INFO(5, 6, 3, 2),
-	SET_QP_INFO(7, 8, 4, 3),
-	SET_QP_INFO(9, 10, 5, 0),
-	SET_QP_INFO(11, 12, 1, 1),
-	SET_QP_INFO(13, 14, 2, 2),
-	SET_QP_INFO(15, 16, 3, 3),
-	SET_QP_INFO(17, 18, 4, 0), /* for now sdest to 0 */
-	SET_QP_INFO(19, 20, 5, 0), /* for now sdest to 0 */
+	SET_QP_INFO(1,  2,  1, 0),
+	SET_QP_INFO(3,  4,  2, 1),
+	SET_QP_INFO(5,  6,  3, 2),
+	SET_QP_INFO(7,  8,  4, 3),
+	SET_QP_INFO(9, 10,  5, 0),
+	SET_QP_INFO(11, 12,  6, 1),
+	SET_QP_INFO(13, 14,  7, 2),
+	SET_QP_INFO(15, 16,  8, 3),
+	SET_QP_INFO(17, 18,  9, 0), /* for now sdest to 0 */
+	SET_QP_INFO(19, 20, 10, 0), /* for now sdest to 0 */
 };
 };
 #endif
 #endif
 
 

+ 10 - 10
arch/powerpc/cpu/mpc85xx/p3041_ids.c

@@ -27,16 +27,16 @@
 #ifdef CONFIG_SYS_DPAA_QBMAN
 #ifdef CONFIG_SYS_DPAA_QBMAN
 struct qportal_info qp_info[CONFIG_SYS_QMAN_NUM_PORTALS] = {
 struct qportal_info qp_info[CONFIG_SYS_QMAN_NUM_PORTALS] = {
 	/* dqrr liodn, frame data liodn, liodn off, sdest */
 	/* dqrr liodn, frame data liodn, liodn off, sdest */
-	SET_QP_INFO(1, 2, 1, 0),
-	SET_QP_INFO(3, 4, 2, 1),
-	SET_QP_INFO(5, 6, 3, 2),
-	SET_QP_INFO(7, 8, 4, 3),
-	SET_QP_INFO(9, 10, 5, 0),
-	SET_QP_INFO(11, 12, 1, 1),
-	SET_QP_INFO(13, 14, 2, 2),
-	SET_QP_INFO(15, 16, 3, 3),
-	SET_QP_INFO(17, 18, 4, 0), /* for now sdest to 0 */
-	SET_QP_INFO(19, 20, 5, 0), /* for now sdest to 0 */
+	SET_QP_INFO(1,  2,  1, 0),
+	SET_QP_INFO(3,  4,  2, 1),
+	SET_QP_INFO(5,  6,  3, 2),
+	SET_QP_INFO(7,  8,  4, 3),
+	SET_QP_INFO(9, 10,  5, 0),
+	SET_QP_INFO(1, 12,  6, 1),
+	SET_QP_INFO(13, 14,  7, 2),
+	SET_QP_INFO(15, 16,  8, 3),
+	SET_QP_INFO(17, 18,  9, 0), /* for now sdest to 0 */
+	SET_QP_INFO(19, 20, 10, 0), /* for now sdest to 0 */
 };
 };
 #endif
 #endif
 
 

+ 10 - 10
arch/powerpc/cpu/mpc85xx/p5020_ids.c

@@ -27,16 +27,16 @@
 #ifdef CONFIG_SYS_DPAA_QBMAN
 #ifdef CONFIG_SYS_DPAA_QBMAN
 struct qportal_info qp_info[CONFIG_SYS_QMAN_NUM_PORTALS] = {
 struct qportal_info qp_info[CONFIG_SYS_QMAN_NUM_PORTALS] = {
 	/* dqrr liodn, frame data liodn, liodn off, sdest */
 	/* dqrr liodn, frame data liodn, liodn off, sdest */
-	SET_QP_INFO(1, 2, 1, 0),
-	SET_QP_INFO(3, 4, 2, 1),
-	SET_QP_INFO(5, 6, 3, 0),
-	SET_QP_INFO(7, 8, 4, 1),
-	SET_QP_INFO(9, 10, 5, 0),
-	SET_QP_INFO(11, 12, 1, 1),
-	SET_QP_INFO(13, 14, 2, 0),
-	SET_QP_INFO(15, 16, 3, 1),
-	SET_QP_INFO(17, 18, 4, 0),
-	SET_QP_INFO(19, 20, 5, 1),
+	SET_QP_INFO(1,  2,  1, 0),
+	SET_QP_INFO(3,  4,  2, 1),
+	SET_QP_INFO(5,  6,  3, 0),
+	SET_QP_INFO(7,  8,  4, 1),
+	SET_QP_INFO(9, 10,  5, 0),
+	SET_QP_INFO(11, 12,  6, 1),
+	SET_QP_INFO(13, 14,  7, 0),
+	SET_QP_INFO(15, 16,  8, 1),
+	SET_QP_INFO(17, 18,  9, 0),
+	SET_QP_INFO(19, 20, 10, 1),
 };
 };
 #endif
 #endif
 
 

+ 17 - 3
arch/powerpc/cpu/mpc85xx/portals.c

@@ -30,11 +30,9 @@
 #include <asm/fsl_portals.h>
 #include <asm/fsl_portals.h>
 #include <asm/fsl_liodn.h>
 #include <asm/fsl_liodn.h>
 
 
-static ccsr_qman_t *qman = (void *)CONFIG_SYS_FSL_QMAN_ADDR;
-static ccsr_bman_t *bman = (void *)CONFIG_SYS_FSL_BMAN_ADDR;
-
 void setup_portals(void)
 void setup_portals(void)
 {
 {
+	ccsr_qman_t *qman = (void *)CONFIG_SYS_FSL_QMAN_ADDR;
 #ifdef CONFIG_FSL_CORENET
 #ifdef CONFIG_FSL_CORENET
 	int i;
 	int i;
 
 
@@ -166,6 +164,20 @@ static int fdt_qportal(void *blob, int off, int id, char *name,
 			num = get_dpaa_liodn(dev, &liodns[0], id);
 			num = get_dpaa_liodn(dev, &liodns[0], id);
 			ret = fdt_setprop(blob, childoff, "fsl,liodn",
 			ret = fdt_setprop(blob, childoff, "fsl,liodn",
 					  &liodns[0], sizeof(u32) * num);
 					  &liodns[0], sizeof(u32) * num);
+			if (!strncmp(name, "pme", 3)) {
+				u32 pme_rev1, pme_rev2;
+				ccsr_pme_t *pme_regs =
+					(void *)CONFIG_SYS_FSL_CORENET_PME_ADDR;
+
+				pme_rev1 = in_be32(&pme_regs->pm_ip_rev_1);
+				pme_rev2 = in_be32(&pme_regs->pm_ip_rev_2);
+				ret = fdt_setprop(blob, childoff,
+					"fsl,pme-rev1", &pme_rev1, sizeof(u32));
+				if (ret < 0)
+					return ret;
+				ret = fdt_setprop(blob, childoff,
+					"fsl,pme-rev2", &pme_rev2, sizeof(u32));
+			}
 #endif
 #endif
 		} else {
 		} else {
 			return childoff;
 			return childoff;
@@ -183,6 +195,7 @@ void fdt_fixup_qportals(void *blob)
 	int off, err;
 	int off, err;
 	unsigned int maj, min;
 	unsigned int maj, min;
 	unsigned int ip_cfg;
 	unsigned int ip_cfg;
+	ccsr_qman_t *qman = (void *)CONFIG_SYS_FSL_QMAN_ADDR;
 	u32 rev_1 = in_be32(&qman->ip_rev_1);
 	u32 rev_1 = in_be32(&qman->ip_rev_1);
 	u32 rev_2 = in_be32(&qman->ip_rev_2);
 	u32 rev_2 = in_be32(&qman->ip_rev_2);
 	char compat[64];
 	char compat[64];
@@ -272,6 +285,7 @@ void fdt_fixup_bportals(void *blob)
 	int off, err;
 	int off, err;
 	unsigned int maj, min;
 	unsigned int maj, min;
 	unsigned int ip_cfg;
 	unsigned int ip_cfg;
+	ccsr_bman_t *bman = (void *)CONFIG_SYS_FSL_BMAN_ADDR;
 	u32 rev_1 = in_be32(&bman->ip_rev_1);
 	u32 rev_1 = in_be32(&bman->ip_rev_1);
 	u32 rev_2 = in_be32(&bman->ip_rev_2);
 	u32 rev_2 = in_be32(&bman->ip_rev_2);
 	char compat[64];
 	char compat[64];

+ 4 - 0
arch/powerpc/cpu/ppc4xx/Makefile

@@ -68,6 +68,10 @@ COBJS	+= miiphy.o
 COBJS	+= uic.o
 COBJS	+= uic.o
 endif
 endif
 
 
+ifdef CONFIG_SPL_BUILD
+COBJS-y += spl_boot.o
+endif
+
 SRCS	:= $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
 SRCS	:= $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
 OBJS	:= $(addprefix $(obj),$(SOBJS) $(COBJS) $(COBJS-y))
 OBJS	:= $(addprefix $(obj),$(SOBJS) $(COBJS) $(COBJS-y))
 START	:= $(addprefix $(obj),$(START))
 START	:= $(addprefix $(obj),$(START))

+ 72 - 0
arch/powerpc/cpu/ppc4xx/spl_boot.c

@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2013 Stefan Roese <sr@denx.de>
+ *
+ * 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.
+ */
+
+#include <common.h>
+#include <spl.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/*
+ * Return selected boot device. On PPC4xx its only NOR flash right now.
+ */
+u32 spl_boot_device(void)
+{
+	return BOOT_DEVICE_NOR;
+}
+
+/*
+ * SPL version of board_init_f()
+ */
+void board_init_f(ulong bootflag)
+{
+	/*
+	 * First we need to initialize the SDRAM, so that the real
+	 * U-Boot or the OS (Linux) can be loaded
+	 */
+	initdram(0);
+
+	/* Clear bss */
+	memset(__bss_start, '\0', __bss_end - __bss_start);
+
+	/*
+	 * Init global_data pointer. Has to be done before calling
+	 * get_clocks(), as it stores some clock values into gd needed
+	 * later on in the serial driver.
+	 */
+	/* Pointer is writable since we allocated a register for it */
+	gd = (gd_t *)(CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_GBL_DATA_OFFSET);
+	/* Clear initial global data */
+	memset((void *)gd, 0, sizeof(gd_t));
+
+	/*
+	 * get_clocks() needs to be called so that the serial driver
+	 * works correctly
+	 */
+	get_clocks();
+
+	/*
+	 * Do rudimental console / serial setup
+	 */
+	preloader_console_init();
+
+	/*
+	 * Call board_init_r() (SPL framework version) to load and boot
+	 * real U-Boot or OS
+	 */
+	board_init_r(NULL, 0);
+	/* Does not return!!! */
+}

+ 33 - 4
arch/powerpc/cpu/ppc4xx/start.S

@@ -232,7 +232,7 @@
  *
  *
  * Use r12 to access the GOT
  * Use r12 to access the GOT
  */
  */
-#if !defined(CONFIG_NAND_SPL)
+#if !defined(CONFIG_NAND_SPL) && !defined(CONFIG_SPL_BUILD)
 	START_GOT
 	START_GOT
 	GOT_ENTRY(_GOT2_TABLE_)
 	GOT_ENTRY(_GOT2_TABLE_)
 	GOT_ENTRY(_FIXUP_TABLE_)
 	GOT_ENTRY(_FIXUP_TABLE_)
@@ -248,7 +248,8 @@
 	END_GOT
 	END_GOT
 #endif /* CONFIG_NAND_SPL */
 #endif /* CONFIG_NAND_SPL */
 
 
-#if defined(CONFIG_NAND_U_BOOT) && !defined(CONFIG_NAND_SPL)
+#if defined(CONFIG_NAND_U_BOOT) && !defined(CONFIG_NAND_SPL) && \
+	!defined(CONFIG_SPL_BUILD)
 	/*
 	/*
 	 * NAND U-Boot image is started from offset 0
 	 * NAND U-Boot image is started from offset 0
 	 */
 	 */
@@ -270,6 +271,18 @@
 	bl	_start_440
 	bl	_start_440
 #endif
 #endif
 
 
+#if defined(CONFIG_SPL) && !defined(CONFIG_SPL_BUILD)
+	/*
+	 * This is the entry of the real U-Boot from a board port
+	 * that supports SPL booting on the PPC4xx. We only need
+	 * to call board_init_f() here. Everything else has already
+	 * been done in the SPL u-boot version.
+	 */
+	GET_GOT			/* initialize GOT access		*/
+	bl	board_init_f	/* run 1st part of board init code (in Flash)*/
+	/* NOTREACHED - board_init_f() does not return */
+#endif
+
 /*
 /*
  * 440 Startup -- on reset only the top 4k of the effective
  * 440 Startup -- on reset only the top 4k of the effective
  * address space is mapped in by an entry in the instruction
  * address space is mapped in by an entry in the instruction
@@ -539,7 +552,7 @@ tlbnx2:	addi	r4,r4,1		/* Next TLB */
  * r3 - 1st arg to board_init(): IMMP pointer
  * r3 - 1st arg to board_init(): IMMP pointer
  * r4 - 2nd arg to board_init(): boot flag
  * r4 - 2nd arg to board_init(): boot flag
  */
  */
-#ifndef CONFIG_NAND_SPL
+#if !defined(CONFIG_NAND_SPL) && !defined(CONFIG_SPL_BUILD)
 	.text
 	.text
 	.long	0x27051956		/* U-Boot Magic Number			*/
 	.long	0x27051956		/* U-Boot Magic Number			*/
 	.globl	version_string
 	.globl	version_string
@@ -612,6 +625,18 @@ _end_of_vectors:
 	.globl	_start
 	.globl	_start
 _start:
 _start:
 
 
+#if defined(CONFIG_SPL) && !defined(CONFIG_SPL_BUILD)
+	/*
+	 * This is the entry of the real U-Boot from a board port
+	 * that supports SPL booting on the PPC4xx. We only need
+	 * to call board_init_f() here. Everything else has already
+	 * been done in the SPL u-boot version.
+	 */
+	GET_GOT			/* initialize GOT access		*/
+	bl	board_init_f	/* run 1st part of board init code (in Flash)*/
+	/* NOTREACHED - board_init_f() does not return */
+#endif
+
 /*****************************************************************************/
 /*****************************************************************************/
 #if defined(CONFIG_440)
 #if defined(CONFIG_440)
 
 
@@ -796,7 +821,9 @@ _start:
 #ifdef CONFIG_NAND_SPL
 #ifdef CONFIG_NAND_SPL
 	bl	nand_boot_common	/* will not return */
 	bl	nand_boot_common	/* will not return */
 #else
 #else
+#ifndef CONFIG_SPL_BUILD
 	GET_GOT
 	GET_GOT
+#endif
 
 
 	bl	cpu_init_f	/* run low-level CPU init code	   (from Flash) */
 	bl	cpu_init_f	/* run low-level CPU init code	   (from Flash) */
 	bl	board_init_f
 	bl	board_init_f
@@ -1080,7 +1107,7 @@ _start:
 	/*----------------------------------------------------------------------- */
 	/*----------------------------------------------------------------------- */
 
 
 
 
-#ifndef CONFIG_NAND_SPL
+#if !defined(CONFIG_NAND_SPL) && !defined(CONFIG_SPL_BUILD)
 /*
 /*
  * This code finishes saving the registers to the exception frame
  * This code finishes saving the registers to the exception frame
  * and jumps to the appropriate handler for the exception.
  * and jumps to the appropriate handler for the exception.
@@ -1262,6 +1289,7 @@ in32r:
 	lwbrx	r3,r0,r3
 	lwbrx	r3,r0,r3
 	blr
 	blr
 
 
+#if !defined(CONFIG_SPL_BUILD)
 /*
 /*
  * void relocate_code (addr_sp, gd, addr_moni)
  * void relocate_code (addr_sp, gd, addr_moni)
  *
  *
@@ -1626,6 +1654,7 @@ __440_msr_continue:
 
 
 	mtlr	r4			/* restore link register	*/
 	mtlr	r4			/* restore link register	*/
 	blr
 	blr
+#endif /* CONFIG_SPL_BUILD */
 
 
 #if defined(CONFIG_440)
 #if defined(CONFIG_440)
 /*----------------------------------------------------------------------------+
 /*----------------------------------------------------------------------------+

+ 74 - 0
arch/powerpc/cpu/ppc4xx/u-boot-spl.lds

@@ -0,0 +1,74 @@
+/*
+ * Copyright 2012-2013 Stefan Roese <sr@denx.de>
+ *
+ * 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
+ */
+
+MEMORY
+{
+	sdram : ORIGIN = CONFIG_SPL_BSS_START_ADDR,
+		LENGTH = CONFIG_SPL_BSS_MAX_SIZE
+	flash : ORIGIN = CONFIG_SPL_TEXT_BASE,
+		LENGTH = CONFIG_SYS_SPL_MAX_LEN
+}
+
+OUTPUT_ARCH(powerpc)
+ENTRY(_start)
+SECTIONS
+{
+#ifdef CONFIG_440
+	.bootpg 0xfffff000 :
+	{
+		arch/powerpc/cpu/ppc4xx/start.o	(.bootpg)
+
+		/*
+		 * PPC440 board need a board specific object with the
+		 * TLB definitions. This needs to get included right after
+		 * start.o, since the first shadow TLB only covers 4k
+		 * of address space.
+		 */
+		CONFIG_BOARDDIR/init.o	(.bootpg)
+	} > flash
+#endif
+
+	.resetvec 0xFFFFFFFC :
+	{
+		KEEP(*(.resetvec))
+	} > flash
+
+	.text :
+	{
+		__start = .;
+		arch/powerpc/cpu/ppc4xx/start.o	(.text)
+		CONFIG_BOARDDIR/init.o	(.text)
+		*(.text*)
+	} > flash
+
+	. = ALIGN(4);
+	.data : { *(SORT_BY_ALIGNMENT(.data*)) } > flash
+
+	. = ALIGN(4);
+	.rodata : { *(SORT_BY_ALIGNMENT(.rodata*)) } > flash
+
+	.bss :
+	{
+		. = ALIGN(4);
+		__bss_start = .;
+		*(.bss*)
+		. = ALIGN(4);
+		__bss_end = .;
+	} > sdram
+}

+ 2 - 0
arch/powerpc/cpu/ppc4xx/u-boot.lds

@@ -96,6 +96,7 @@ SECTIONS
   . = ALIGN(256);
   . = ALIGN(256);
   __init_end = .;
   __init_end = .;
 
 
+#ifndef CONFIG_SPL
 #ifdef CONFIG_440
 #ifdef CONFIG_440
   .bootpg RESET_VECTOR_ADDRESS - 0xffc :
   .bootpg RESET_VECTOR_ADDRESS - 0xffc :
   {
   {
@@ -132,6 +133,7 @@ SECTIONS
 #if (RESET_VECTOR_ADDRESS == 0xfffffffc)
 #if (RESET_VECTOR_ADDRESS == 0xfffffffc)
   . |= 0x10;
   . |= 0x10;
 #endif
 #endif
+#endif /* CONFIG_SPL */
 
 
   __bss_start = .;
   __bss_start = .;
   .bss (NOLOAD)       :
   .bss (NOLOAD)       :

+ 9 - 3
arch/powerpc/include/asm/config_mpc85xx.h

@@ -333,7 +333,9 @@
 #define CONFIG_SYS_FSL_USB_INTERNAL_UTMI_PHY
 #define CONFIG_SYS_FSL_USB_INTERNAL_UTMI_PHY
 #define CONFIG_SYS_FSL_ERRATUM_ESDHC111
 #define CONFIG_SYS_FSL_ERRATUM_ESDHC111
 #define CONFIG_SYS_FSL_ERRATUM_NMG_CPU_A011
 #define CONFIG_SYS_FSL_ERRATUM_NMG_CPU_A011
+#define CONFIG_SYS_FSL_ERRATUM_USB14
 #define CONFIG_SYS_FSL_ERRATUM_CPU_A003999
 #define CONFIG_SYS_FSL_ERRATUM_CPU_A003999
+#define CONFIG_SYS_FSL_ERRATUM_DDR_A003
 #define CONFIG_SYS_FSL_ERRATUM_DDR_A003474
 #define CONFIG_SYS_FSL_ERRATUM_DDR_A003474
 #define CONFIG_SYS_FSL_SRIO_PCIE_BOOT_MASTER
 #define CONFIG_SYS_FSL_SRIO_PCIE_BOOT_MASTER
 #define CONFIG_SYS_FSL_SRIO_MAX_PORTS	2
 #define CONFIG_SYS_FSL_SRIO_MAX_PORTS	2
@@ -365,7 +367,9 @@
 #define CONFIG_SYS_FSL_USB_INTERNAL_UTMI_PHY
 #define CONFIG_SYS_FSL_USB_INTERNAL_UTMI_PHY
 #define CONFIG_SYS_FSL_ERRATUM_ESDHC111
 #define CONFIG_SYS_FSL_ERRATUM_ESDHC111
 #define CONFIG_SYS_FSL_ERRATUM_NMG_CPU_A011
 #define CONFIG_SYS_FSL_ERRATUM_NMG_CPU_A011
+#define CONFIG_SYS_FSL_ERRATUM_USB14
 #define CONFIG_SYS_FSL_ERRATUM_CPU_A003999
 #define CONFIG_SYS_FSL_ERRATUM_CPU_A003999
+#define CONFIG_SYS_FSL_ERRATUM_DDR_A003
 #define CONFIG_SYS_FSL_ERRATUM_DDR_A003474
 #define CONFIG_SYS_FSL_ERRATUM_DDR_A003474
 #define CONFIG_SYS_FSL_SRIO_PCIE_BOOT_MASTER
 #define CONFIG_SYS_FSL_SRIO_PCIE_BOOT_MASTER
 #define CONFIG_SYS_FSL_SRIO_MAX_PORTS	2
 #define CONFIG_SYS_FSL_SRIO_MAX_PORTS	2
@@ -442,6 +446,8 @@
 #define CONFIG_SYS_FSL_USB2_PHY_ENABLE
 #define CONFIG_SYS_FSL_USB2_PHY_ENABLE
 #define CONFIG_SYS_FSL_USB_INTERNAL_UTMI_PHY
 #define CONFIG_SYS_FSL_USB_INTERNAL_UTMI_PHY
 #define CONFIG_SYS_FSL_ERRATUM_ESDHC111
 #define CONFIG_SYS_FSL_ERRATUM_ESDHC111
+#define CONFIG_SYS_FSL_ERRATUM_USB14
+#define CONFIG_SYS_FSL_ERRATUM_DDR_A003
 #define CONFIG_SYS_FSL_ERRATUM_DDR_A003474
 #define CONFIG_SYS_FSL_ERRATUM_DDR_A003474
 #define CONFIG_SYS_FSL_SRIO_PCIE_BOOT_MASTER
 #define CONFIG_SYS_FSL_SRIO_PCIE_BOOT_MASTER
 #define CONFIG_SYS_FSL_SRIO_MAX_PORTS	2
 #define CONFIG_SYS_FSL_SRIO_MAX_PORTS	2
@@ -473,7 +479,7 @@
 #define CONFIG_SYS_FSL_USB2_PHY_ENABLE
 #define CONFIG_SYS_FSL_USB2_PHY_ENABLE
 #define CONFIG_SYS_FSL_USB_INTERNAL_UTMI_PHY
 #define CONFIG_SYS_FSL_USB_INTERNAL_UTMI_PHY
 #define CONFIG_SYS_FSL_ERRATUM_ESDHC111
 #define CONFIG_SYS_FSL_ERRATUM_ESDHC111
-#define CONFIG_SYS_FSL_ERRATUM_USB138
+#define CONFIG_SYS_FSL_ERRATUM_USB14
 #define CONFIG_SYS_FSL_ERRATUM_DDR_A003
 #define CONFIG_SYS_FSL_ERRATUM_DDR_A003
 #define CONFIG_SYS_FSL_ERRATUM_DDR_A003474
 #define CONFIG_SYS_FSL_ERRATUM_DDR_A003474
 #define CONFIG_SYS_FSL_ERRATUM_A004699
 #define CONFIG_SYS_FSL_ERRATUM_A004699
@@ -490,7 +496,6 @@
 #define CONFIG_NUM_DDR_CONTROLLERS	1
 #define CONFIG_NUM_DDR_CONTROLLERS	1
 #define CONFIG_SYS_CCSRBAR_DEFAULT	0xff700000
 #define CONFIG_SYS_CCSRBAR_DEFAULT	0xff700000
 #define CONFIG_NAND_FSL_IFC
 #define CONFIG_NAND_FSL_IFC
-#define CONFIG_SYS_FSL_ERRATUM_IFC_A003399
 #define CONFIG_SYS_FSL_ERRATUM_ESDHC111
 #define CONFIG_SYS_FSL_ERRATUM_ESDHC111
 
 
 #elif defined(CONFIG_BSC9132)
 #elif defined(CONFIG_BSC9132)
@@ -503,7 +508,6 @@
 #define CONFIG_NUM_DDR_CONTROLLERS	2
 #define CONFIG_NUM_DDR_CONTROLLERS	2
 #define CONFIG_SYS_CCSRBAR_DEFAULT	0xff700000
 #define CONFIG_SYS_CCSRBAR_DEFAULT	0xff700000
 #define CONFIG_NAND_FSL_IFC
 #define CONFIG_NAND_FSL_IFC
-#define CONFIG_SYS_FSL_ERRATUM_IFC_A003399
 #define CONFIG_SYS_FSL_ERRATUM_ESDHC111
 #define CONFIG_SYS_FSL_ERRATUM_ESDHC111
 #define CONFIG_SYS_FSL_ESDHC_P1010_BROKEN_SDCLK
 #define CONFIG_SYS_FSL_ESDHC_P1010_BROKEN_SDCLK
 #define CONFIG_SYS_FSL_PCIE_COMPAT	"fsl,qoriq-pcie-v2.2"
 #define CONFIG_SYS_FSL_PCIE_COMPAT	"fsl,qoriq-pcie-v2.2"
@@ -560,6 +564,7 @@
 #define CONFIG_SYS_FSL_PCIE_COMPAT	"fsl,qoriq-pcie-v2.4"
 #define CONFIG_SYS_FSL_PCIE_COMPAT	"fsl,qoriq-pcie-v2.4"
 #define CONFIG_SYS_FSL_USB1_PHY_ENABLE
 #define CONFIG_SYS_FSL_USB1_PHY_ENABLE
 #define CONFIG_SYS_FSL_ERRATUM_A_004934
 #define CONFIG_SYS_FSL_ERRATUM_A_004934
+#define CONFIG_SYS_FSL_ERRATUM_A005871
 #define CONFIG_SYS_CCSRBAR_DEFAULT	0xfe000000
 #define CONFIG_SYS_CCSRBAR_DEFAULT	0xfe000000
 
 
 #elif defined(CONFIG_PPC_B4860)
 #elif defined(CONFIG_PPC_B4860)
@@ -585,6 +590,7 @@
 #define CONFIG_SYS_FSL_SRIO_IB_WIN_NUM	5
 #define CONFIG_SYS_FSL_SRIO_IB_WIN_NUM	5
 #define CONFIG_SYS_FSL_USB1_PHY_ENABLE
 #define CONFIG_SYS_FSL_USB1_PHY_ENABLE
 #define CONFIG_SYS_FSL_ERRATUM_A_004934
 #define CONFIG_SYS_FSL_ERRATUM_A_004934
+#define CONFIG_SYS_FSL_ERRATUM_A005871
 #define CONFIG_SYS_CCSRBAR_DEFAULT	0xfe000000
 #define CONFIG_SYS_CCSRBAR_DEFAULT	0xfe000000
 
 
 #else
 #else

+ 4 - 0
arch/powerpc/include/asm/fsl_memac.h

@@ -222,6 +222,10 @@ struct memac {
 
 
 /* IF_MODE - Interface Mode Register */
 /* IF_MODE - Interface Mode Register */
 #define IF_MODE_EN_AUTO	0x00008000 /* 1 - Enable automatic speed selection */
 #define IF_MODE_EN_AUTO	0x00008000 /* 1 - Enable automatic speed selection */
+#define IF_MODE_SETSP_100M	0x00000000 /* 00 - 100Mbps RGMII */
+#define IF_MODE_SETSP_10M	0x00002000 /* 01 - 10Mbps RGMII */
+#define IF_MODE_SETSP_1000M	0x00004000 /* 10 - 1000Mbps RGMII */
+#define IF_MODE_SETSP_MASK	0x00006000 /* setsp mask bits */
 #define IF_MODE_XGMII	0x00000000 /* 00- XGMII(10) interface mode */
 #define IF_MODE_XGMII	0x00000000 /* 00- XGMII(10) interface mode */
 #define IF_MODE_GMII		0x00000002 /* 10- GMII interface mode */
 #define IF_MODE_GMII		0x00000002 /* 10- GMII interface mode */
 #define IF_MODE_MASK	0x00000003 /* mask for mode interface mode */
 #define IF_MODE_MASK	0x00000003 /* mask for mode interface mode */

+ 11 - 1
arch/powerpc/include/asm/immap_85xx.h

@@ -2914,7 +2914,8 @@ struct ccsr_pman {
 #define CONFIG_SYS_MPC85xx_IFC_OFFSET		0x124000
 #define CONFIG_SYS_MPC85xx_IFC_OFFSET		0x124000
 #define CONFIG_SYS_MPC85xx_GPIO_OFFSET		0x130000
 #define CONFIG_SYS_MPC85xx_GPIO_OFFSET		0x130000
 #define CONFIG_SYS_FSL_CORENET_RMAN_OFFSET	0x1e0000
 #define CONFIG_SYS_FSL_CORENET_RMAN_OFFSET	0x1e0000
-#ifdef CONFIG_SYS_FSL_QORIQ_CHASSIS2
+#if defined(CONFIG_SYS_FSL_QORIQ_CHASSIS2) && !defined(CONFIG_PPC_B4860)\
+	&& !defined(CONFIG_PPC_B4420)
 #define CONFIG_SYS_MPC85xx_PCIE1_OFFSET		0x240000
 #define CONFIG_SYS_MPC85xx_PCIE1_OFFSET		0x240000
 #define CONFIG_SYS_MPC85xx_PCIE2_OFFSET		0x250000
 #define CONFIG_SYS_MPC85xx_PCIE2_OFFSET		0x250000
 #define CONFIG_SYS_MPC85xx_PCIE3_OFFSET		0x260000
 #define CONFIG_SYS_MPC85xx_PCIE3_OFFSET		0x260000
@@ -3160,4 +3161,13 @@ struct ccsr_cluster_l2 {
 #define CONFIG_SYS_FSL_CLUSTER_1_L2 \
 #define CONFIG_SYS_FSL_CLUSTER_1_L2 \
 	(CONFIG_SYS_IMMR + CONFIG_SYS_FSL_CLUSTER_1_L2_OFFSET)
 	(CONFIG_SYS_IMMR + CONFIG_SYS_FSL_CLUSTER_1_L2_OFFSET)
 #endif /* CONFIG_SYS_FSL_QORIQ_CHASSIS2 */
 #endif /* CONFIG_SYS_FSL_QORIQ_CHASSIS2 */
+
+#define	CONFIG_SYS_DCSR_DCFG_OFFSET	0X20000
+struct dcsr_dcfg_regs {
+	u8  res_0[0x520];
+	u32 ecccr1;
+#define	DCSR_DCFG_ECC_DISABLE_USB1	0x00008000
+#define	DCSR_DCFG_ECC_DISABLE_USB2	0x00004000
+	u8  res_524[0x1000 - 0x524]; /* 0x524 - 0x1000 */
+};
 #endif /*__IMMAP_85xx__*/
 #endif /*__IMMAP_85xx__*/

+ 0 - 9
arch/powerpc/lib/board.c

@@ -1050,15 +1050,6 @@ void board_init_r(gd_t *id, ulong dest_addr)
 	/* NOTREACHED - no way out of command loop except booting */
 	/* NOTREACHED - no way out of command loop except booting */
 }
 }
 
 
-void hang(void)
-{
-	puts("### ERROR ### Please RESET the board ###\n");
-	bootstage_error(BOOTSTAGE_ID_NEED_RESET);
-	for (;;)
-		;
-}
-
-
 #if 0	/* We could use plain global data, but the resulting code is bigger */
 #if 0	/* We could use plain global data, but the resulting code is bigger */
 /*
 /*
  * Pointer to initial global data area
  * Pointer to initial global data area

+ 4 - 1
arch/sandbox/config.mk

@@ -18,5 +18,8 @@
 # MA 02111-1307 USA
 # MA 02111-1307 USA
 
 
 PLATFORM_CPPFLAGS += -DCONFIG_SANDBOX -D__SANDBOX__ -U_FORTIFY_SOURCE
 PLATFORM_CPPFLAGS += -DCONFIG_SANDBOX -D__SANDBOX__ -U_FORTIFY_SOURCE
-PLATFORM_CPPFLAGS += -DCONFIG_ARCH_MAP_SYSMEM
+PLATFORM_CPPFLAGS += -DCONFIG_ARCH_MAP_SYSMEM -DCONFIG_SYS_GENERIC_BOARD
 PLATFORM_LIBS += -lrt
 PLATFORM_LIBS += -lrt
+
+# Support generic board on sandbox
+__HAVE_ARCH_GENERIC_BOARD := y

+ 5 - 0
arch/sandbox/cpu/cpu.c

@@ -57,6 +57,11 @@ void *map_physmem(phys_addr_t paddr, unsigned long len, unsigned long flags)
 	return (void *)(gd->arch.ram_buf + paddr);
 	return (void *)(gd->arch.ram_buf + paddr);
 }
 }
 
 
+phys_addr_t map_to_sysmem(void *ptr)
+{
+	return (u8 *)ptr - gd->arch.ram_buf;
+}
+
 void flush_dcache_range(unsigned long start, unsigned long stop)
 void flush_dcache_range(unsigned long start, unsigned long stop)
 {
 {
 }
 }

+ 8 - 1
arch/sandbox/cpu/start.c

@@ -90,7 +90,7 @@ int sandbox_main_loop_init(void)
 
 
 	/* Execute command if required */
 	/* Execute command if required */
 	if (state->cmd) {
 	if (state->cmd) {
-		run_command(state->cmd, 0);
+		run_command_list(state->cmd, -1, 0);
 		os_exit(state->exit_type);
 		os_exit(state->exit_type);
 	}
 	}
 
 
@@ -104,6 +104,13 @@ static int sb_cmdline_cb_command(struct sandbox_state *state, const char *arg)
 }
 }
 SB_CMDLINE_OPT_SHORT(command, 'c', 1, "Execute U-Boot command");
 SB_CMDLINE_OPT_SHORT(command, 'c', 1, "Execute U-Boot command");
 
 
+static int sb_cmdline_cb_fdt(struct sandbox_state *state, const char *arg)
+{
+	state->fdt_fname = arg;
+	return 0;
+}
+SB_CMDLINE_OPT_SHORT(fdt, 'd', 1, "Specify U-Boot's control FDT");
+
 int main(int argc, char *argv[])
 int main(int argc, char *argv[])
 {
 {
 	struct sandbox_state *state;
 	struct sandbox_state *state;

+ 8 - 0
arch/sandbox/include/asm/io.h

@@ -20,6 +20,9 @@
  * MA 02111-1307 USA
  * MA 02111-1307 USA
  */
  */
 
 
+#ifndef __SANDBOX_ASM_IO_H
+#define __SANDBOX_ASM_IO_H
+
 /*
 /*
  * Given a physical address and a length, return a virtual address
  * Given a physical address and a length, return a virtual address
  * that can be used to access the memory range with the caching
  * that can be used to access the memory range with the caching
@@ -49,3 +52,8 @@ static inline void *map_sysmem(phys_addr_t paddr, unsigned long len)
 static inline void unmap_sysmem(const void *vaddr)
 static inline void unmap_sysmem(const void *vaddr)
 {
 {
 }
 }
+
+/* Map from a pointer to our RAM buffer */
+phys_addr_t map_to_sysmem(void *ptr);
+
+#endif

+ 1 - 0
arch/sandbox/include/asm/state.h

@@ -34,6 +34,7 @@ enum exit_type_id {
 /* The complete state of the test system */
 /* The complete state of the test system */
 struct sandbox_state {
 struct sandbox_state {
 	const char *cmd;		/* Command to execute */
 	const char *cmd;		/* Command to execute */
+	const char *fdt_fname;		/* Filename of FDT binary */
 	enum exit_type_id exit_type;	/* How we exited U-Boot */
 	enum exit_type_id exit_type;	/* How we exited U-Boot */
 	const char *parse_err;		/* Error to report from parsing */
 	const char *parse_err;		/* Error to report from parsing */
 	int argc;			/* Program arguments */
 	int argc;			/* Program arguments */

+ 2 - 20
arch/sandbox/include/asm/u-boot.h

@@ -36,26 +36,8 @@
 #ifndef _U_BOOT_H_
 #ifndef _U_BOOT_H_
 #define _U_BOOT_H_	1
 #define _U_BOOT_H_	1
 
 
-typedef struct bd_info {
-	unsigned long	bi_memstart;	/* start of DRAM memory */
-	phys_size_t	bi_memsize;	/* size	 of DRAM memory in bytes */
-	unsigned long	bi_flashstart;	/* start of FLASH memory */
-	unsigned long	bi_flashsize;	/* size	 of FLASH memory */
-	unsigned long	bi_flashoffset; /* reserved area for startup monitor */
-	unsigned long	bi_sramstart;	/* start of SRAM memory */
-	unsigned long	bi_sramsize;	/* size	 of SRAM memory */
-	unsigned long	bi_bootflags;	/* boot / reboot flag (for LynxOS) */
-	unsigned short	bi_ethspeed;	/* Ethernet speed in Mbps */
-	unsigned long	bi_intfreq;	/* Internal Freq, in MHz */
-	unsigned long	bi_busfreq;	/* Bus Freq, in MHz */
-	unsigned int	bi_baudrate;	/* Console Baudrate */
-	unsigned long   bi_boot_params;	/* where this board expects params */
-	struct				/* RAM configuration */
-	{
-		ulong start;
-		ulong size;
-	} bi_dram[CONFIG_NR_DRAM_BANKS];
-} bd_t;
+/* Use the generic board which requires a unified bd_info */
+#include <asm-generic/u-boot.h>
 
 
 /* For image.h:image_check_target_arch() */
 /* For image.h:image_check_target_arch() */
 #define IH_ARCH_DEFAULT IH_ARCH_SANDBOX
 #define IH_ARCH_DEFAULT IH_ARCH_SANDBOX

+ 0 - 1
arch/sandbox/lib/Makefile

@@ -27,7 +27,6 @@ include $(TOPDIR)/config.mk
 
 
 LIB	= $(obj)lib$(ARCH).o
 LIB	= $(obj)lib$(ARCH).o
 
 
-COBJS-y	+= board.o
 COBJS-y	+= interrupts.o
 COBJS-y	+= interrupts.o
 
 
 SRCS	:= $(COBJS-y:.o=.c)
 SRCS	:= $(COBJS-y:.o=.c)

+ 0 - 285
arch/sandbox/lib/board.c

@@ -1,285 +0,0 @@
-/*
- * Copyright (c) 2011 The Chromium OS Authors.
- *
- * (C) Copyright 2002-2006
- * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
- *
- * (C) Copyright 2002
- * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
- * Marius Groeger <mgroeger@sysgo.de>
- *
- * 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
- */
-
-/*
- * This file was taken from ARM and changed to remove things we don't
- * need. This is most of it, so have tried to avoid being over-zealous!
- * For example, we want to have an emulation of the 'DRAM' used by
- * U-Boot.
- *
- * has been talk upstream of unifying the architectures w.r.t board.c,
- * so the less change here the better.
- */
-
-#include <common.h>
-#include <command.h>
-#include <malloc.h>
-#include <stdio_dev.h>
-#include <timestamp.h>
-#include <version.h>
-#include <serial.h>
-
-#include <os.h>
-
-DECLARE_GLOBAL_DATA_PTR;
-
-static gd_t gd_mem;
-
-/************************************************************************
- * Init Utilities							*
- ************************************************************************
- * Some of this code should be moved into the core functions,
- * or dropped completely,
- * but let's get it working (again) first...
- */
-
-static int display_banner(void)
-{
-	display_options();
-
-	return 0;
-}
-
-/**
- * Configure and report on the DRAM configuration, which in our case is
- * fairly simple.
- */
-static int display_dram_config(void)
-{
-	ulong size = 0;
-	int i;
-
-	debug("RAM Configuration:\n");
-
-	for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
-#ifdef DEBUG
-		printf("Bank #%d: %08lx ", i, gd->bd->bi_dram[i].start);
-		print_size(gd->bd->bi_dram[i].size, "\n");
-#endif
-		size += gd->bd->bi_dram[i].size;
-	}
-	puts("DRAM:  ");
-	print_size(size, "\n");
-	return 0;
-}
-
-/*
- * Breathe some life into the board...
- *
- * Initialize a serial port as console, and carry out some hardware
- * tests.
- *
- * The first part of initialization is running from Flash memory;
- * its main purpose is to initialize the RAM so that we
- * can relocate the monitor code to RAM.
- */
-
-/*
- * All attempts to come up with a "common" initialization sequence
- * that works for all boards and architectures failed: some of the
- * requirements are just _too_ different. To get rid of the resulting
- * mess of board dependent #ifdef'ed code we now make the whole
- * initialization sequence configurable to the user.
- *
- * The requirements for any new initalization function is simple: it
- * receives a pointer to the "global data" structure as it's only
- * argument, and returns an integer return code, where 0 means
- * "continue" and != 0 means "fatal error, hang the system".
- */
-typedef int (init_fnc_t) (void);
-
-void __dram_init_banksize(void)
-{
-	gd->bd->bi_dram[0].start = 0;
-	gd->bd->bi_dram[0].size =  gd->ram_size;
-}
-
-void dram_init_banksize(void)
-	__attribute__((weak, alias("__dram_init_banksize")));
-
-init_fnc_t *init_sequence[] = {
-#if defined(CONFIG_ARCH_CPU_INIT)
-	arch_cpu_init,		/* basic arch cpu dependent setup */
-#endif
-#if defined(CONFIG_BOARD_EARLY_INIT_F)
-	board_early_init_f,
-#endif
-	timer_init,		/* initialize timer */
-	env_init,		/* initialize environment */
-	serial_init,		/* serial communications setup */
-	console_init_f,		/* stage 1 init of console */
-	sandbox_early_getopt_check,	/* process command line flags (err/help) */
-	display_banner,		/* say that we are here */
-#if defined(CONFIG_DISPLAY_CPUINFO)
-	print_cpuinfo,		/* display cpu info (and speed) */
-#endif
-#if defined(CONFIG_DISPLAY_BOARDINFO)
-	checkboard,		/* display board info */
-#endif
-	dram_init,		/* configure available RAM banks */
-	NULL,
-};
-
-void board_init_f(ulong bootflag)
-{
-	init_fnc_t **init_fnc_ptr;
-	uchar *mem;
-	unsigned long addr_sp, addr, size;
-
-	gd = &gd_mem;
-	assert(gd);
-
-	memset((void *)gd, 0, sizeof(gd_t));
-
-#if defined(CONFIG_OF_EMBED)
-	/* Get a pointer to the FDT */
-	gd->fdt_blob = _binary_dt_dtb_start;
-#elif defined(CONFIG_OF_SEPARATE)
-	/* FDT is at end of image */
-	gd->fdt_blob = (void *)(_end_ofs + _TEXT_BASE);
-#endif
-
-	for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {
-		if ((*init_fnc_ptr)() != 0)
-			hang();
-	}
-
-	size = CONFIG_SYS_SDRAM_SIZE;
-	mem = os_malloc(CONFIG_SYS_SDRAM_SIZE);
-
-	assert(mem);
-	gd->arch.ram_buf = mem;
-	addr = (ulong)(mem + size);
-
-	/*
-	 * reserve memory for malloc() arena
-	 */
-	addr_sp = addr - TOTAL_MALLOC_LEN;
-	debug("Reserving %dk for malloc() at: %08lx\n",
-			TOTAL_MALLOC_LEN >> 10, addr_sp);
-	/*
-	 * (permanently) allocate a Board Info struct
-	 * and a permanent copy of the "global" data
-	 */
-	addr_sp -= sizeof(bd_t);
-	gd->bd = (bd_t *) addr_sp;
-	debug("Reserving %zu Bytes for Board Info at: %08lx\n",
-			sizeof(bd_t), addr_sp);
-
-	/* Ram ist board specific, so move it to board code ... */
-	dram_init_banksize();
-	display_dram_config();	/* and display it */
-
-	/* We don't relocate, so just run the post-relocation code */
-	board_init_r(NULL, 0);
-
-	/* NOTREACHED - no way out of command loop except booting */
-}
-
-/************************************************************************
- *
- * This is the next part if the initialization sequence: we are now
- * running from RAM and have a "normal" C environment, i. e. global
- * data can be written, BSS has been cleared, the stack size in not
- * that critical any more, etc.
- *
- ************************************************************************
- */
-
-void board_init_r(gd_t *id, ulong dest_addr)
-{
-
-	if (id)
-		gd = id;
-
-	gd->flags |= GD_FLG_RELOC;	/* tell others: relocation done */
-
-	serial_initialize();
-
-#ifdef CONFIG_POST
-	post_output_backlog();
-#endif
-
-	/* The Malloc area is at the top of simulated DRAM */
-	mem_malloc_init((ulong)gd->arch.ram_buf + gd->ram_size -
-			TOTAL_MALLOC_LEN, TOTAL_MALLOC_LEN);
-
-	/* initialize environment */
-	env_relocate();
-
-	stdio_init();	/* get the devices list going. */
-
-	jumptable_init();
-
-	console_init_r();	/* fully init console as a device */
-
-#if defined(CONFIG_DISPLAY_BOARDINFO_LATE)
-	checkboard();
-#endif
-
-#if defined(CONFIG_ARCH_MISC_INIT)
-	/* miscellaneous arch dependent initialisations */
-	arch_misc_init();
-#endif
-#if defined(CONFIG_MISC_INIT_R)
-	/* miscellaneous platform dependent initialisations */
-	misc_init_r();
-#endif
-
-	 /* set up exceptions */
-	interrupt_init();
-	/* enable exceptions */
-	enable_interrupts();
-
-#ifdef CONFIG_BOARD_LATE_INIT
-	board_late_init();
-#endif
-
-#ifdef CONFIG_POST
-	post_run(NULL, POST_RAM | post_bootmode_get(0));
-#endif
-
-	sandbox_main_loop_init();
-
-	/*
-	 * For now, run the main loop. Later we might let this be done
-	 * in the main program.
-	 */
-	while (1)
-		main_loop();
-
-	/* NOTREACHED - no way out of command loop except booting */
-}
-
-void hang(void)
-{
-	puts("### ERROR ### Please RESET the board ###\n");
-	for (;;)
-		;
-}

+ 0 - 9
arch/sh/lib/board.c

@@ -200,12 +200,3 @@ void sh_generic_init(void)
 		main_loop();
 		main_loop();
 	}
 	}
 }
 }
-
-/***********************************************************************/
-
-void hang(void)
-{
-	puts("Board ERROR\n");
-	for (;;)
-		;
-}

+ 0 - 9
arch/sparc/lib/board.c

@@ -411,13 +411,4 @@ void board_init_f(ulong bootflag)
 
 
 }
 }
 
 
-void hang(void)
-{
-	puts("### ERROR ### Please RESET the board ###\n");
-#ifdef CONFIG_SHOW_BOOT_PROGRESS
-	bootstage_error(BOOTSTAGE_ID_NEED_RESET);
-#endif
-	for (;;) ;
-}
-
 /************************************************************************/
 /************************************************************************/

+ 0 - 7
arch/x86/lib/board.c

@@ -264,10 +264,3 @@ void board_init_r(gd_t *id, ulong dest_addr)
 
 
 	/* NOTREACHED - no way out of command loop except booting */
 	/* NOTREACHED - no way out of command loop except booting */
 }
 }
-
-void hang(void)
-{
-	puts("### ERROR ### Please RESET the board ###\n");
-	for (;;)
-		;
-}

+ 20 - 6
board/a3m071/a3m071.c

@@ -8,7 +8,7 @@
  * (C) Copyright 2006
  * (C) Copyright 2006
  * MicroSys GmbH
  * MicroSys GmbH
  *
  *
- * Copyright 2012 Stefan Roese <sr@denx.de>
+ * Copyright 2012-2013 Stefan Roese <sr@denx.de>
  *
  *
  * See file CREDITS for list of people who contributed to this
  * See file CREDITS for list of people who contributed to this
  * project.
  * project.
@@ -241,12 +241,26 @@ void spl_board_init(void)
 
 
 	/* And write new value back to register */
 	/* And write new value back to register */
 	out_be32(&mm->ipbi_ws_ctrl, val);
 	out_be32(&mm->ipbi_ws_ctrl, val);
-#endif
 
 
-	/*
-	 * No need to change the pin multiplexing (MPC5XXX_GPS_PORT_CONFIG)
-	 * as all 3 config versions (failsave level) have the same setup.
-	 */
+
+	/* Setup pin multiplexing */
+	if (failsavelevel == 2) {
+		/* fpga-version ok */
+#if defined(CONFIG_SYS_GPS_PORT_CONFIG_2)
+		out_be32(&gpio->port_config, CONFIG_SYS_GPS_PORT_CONFIG_2);
+#endif
+	} else if (failsavelevel == 1) {
+		/* digiboard-version ok - fpga not */
+#if defined(CONFIG_SYS_GPS_PORT_CONFIG_1)
+		out_be32(&gpio->port_config, CONFIG_SYS_GPS_PORT_CONFIG_1);
+#endif
+	} else {
+		/* full failsave-mode */
+#if defined(CONFIG_SYS_GPS_PORT_CONFIG)
+		out_be32(&gpio->port_config, CONFIG_SYS_GPS_PORT_CONFIG);
+#endif
+	}
+#endif
 
 
 	/*
 	/*
 	 * Setup gpio_wkup_7 as watchdog AS INPUT to disable it - see
 	 * Setup gpio_wkup_7 as watchdog AS INPUT to disable it - see

+ 17 - 2
board/freescale/b4860qds/tlb.c

@@ -111,8 +111,6 @@ struct fsl_e_tlb_entry tlb_table[] = {
 #ifdef CONFIG_SYS_NAND_BASE
 #ifdef CONFIG_SYS_NAND_BASE
 	/*
 	/*
 	 * *I*G - NAND
 	 * *I*G - NAND
-	 * entry 14 and 15 has been used hard coded, they will be disabled
-	 * in cpu_init_f, so we use entry 16 for nand.
 	 */
 	 */
 	SET_TLB_ENTRY(1, CONFIG_SYS_NAND_BASE, CONFIG_SYS_NAND_BASE_PHYS,
 	SET_TLB_ENTRY(1, CONFIG_SYS_NAND_BASE, CONFIG_SYS_NAND_BASE_PHYS,
 			MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
 			MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
@@ -122,6 +120,23 @@ struct fsl_e_tlb_entry tlb_table[] = {
 		      MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
 		      MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
 		      0, 12, BOOKE_PAGESZ_4K, 1),
 		      0, 12, BOOKE_PAGESZ_4K, 1),
 
 
+	/*
+	 * *I*G - SRIO
+	 * entry 14 and 15 has been used hard coded, they will be disabled
+	 * in cpu_init_f, so we use entry 16 for SRIO2.
+	 */
+#ifdef CONFIG_SYS_SRIO1_MEM_PHYS
+	/* *I*G* - SRIO1 */
+	SET_TLB_ENTRY(1, CONFIG_SYS_SRIO1_MEM_VIRT, CONFIG_SYS_SRIO1_MEM_PHYS,
+		MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
+		      0, 13, BOOKE_PAGESZ_256M, 1),
+#endif
+#ifdef CONFIG_SYS_SRIO2_MEM_PHYS
+	/* *I*G* - SRIO2 */
+	SET_TLB_ENTRY(1, CONFIG_SYS_SRIO2_MEM_VIRT, CONFIG_SYS_SRIO2_MEM_PHYS,
+		MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
+		      0, 16, BOOKE_PAGESZ_256M, 1),
+#endif
 };
 };
 
 
 int num_tlb_entries = ARRAY_SIZE(tlb_table);
 int num_tlb_entries = ARRAY_SIZE(tlb_table);

+ 6 - 0
board/freescale/common/Makefile

@@ -33,10 +33,14 @@ COBJS-$(CONFIG_FSL_CADMUS)	+= cadmus.o
 COBJS-$(CONFIG_FSL_VIA)		+= cds_via.o
 COBJS-$(CONFIG_FSL_VIA)		+= cds_via.o
 COBJS-$(CONFIG_FMAN_ENET)	+= fman.o
 COBJS-$(CONFIG_FMAN_ENET)	+= fman.o
 COBJS-$(CONFIG_FSL_PIXIS)	+= pixis.o
 COBJS-$(CONFIG_FSL_PIXIS)	+= pixis.o
+ifndef CONFIG_SPL_BUILD
 COBJS-$(CONFIG_FSL_NGPIXIS)	+= ngpixis.o
 COBJS-$(CONFIG_FSL_NGPIXIS)	+= ngpixis.o
+endif
 COBJS-$(CONFIG_FSL_QIXIS)	+= qixis.o
 COBJS-$(CONFIG_FSL_QIXIS)	+= qixis.o
 COBJS-$(CONFIG_PQ_MDS_PIB)	+= pq-mds-pib.o
 COBJS-$(CONFIG_PQ_MDS_PIB)	+= pq-mds-pib.o
+ifndef CONFIG_SPL_BUILD
 COBJS-$(CONFIG_ID_EEPROM)	+= sys_eeprom.o
 COBJS-$(CONFIG_ID_EEPROM)	+= sys_eeprom.o
+endif
 COBJS-$(CONFIG_FSL_SGMII_RISER)	+= sgmii_riser.o
 COBJS-$(CONFIG_FSL_SGMII_RISER)	+= sgmii_riser.o
 ifndef CONFIG_RAMBOOT_PBL
 ifndef CONFIG_RAMBOOT_PBL
 COBJS-$(CONFIG_FSL_FIXED_MMC_LOCATION)	+= sdhc_boot.o
 COBJS-$(CONFIG_FSL_FIXED_MMC_LOCATION)	+= sdhc_boot.o
@@ -48,7 +52,9 @@ COBJS-$(CONFIG_MPC8555CDS)	+= cds_pci_ft.o
 
 
 COBJS-$(CONFIG_MPC8536DS)	+= ics307_clk.o
 COBJS-$(CONFIG_MPC8536DS)	+= ics307_clk.o
 COBJS-$(CONFIG_MPC8572DS)	+= ics307_clk.o
 COBJS-$(CONFIG_MPC8572DS)	+= ics307_clk.o
+ifndef CONFIG_SPL_BUILD
 COBJS-$(CONFIG_P1022DS)		+= ics307_clk.o
 COBJS-$(CONFIG_P1022DS)		+= ics307_clk.o
+endif
 COBJS-$(CONFIG_P2020DS)		+= ics307_clk.o
 COBJS-$(CONFIG_P2020DS)		+= ics307_clk.o
 COBJS-$(CONFIG_P3041DS)		+= ics307_clk.o
 COBJS-$(CONFIG_P3041DS)		+= ics307_clk.o
 COBJS-$(CONFIG_P4080DS)		+= ics307_clk.o
 COBJS-$(CONFIG_P4080DS)		+= ics307_clk.o

+ 23 - 3
board/freescale/common/cds_pci_ft.c

@@ -31,7 +31,8 @@ static void cds_pci_fixup(void *blob)
 	int node;
 	int node;
 	const char *path;
 	const char *path;
 	int len, slot, i;
 	int len, slot, i;
-	u32 *map = NULL;
+	u32 *map = NULL, *piccells = NULL;
+	int off, cells;
 
 
 	node = fdt_path_offset(blob, "/aliases");
 	node = fdt_path_offset(blob, "/aliases");
 	if (node >= 0) {
 	if (node >= 0) {
@@ -41,6 +42,25 @@ static void cds_pci_fixup(void *blob)
 			if (node >= 0) {
 			if (node >= 0) {
 				map = fdt_getprop_w(blob, node, "interrupt-map", &len);
 				map = fdt_getprop_w(blob, node, "interrupt-map", &len);
 			}
 			}
+			/* Each item in "interrupt-map" property is translated with
+			 * following cells:
+			 * PCI #address-cells, PCI #interrupt-cells,
+			 * PIC address, PIC #address-cells, PIC #interrupt-cells.
+			 */
+			cells = fdt_getprop_u32_default(blob, path, "#address-cells", 1);
+			cells += fdt_getprop_u32_default(blob, path, "#interrupt-cells", 1);
+			off = fdt_node_offset_by_phandle(blob, fdt32_to_cpu(*(map+cells)));
+			if (off <= 0)
+				return;
+			cells += 1;
+			piccells = (u32 *)fdt_getprop(blob, off, "#address-cells", NULL);
+			if (piccells == NULL)
+				return;
+			cells += *piccells;
+			piccells = (u32 *)fdt_getprop(blob, off, "#interrupt-cells", NULL);
+			if (piccells == NULL)
+				return;
+			cells += *piccells;
 		}
 		}
 	}
 	}
 
 
@@ -49,12 +69,12 @@ static void cds_pci_fixup(void *blob)
 
 
 		slot = get_pci_slot();
 		slot = get_pci_slot();
 
 
-		for (i=0;i<len;i+=7) {
+		for (i=0;i<len;i+=cells) {
 			/* We rotate the interrupt pins so that the mapping
 			/* We rotate the interrupt pins so that the mapping
 			 * changes depending on the slot the carrier card is in.
 			 * changes depending on the slot the carrier card is in.
 			 */
 			 */
 			map[3] = ((map[3] + slot - 2) % 4) + 1;
 			map[3] = ((map[3] + slot - 2) % 4) + 1;
-			map+=7;
+			map+=cells;
 		}
 		}
 	}
 	}
 }
 }

+ 1 - 1
board/freescale/common/sdhc_boot.c

@@ -32,7 +32,7 @@
 #define ESDHC_BOOT_IMAGE_SIZE	0x48
 #define ESDHC_BOOT_IMAGE_SIZE	0x48
 #define ESDHC_BOOT_IMAGE_ADDR	0x50
 #define ESDHC_BOOT_IMAGE_ADDR	0x50
 
 
-int mmc_get_env_addr(struct mmc *mmc, u32 *env_addr)
+int mmc_get_env_addr(struct mmc *mmc, int copy, u32 *env_addr)
 {
 {
 	u8 *tmp_buf;
 	u8 *tmp_buf;
 	u32 blklen, code_offset, code_len, n;
 	u32 blklen, code_offset, code_len, n;

+ 1 - 1
board/freescale/p1010rdb/p1010rdb.c

@@ -217,7 +217,7 @@ void fdt_del_flexcan(void *blob)
 	int nodeoff = 0;
 	int nodeoff = 0;
 
 
 	while ((nodeoff = fdt_node_offset_by_compatible(blob, 0,
 	while ((nodeoff = fdt_node_offset_by_compatible(blob, 0,
-				"fsl,flexcan-v1.0")) >= 0) {
+				"fsl,p1010-flexcan")) >= 0) {
 		fdt_del_node(blob, nodeoff);
 		fdt_del_node(blob, nodeoff);
 	}
 	}
 }
 }

+ 14 - 0
board/freescale/p1022ds/Makefile

@@ -11,12 +11,26 @@ include $(TOPDIR)/config.mk
 
 
 LIB	= $(obj)lib$(BOARD).o
 LIB	= $(obj)lib$(BOARD).o
 
 
+MINIMAL=
+
+ifdef CONFIG_SPL_BUILD
+ifdef CONFIG_SPL_INIT_MINIMAL
+MINIMAL=y
+endif
+endif
+
+ifdef MINIMAL
+
+COBJS-y        += spl_minimal.o tlb.o law.o
+
+else
 COBJS-y	+= $(BOARD).o
 COBJS-y	+= $(BOARD).o
 COBJS-y	+= ddr.o
 COBJS-y	+= ddr.o
 COBJS-y	+= law.o
 COBJS-y	+= law.o
 COBJS-y	+= tlb.o
 COBJS-y	+= tlb.o
 
 
 COBJS-$(CONFIG_FSL_DIU_FB) += diu.o
 COBJS-$(CONFIG_FSL_DIU_FB) += diu.o
+endif
 
 
 SRCS	:= $(SOBJS:.o=.S) $(COBJS-y:.o=.c)
 SRCS	:= $(SOBJS:.o=.S) $(COBJS-y:.o=.c)
 OBJS	:= $(addprefix $(obj),$(COBJS-y))
 OBJS	:= $(addprefix $(obj),$(COBJS-y))

+ 1 - 0
board/freescale/p1022ds/law.c

@@ -16,6 +16,7 @@
 struct law_entry law_table[] = {
 struct law_entry law_table[] = {
 	SET_LAW(CONFIG_SYS_FLASH_BASE_PHYS, LAW_SIZE_256M, LAW_TRGT_IF_LBC),
 	SET_LAW(CONFIG_SYS_FLASH_BASE_PHYS, LAW_SIZE_256M, LAW_TRGT_IF_LBC),
 	SET_LAW(PIXIS_BASE_PHYS, LAW_SIZE_4K, LAW_TRGT_IF_LBC),
 	SET_LAW(PIXIS_BASE_PHYS, LAW_SIZE_4K, LAW_TRGT_IF_LBC),
+	SET_LAW(CONFIG_SYS_NAND_BASE_PHYS, LAW_SIZE_32K, LAW_TRGT_IF_LBC),
 };
 };
 
 
 int num_law_entries = ARRAY_SIZE(law_table);
 int num_law_entries = ARRAY_SIZE(law_table);

+ 129 - 0
board/freescale/p1022ds/spl_minimal.c

@@ -0,0 +1,129 @@
+/*
+ * Copyright 2011 Freescale Semiconductor, Inc.
+ *
+ * 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 <ns16550.h>
+#include <asm/io.h>
+#include <nand.h>
+#include <asm/fsl_law.h>
+#include <asm/fsl_ddr_sdram.h>
+
+
+/*
+ * Fixed sdram init -- doesn't use serial presence detect.
+ */
+void sdram_init(void)
+{
+	volatile ccsr_ddr_t *ddr = (ccsr_ddr_t *)CONFIG_SYS_MPC8xxx_DDR_ADDR;
+
+	__raw_writel(CONFIG_SYS_DDR_CS0_BNDS, &ddr->cs0_bnds);
+	__raw_writel(CONFIG_SYS_DDR_CS0_CONFIG, &ddr->cs0_config);
+#if CONFIG_CHIP_SELECTS_PER_CTRL > 1
+	__raw_writel(CONFIG_SYS_DDR_CS1_BNDS, &ddr->cs1_bnds);
+	__raw_writel(CONFIG_SYS_DDR_CS1_CONFIG, &ddr->cs1_config);
+#endif
+	__raw_writel(CONFIG_SYS_DDR_TIMING_3, &ddr->timing_cfg_3);
+	__raw_writel(CONFIG_SYS_DDR_TIMING_0, &ddr->timing_cfg_0);
+	__raw_writel(CONFIG_SYS_DDR_TIMING_1, &ddr->timing_cfg_1);
+	__raw_writel(CONFIG_SYS_DDR_TIMING_2, &ddr->timing_cfg_2);
+
+	__raw_writel(CONFIG_SYS_DDR_CONTROL_2, &ddr->sdram_cfg_2);
+	__raw_writel(CONFIG_SYS_DDR_MODE_1, &ddr->sdram_mode);
+	__raw_writel(CONFIG_SYS_DDR_MODE_2, &ddr->sdram_mode_2);
+
+	__raw_writel(CONFIG_SYS_DDR_INTERVAL, &ddr->sdram_interval);
+	__raw_writel(CONFIG_SYS_DDR_DATA_INIT, &ddr->sdram_data_init);
+	__raw_writel(CONFIG_SYS_DDR_CLK_CTRL, &ddr->sdram_clk_cntl);
+
+	__raw_writel(CONFIG_SYS_DDR_TIMING_4, &ddr->timing_cfg_4);
+	__raw_writel(CONFIG_SYS_DDR_TIMING_5, &ddr->timing_cfg_5);
+	__raw_writel(CONFIG_SYS_DDR_ZQ_CONTROL, &ddr->ddr_zq_cntl);
+	__raw_writel(CONFIG_SYS_DDR_WRLVL_CONTROL, &ddr->ddr_wrlvl_cntl);
+
+	/* Set, but do not enable the memory */
+	__raw_writel(CONFIG_SYS_DDR_CONTROL & ~SDRAM_CFG_MEM_EN,
+			&ddr->sdram_cfg);
+
+	in_be32(&ddr->sdram_cfg);
+	udelay(500);
+
+	/* Let the controller go */
+	out_be32(&ddr->sdram_cfg, in_be32(&ddr->sdram_cfg) | SDRAM_CFG_MEM_EN);
+	in_be32(&ddr->sdram_cfg);
+
+	set_next_law(0, CONFIG_SYS_SDRAM_SIZE_LAW, LAW_TRGT_IF_DDR_1);
+}
+
+const static u32 sysclk_tbl[] = {
+	66666000, 7499900, 83332500, 8999900,
+	99999000, 11111000, 12499800, 13333200
+};
+
+void board_init_f(ulong bootflag)
+{
+	int px_spd;
+	u32 plat_ratio, sys_clk, bus_clk;
+	ccsr_gur_t *gur = (void *)CONFIG_SYS_MPC85xx_GUTS_ADDR;
+
+	/* for FPGA */
+	set_lbc_br(2, CONFIG_SYS_BR2_PRELIM);
+	set_lbc_or(2, CONFIG_SYS_OR2_PRELIM);
+
+	/* initialize selected port with appropriate baud rate */
+	px_spd = in_8((unsigned char *)(PIXIS_BASE + PIXIS_SPD));
+	sys_clk = sysclk_tbl[px_spd & PIXIS_SPD_SYSCLK_MASK];
+	plat_ratio = in_be32(&gur->porpllsr) & MPC85xx_PORPLLSR_PLAT_RATIO;
+	bus_clk = sys_clk * plat_ratio / 2;
+
+	NS16550_init((NS16550_t)CONFIG_SYS_NS16550_COM1,
+			bus_clk / 16 / CONFIG_BAUDRATE);
+
+	puts("\nNAND boot... ");
+
+	/* Initialize the DDR3 */
+	sdram_init();
+
+	/* copy code to RAM and jump to it - this should not return */
+	/* NOTE - code has to be copied out of NAND buffer before
+	 * other blocks can be read.
+	 */
+	relocate_code(CONFIG_SPL_RELOC_STACK, 0,
+			CONFIG_SPL_RELOC_TEXT_BASE);
+}
+
+void board_init_r(gd_t *gd, ulong dest_addr)
+{
+	nand_boot();
+}
+
+void putc(char c)
+{
+	if (c == '\n')
+		NS16550_putc((NS16550_t)CONFIG_SYS_NS16550_COM1, '\r');
+
+	NS16550_putc((NS16550_t)CONFIG_SYS_NS16550_COM1, c);
+}
+
+void puts(const char *str)
+{
+	while (*str)
+		putc(*str++);
+}

+ 14 - 6
board/freescale/p1022ds/tlb.c

@@ -41,6 +41,7 @@ struct fsl_e_tlb_entry tlb_table[] = {
 		      MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
 		      MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
 		      0, 1, BOOKE_PAGESZ_1M, 1),
 		      0, 1, BOOKE_PAGESZ_1M, 1),
 
 
+#ifndef CONFIG_SPL_BUILD
 	/* W**G* - Flash/promjet, localbus */
 	/* W**G* - Flash/promjet, localbus */
 	/* This will be changed to *I*G* after relocation to RAM. */
 	/* This will be changed to *I*G* after relocation to RAM. */
 	SET_TLB_ENTRY(1, CONFIG_SYS_FLASH_BASE, CONFIG_SYS_FLASH_BASE_PHYS,
 	SET_TLB_ENTRY(1, CONFIG_SYS_FLASH_BASE, CONFIG_SYS_FLASH_BASE_PHYS,
@@ -67,24 +68,31 @@ struct fsl_e_tlb_entry tlb_table[] = {
 	SET_TLB_ENTRY(1, CONFIG_SYS_PCIE3_IO_VIRT, CONFIG_SYS_PCIE3_IO_PHYS,
 	SET_TLB_ENTRY(1, CONFIG_SYS_PCIE3_IO_VIRT, CONFIG_SYS_PCIE3_IO_PHYS,
 		      MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
 		      MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
 		      0, 6, BOOKE_PAGESZ_256K, 1),
 		      0, 6, BOOKE_PAGESZ_256K, 1),
+#endif
 
 
 	SET_TLB_ENTRY(1, PIXIS_BASE, PIXIS_BASE_PHYS,
 	SET_TLB_ENTRY(1, PIXIS_BASE, PIXIS_BASE_PHYS,
 		      MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
 		      MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
 		      0, 7, BOOKE_PAGESZ_4K, 1),
 		      0, 7, BOOKE_PAGESZ_4K, 1),
 
 
-#ifdef CONFIG_SYS_RAMBOOT
-	/* *I*G - eSDHC/eSPI/NAND boot */
+#if defined(CONFIG_SYS_RAMBOOT) || defined(CONFIG_SPL)
+	/* **** - eSDHC/eSPI/NAND boot */
 	SET_TLB_ENTRY(1, CONFIG_SYS_DDR_SDRAM_BASE, CONFIG_SYS_DDR_SDRAM_BASE,
 	SET_TLB_ENTRY(1, CONFIG_SYS_DDR_SDRAM_BASE, CONFIG_SYS_DDR_SDRAM_BASE,
 			MAS3_SX|MAS3_SW|MAS3_SR, 0,
 			MAS3_SX|MAS3_SW|MAS3_SR, 0,
 			0, 8, BOOKE_PAGESZ_1G, 1),
 			0, 8, BOOKE_PAGESZ_1G, 1),
-
-	/* map the second 1G */
+	/* **** - eSDHC/eSPI/NAND boot - second 1GB of memory */
 	SET_TLB_ENTRY(1, CONFIG_SYS_DDR_SDRAM_BASE + 0x40000000,
 	SET_TLB_ENTRY(1, CONFIG_SYS_DDR_SDRAM_BASE + 0x40000000,
 			CONFIG_SYS_DDR_SDRAM_BASE + 0x40000000,
 			CONFIG_SYS_DDR_SDRAM_BASE + 0x40000000,
-			MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
+			MAS3_SX|MAS3_SW|MAS3_SR, 0,
 			0, 9, BOOKE_PAGESZ_1G, 1),
 			0, 9, BOOKE_PAGESZ_1G, 1),
 #endif
 #endif
-#
+
+#ifdef CONFIG_SYS_NAND_BASE
+	/* *I*G - NAND */
+	SET_TLB_ENTRY(1, CONFIG_SYS_NAND_BASE, CONFIG_SYS_NAND_BASE_PHYS,
+			MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
+			0, 10, BOOKE_PAGESZ_16K, 1),
+#endif
+
 };
 };
 
 
 int num_tlb_entries = ARRAY_SIZE(tlb_table);
 int num_tlb_entries = ARRAY_SIZE(tlb_table);

+ 65 - 1
board/freescale/p1_p2_rdb_pc/p1_p2_rdb_pc.c

@@ -55,6 +55,13 @@
 #define GPIO_SLIC_PIN		30
 #define GPIO_SLIC_PIN		30
 #define GPIO_SLIC_DATA		(1 << (31 - GPIO_SLIC_PIN))
 #define GPIO_SLIC_DATA		(1 << (31 - GPIO_SLIC_PIN))
 
 
+#if defined(CONFIG_P1021RDB) && !defined(CONFIG_SYS_RAMBOOT)
+#define GPIO_DDR_RST_PORT	1
+#define GPIO_DDR_RST_PIN	8
+#define GPIO_DDR_RST_DATA	(1 << (31 - GPIO_DDR_RST_PIN))
+
+#define GPIO_2BIT_MASK		(0x3 << (32 - (GPIO_DDR_RST_PIN + 1) * 2))
+#endif
 
 
 #if defined(CONFIG_P1025RDB) || defined(CONFIG_P1021RDB)
 #if defined(CONFIG_P1025RDB) || defined(CONFIG_P1021RDB)
 #define PCA_IOPORT_I2C_ADDR		0x23
 #define PCA_IOPORT_I2C_ADDR		0x23
@@ -67,7 +74,7 @@
 const qe_iop_conf_t qe_iop_conf_tab[] = {
 const qe_iop_conf_t qe_iop_conf_tab[] = {
 	/* GPIO */
 	/* GPIO */
 	{1,   1, 2, 0, 0}, /* GPIO7/PB1   - LOAD_DEFAULT_N */
 	{1,   1, 2, 0, 0}, /* GPIO7/PB1   - LOAD_DEFAULT_N */
-#if 0
+#if defined(CONFIG_P1021RDB) && !defined(CONFIG_SYS_RAMBOOT)
 	{1,   8, 1, 1, 0}, /* GPIO10/PB8  - DDR_RST */
 	{1,   8, 1, 1, 0}, /* GPIO10/PB8  - DDR_RST */
 #endif
 #endif
 	{0,  15, 1, 0, 0}, /* GPIO11/A15  - WDI */
 	{0,  15, 1, 0, 0}, /* GPIO11/A15  - WDI */
@@ -159,6 +166,16 @@ void board_gpio_init(void)
 	ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
 	ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
 	par_io_t *par_io = (par_io_t *) &(gur->qe_par_io);
 	par_io_t *par_io = (par_io_t *) &(gur->qe_par_io);
 
 
+#if defined(CONFIG_P1021RDB) && !defined(CONFIG_SYS_RAMBOOT)
+	/* reset DDR3 */
+	setbits_be32(&par_io[GPIO_DDR_RST_PORT].cpdat, GPIO_DDR_RST_DATA);
+	udelay(1000);
+	clrbits_be32(&par_io[GPIO_DDR_RST_PORT].cpdat, GPIO_DDR_RST_DATA);
+	udelay(1000);
+	setbits_be32(&par_io[GPIO_DDR_RST_PORT].cpdat, GPIO_DDR_RST_DATA);
+	/* disable CE_PB8 */
+	clrbits_be32(&par_io[GPIO_DDR_RST_PORT].cpdir1, GPIO_2BIT_MASK);
+#endif
 	/* Enable VSC7385 switch */
 	/* Enable VSC7385 switch */
 	setbits_be32(&par_io[GPIO_GETH_SW_PORT].cpdat, GPIO_GETH_SW_DATA);
 	setbits_be32(&par_io[GPIO_GETH_SW_PORT].cpdat, GPIO_GETH_SW_DATA);
 
 
@@ -421,6 +438,8 @@ void ft_board_setup(void *blob, bd_t *bd)
 {
 {
 	phys_addr_t base;
 	phys_addr_t base;
 	phys_size_t size;
 	phys_size_t size;
+	const char *soc_usb_compat = "fsl-usb2-dr";
+	int err, usb1_off, usb2_off;
 
 
 	ft_cpu_setup(blob, bd);
 	ft_cpu_setup(blob, bd);
 
 
@@ -442,5 +461,50 @@ void ft_board_setup(void *blob, bd_t *bd)
 #if defined(CONFIG_HAS_FSL_DR_USB)
 #if defined(CONFIG_HAS_FSL_DR_USB)
 	fdt_fixup_dr_usb(blob, bd);
 	fdt_fixup_dr_usb(blob, bd);
 #endif
 #endif
+
+#if defined(CONFIG_SDCARD) || defined(CONFIG_SPIFLASH)
+	/* Delete eLBC node as it is muxed with USB2 controller */
+	if (hwconfig("usb2")) {
+		const char *soc_elbc_compat = "fsl,p1020-elbc";
+		int off = fdt_node_offset_by_compatible(blob, -1,
+				soc_elbc_compat);
+		if (off < 0) {
+			printf("WARNING: could not find compatible node %s: %s.\n",
+			       soc_elbc_compat,
+			       fdt_strerror(off));
+				return;
+		}
+		err = fdt_del_node(blob, off);
+		if (err < 0) {
+			printf("WARNING: could not remove %s: %s.\n",
+			       soc_elbc_compat, fdt_strerror(err));
+		}
+		return;
+	}
+#endif
+
+/* Delete USB2 node as it is muxed with eLBC */
+	usb1_off = fdt_node_offset_by_compatible(blob, -1,
+		soc_usb_compat);
+	if (usb1_off < 0) {
+		printf("WARNING: could not find compatible node %s: %s.\n",
+		       soc_usb_compat,
+		       fdt_strerror(usb1_off));
+		return;
+	}
+	usb2_off = fdt_node_offset_by_compatible(blob, usb1_off,
+			soc_usb_compat);
+	if (usb2_off < 0) {
+		printf("WARNING: could not find compatible node %s: %s.\n",
+		       soc_usb_compat,
+		       fdt_strerror(usb2_off));
+		return;
+	}
+	err = fdt_del_node(blob, usb2_off);
+	if (err < 0) {
+		printf("WARNING: could not remove %s: %s.\n",
+		       soc_usb_compat, fdt_strerror(err));
+	}
+
 }
 }
 #endif
 #endif

+ 15 - 0
board/freescale/p1_p2_rdb_pc/spl_minimal.c

@@ -81,6 +81,8 @@ void board_init_f(ulong bootflag)
 	ccsr_gur_t *gur = (void *)CONFIG_SYS_MPC85xx_GUTS_ADDR;
 	ccsr_gur_t *gur = (void *)CONFIG_SYS_MPC85xx_GUTS_ADDR;
 #ifndef CONFIG_QE
 #ifndef CONFIG_QE
 	ccsr_gpio_t *pgpio = (void *)(CONFIG_SYS_MPC85xx_GPIO_ADDR);
 	ccsr_gpio_t *pgpio = (void *)(CONFIG_SYS_MPC85xx_GPIO_ADDR);
+#elif defined(CONFIG_P1021RDB)
+	par_io_t *par_io = (par_io_t *)&(gur->qe_par_io);
 #endif
 #endif
 
 
 	/* initialize selected port with appropriate baud rate */
 	/* initialize selected port with appropriate baud rate */
@@ -102,6 +104,19 @@ void board_init_f(ulong bootflag)
 	__raw_writel(0x00200000, &pgpio->gpdat);
 	__raw_writel(0x00200000, &pgpio->gpdat);
 	udelay(1000);
 	udelay(1000);
 	__raw_writel(0x00000000, &pgpio->gpdir);
 	__raw_writel(0x00000000, &pgpio->gpdir);
+#elif defined(CONFIG_P1021RDB)
+	/* init DDR3 reset signal CE_PB8 */
+	out_be32(&par_io[1].cpdir1, 0x00004000);
+	out_be32(&par_io[1].cpodr, 0x00800000);
+	out_be32(&par_io[1].cppar1, 0x00000000);
+	/* reset DDR3 */
+	out_be32(&par_io[1].cpdat, 0x00800000);
+	udelay(1000);
+	out_be32(&par_io[1].cpdat, 0x00000000);
+	udelay(1000);
+	out_be32(&par_io[1].cpdat, 0x00800000);
+	/* disable the CE_PB8 */
+	out_be32(&par_io[1].cpdir1, 0x00000000);
 #endif
 #endif
 
 
 #ifndef CONFIG_SYS_INIT_L2_ADDR
 #ifndef CONFIG_SYS_INIT_L2_ADDR

+ 9 - 0
board/h2200/h2200.c

@@ -32,6 +32,15 @@ int board_eth_init(bd_t *bis)
 	return 0;
 	return 0;
 }
 }
 
 
+void reset_cpu(ulong ignore)
+{
+	/* Enable VLIO interface on Hamcop */
+	writeb(0x1, 0x4000);
+
+	/* Reset board (cold reset) */
+	writeb(0xff, 0x4002);
+}
+
 int board_init(void)
 int board_init(void)
 {
 {
 	/* We have RAM, disable cache */
 	/* We have RAM, disable cache */

+ 73 - 2
board/lwmon5/lwmon5.c

@@ -1,5 +1,5 @@
 /*
 /*
- * (C) Copyright 2007-2010
+ * (C) Copyright 2007-2013
  * Stefan Roese, DENX Software Engineering, sr@denx.de.
  * Stefan Roese, DENX Software Engineering, sr@denx.de.
  *
  *
  * This program is free software; you can redistribute it and/or
  * This program is free software; you can redistribute it and/or
@@ -200,9 +200,11 @@ int misc_init_r(void)
 	u32 pbcr;
 	u32 pbcr;
 	int size_val = 0;
 	int size_val = 0;
 	u32 reg;
 	u32 reg;
+#ifndef CONFIG_LCD4_LWMON5
 	unsigned long usb2d0cr = 0;
 	unsigned long usb2d0cr = 0;
 	unsigned long usb2phy0cr, usb2h0cr = 0;
 	unsigned long usb2phy0cr, usb2h0cr = 0;
 	unsigned long sdr0_pfc1, sdr0_srst;
 	unsigned long sdr0_pfc1, sdr0_srst;
+#endif
 
 
 	/*
 	/*
 	 * FLASH stuff...
 	 * FLASH stuff...
@@ -233,6 +235,7 @@ int misc_init_r(void)
 		      CONFIG_ENV_ADDR_REDUND + 2 * CONFIG_ENV_SECT_SIZE - 1,
 		      CONFIG_ENV_ADDR_REDUND + 2 * CONFIG_ENV_SECT_SIZE - 1,
 		      &flash_info[cfi_flash_num_flash_banks - 1]);
 		      &flash_info[cfi_flash_num_flash_banks - 1]);
 
 
+#ifndef CONFIG_LCD4_LWMON5
 	/*
 	/*
 	 * USB suff...
 	 * USB suff...
 	 */
 	 */
@@ -306,6 +309,7 @@ int misc_init_r(void)
 	/* 7. Reassert internal PHY reset: */
 	/* 7. Reassert internal PHY reset: */
 	mtsdr(SDR0_SRST1, SDR0_SRST1_USB20PHY);
 	mtsdr(SDR0_SRST1, SDR0_SRST1_USB20PHY);
 	udelay(1000);
 	udelay(1000);
+#endif
 
 
 	/*
 	/*
 	 * Clear resets
 	 * Clear resets
@@ -313,7 +317,9 @@ int misc_init_r(void)
 	mtsdr(SDR0_SRST1, 0x00000000);
 	mtsdr(SDR0_SRST1, 0x00000000);
 	mtsdr(SDR0_SRST0, 0x00000000);
 	mtsdr(SDR0_SRST0, 0x00000000);
 
 
+#ifndef CONFIG_LCD4_LWMON5
 	printf("USB:   Host(int phy) Device(ext phy)\n");
 	printf("USB:   Host(int phy) Device(ext phy)\n");
+#endif
 
 
 	/*
 	/*
 	 * Clear PLB4A0_ACR[WRP]
 	 * Clear PLB4A0_ACR[WRP]
@@ -323,10 +329,12 @@ int misc_init_r(void)
 	reg = mfdcr(PLB4A0_ACR) & ~PLB4Ax_ACR_WRP_MASK;
 	reg = mfdcr(PLB4A0_ACR) & ~PLB4Ax_ACR_WRP_MASK;
 	mtdcr(PLB4A0_ACR, reg);
 	mtdcr(PLB4A0_ACR, reg);
 
 
+#ifndef CONFIG_LCD4_LWMON5
 	/*
 	/*
 	 * Init matrix keyboard
 	 * Init matrix keyboard
 	 */
 	 */
 	misc_init_r_kbd();
 	misc_init_r_kbd();
+#endif
 
 
 	return 0;
 	return 0;
 }
 }
@@ -336,7 +344,7 @@ int checkboard(void)
 	char buf[64];
 	char buf[64];
 	int i = getenv_f("serial#", buf, sizeof(buf));
 	int i = getenv_f("serial#", buf, sizeof(buf));
 
 
-	puts("Board: lwmon5");
+	printf("Board: %s", __stringify(CONFIG_HOSTNAME));
 
 
 	if (i > 0) {
 	if (i > 0) {
 		puts(", serial# ");
 		puts(", serial# ");
@@ -495,3 +503,66 @@ void board_reset(void)
 {
 {
 	gpio_write_bit(CONFIG_SYS_GPIO_BOARD_RESET, 1);
 	gpio_write_bit(CONFIG_SYS_GPIO_BOARD_RESET, 1);
 }
 }
+
+#ifdef CONFIG_SPL_OS_BOOT
+/*
+ * lwmon5 specific implementation of spl_start_uboot()
+ *
+ * RETURN
+ * 0 if booting into OS is selected (default)
+ * 1 if booting into U-Boot is selected
+ */
+int spl_start_uboot(void)
+{
+	char s[8];
+
+	env_init();
+	getenv_f("boot_os", s, sizeof(s));
+	if ((s != NULL) && (strcmp(s, "yes") == 0))
+		return 0;
+
+	return 1;
+}
+
+/*
+ * This function is called from the SPL U-Boot version for
+ * early init stuff, that needs to be done for OS (e.g. Linux)
+ * booting. Doing it later in the real U-Boot would not work
+ * in case that the SPL U-Boot boots Linux directly.
+ */
+void spl_board_init(void)
+{
+	const gdc_regs *regs = board_get_regs();
+
+	/*
+	 * Setup PFC registers, mainly for ethernet support
+	 * later on in Linux
+	 */
+	board_early_init_f();
+
+	/*
+	 * Clear resets
+	 */
+	mtsdr(SDR0_SRST1, 0x00000000);
+	mtsdr(SDR0_SRST0, 0x00000000);
+
+	/*
+	 * Reset Lime controller
+	 */
+	gpio_write_bit(CONFIG_SYS_GPIO_LIME_S, 1);
+	udelay(500);
+	gpio_write_bit(CONFIG_SYS_GPIO_LIME_RST, 1);
+
+	out_be32((void *)CONFIG_SYS_LIME_SDRAM_CLOCK, CONFIG_SYS_MB862xx_CCF);
+	udelay(300);
+	out_be32((void *)CONFIG_SYS_LIME_MMR, CONFIG_SYS_MB862xx_MMR);
+
+	while (regs->index) {
+		out_be32((void *)(CONFIG_SYS_LIME_BASE_0 + GC_DISP_BASE) +
+			 regs->index, regs->value);
+		regs++;
+	}
+
+	board_backlight_brightness(DEFAULT_BRIGHTNESS);
+}
+#endif

+ 3 - 1
board/lwmon5/sdram.c

@@ -6,7 +6,7 @@
  * Alain Saurel,	    AMCC/IBM, alain.saurel@fr.ibm.com
  * Alain Saurel,	    AMCC/IBM, alain.saurel@fr.ibm.com
  * Robert Snyder,	    AMCC/IBM, rob.snyder@fr.ibm.com
  * Robert Snyder,	    AMCC/IBM, rob.snyder@fr.ibm.com
  *
  *
- * (C) Copyright 2007-2008
+ * (C) Copyright 2007-2013
  * Stefan Roese, DENX Software Engineering, sr@denx.de.
  * Stefan Roese, DENX Software Engineering, sr@denx.de.
  *
  *
  * This program is free software; you can redistribute it and/or
  * This program is free software; you can redistribute it and/or
@@ -160,6 +160,7 @@ static void program_ecc(u32 start_address,
  ************************************************************************/
  ************************************************************************/
 phys_size_t initdram (int board_type)
 phys_size_t initdram (int board_type)
 {
 {
+#if defined(CONFIG_SPL_BUILD) || !defined(CONFIG_LCD4_LWMON5)
 	/* CL=4 */
 	/* CL=4 */
 	mtsdram(DDR0_02, 0x00000000);
 	mtsdram(DDR0_02, 0x00000000);
 
 
@@ -253,6 +254,7 @@ phys_size_t initdram (int board_type)
 	 * exceptions are enabled.
 	 * exceptions are enabled.
 	 */
 	 */
 	set_mcsr(get_mcsr());
 	set_mcsr(get_mcsr());
+#endif /* CONFIG_SPL_BUILD */
 
 
 	return (CONFIG_SYS_MBYTES_SDRAM << 20);
 	return (CONFIG_SYS_MBYTES_SDRAM << 20);
 }
 }

+ 1 - 1
board/sandbox/sandbox/sandbox.c

@@ -56,6 +56,6 @@ int timer_init(void)
 
 
 int dram_init(void)
 int dram_init(void)
 {
 {
-	gd->ram_size = CONFIG_DRAM_SIZE;
+	gd->ram_size = CONFIG_SYS_SDRAM_SIZE;
 	return 0;
 	return 0;
 }
 }

+ 8 - 3
board/xilinx/microblaze-generic/microblaze-generic.c

@@ -38,10 +38,15 @@ int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 	*((unsigned long *)(CONFIG_SYS_GPIO_0_ADDR)) =
 	*((unsigned long *)(CONFIG_SYS_GPIO_0_ADDR)) =
 	    ++(*((unsigned long *)(CONFIG_SYS_GPIO_0_ADDR)));
 	    ++(*((unsigned long *)(CONFIG_SYS_GPIO_0_ADDR)));
 #endif
 #endif
-#ifdef CONFIG_SYS_RESET_ADDRESS
-	puts ("Reseting board\n");
-	asm ("bra r0");
+
+#ifdef CONFIG_XILINX_TB_WATCHDOG
+	hw_watchdog_disable();
 #endif
 #endif
+
+	puts ("Reseting board\n");
+	__asm__ __volatile__ ("	mts rmsr, r0;" \
+				"bra r0");
+
 	return 0;
 	return 0;
 }
 }
 
 

+ 4 - 0
board/xilinx/microblaze-generic/xparameters.h

@@ -77,3 +77,7 @@
 #define XILINX_LLTEMAC_SDMA_CTRL_BASEADDR	0x42000180
 #define XILINX_LLTEMAC_SDMA_CTRL_BASEADDR	0x42000180
 #define XILINX_LLTEMAC_BASEADDR1		0x44200000
 #define XILINX_LLTEMAC_BASEADDR1		0x44200000
 #define XILINX_LLTEMAC_FIFO_BASEADDR1		0x42100000
 #define XILINX_LLTEMAC_FIFO_BASEADDR1		0x42100000
+
+/* Watchdog IP is wxi_timebase_wdt_0 */
+#define XILINX_WATCHDOG_BASEADDR	0x50000000
+#define XILINX_WATCHDOG_IRQ		1

+ 3 - 0
boards.cfg

@@ -811,6 +811,8 @@ P1021RDB-PC_NAND             powerpc     mpc85xx     p1_p2_rdb_pc        freesca
 P1021RDB-PC_SDCARD           powerpc     mpc85xx     p1_p2_rdb_pc        freescale      -           p1_p2_rdb_pc:P1021RDB,SDCARD
 P1021RDB-PC_SDCARD           powerpc     mpc85xx     p1_p2_rdb_pc        freescale      -           p1_p2_rdb_pc:P1021RDB,SDCARD
 P1021RDB-PC_SPIFLASH         powerpc     mpc85xx     p1_p2_rdb_pc        freescale      -           p1_p2_rdb_pc:P1021RDB,SPIFLASH
 P1021RDB-PC_SPIFLASH         powerpc     mpc85xx     p1_p2_rdb_pc        freescale      -           p1_p2_rdb_pc:P1021RDB,SPIFLASH
 P1022DS                      powerpc     mpc85xx     p1022ds             freescale
 P1022DS                      powerpc     mpc85xx     p1022ds             freescale
+P1022DS_NAND                 powerpc     mpc85xx     p1022ds             freescale	-	    P1022DS:NAND
+P1022DS_36BIT_NAND           powerpc     mpc85xx     p1022ds             freescale	-	    P1022DS:36BIT,NAND
 P1022DS_SPIFLASH             powerpc     mpc85xx     p1022ds             freescale	-	    P1022DS:SPIFLASH
 P1022DS_SPIFLASH             powerpc     mpc85xx     p1022ds             freescale	-	    P1022DS:SPIFLASH
 P1022DS_36BIT_SPIFLASH       powerpc     mpc85xx     p1022ds             freescale	-	    P1022DS:36BIT,SPIFLASH
 P1022DS_36BIT_SPIFLASH       powerpc     mpc85xx     p1022ds             freescale	-	    P1022DS:36BIT,SPIFLASH
 P1022DS_SDCARD               powerpc     mpc85xx     p1022ds             freescale	-	    P1022DS:SDCARD
 P1022DS_SDCARD               powerpc     mpc85xx     p1022ds             freescale	-	    P1022DS:SDCARD
@@ -1010,6 +1012,7 @@ JSE                          powerpc     ppc4xx      jse
 korat                        powerpc     ppc4xx
 korat                        powerpc     ppc4xx
 korat_perm                   powerpc     ppc4xx      korat               -              -           korat:KORAT_PERMANENT
 korat_perm                   powerpc     ppc4xx      korat               -              -           korat:KORAT_PERMANENT
 lwmon5                       powerpc     ppc4xx
 lwmon5                       powerpc     ppc4xx
+lcd4_lwmon5                  powerpc     ppc4xx      lwmon5              -              -           lwmon5:LCD4_LWMON5
 pcs440ep                     powerpc     ppc4xx
 pcs440ep                     powerpc     ppc4xx
 quad100hd                    powerpc     ppc4xx
 quad100hd                    powerpc     ppc4xx
 sbc405                       powerpc     ppc4xx
 sbc405                       powerpc     ppc4xx

+ 93 - 15
common/board_f.c

@@ -31,6 +31,7 @@
 #include <version.h>
 #include <version.h>
 #include <environment.h>
 #include <environment.h>
 #include <fdtdec.h>
 #include <fdtdec.h>
+#include <fs.h>
 #if defined(CONFIG_CMD_IDE)
 #if defined(CONFIG_CMD_IDE)
 #include <ide.h>
 #include <ide.h>
 #endif
 #endif
@@ -49,9 +50,11 @@
 #include <mpc5xxx.h>
 #include <mpc5xxx.h>
 #endif
 #endif
 
 
+#include <os.h>
 #include <post.h>
 #include <post.h>
 #include <spi.h>
 #include <spi.h>
 #include <watchdog.h>
 #include <watchdog.h>
+#include <asm/errno.h>
 #include <asm/io.h>
 #include <asm/io.h>
 #ifdef CONFIG_MP
 #ifdef CONFIG_MP
 #include <asm/mp.h>
 #include <asm/mp.h>
@@ -61,6 +64,9 @@
 #include <asm/init_helpers.h>
 #include <asm/init_helpers.h>
 #include <asm/relocate.h>
 #include <asm/relocate.h>
 #endif
 #endif
+#ifdef CONFIG_SANDBOX
+#include <asm/state.h>
+#endif
 #include <linux/compiler.h>
 #include <linux/compiler.h>
 
 
 /*
 /*
@@ -155,6 +161,7 @@ static int init_baud_rate(void)
 
 
 static int display_text_info(void)
 static int display_text_info(void)
 {
 {
+#ifndef CONFIG_SANDBOX
 	ulong bss_start, bss_end;
 	ulong bss_start, bss_end;
 
 
 #ifdef CONFIG_SYS_SYM_OFFSETS
 #ifdef CONFIG_SYS_SYM_OFFSETS
@@ -166,6 +173,7 @@ static int display_text_info(void)
 #endif
 #endif
 	debug("U-Boot code: %08X -> %08lX  BSS: -> %08lX\n",
 	debug("U-Boot code: %08X -> %08lX  BSS: -> %08lX\n",
 	      CONFIG_SYS_TEXT_BASE, bss_start, bss_end);
 	      CONFIG_SYS_TEXT_BASE, bss_start, bss_end);
+#endif
 
 
 #ifdef CONFIG_MODEM_SUPPORT
 #ifdef CONFIG_MODEM_SUPPORT
 	debug("Modem Support enabled\n");
 	debug("Modem Support enabled\n");
@@ -284,6 +292,8 @@ static int setup_mon_len(void)
 {
 {
 #ifdef CONFIG_SYS_SYM_OFFSETS
 #ifdef CONFIG_SYS_SYM_OFFSETS
 	gd->mon_len = _bss_end_ofs;
 	gd->mon_len = _bss_end_ofs;
+#elif defined(CONFIG_SANDBOX)
+	gd->mon_len = (ulong)&_end - (ulong)_init;
 #else
 #else
 	/* TODO: use (ulong)&__bss_end - (ulong)&__text_start; ? */
 	/* TODO: use (ulong)&__bss_end - (ulong)&__text_start; ? */
 	gd->mon_len = (ulong)&__bss_end - CONFIG_SYS_MONITOR_BASE;
 	gd->mon_len = (ulong)&__bss_end - CONFIG_SYS_MONITOR_BASE;
@@ -296,6 +306,66 @@ __weak int arch_cpu_init(void)
 	return 0;
 	return 0;
 }
 }
 
 
+#ifdef CONFIG_OF_HOSTFILE
+
+#define CHECK(x)		err = (x); if (err) goto failed;
+
+/* Create an empty device tree blob */
+static int make_empty_fdt(void *fdt)
+{
+	int err;
+
+	CHECK(fdt_create(fdt, 256));
+	CHECK(fdt_finish_reservemap(fdt));
+	CHECK(fdt_begin_node(fdt, ""));
+	CHECK(fdt_end_node(fdt));
+	CHECK(fdt_finish(fdt));
+
+	return 0;
+failed:
+	printf("Unable to create empty FDT: %s\n", fdt_strerror(err));
+	return -EACCES;
+}
+
+static int read_fdt_from_file(void)
+{
+	struct sandbox_state *state = state_get_current();
+	void *blob;
+	int size;
+	int err;
+
+	blob = map_sysmem(CONFIG_SYS_FDT_LOAD_ADDR, 0);
+	if (!state->fdt_fname) {
+		err = make_empty_fdt(blob);
+		if (!err)
+			goto done;
+		return err;
+	}
+	err = fs_set_blk_dev("host", NULL, FS_TYPE_SANDBOX);
+	if (err)
+		return err;
+	size = fs_read(state->fdt_fname, CONFIG_SYS_FDT_LOAD_ADDR, 0, 0);
+	if (size < 0)
+		return -EIO;
+
+done:
+	gd->fdt_blob = blob;
+
+	return 0;
+}
+#endif
+
+#ifdef CONFIG_SANDBOX
+static int setup_ram_buf(void)
+{
+	gd->arch.ram_buf = os_malloc(CONFIG_SYS_SDRAM_SIZE);
+	assert(gd->arch.ram_buf);
+	gd->ram_size = CONFIG_SYS_SDRAM_SIZE;
+
+	return 0;
+}
+#endif
+
 static int setup_fdt(void)
 static int setup_fdt(void)
 {
 {
 #ifdef CONFIG_OF_EMBED
 #ifdef CONFIG_OF_EMBED
@@ -308,6 +378,11 @@ static int setup_fdt(void)
 # else
 # else
 	gd->fdt_blob = (ulong *)&_end;
 	gd->fdt_blob = (ulong *)&_end;
 # endif
 # endif
+#elif defined(CONFIG_OF_HOSTFILE)
+	if (read_fdt_from_file()) {
+		puts("Failed to read control FDT\n");
+		return -1;
+	}
 #endif
 #endif
 	/* Allow the early environment to override the fdt address */
 	/* Allow the early environment to override the fdt address */
 	gd->fdt_blob = (void *)getenv_ulong("fdtcontroladdr", 16,
 	gd->fdt_blob = (void *)getenv_ulong("fdtcontroladdr", 16,
@@ -470,7 +545,7 @@ static int reserve_malloc(void)
 static int reserve_board(void)
 static int reserve_board(void)
 {
 {
 	gd->dest_addr_sp -= sizeof(bd_t);
 	gd->dest_addr_sp -= sizeof(bd_t);
-	gd->bd = (bd_t *)gd->dest_addr_sp;
+	gd->bd = (bd_t *)map_sysmem(gd->dest_addr_sp, sizeof(bd_t));
 	memset(gd->bd, '\0', sizeof(bd_t));
 	memset(gd->bd, '\0', sizeof(bd_t));
 	debug("Reserving %zu Bytes for Board Info at: %08lx\n",
 	debug("Reserving %zu Bytes for Board Info at: %08lx\n",
 			sizeof(bd_t), gd->dest_addr_sp);
 			sizeof(bd_t), gd->dest_addr_sp);
@@ -489,7 +564,7 @@ static int setup_machine(void)
 static int reserve_global_data(void)
 static int reserve_global_data(void)
 {
 {
 	gd->dest_addr_sp -= sizeof(gd_t);
 	gd->dest_addr_sp -= sizeof(gd_t);
-	gd->new_gd = (gd_t *)gd->dest_addr_sp;
+	gd->new_gd = (gd_t *)map_sysmem(gd->dest_addr_sp, sizeof(gd_t));
 	debug("Reserving %zu Bytes for Global Data at: %08lx\n",
 	debug("Reserving %zu Bytes for Global Data at: %08lx\n",
 			sizeof(gd_t), gd->dest_addr_sp);
 			sizeof(gd_t), gd->dest_addr_sp);
 	return 0;
 	return 0;
@@ -506,9 +581,9 @@ static int reserve_fdt(void)
 		gd->fdt_size = ALIGN(fdt_totalsize(gd->fdt_blob) + 0x1000, 32);
 		gd->fdt_size = ALIGN(fdt_totalsize(gd->fdt_blob) + 0x1000, 32);
 
 
 		gd->dest_addr_sp -= gd->fdt_size;
 		gd->dest_addr_sp -= gd->fdt_size;
-		gd->new_fdt = (void *)gd->dest_addr_sp;
-		debug("Reserving %lu Bytes for FDT at: %p\n",
-		      gd->fdt_size, gd->new_fdt);
+		gd->new_fdt = map_sysmem(gd->dest_addr_sp, gd->fdt_size);
+		debug("Reserving %lu Bytes for FDT at: %08lx\n",
+		      gd->fdt_size, gd->dest_addr_sp);
 	}
 	}
 
 
 	return 0;
 	return 0;
@@ -709,8 +784,9 @@ static int setup_reloc(void)
 	memcpy(gd->new_gd, (char *)gd, sizeof(gd_t));
 	memcpy(gd->new_gd, (char *)gd, sizeof(gd_t));
 
 
 	debug("Relocation Offset is: %08lx\n", gd->reloc_off);
 	debug("Relocation Offset is: %08lx\n", gd->reloc_off);
-	debug("Relocating to %08lx, new gd at %p, sp at %08lx\n",
-	      gd->dest_addr, gd->new_gd, gd->dest_addr_sp);
+	debug("Relocating to %08lx, new gd at %08lx, sp at %08lx\n",
+	      gd->dest_addr, (ulong)map_to_sysmem(gd->new_gd),
+	      gd->dest_addr_sp);
 
 
 	return 0;
 	return 0;
 }
 }
@@ -736,6 +812,8 @@ static int jump_to_copy(void)
 	 * (CPU cache)
 	 * (CPU cache)
 	 */
 	 */
 	board_init_f_r_trampoline(gd->start_addr_sp);
 	board_init_f_r_trampoline(gd->start_addr_sp);
+#elif defined(CONFIG_SANDBOX)
+	board_init_r(gd->new_gd, 0);
 #else
 #else
 	relocate_code(gd->dest_addr_sp, gd->new_gd, gd->dest_addr);
 	relocate_code(gd->dest_addr_sp, gd->new_gd, gd->dest_addr);
 #endif
 #endif
@@ -757,6 +835,9 @@ static init_fnc_t init_sequence_f[] = {
 		!defined(CONFIG_MPC83xx) && !defined(CONFIG_MPC85xx) && \
 		!defined(CONFIG_MPC83xx) && !defined(CONFIG_MPC85xx) && \
 		!defined(CONFIG_MPC86xx) && !defined(CONFIG_X86)
 		!defined(CONFIG_MPC86xx) && !defined(CONFIG_X86)
 	zero_global_data,
 	zero_global_data,
+#endif
+#ifdef CONFIG_SANDBOX
+	setup_ram_buf,
 #endif
 #endif
 	setup_fdt,
 	setup_fdt,
 	setup_mon_len,
 	setup_mon_len,
@@ -816,8 +897,11 @@ static init_fnc_t init_sequence_f[] = {
 	init_baud_rate,		/* initialze baudrate settings */
 	init_baud_rate,		/* initialze baudrate settings */
 	serial_init,		/* serial communications setup */
 	serial_init,		/* serial communications setup */
 	console_init_f,		/* stage 1 init of console */
 	console_init_f,		/* stage 1 init of console */
-#if defined(CONFIG_X86) && defined(CONFIG_OF_CONTROL)
-	prepare_fdt,		/* TODO(sjg@chromium.org): remove */
+#ifdef CONFIG_SANDBOX
+	sandbox_early_getopt_check,
+#endif
+#ifdef CONFIG_OF_CONTROL
+	fdtdec_prepare_fdt,
 #endif
 #endif
 	display_options,	/* say that we are here */
 	display_options,	/* say that we are here */
 	display_text_info,	/* show debugging info if required */
 	display_text_info,	/* show debugging info if required */
@@ -1003,9 +1087,3 @@ void board_init_f_r(void)
 	hang();
 	hang();
 }
 }
 #endif /* CONFIG_X86 */
 #endif /* CONFIG_X86 */
-
-void hang(void)
-{
-	puts("### ERROR ### Please RESET the board ###\n");
-	for (;;);
-}

+ 6 - 2
common/board_r.c

@@ -136,7 +136,7 @@ static int initr_reloc_global_data(void)
 {
 {
 #ifdef CONFIG_SYS_SYM_OFFSETS
 #ifdef CONFIG_SYS_SYM_OFFSETS
 	monitor_flash_len = _end_ofs;
 	monitor_flash_len = _end_ofs;
-#else
+#elif !defined(CONFIG_SANDBOX)
 	monitor_flash_len = (ulong)&__init_end - gd->dest_addr;
 	monitor_flash_len = (ulong)&__init_end - gd->dest_addr;
 #endif
 #endif
 #if defined(CONFIG_MPC85xx) || defined(CONFIG_MPC86xx)
 #if defined(CONFIG_MPC85xx) || defined(CONFIG_MPC86xx)
@@ -264,7 +264,8 @@ static int initr_malloc(void)
 
 
 	/* The malloc area is immediately below the monitor copy in DRAM */
 	/* The malloc area is immediately below the monitor copy in DRAM */
 	malloc_start = gd->dest_addr - TOTAL_MALLOC_LEN;
 	malloc_start = gd->dest_addr - TOTAL_MALLOC_LEN;
-	mem_malloc_init(malloc_start, TOTAL_MALLOC_LEN);
+	mem_malloc_init((ulong)map_sysmem(malloc_start, TOTAL_MALLOC_LEN),
+			TOTAL_MALLOC_LEN);
 	return 0;
 	return 0;
 }
 }
 
 
@@ -691,6 +692,9 @@ static int initr_modem(void)
 
 
 static int run_main_loop(void)
 static int run_main_loop(void)
 {
 {
+#ifdef CONFIG_SANDBOX
+	sandbox_main_loop_init();
+#endif
 	/* main_loop() can return to retry autoboot, if so just run it again */
 	/* main_loop() can return to retry autoboot, if so just run it again */
 	for (;;)
 	for (;;)
 		main_loop();
 		main_loop();

+ 57 - 30
common/cmd_fdt.c

@@ -31,6 +31,7 @@
 #include <asm/global_data.h>
 #include <asm/global_data.h>
 #include <libfdt.h>
 #include <libfdt.h>
 #include <fdt_support.h>
 #include <fdt_support.h>
+#include <asm/io.h>
 
 
 #define MAX_LEVEL	32		/* how deeply nested we will go */
 #define MAX_LEVEL	32		/* how deeply nested we will go */
 #define SCRATCHPAD	1024		/* bytes of scratchpad memory */
 #define SCRATCHPAD	1024		/* bytes of scratchpad memory */
@@ -43,7 +44,7 @@
  */
  */
 DECLARE_GLOBAL_DATA_PTR;
 DECLARE_GLOBAL_DATA_PTR;
 
 
-static int fdt_valid(void);
+static int fdt_valid(struct fdt_header **blobp);
 static int fdt_parse_prop(char *const*newval, int count, char *data, int *len);
 static int fdt_parse_prop(char *const*newval, int count, char *data, int *len);
 static int fdt_print(const char *pathp, char *prop, int depth);
 static int fdt_print(const char *pathp, char *prop, int depth);
 static int is_printable_string(const void *data, int len);
 static int is_printable_string(const void *data, int len);
@@ -55,7 +56,10 @@ struct fdt_header *working_fdt;
 
 
 void set_working_fdt_addr(void *addr)
 void set_working_fdt_addr(void *addr)
 {
 {
-	working_fdt = addr;
+	void *buf;
+
+	buf = map_sysmem((ulong)addr, 0);
+	working_fdt = buf;
 	setenv_addr("fdtaddr", addr);
 	setenv_addr("fdtaddr", addr);
 }
 }
 
 
@@ -100,40 +104,59 @@ static int do_fdt(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 	 */
 	 */
 	if (argv[1][0] == 'a') {
 	if (argv[1][0] == 'a') {
 		unsigned long addr;
 		unsigned long addr;
+		int control = 0;
+		struct fdt_header *blob;
 		/*
 		/*
 		 * Set the address [and length] of the fdt.
 		 * Set the address [and length] of the fdt.
 		 */
 		 */
-		if (argc == 2) {
-			if (!fdt_valid()) {
+		argc -= 2;
+		argv += 2;
+/* Temporary #ifdef - some archs don't have fdt_blob yet */
+#ifdef CONFIG_OF_CONTROL
+		if (argc && !strcmp(*argv, "-c")) {
+			control = 1;
+			argc--;
+			argv++;
+		}
+#endif
+		if (argc == 0) {
+			if (control)
+				blob = (struct fdt_header *)gd->fdt_blob;
+			else
+				blob = working_fdt;
+			if (!blob || !fdt_valid(&blob))
 				return 1;
 				return 1;
-			}
-			printf("The address of the fdt is %p\n", working_fdt);
+			printf("The address of the fdt is %#08lx\n",
+			       control ? (ulong)blob :
+					getenv_hex("fdtaddr", 0));
 			return 0;
 			return 0;
 		}
 		}
 
 
-		addr = simple_strtoul(argv[2], NULL, 16);
-		set_working_fdt_addr((void *)addr);
-
-		if (!fdt_valid()) {
+		addr = simple_strtoul(argv[0], NULL, 16);
+		blob = map_sysmem(addr, 0);
+		if (!fdt_valid(&blob))
 			return 1;
 			return 1;
-		}
+		if (control)
+			gd->fdt_blob = blob;
+		else
+			set_working_fdt_addr(blob);
 
 
-		if (argc >= 4) {
+		if (argc >= 2) {
 			int  len;
 			int  len;
 			int  err;
 			int  err;
 			/*
 			/*
 			 * Optional new length
 			 * Optional new length
 			 */
 			 */
-			len = simple_strtoul(argv[3], NULL, 16);
-			if (len < fdt_totalsize(working_fdt)) {
+			len = simple_strtoul(argv[1], NULL, 16);
+			if (len < fdt_totalsize(blob)) {
 				printf ("New length %d < existing length %d, "
 				printf ("New length %d < existing length %d, "
 					"ignoring.\n",
 					"ignoring.\n",
-					len, fdt_totalsize(working_fdt));
+					len, fdt_totalsize(blob));
 			} else {
 			} else {
 				/*
 				/*
 				 * Open in place with a new length.
 				 * Open in place with a new length.
 				 */
 				 */
-				err = fdt_open_into(working_fdt, working_fdt, len);
+				err = fdt_open_into(blob, blob, len);
 				if (err != 0) {
 				if (err != 0) {
 					printf ("libfdt fdt_open_into(): %s\n",
 					printf ("libfdt fdt_open_into(): %s\n",
 						fdt_strerror(err));
 						fdt_strerror(err));
@@ -167,9 +190,8 @@ static int do_fdt(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 		 * Set the address and length of the fdt.
 		 * Set the address and length of the fdt.
 		 */
 		 */
 		working_fdt = (struct fdt_header *)simple_strtoul(argv[2], NULL, 16);
 		working_fdt = (struct fdt_header *)simple_strtoul(argv[2], NULL, 16);
-		if (!fdt_valid()) {
+		if (!fdt_valid(&working_fdt))
 			return 1;
 			return 1;
-		}
 
 
 		newaddr = (struct fdt_header *)simple_strtoul(argv[3],NULL,16);
 		newaddr = (struct fdt_header *)simple_strtoul(argv[3],NULL,16);
 
 
@@ -592,16 +614,23 @@ static int do_fdt(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 
 
 /****************************************************************************/
 /****************************************************************************/
 
 
-static int fdt_valid(void)
+/**
+ * fdt_valid() - Check if an FDT is valid. If not, change it to NULL
+ *
+ * @blobp: Pointer to FDT pointer
+ * @return 1 if OK, 0 if bad (in which case *blobp is set to NULL)
+ */
+static int fdt_valid(struct fdt_header **blobp)
 {
 {
-	int  err;
+	const void *blob = *blobp;
+	int err;
 
 
-	if (working_fdt == NULL) {
+	if (blob == NULL) {
 		printf ("The address of the fdt is invalid (NULL).\n");
 		printf ("The address of the fdt is invalid (NULL).\n");
 		return 0;
 		return 0;
 	}
 	}
 
 
-	err = fdt_check_header(working_fdt);
+	err = fdt_check_header(blob);
 	if (err == 0)
 	if (err == 0)
 		return 1;	/* valid */
 		return 1;	/* valid */
 
 
@@ -611,23 +640,21 @@ static int fdt_valid(void)
 		 * Be more informative on bad version.
 		 * Be more informative on bad version.
 		 */
 		 */
 		if (err == -FDT_ERR_BADVERSION) {
 		if (err == -FDT_ERR_BADVERSION) {
-			if (fdt_version(working_fdt) <
+			if (fdt_version(blob) <
 			    FDT_FIRST_SUPPORTED_VERSION) {
 			    FDT_FIRST_SUPPORTED_VERSION) {
 				printf (" - too old, fdt %d < %d",
 				printf (" - too old, fdt %d < %d",
-					fdt_version(working_fdt),
+					fdt_version(blob),
 					FDT_FIRST_SUPPORTED_VERSION);
 					FDT_FIRST_SUPPORTED_VERSION);
-				working_fdt = NULL;
 			}
 			}
-			if (fdt_last_comp_version(working_fdt) >
+			if (fdt_last_comp_version(blob) >
 			    FDT_LAST_SUPPORTED_VERSION) {
 			    FDT_LAST_SUPPORTED_VERSION) {
 				printf (" - too new, fdt %d > %d",
 				printf (" - too new, fdt %d > %d",
-					fdt_version(working_fdt),
+					fdt_version(blob),
 					FDT_LAST_SUPPORTED_VERSION);
 					FDT_LAST_SUPPORTED_VERSION);
-				working_fdt = NULL;
 			}
 			}
-			return 0;
 		}
 		}
 		printf("\n");
 		printf("\n");
+		*blobp = NULL;
 		return 0;
 		return 0;
 	}
 	}
 	return 1;
 	return 1;
@@ -958,7 +985,7 @@ static int fdt_print(const char *pathp, char *prop, int depth)
 /********************************************************************/
 /********************************************************************/
 #ifdef CONFIG_SYS_LONGHELP
 #ifdef CONFIG_SYS_LONGHELP
 static char fdt_help_text[] =
 static char fdt_help_text[] =
-	"addr   <addr> [<length>]        - Set the fdt location to <addr>\n"
+	"addr [-c]  <addr> [<length>]   - Set the [control] fdt location to <addr>\n"
 #ifdef CONFIG_OF_BOARD_SETUP
 #ifdef CONFIG_OF_BOARD_SETUP
 	"fdt boardsetup                      - Do board-specific set up\n"
 	"fdt boardsetup                      - Do board-specific set up\n"
 #endif
 #endif

+ 5 - 0
common/cmd_ide.c

@@ -455,6 +455,8 @@ void ide_init(void)
 		ide_dev_desc[i].dev = i;
 		ide_dev_desc[i].dev = i;
 		ide_dev_desc[i].part_type = PART_TYPE_UNKNOWN;
 		ide_dev_desc[i].part_type = PART_TYPE_UNKNOWN;
 		ide_dev_desc[i].blksz = 0;
 		ide_dev_desc[i].blksz = 0;
+		ide_dev_desc[i].log2blksz =
+			LOG2_INVALID(typeof(ide_dev_desc[i].log2blksz));
 		ide_dev_desc[i].lba = 0;
 		ide_dev_desc[i].lba = 0;
 		ide_dev_desc[i].block_read = ide_read;
 		ide_dev_desc[i].block_read = ide_read;
 		ide_dev_desc[i].block_write = ide_write;
 		ide_dev_desc[i].block_write = ide_write;
@@ -806,6 +808,7 @@ static void ide_ident(block_dev_desc_t *dev_desc)
 	/* assuming HD */
 	/* assuming HD */
 	dev_desc->type = DEV_TYPE_HARDDISK;
 	dev_desc->type = DEV_TYPE_HARDDISK;
 	dev_desc->blksz = ATA_BLOCKSIZE;
 	dev_desc->blksz = ATA_BLOCKSIZE;
+	dev_desc->log2blksz = LOG2(dev_desc->blksz);
 	dev_desc->lun = 0;	/* just to fill something in... */
 	dev_desc->lun = 0;	/* just to fill something in... */
 
 
 #if 0				/* only used to test the powersaving mode,
 #if 0				/* only used to test the powersaving mode,
@@ -1448,6 +1451,7 @@ static void atapi_inquiry(block_dev_desc_t *dev_desc)
 	dev_desc->lun = 0;
 	dev_desc->lun = 0;
 	dev_desc->lba = 0;
 	dev_desc->lba = 0;
 	dev_desc->blksz = 0;
 	dev_desc->blksz = 0;
+	dev_desc->log2blksz = LOG2_INVALID(typeof(dev_desc->log2blksz));
 	dev_desc->type = iobuf[0] & 0x1f;
 	dev_desc->type = iobuf[0] & 0x1f;
 
 
 	if ((iobuf[1] & 0x80) == 0x80)
 	if ((iobuf[1] & 0x80) == 0x80)
@@ -1492,6 +1496,7 @@ static void atapi_inquiry(block_dev_desc_t *dev_desc)
 	dev_desc->blksz = ((unsigned long) iobuf[4] << 24) +
 	dev_desc->blksz = ((unsigned long) iobuf[4] << 24) +
 		((unsigned long) iobuf[5] << 16) +
 		((unsigned long) iobuf[5] << 16) +
 		((unsigned long) iobuf[6] << 8) + ((unsigned long) iobuf[7]);
 		((unsigned long) iobuf[6] << 8) + ((unsigned long) iobuf[7]);
+	dev_desc->log2blksz = LOG2(dev_desc->blksz);
 #ifdef CONFIG_LBA48
 #ifdef CONFIG_LBA48
 	/* ATAPI devices cannot use 48bit addressing (ATA/ATAPI v7) */
 	/* ATAPI devices cannot use 48bit addressing (ATA/ATAPI v7) */
 	dev_desc->lba48 = 0;
 	dev_desc->lba48 = 0;

+ 80 - 22
common/cmd_nvedit.c

@@ -1,5 +1,5 @@
 /*
 /*
- * (C) Copyright 2000-2010
+ * (C) Copyright 2000-2013
  * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
  * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
  *
  *
  * (C) Copyright 2001 Sysgo Real-Time Solutions, GmbH <www.elinos.com>
  * (C) Copyright 2001 Sysgo Real-Time Solutions, GmbH <www.elinos.com>
@@ -164,31 +164,57 @@ static int do_env_print(cmd_tbl_t *cmdtp, int flag, int argc,
 static int do_env_grep(cmd_tbl_t *cmdtp, int flag,
 static int do_env_grep(cmd_tbl_t *cmdtp, int flag,
 		       int argc, char * const argv[])
 		       int argc, char * const argv[])
 {
 {
-	ENTRY *match;
-	unsigned char matched[env_htab.size / 8];
-	int rcode = 1, arg = 1, idx;
+	char *res = NULL;
+	int len, grep_how, grep_what;
 
 
 	if (argc < 2)
 	if (argc < 2)
 		return CMD_RET_USAGE;
 		return CMD_RET_USAGE;
 
 
-	memset(matched, 0, env_htab.size / 8);
+	grep_how  = H_MATCH_SUBSTR;	/* default: substring search	*/
+	grep_what = H_MATCH_BOTH;	/* default: grep names and values */
 
 
-	while (arg <= argc) {
-		idx = 0;
-		while ((idx = hstrstr_r(argv[arg], idx, &match, &env_htab))) {
-			if (!(matched[idx / 8] & (1 << (idx & 7)))) {
-				puts(match->key);
-				puts("=");
-				puts(match->data);
-				puts("\n");
+	while (argc > 1 && **(argv + 1) == '-') {
+		char *arg = *++argv;
+
+		--argc;
+		while (*++arg) {
+			switch (*arg) {
+#ifdef CONFIG_REGEX
+			case 'e':		/* use regex matching */
+				grep_how  = H_MATCH_REGEX;
+				break;
+#endif
+			case 'n':		/* grep for name */
+				grep_what = H_MATCH_KEY;
+				break;
+			case 'v':		/* grep for value */
+				grep_what = H_MATCH_DATA;
+				break;
+			case 'b':		/* grep for both */
+				grep_what = H_MATCH_BOTH;
+				break;
+			case '-':
+				goto DONE;
+			default:
+				return CMD_RET_USAGE;
 			}
 			}
-			matched[idx / 8] |= 1 << (idx & 7);
-			rcode = 0;
 		}
 		}
-		arg++;
 	}
 	}
 
 
-	return rcode;
+DONE:
+	len = hexport_r(&env_htab, '\n',
+			flag | grep_what | grep_how,
+			&res, 0, argc, argv);
+
+	if (len > 0) {
+		puts(res);
+		free(res);
+	}
+
+	if (len < 2)
+		return 1;
+
+	return 0;
 }
 }
 #endif
 #endif
 #endif /* CONFIG_SPL_BUILD */
 #endif /* CONFIG_SPL_BUILD */
@@ -315,6 +341,21 @@ int setenv_hex(const char *varname, ulong value)
 	return setenv(varname, str);
 	return setenv(varname, str);
 }
 }
 
 
+ulong getenv_hex(const char *varname, ulong default_val)
+{
+	const char *s;
+	ulong value;
+	char *endp;
+
+	s = getenv(varname);
+	if (s)
+		value = simple_strtoul(s, &endp, 16);
+	if (!s || endp == s)
+		return default_val;
+
+	return value;
+}
+
 #ifndef CONFIG_SPL_BUILD
 #ifndef CONFIG_SPL_BUILD
 static int do_env_set(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 static int do_env_set(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 {
 {
@@ -877,7 +918,9 @@ NXTARG:		;
 	argv++;
 	argv++;
 
 
 	if (sep) {		/* export as text file */
 	if (sep) {		/* export as text file */
-		len = hexport_r(&env_htab, sep, 0, &addr, size, argc, argv);
+		len = hexport_r(&env_htab, sep,
+				H_MATCH_KEY | H_MATCH_IDENT,
+				&addr, size, argc, argv);
 		if (len < 0) {
 		if (len < 0) {
 			error("Cannot export environment: errno = %d\n", errno);
 			error("Cannot export environment: errno = %d\n", errno);
 			return 1;
 			return 1;
@@ -895,7 +938,9 @@ NXTARG:		;
 	else			/* export as raw binary data */
 	else			/* export as raw binary data */
 		res = addr;
 		res = addr;
 
 
-	len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, argc, argv);
+	len = hexport_r(&env_htab, '\0',
+			H_MATCH_KEY | H_MATCH_IDENT,
+			&res, ENV_SIZE, argc, argv);
 	if (len < 0) {
 	if (len < 0) {
 		error("Cannot export environment: errno = %d\n", errno);
 		error("Cannot export environment: errno = %d\n", errno);
 		return 1;
 		return 1;
@@ -1114,7 +1159,11 @@ static char env_help_text[] =
 	"env flags - print variables that have non-default flags\n"
 	"env flags - print variables that have non-default flags\n"
 #endif
 #endif
 #if defined(CONFIG_CMD_GREPENV)
 #if defined(CONFIG_CMD_GREPENV)
-	"env grep string [...] - search environment\n"
+#ifdef CONFIG_REGEX
+	"env grep [-e] [-n | -v | -b] string [...] - search environment\n"
+#else
+	"env grep [-n | -v | -b] string [...] - search environment\n"
+#endif
 #endif
 #endif
 #if defined(CONFIG_CMD_IMPORTENV)
 #if defined(CONFIG_CMD_IMPORTENV)
 	"env import [-d] [-t | -b | -c] addr [size] - import environment\n"
 	"env import [-d] [-t | -b | -c] addr [size] - import environment\n"
@@ -1161,8 +1210,17 @@ U_BOOT_CMD_COMPLETE(
 U_BOOT_CMD_COMPLETE(
 U_BOOT_CMD_COMPLETE(
 	grepenv, CONFIG_SYS_MAXARGS, 0,  do_env_grep,
 	grepenv, CONFIG_SYS_MAXARGS, 0,  do_env_grep,
 	"search environment variables",
 	"search environment variables",
-	"string ...\n"
-	"    - list environment name=value pairs matching 'string'",
+#ifdef CONFIG_REGEX
+	"[-e] [-n | -v | -b] string ...\n"
+#else
+	"[-n | -v | -b] string ...\n"
+#endif
+	"    - list environment name=value pairs matching 'string'\n"
+#ifdef CONFIG_REGEX
+	"      \"-e\": enable regular expressions;\n"
+#endif
+	"      \"-n\": search variable names; \"-v\": search values;\n"
+	"      \"-b\": search both names and values (default)",
 	var_complete
 	var_complete
 );
 );
 #endif
 #endif

+ 14 - 4
common/cmd_sandbox.c

@@ -32,9 +32,16 @@ static int do_sandbox_ls(cmd_tbl_t *cmdtp, int flag, int argc,
 	return do_ls(cmdtp, flag, argc, argv, FS_TYPE_SANDBOX);
 	return do_ls(cmdtp, flag, argc, argv, FS_TYPE_SANDBOX);
 }
 }
 
 
+static int do_sandbox_save(cmd_tbl_t *cmdtp, int flag, int argc,
+			   char * const argv[])
+{
+	return do_save(cmdtp, flag, argc, argv, FS_TYPE_SANDBOX, 16);
+}
+
 static cmd_tbl_t cmd_sandbox_sub[] = {
 static cmd_tbl_t cmd_sandbox_sub[] = {
-	U_BOOT_CMD_MKENT(load, 3, 0, do_sandbox_load, "", ""),
+	U_BOOT_CMD_MKENT(load, 7, 0, do_sandbox_load, "", ""),
 	U_BOOT_CMD_MKENT(ls, 3, 0, do_sandbox_ls, "", ""),
 	U_BOOT_CMD_MKENT(ls, 3, 0, do_sandbox_ls, "", ""),
+	U_BOOT_CMD_MKENT(save, 6, 0, do_sandbox_save, "", ""),
 };
 };
 
 
 static int do_sandbox(cmd_tbl_t *cmdtp, int flag, int argc,
 static int do_sandbox(cmd_tbl_t *cmdtp, int flag, int argc,
@@ -56,8 +63,11 @@ static int do_sandbox(cmd_tbl_t *cmdtp, int flag, int argc,
 }
 }
 
 
 U_BOOT_CMD(
 U_BOOT_CMD(
-	sb,	6,	1,	do_sandbox,
+	sb,	8,	1,	do_sandbox,
 	"Miscellaneous sandbox commands",
 	"Miscellaneous sandbox commands",
-	"load host <addr> <filename> [<bytes> <offset>]  - load a file from host\n"
-	"sb ls host <filename>      - save a file to host"
+	"load host <dev> <addr> <filename> [<bytes> <offset>]  - "
+		"load a file from host\n"
+	"sb ls host <filename>                      - list files on host\n"
+	"sb save host <dev> <filename> <addr> <bytes> [<offset>] - "
+		"save a file to host\n"
 );
 );

+ 1 - 0
common/cmd_sata.c

@@ -44,6 +44,7 @@ int __sata_initialize(void)
 		sata_dev_desc[i].type = DEV_TYPE_HARDDISK;
 		sata_dev_desc[i].type = DEV_TYPE_HARDDISK;
 		sata_dev_desc[i].lba = 0;
 		sata_dev_desc[i].lba = 0;
 		sata_dev_desc[i].blksz = 512;
 		sata_dev_desc[i].blksz = 512;
+		sata_dev_desc[i].log2blksz = LOG2(sata_dev_desc[i].blksz);
 		sata_dev_desc[i].block_read = sata_read;
 		sata_dev_desc[i].block_read = sata_read;
 		sata_dev_desc[i].block_write = sata_write;
 		sata_dev_desc[i].block_write = sata_write;
 
 

+ 4 - 0
common/cmd_scsi.c

@@ -106,6 +106,8 @@ void scsi_scan(int mode)
 		scsi_dev_desc[i].lun=0xff;
 		scsi_dev_desc[i].lun=0xff;
 		scsi_dev_desc[i].lba=0;
 		scsi_dev_desc[i].lba=0;
 		scsi_dev_desc[i].blksz=0;
 		scsi_dev_desc[i].blksz=0;
+		scsi_dev_desc[i].log2blksz =
+			LOG2_INVALID(typeof(scsi_dev_desc[i].log2blksz));
 		scsi_dev_desc[i].type=DEV_TYPE_UNKNOWN;
 		scsi_dev_desc[i].type=DEV_TYPE_UNKNOWN;
 		scsi_dev_desc[i].vendor[0]=0;
 		scsi_dev_desc[i].vendor[0]=0;
 		scsi_dev_desc[i].product[0]=0;
 		scsi_dev_desc[i].product[0]=0;
@@ -166,6 +168,8 @@ void scsi_scan(int mode)
 			}
 			}
 			scsi_dev_desc[scsi_max_devs].lba=capacity;
 			scsi_dev_desc[scsi_max_devs].lba=capacity;
 			scsi_dev_desc[scsi_max_devs].blksz=blksz;
 			scsi_dev_desc[scsi_max_devs].blksz=blksz;
+			scsi_dev_desc[scsi_max_devs].log2blksz =
+				LOG2(scsi_dev_desc[scsi_max_devs].blksz);
 			scsi_dev_desc[scsi_max_devs].type=perq;
 			scsi_dev_desc[scsi_max_devs].type=perq;
 			init_part(&scsi_dev_desc[scsi_max_devs]);
 			init_part(&scsi_dev_desc[scsi_max_devs]);
 removable:
 removable:

+ 287 - 9
common/cmd_setexpr.c

@@ -1,5 +1,6 @@
 /*
 /*
  * Copyright 2008 Freescale Semiconductor, Inc.
  * Copyright 2008 Freescale Semiconductor, Inc.
+ * Copyright 2013 Wolfgang Denk <wd@denx.de>
  *
  *
  * See file CREDITS for list of people who contributed to this
  * See file CREDITS for list of people who contributed to this
  * project.
  * project.
@@ -50,28 +51,295 @@ static ulong get_arg(char *s, int w)
 	}
 	}
 }
 }
 
 
+#ifdef CONFIG_REGEX
+
+#include <slre.h>
+
+#define SLRE_BUFSZ	16384
+#define SLRE_PATSZ	4096
+
+/*
+ * memstr - Find the first substring in memory
+ * @s1: The string to be searched
+ * @s2: The string to search for
+ *
+ * Similar to and based on strstr(),
+ * but strings do not need to be NUL terminated.
+ */
+static char *memstr(const char *s1, int l1, const char *s2, int l2)
+{
+	if (!l2)
+		return (char *)s1;
+
+	while (l1 >= l2) {
+		l1--;
+		if (!memcmp(s1, s2, l2))
+			return (char *)s1;
+		s1++;
+	}
+	return NULL;
+}
+
+static char *substitute(char *string,	/* string buffer */
+			int *slen,	/* current string length */
+			int ssize,	/* string bufer size */
+			const char *old,/* old (replaced) string */
+			int olen,	/* length of old string */
+			const char *new,/* new (replacement) string */
+			int nlen)	/* length of new string */
+{
+	char *p = memstr(string, *slen, old, olen);
+
+	if (p == NULL)
+		return NULL;
+
+	debug("## Match at pos %ld: match len %d, subst len %d\n",
+		(long)(p - string), olen, nlen);
+
+	/* make sure replacement matches */
+	if (*slen + nlen - olen > ssize) {
+		printf("## error: substitution buffer overflow\n");
+		return NULL;
+	}
+
+	/* move tail if needed */
+	if (olen != nlen) {
+		int tail, len;
+
+		len = (olen > nlen) ? olen : nlen;
+
+		tail = ssize - (p + len - string);
+
+		debug("## tail len %d\n", tail);
+
+		memmove(p + nlen, p + olen, tail);
+	}
+
+	/* insert substitue */
+	memcpy(p, new, nlen);
+
+	*slen += nlen - olen;
+
+	return p + nlen;
+}
+
+/*
+ * Perform regex operations on a environment variable
+ *
+ * Returns 0 if OK, 1 in case of errors.
+ */
+static int regex_sub(const char *name,
+	const char *r, const char *s, const char *t,
+	int global)
+{
+	struct slre slre;
+	char data[SLRE_BUFSZ];
+	char *datap = data;
+	const char *value;
+	int res, len, nlen, loop;
+
+	if (name == NULL)
+		return 1;
+
+	if (slre_compile(&slre, r) == 0) {
+		printf("Error compiling regex: %s\n", slre.err_str);
+		return 1;
+	}
+
+	if (t == NULL) {
+		value = getenv(name);
+
+		if (value == NULL) {
+			printf("## Error: variable \"%s\" not defined\n", name);
+			return 1;
+		}
+		t = value;
+	}
+
+	debug("REGEX on %s=%s\n", name, t);
+	debug("REGEX=\"%s\", SUBST=\"%s\", GLOBAL=%d\n",
+		r, s ? s : "<NULL>", global);
+
+	len = strlen(t);
+	if (len + 1 > SLRE_BUFSZ) {
+		printf("## error: subst buffer overflow: have %d, need %d\n",
+			SLRE_BUFSZ, len + 1);
+		return 1;
+	}
+
+	strcpy(data, t);
+
+	if (s == NULL)
+		nlen = 0;
+	else
+		nlen = strlen(s);
+
+	for (loop = 0;; loop++) {
+		struct cap caps[slre.num_caps + 2];
+		char nbuf[SLRE_PATSZ];
+		const char *old;
+		char *np;
+		int i, olen;
+
+		(void) memset(caps, 0, sizeof(caps));
+
+		res = slre_match(&slre, datap, len, caps);
+
+		debug("Result: %d\n", res);
+
+		for (i = 0; i < slre.num_caps; i++) {
+			if (caps[i].len > 0) {
+				debug("Substring %d: [%.*s]\n", i,
+					caps[i].len, caps[i].ptr);
+			}
+		}
+
+		if (res == 0) {
+			if (loop == 0) {
+				printf("%s: No match\n", t);
+				return 1;
+			} else {
+				break;
+			}
+		}
+
+		debug("## MATCH ## %s\n", data);
+
+		if (s == NULL) {
+			printf("%s=%s\n", name, t);
+			return 1;
+		}
+
+		old = caps[0].ptr;
+		olen = caps[0].len;
+
+		if (nlen + 1 >= SLRE_PATSZ) {
+			printf("## error: pattern buffer overflow: have %d, need %d\n",
+				SLRE_BUFSZ, nlen + 1);
+			return 1;
+		}
+		strcpy(nbuf, s);
+
+		debug("## SUBST(1) ## %s\n", nbuf);
+
+		/*
+		 * Handle back references
+		 *
+		 * Support for \0 ... \9, where \0 is the
+		 * whole matched pattern (similar to &).
+		 *
+		 * Implementation is a bit simpleminded as
+		 * backrefs are substituted sequentially, one
+		 * by one.  This will lead to somewhat
+		 * unexpected results if the replacement
+		 * strings contain any \N strings then then
+		 * may get substitued, too.  We accept this
+		 * restriction for the sake of simplicity.
+		 */
+		for (i = 0; i < 10; ++i) {
+			char backref[2] = {
+				'\\',
+				'0',
+			};
+
+			if (caps[i].len == 0)
+				break;
+
+			backref[1] += i;
+
+			debug("## BACKREF %d: replace \"%.*s\" by \"%.*s\" in \"%s\"\n",
+				i,
+				2, backref,
+				caps[i].len, caps[i].ptr,
+				nbuf);
+
+			for (np = nbuf;;) {
+				char *p = memstr(np, nlen, backref, 2);
+
+				if (p == NULL)
+					break;
+
+				np = substitute(np, &nlen,
+					SLRE_PATSZ,
+					backref, 2,
+					caps[i].ptr, caps[i].len);
+
+				if (np == NULL)
+					return 1;
+			}
+		}
+		debug("## SUBST(2) ## %s\n", nbuf);
+
+		datap = substitute(datap, &len, SLRE_BUFSZ,
+				old, olen,
+				nbuf, nlen);
+
+		if (datap == NULL)
+			return 1;
+
+		debug("## REMAINDER: %s\n", datap);
+
+		debug("## RESULT: %s\n", data);
+
+		if (!global)
+			break;
+	}
+	debug("## FINAL (now setenv()) :  %s\n", data);
+
+	printf("%s=%s\n", name, data);
+
+	return setenv(name, data);
+}
+#endif
+
 static int do_setexpr(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 static int do_setexpr(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 {
 {
 	ulong a, b;
 	ulong a, b;
 	ulong value;
 	ulong value;
 	int w;
 	int w;
 
 
-	/* Validate arguments */
-	if (argc != 5 && argc != 3)
-		return CMD_RET_USAGE;
-	if (argc == 5 && strlen(argv[3]) != 1)
+	/*
+	 * We take 3, 5, or 6 arguments:
+	 * 3 : setexpr name value
+	 * 5 : setexpr name val1 op val2
+	 *     setexpr name [g]sub r s
+	 * 6 : setexpr name [g]sub r s t
+	 */
+
+	/* > 6 already tested by max command args */
+	if ((argc < 3) || (argc == 4))
 		return CMD_RET_USAGE;
 		return CMD_RET_USAGE;
 
 
 	w = cmd_get_data_size(argv[0], 4);
 	w = cmd_get_data_size(argv[0], 4);
 
 
 	a = get_arg(argv[2], w);
 	a = get_arg(argv[2], w);
 
 
+	/* plain assignment: "setexpr name value" */
 	if (argc == 3) {
 	if (argc == 3) {
 		setenv_hex(argv[1], a);
 		setenv_hex(argv[1], a);
-
 		return 0;
 		return 0;
 	}
 	}
 
 
+	/* 5 or 6 args (6 args only with [g]sub) */
+#ifdef CONFIG_REGEX
+	/*
+	 * rexep handling: "setexpr name [g]sub r s [t]"
+	 * with 5 args, "t" will be NULL
+	 */
+	if (strcmp(argv[2], "gsub") == 0)
+		return regex_sub(argv[1], argv[3], argv[4], argv[5], 1);
+
+	if (strcmp(argv[2], "sub") == 0)
+		return regex_sub(argv[1], argv[3], argv[4], argv[5], 0);
+#endif
+
+	/* standard operators: "setexpr name val1 op val2" */
+	if (argc != 5)
+		return CMD_RET_USAGE;
+
+	if (strlen(argv[3]) != 1)
+		return CMD_RET_USAGE;
+
 	b = get_arg(argv[4], w);
 	b = get_arg(argv[4], w);
 
 
 	switch (argv[3][0]) {
 	switch (argv[3][0]) {
@@ -110,13 +378,23 @@ static int do_setexpr(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 }
 }
 
 
 U_BOOT_CMD(
 U_BOOT_CMD(
-	setexpr, 5, 0, do_setexpr,
+	setexpr, 6, 0, do_setexpr,
 	"set environment variable as the result of eval expression",
 	"set environment variable as the result of eval expression",
 	"[.b, .w, .l] name [*]value1 <op> [*]value2\n"
 	"[.b, .w, .l] name [*]value1 <op> [*]value2\n"
 	"    - set environment variable 'name' to the result of the evaluated\n"
 	"    - set environment variable 'name' to the result of the evaluated\n"
-	"      express specified by <op>.  <op> can be &, |, ^, +, -, *, /, %\n"
+	"      expression specified by <op>.  <op> can be &, |, ^, +, -, *, /, %\n"
 	"      size argument is only meaningful if value1 and/or value2 are\n"
 	"      size argument is only meaningful if value1 and/or value2 are\n"
 	"      memory addresses (*)\n"
 	"      memory addresses (*)\n"
-	"setexpr[.b, .w, .l] name *value\n"
-	"    - load a memory address into a variable"
+	"setexpr[.b, .w, .l] name [*]value\n"
+	"    - load a value into a variable"
+#ifdef CONFIG_REGEX
+	"\n"
+	"setexpr name gsub r s [t]\n"
+	"    - For each substring matching the regular expression <r> in the\n"
+	"      string <t>, substitute the string <s>.  The result is\n"
+	"      assigned to <name>.  If <t> is not supplied, use the old\n"
+	"      value of <name>\n"
+	"setexpr name sub r s [t]\n"
+	"    - Just like gsub(), but replace only the first matching substring"
+#endif
 );
 );

+ 7 - 4
common/cmd_source.c

@@ -36,6 +36,7 @@
 #include <image.h>
 #include <image.h>
 #include <malloc.h>
 #include <malloc.h>
 #include <asm/byteorder.h>
 #include <asm/byteorder.h>
+#include <asm/io.h>
 #if defined(CONFIG_8xx)
 #if defined(CONFIG_8xx)
 #include <mpc8xx.h>
 #include <mpc8xx.h>
 #endif
 #endif
@@ -44,9 +45,10 @@ int
 source (ulong addr, const char *fit_uname)
 source (ulong addr, const char *fit_uname)
 {
 {
 	ulong		len;
 	ulong		len;
-	image_header_t	*hdr;
+	const image_header_t *hdr;
 	ulong		*data;
 	ulong		*data;
 	int		verify;
 	int		verify;
+	void *buf;
 #if defined(CONFIG_FIT)
 #if defined(CONFIG_FIT)
 	const void*	fit_hdr;
 	const void*	fit_hdr;
 	int		noffset;
 	int		noffset;
@@ -56,9 +58,10 @@ source (ulong addr, const char *fit_uname)
 
 
 	verify = getenv_yesno ("verify");
 	verify = getenv_yesno ("verify");
 
 
-	switch (genimg_get_format ((void *)addr)) {
+	buf = map_sysmem(addr, 0);
+	switch (genimg_get_format(buf)) {
 	case IMAGE_FORMAT_LEGACY:
 	case IMAGE_FORMAT_LEGACY:
-		hdr = (image_header_t *)addr;
+		hdr = buf;
 
 
 		if (!image_check_magic (hdr)) {
 		if (!image_check_magic (hdr)) {
 			puts ("Bad magic number\n");
 			puts ("Bad magic number\n");
@@ -104,7 +107,7 @@ source (ulong addr, const char *fit_uname)
 			return 1;
 			return 1;
 		}
 		}
 
 
-		fit_hdr = (const void *)addr;
+		fit_hdr = buf;
 		if (!fit_check_format (fit_hdr)) {
 		if (!fit_check_format (fit_hdr)) {
 			puts ("Bad FIT image format\n");
 			puts ("Bad FIT image format\n");
 			return 1;
 			return 1;

+ 123 - 9
common/env_mmc.c

@@ -32,6 +32,11 @@
 #include <search.h>
 #include <search.h>
 #include <errno.h>
 #include <errno.h>
 
 
+#if defined(CONFIG_ENV_SIZE_REDUND) &&  \
+	(CONFIG_ENV_SIZE_REDUND != CONFIG_ENV_SIZE)
+#error CONFIG_ENV_SIZE_REDUND should be the same as CONFIG_ENV_SIZE
+#endif
+
 char *env_name_spec = "MMC";
 char *env_name_spec = "MMC";
 
 
 #ifdef ENV_IS_EMBEDDED
 #ifdef ENV_IS_EMBEDDED
@@ -46,9 +51,13 @@ DECLARE_GLOBAL_DATA_PTR;
 #define CONFIG_ENV_OFFSET 0
 #define CONFIG_ENV_OFFSET 0
 #endif
 #endif
 
 
-__weak int mmc_get_env_addr(struct mmc *mmc, u32 *env_addr)
+__weak int mmc_get_env_addr(struct mmc *mmc, int copy, u32 *env_addr)
 {
 {
 	*env_addr = CONFIG_ENV_OFFSET;
 	*env_addr = CONFIG_ENV_OFFSET;
+#ifdef CONFIG_ENV_OFFSET_REDUND
+	if (copy)
+		*env_addr = CONFIG_ENV_OFFSET_REDUND;
+#endif
 	return 0;
 	return 0;
 }
 }
 
 
@@ -110,6 +119,10 @@ static inline int write_env(struct mmc *mmc, unsigned long size,
 	return (n == blk_cnt) ? 0 : -1;
 	return (n == blk_cnt) ? 0 : -1;
 }
 }
 
 
+#ifdef CONFIG_ENV_OFFSET_REDUND
+static unsigned char env_flags;
+#endif
+
 int saveenv(void)
 int saveenv(void)
 {
 {
 	ALLOC_CACHE_ALIGN_BUFFER(env_t, env_new, 1);
 	ALLOC_CACHE_ALIGN_BUFFER(env_t, env_new, 1);
@@ -117,16 +130,11 @@ int saveenv(void)
 	char	*res;
 	char	*res;
 	struct mmc *mmc = find_mmc_device(CONFIG_SYS_MMC_ENV_DEV);
 	struct mmc *mmc = find_mmc_device(CONFIG_SYS_MMC_ENV_DEV);
 	u32	offset;
 	u32	offset;
-	int	ret;
+	int	ret, copy = 0;
 
 
 	if (init_mmc_for_env(mmc))
 	if (init_mmc_for_env(mmc))
 		return 1;
 		return 1;
 
 
-	if (mmc_get_env_addr(mmc, &offset)) {
-		ret = 1;
-		goto fini;
-	}
-
 	res = (char *)&env_new->data;
 	res = (char *)&env_new->data;
 	len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL);
 	len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL);
 	if (len < 0) {
 	if (len < 0) {
@@ -136,7 +144,21 @@ int saveenv(void)
 	}
 	}
 
 
 	env_new->crc = crc32(0, &env_new->data[0], ENV_SIZE);
 	env_new->crc = crc32(0, &env_new->data[0], ENV_SIZE);
-	printf("Writing to MMC(%d)... ", CONFIG_SYS_MMC_ENV_DEV);
+
+#ifdef CONFIG_ENV_OFFSET_REDUND
+	env_new->flags	= ++env_flags; /* increase the serial */
+
+	if (gd->env_valid == 1)
+		copy = 1;
+#endif
+
+	if (mmc_get_env_addr(mmc, copy, &offset)) {
+		ret = 1;
+		goto fini;
+	}
+
+	printf("Writing to %sMMC(%d)... ", copy ? "redundant " : "",
+	       CONFIG_SYS_MMC_ENV_DEV);
 	if (write_env(mmc, CONFIG_ENV_SIZE, offset, (u_char *)env_new)) {
 	if (write_env(mmc, CONFIG_ENV_SIZE, offset, (u_char *)env_new)) {
 		puts("failed\n");
 		puts("failed\n");
 		ret = 1;
 		ret = 1;
@@ -146,6 +168,10 @@ int saveenv(void)
 	puts("done\n");
 	puts("done\n");
 	ret = 0;
 	ret = 0;
 
 
+#ifdef CONFIG_ENV_OFFSET_REDUND
+	gd->env_valid = gd->env_valid == 2 ? 1 : 2;
+#endif
+
 fini:
 fini:
 	fini_mmc_for_env(mmc);
 	fini_mmc_for_env(mmc);
 	return ret;
 	return ret;
@@ -166,6 +192,93 @@ static inline int read_env(struct mmc *mmc, unsigned long size,
 	return (n == blk_cnt) ? 0 : -1;
 	return (n == blk_cnt) ? 0 : -1;
 }
 }
 
 
+#ifdef CONFIG_ENV_OFFSET_REDUND
+void env_relocate_spec(void)
+{
+#if !defined(ENV_IS_EMBEDDED)
+	struct mmc *mmc = find_mmc_device(CONFIG_SYS_MMC_ENV_DEV);
+	u32 offset1, offset2;
+	int read1_fail = 0, read2_fail = 0;
+	int crc1_ok = 0, crc2_ok = 0;
+	env_t *ep, *tmp_env1, *tmp_env2;
+	int ret;
+
+	tmp_env1 = (env_t *)malloc(CONFIG_ENV_SIZE);
+	tmp_env2 = (env_t *)malloc(CONFIG_ENV_SIZE);
+	if (tmp_env1 == NULL || tmp_env2 == NULL) {
+		puts("Can't allocate buffers for environment\n");
+		ret = 1;
+		goto err;
+	}
+
+	if (init_mmc_for_env(mmc)) {
+		ret = 1;
+		goto err;
+	}
+
+	if (mmc_get_env_addr(mmc, 0, &offset1) ||
+	    mmc_get_env_addr(mmc, 1, &offset2)) {
+		ret = 1;
+		goto fini;
+	}
+
+	read1_fail = read_env(mmc, CONFIG_ENV_SIZE, offset1, tmp_env1);
+	read2_fail = read_env(mmc, CONFIG_ENV_SIZE, offset2, tmp_env2);
+
+	if (read1_fail && read2_fail)
+		puts("*** Error - No Valid Environment Area found\n");
+	else if (read1_fail || read2_fail)
+		puts("*** Warning - some problems detected "
+		     "reading environment; recovered successfully\n");
+
+	crc1_ok = !read1_fail &&
+		(crc32(0, tmp_env1->data, ENV_SIZE) == tmp_env1->crc);
+	crc2_ok = !read2_fail &&
+		(crc32(0, tmp_env2->data, ENV_SIZE) == tmp_env2->crc);
+
+	if (!crc1_ok && !crc2_ok) {
+		ret = 1;
+		goto fini;
+	} else if (crc1_ok && !crc2_ok) {
+		gd->env_valid = 1;
+	} else if (!crc1_ok && crc2_ok) {
+		gd->env_valid = 2;
+	} else {
+		/* both ok - check serial */
+		if (tmp_env1->flags == 255 && tmp_env2->flags == 0)
+			gd->env_valid = 2;
+		else if (tmp_env2->flags == 255 && tmp_env1->flags == 0)
+			gd->env_valid = 1;
+		else if (tmp_env1->flags > tmp_env2->flags)
+			gd->env_valid = 1;
+		else if (tmp_env2->flags > tmp_env1->flags)
+			gd->env_valid = 2;
+		else /* flags are equal - almost impossible */
+			gd->env_valid = 1;
+	}
+
+	free(env_ptr);
+
+	if (gd->env_valid == 1)
+		ep = tmp_env1;
+	else
+		ep = tmp_env2;
+
+	env_flags = ep->flags;
+	env_import((char *)ep, 0);
+	ret = 0;
+
+fini:
+	fini_mmc_for_env(mmc);
+err:
+	if (ret)
+		set_default_env(NULL);
+
+	free(tmp_env1);
+	free(tmp_env2);
+#endif
+}
+#else /* ! CONFIG_ENV_OFFSET_REDUND */
 void env_relocate_spec(void)
 void env_relocate_spec(void)
 {
 {
 #if !defined(ENV_IS_EMBEDDED)
 #if !defined(ENV_IS_EMBEDDED)
@@ -179,7 +292,7 @@ void env_relocate_spec(void)
 		goto err;
 		goto err;
 	}
 	}
 
 
-	if (mmc_get_env_addr(mmc, &offset)) {
+	if (mmc_get_env_addr(mmc, 0, &offset)) {
 		ret = 1;
 		ret = 1;
 		goto fini;
 		goto fini;
 	}
 	}
@@ -199,3 +312,4 @@ err:
 		set_default_env(NULL);
 		set_default_env(NULL);
 #endif
 #endif
 }
 }
+#endif /* CONFIG_ENV_OFFSET_REDUND */

+ 11 - 0
common/flash.c

@@ -149,6 +149,9 @@ flash_write (char *src, ulong addr, ulong cnt)
 	flash_info_t *info_first = addr2info (addr);
 	flash_info_t *info_first = addr2info (addr);
 	flash_info_t *info_last  = addr2info (end );
 	flash_info_t *info_last  = addr2info (end );
 	flash_info_t *info;
 	flash_info_t *info;
+	__maybe_unused char *src_orig = src;
+	__maybe_unused char *addr_orig = (char *)addr;
+	__maybe_unused ulong cnt_orig = cnt;
 
 
 	if (cnt == 0) {
 	if (cnt == 0) {
 		return (ERR_OK);
 		return (ERR_OK);
@@ -185,6 +188,14 @@ flash_write (char *src, ulong addr, ulong cnt)
 		addr += len;
 		addr += len;
 		src  += len;
 		src  += len;
 	}
 	}
+
+#if defined(CONFIG_FLASH_VERIFY)
+	if (memcmp(src_orig, addr_orig, cnt_orig)) {
+		printf("\nVerify failed!\n");
+		return ERR_PROG_ERROR;
+	}
+#endif /* CONFIG_SYS_FLASH_VERIFY_AFTER_WRITE */
+
 	return (ERR_OK);
 	return (ERR_OK);
 #endif /* CONFIG_SPD823TS */
 #endif /* CONFIG_SPD823TS */
 }
 }

+ 0 - 8
common/main.c

@@ -45,10 +45,6 @@
 #include <fdtdec.h>
 #include <fdtdec.h>
 #endif
 #endif
 
 
-#ifdef CONFIG_OF_LIBFDT
-#include <fdt_support.h>
-#endif /* CONFIG_OF_LIBFDT */
-
 #include <post.h>
 #include <post.h>
 #include <linux/ctype.h>
 #include <linux/ctype.h>
 #include <menu.h>
 #include <menu.h>
@@ -376,10 +372,6 @@ void main_loop (void)
 
 
 	bootstage_mark_name(BOOTSTAGE_ID_MAIN_LOOP, "main_loop");
 	bootstage_mark_name(BOOTSTAGE_ID_MAIN_LOOP, "main_loop");
 
 
-#if defined CONFIG_OF_CONTROL
-       set_working_fdt_addr((void *)gd->fdt_blob);
-#endif /* CONFIG_OF_CONTROL */
-
 #ifdef CONFIG_BOOTCOUNT_LIMIT
 #ifdef CONFIG_BOOTCOUNT_LIMIT
 	bootcount = bootcount_load();
 	bootcount = bootcount_load();
 	bootcount++;
 	bootcount++;

+ 0 - 7
common/spl/spl.c

@@ -48,13 +48,6 @@ struct spl_image_info spl_image;
 /* Define board data structure */
 /* Define board data structure */
 static bd_t bdata __attribute__ ((section(".data")));
 static bd_t bdata __attribute__ ((section(".data")));
 
 
-inline void hang(void)
-{
-	puts("### ERROR ### Please RESET the board ###\n");
-	for (;;)
-		;
-}
-
 /*
 /*
  * Default function to determine if u-boot or the OS should
  * Default function to determine if u-boot or the OS should
  * be started. This implementation always returns 1.
  * be started. This implementation always returns 1.

+ 1 - 0
common/usb_storage.c

@@ -1430,6 +1430,7 @@ int usb_stor_get_info(struct usb_device *dev, struct us_data *ss,
 			*capacity, *blksz);
 			*capacity, *blksz);
 	dev_desc->lba = *capacity;
 	dev_desc->lba = *capacity;
 	dev_desc->blksz = *blksz;
 	dev_desc->blksz = *blksz;
+	dev_desc->log2blksz = LOG2(dev_desc->blksz);
 	dev_desc->type = perq;
 	dev_desc->type = perq;
 	USB_STOR_PRINTF(" address %d\n", dev_desc->target);
 	USB_STOR_PRINTF(" address %d\n", dev_desc->target);
 	USB_STOR_PRINTF("partype: %d\n", dev_desc->part_type);
 	USB_STOR_PRINTF("partype: %d\n", dev_desc->part_type);

+ 6 - 2
config.mk

@@ -222,6 +222,10 @@ ifneq ($(CONFIG_SPL_PAD_TO),)
 CPPFLAGS += -DCONFIG_SPL_PAD_TO=$(CONFIG_SPL_PAD_TO)
 CPPFLAGS += -DCONFIG_SPL_PAD_TO=$(CONFIG_SPL_PAD_TO)
 endif
 endif
 
 
+ifneq ($(CONFIG_UBOOT_PAD_TO),)
+CPPFLAGS += -DCONFIG_UBOOT_PAD_TO=$(CONFIG_UBOOT_PAD_TO)
+endif
+
 ifeq ($(CONFIG_SPL_BUILD),y)
 ifeq ($(CONFIG_SPL_BUILD),y)
 CPPFLAGS += -DCONFIG_SPL_BUILD
 CPPFLAGS += -DCONFIG_SPL_BUILD
 endif
 endif
@@ -229,8 +233,8 @@ endif
 # Does this architecture support generic board init?
 # Does this architecture support generic board init?
 ifeq ($(__HAVE_ARCH_GENERIC_BOARD),)
 ifeq ($(__HAVE_ARCH_GENERIC_BOARD),)
 ifneq ($(CONFIG_SYS_GENERIC_BOARD),)
 ifneq ($(CONFIG_SYS_GENERIC_BOARD),)
-$(error Your architecture does not support generic board. Please undefined \
-CONFIG_SYS_GENERIC_BOARD in your board config file)
+CHECK_GENERIC_BOARD = $(error Your architecture does not support generic board. \
+Please undefined CONFIG_SYS_GENERIC_BOARD in your board config file)
 endif
 endif
 endif
 endif
 
 

+ 16 - 3
disk/part_dos.c

@@ -74,13 +74,26 @@ static void print_one_part(dos_partition_t *p, int ext_part_sector,
 
 
 static int test_block_type(unsigned char *buffer)
 static int test_block_type(unsigned char *buffer)
 {
 {
+	int slot;
+	struct dos_partition *p;
+
 	if((buffer[DOS_PART_MAGIC_OFFSET + 0] != 0x55) ||
 	if((buffer[DOS_PART_MAGIC_OFFSET + 0] != 0x55) ||
 	    (buffer[DOS_PART_MAGIC_OFFSET + 1] != 0xaa) ) {
 	    (buffer[DOS_PART_MAGIC_OFFSET + 1] != 0xaa) ) {
 		return (-1);
 		return (-1);
 	} /* no DOS Signature at all */
 	} /* no DOS Signature at all */
-	if (strncmp((char *)&buffer[DOS_PBR_FSTYPE_OFFSET],"FAT",3)==0 ||
-	    strncmp((char *)&buffer[DOS_PBR32_FSTYPE_OFFSET],"FAT32",5)==0) {
-		return DOS_PBR; /* is PBR */
+	p = (struct dos_partition *)&buffer[DOS_PART_TBL_OFFSET];
+	for (slot = 0; slot < 3; slot++) {
+		if (p->boot_ind != 0 && p->boot_ind != 0x80) {
+			if (!slot &&
+			    (strncmp((char *)&buffer[DOS_PBR_FSTYPE_OFFSET],
+				     "FAT", 3) == 0 ||
+			     strncmp((char *)&buffer[DOS_PBR32_FSTYPE_OFFSET],
+				     "FAT32", 5) == 0)) {
+				return DOS_PBR; /* is PBR */
+			} else {
+				return -1;
+			}
+		}
 	}
 	}
 	return DOS_MBR;	    /* Is MBR */
 	return DOS_MBR;	    /* Is MBR */
 }
 }

+ 22 - 16
disk/part_efi.c

@@ -115,7 +115,7 @@ static inline int is_bootable(gpt_entry *p)
 
 
 void print_part_efi(block_dev_desc_t * dev_desc)
 void print_part_efi(block_dev_desc_t * dev_desc)
 {
 {
-	ALLOC_CACHE_ALIGN_BUFFER(gpt_header, gpt_head, 1);
+	ALLOC_CACHE_ALIGN_BUFFER_PAD(gpt_header, gpt_head, 1, dev_desc->blksz);
 	gpt_entry *gpt_pte = NULL;
 	gpt_entry *gpt_pte = NULL;
 	int i = 0;
 	int i = 0;
 	char uuid[37];
 	char uuid[37];
@@ -162,7 +162,7 @@ void print_part_efi(block_dev_desc_t * dev_desc)
 int get_partition_info_efi(block_dev_desc_t * dev_desc, int part,
 int get_partition_info_efi(block_dev_desc_t * dev_desc, int part,
 				disk_partition_t * info)
 				disk_partition_t * info)
 {
 {
-	ALLOC_CACHE_ALIGN_BUFFER(gpt_header, gpt_head, 1);
+	ALLOC_CACHE_ALIGN_BUFFER_PAD(gpt_header, gpt_head, 1, dev_desc->blksz);
 	gpt_entry *gpt_pte = NULL;
 	gpt_entry *gpt_pte = NULL;
 
 
 	/* "part" argument must be at least 1 */
 	/* "part" argument must be at least 1 */
@@ -190,7 +190,7 @@ int get_partition_info_efi(block_dev_desc_t * dev_desc, int part,
 	/* The ending LBA is inclusive, to calculate size, add 1 to it */
 	/* The ending LBA is inclusive, to calculate size, add 1 to it */
 	info->size = ((u64)le64_to_cpu(gpt_pte[part - 1].ending_lba) + 1)
 	info->size = ((u64)le64_to_cpu(gpt_pte[part - 1].ending_lba) + 1)
 		     - info->start;
 		     - info->start;
-	info->blksz = GPT_BLOCK_SIZE;
+	info->blksz = dev_desc->blksz;
 
 
 	sprintf((char *)info->name, "%s",
 	sprintf((char *)info->name, "%s",
 			print_efiname(&gpt_pte[part - 1]));
 			print_efiname(&gpt_pte[part - 1]));
@@ -210,7 +210,7 @@ int get_partition_info_efi(block_dev_desc_t * dev_desc, int part,
 
 
 int test_part_efi(block_dev_desc_t * dev_desc)
 int test_part_efi(block_dev_desc_t * dev_desc)
 {
 {
-	ALLOC_CACHE_ALIGN_BUFFER(legacy_mbr, legacymbr, 1);
+	ALLOC_CACHE_ALIGN_BUFFER_PAD(legacy_mbr, legacymbr, 1, dev_desc->blksz);
 
 
 	/* Read legacy MBR from block 0 and validate it */
 	/* Read legacy MBR from block 0 and validate it */
 	if ((dev_desc->block_read(dev_desc->dev, 0, 1, (ulong *)legacymbr) != 1)
 	if ((dev_desc->block_read(dev_desc->dev, 0, 1, (ulong *)legacymbr) != 1)
@@ -311,9 +311,8 @@ static int string_uuid(char *uuid, u8 *dst)
 int write_gpt_table(block_dev_desc_t *dev_desc,
 int write_gpt_table(block_dev_desc_t *dev_desc,
 		gpt_header *gpt_h, gpt_entry *gpt_e)
 		gpt_header *gpt_h, gpt_entry *gpt_e)
 {
 {
-	const int pte_blk_num = (gpt_h->num_partition_entries
-		* sizeof(gpt_entry)) / dev_desc->blksz;
-
+	const int pte_blk_cnt = BLOCK_CNT((gpt_h->num_partition_entries
+					   * sizeof(gpt_entry)), dev_desc);
 	u32 calc_crc32;
 	u32 calc_crc32;
 	u64 val;
 	u64 val;
 
 
@@ -336,8 +335,8 @@ int write_gpt_table(block_dev_desc_t *dev_desc,
 	if (dev_desc->block_write(dev_desc->dev, 1, 1, gpt_h) != 1)
 	if (dev_desc->block_write(dev_desc->dev, 1, 1, gpt_h) != 1)
 		goto err;
 		goto err;
 
 
-	if (dev_desc->block_write(dev_desc->dev, 2, pte_blk_num, gpt_e)
-	    != pte_blk_num)
+	if (dev_desc->block_write(dev_desc->dev, 2, pte_blk_cnt, gpt_e)
+	    != pte_blk_cnt)
 		goto err;
 		goto err;
 
 
 	/* recalculate the values for the Second GPT Header */
 	/* recalculate the values for the Second GPT Header */
@@ -352,7 +351,7 @@ int write_gpt_table(block_dev_desc_t *dev_desc,
 
 
 	if (dev_desc->block_write(dev_desc->dev,
 	if (dev_desc->block_write(dev_desc->dev,
 				  le32_to_cpu(gpt_h->last_usable_lba + 1),
 				  le32_to_cpu(gpt_h->last_usable_lba + 1),
-				  pte_blk_num, gpt_e) != pte_blk_num)
+				  pte_blk_cnt, gpt_e) != pte_blk_cnt)
 		goto err;
 		goto err;
 
 
 	if (dev_desc->block_write(dev_desc->dev,
 	if (dev_desc->block_write(dev_desc->dev,
@@ -462,13 +461,18 @@ int gpt_restore(block_dev_desc_t *dev_desc, char *str_disk_guid,
 {
 {
 	int ret;
 	int ret;
 
 
-	gpt_header *gpt_h = calloc(1, sizeof(gpt_header));
+	gpt_header *gpt_h = calloc(1, PAD_TO_BLOCKSIZE(sizeof(gpt_header),
+						       dev_desc));
+	gpt_entry *gpt_e;
+
 	if (gpt_h == NULL) {
 	if (gpt_h == NULL) {
 		printf("%s: calloc failed!\n", __func__);
 		printf("%s: calloc failed!\n", __func__);
 		return -1;
 		return -1;
 	}
 	}
 
 
-	gpt_entry *gpt_e = calloc(GPT_ENTRY_NUMBERS, sizeof(gpt_entry));
+	gpt_e = calloc(1, PAD_TO_BLOCKSIZE(GPT_ENTRY_NUMBERS
+					       * sizeof(gpt_entry),
+					       dev_desc));
 	if (gpt_e == NULL) {
 	if (gpt_e == NULL) {
 		printf("%s: calloc failed!\n", __func__);
 		printf("%s: calloc failed!\n", __func__);
 		free(gpt_h);
 		free(gpt_h);
@@ -652,7 +656,7 @@ static int is_gpt_valid(block_dev_desc_t * dev_desc, unsigned long long lba,
 static gpt_entry *alloc_read_gpt_entries(block_dev_desc_t * dev_desc,
 static gpt_entry *alloc_read_gpt_entries(block_dev_desc_t * dev_desc,
 					 gpt_header * pgpt_head)
 					 gpt_header * pgpt_head)
 {
 {
-	size_t count = 0;
+	size_t count = 0, blk_cnt;
 	gpt_entry *pte = NULL;
 	gpt_entry *pte = NULL;
 
 
 	if (!dev_desc || !pgpt_head) {
 	if (!dev_desc || !pgpt_head) {
@@ -669,7 +673,8 @@ static gpt_entry *alloc_read_gpt_entries(block_dev_desc_t * dev_desc,
 
 
 	/* Allocate memory for PTE, remember to FREE */
 	/* Allocate memory for PTE, remember to FREE */
 	if (count != 0) {
 	if (count != 0) {
-		pte = memalign(ARCH_DMA_MINALIGN, count);
+		pte = memalign(ARCH_DMA_MINALIGN,
+			       PAD_TO_BLOCKSIZE(count, dev_desc));
 	}
 	}
 
 
 	if (count == 0 || pte == NULL) {
 	if (count == 0 || pte == NULL) {
@@ -680,10 +685,11 @@ static gpt_entry *alloc_read_gpt_entries(block_dev_desc_t * dev_desc,
 	}
 	}
 
 
 	/* Read GPT Entries from device */
 	/* Read GPT Entries from device */
+	blk_cnt = BLOCK_CNT(count, dev_desc);
 	if (dev_desc->block_read (dev_desc->dev,
 	if (dev_desc->block_read (dev_desc->dev,
 		le64_to_cpu(pgpt_head->partition_entry_lba),
 		le64_to_cpu(pgpt_head->partition_entry_lba),
-		(lbaint_t) (count / GPT_BLOCK_SIZE), pte)
-		!= (count / GPT_BLOCK_SIZE)) {
+		(lbaint_t) (blk_cnt), pte)
+		!= blk_cnt) {
 
 
 		printf("*** ERROR: Can't read GPT Entries ***\n");
 		printf("*** ERROR: Can't read GPT Entries ***\n");
 		free(pte);
 		free(pte);

+ 3 - 0
disk/part_iso.c

@@ -73,6 +73,9 @@ int get_partition_info_iso_verb(block_dev_desc_t * dev_desc, int part_num, disk_
 	iso_val_entry_t *pve = (iso_val_entry_t *)tmpbuf;
 	iso_val_entry_t *pve = (iso_val_entry_t *)tmpbuf;
 	iso_init_def_entry_t *pide;
 	iso_init_def_entry_t *pide;
 
 
+	if (dev_desc->blksz != CD_SECTSIZE)
+		return -1;
+
 	/* the first sector (sector 0x10) must be a primary volume desc */
 	/* the first sector (sector 0x10) must be a primary volume desc */
 	blkaddr=PVD_OFFSET;
 	blkaddr=PVD_OFFSET;
 	if (dev_desc->block_read (dev_desc->dev, PVD_OFFSET, 1, (ulong *) tmpbuf) != 1)
 	if (dev_desc->block_read (dev_desc->dev, PVD_OFFSET, 1, (ulong *) tmpbuf) != 1)

+ 5 - 1
doc/README.fdt-control

@@ -142,7 +142,11 @@ join the two:
 
 
 and then flash image.bin onto your board.
 and then flash image.bin onto your board.
 
 
-You cannot use both of these options at the same time.
+If CONFIG_OF_HOSTFILE is defined, then it will be read from a file on
+startup. This is only useful for sandbox. Use the -d flag to U-Boot to
+specify the file to read.
+
+You cannot use more than one of these options at the same time.
 
 
 If you wish to put the fdt at a different address in memory, you can
 If you wish to put the fdt at a different address in memory, you can
 define the "fdtcontroladdr" environment variable. This is the hex
 define the "fdtcontroladdr" environment variable. This is the hex

+ 199 - 0
doc/README.p1010rdb

@@ -0,0 +1,199 @@
+Overview
+=========
+The P1010RDB is a Freescale reference design board that hosts the P1010 SoC.
+
+The P1010 is a cost-effective, low-power, highly integrated host processor
+based on a Power Architecture e500v2 core (maximum core frequency 800/1000 MHz),
+that addresses the requirements of several routing, gateways, storage, consumer,
+and industrial applications. Applications of interest include the main CPUs and
+I/O processors in network attached storage (NAS), the voice over IP (VoIP)
+router/gateway, and wireless LAN (WLAN) and industrial controllers.
+
+The P1010RDB board features are as follows:
+Memory subsystem:
+	- 1Gbyte unbuffered DDR3 SDRAM discrete devices (32-bit bus)
+	- 32 Mbyte NOR flash single-chip memory
+	- 32 Mbyte NAND flash memory
+	- 256 Kbit M24256 I2C EEPROM
+	- 16 Mbyte SPI memory
+	- I2C Board EEPROM 128x8 bit memory
+	- SD/MMC connector to interface with the SD memory card
+Interfaces:
+	- PCIe:
+		- Lane0: x1 mini-PCIe slot
+		- Lane1: x1 PCIe standard slot
+	- SATA:
+		- 1 internal SATA connector to 2.5" 160G SATA2 HDD
+		- 1 eSATA connector to rear panel
+	- 10/100/1000 BaseT Ethernet ports:
+		- eTSEC1, RGMII: one 10/100/1000 port using Vitesse VSC8641XKO
+		- eTSEC2, SGMII: one 10/100/1000 port using Vitesse VSC8221
+		- eTSEC3, SGMII: one 10/100/1000 port using Vitesse VSC8221
+	- USB 2.0 port:
+		- x1 USB2.0 port: via an ULPI PHY to micro-AB connector
+		- x1 USB2.0 poort via an internal PHY to micro-AB connector
+	- FlexCAN ports:
+		- x2 DB-9 female connectors for FlexCAN bus(revision 2.0B)
+		   interface;
+	- DUART interface:
+		- DUART interface: supports two UARTs up to 115200 bps for
+		  console display
+		- J45 connectors are used for these 2 UART ports.
+	- TDM
+		- 2 FXS ports connected via an external SLIC to the TDM
+		   interface. SLIC is controllled via SPI.
+		- 1 FXO port connected via a relay to FXS for switchover to
+		   POTS
+Board connectors:
+	- Mini-ITX power supply connector
+	- JTAG/COP for debugging
+IEEE Std. 1588 signals for test and measurement
+Real-time clock on I2C bus
+POR
+	- support critical POR setting changed via switch on board
+PCB
+	- 6-layer routing (4-layer signals, 2-layer power and ground)
+
+
+Serial Port Configuration on P1010RDB
+=====================================
+Configure the serial port of the attached computer with the following values:
+	-Data rate: 115200 bps
+	-Number of data bits: 8
+	-Parity: None
+	-Number of Stop bits: 1
+	-Flow Control: Hardware/None
+
+
+Settings of DIP-switch
+======================
+  SW4[1:4]= 1111 and SW6[4]=0 for boot from 16bit NOR flash
+  SW4[1:4]= 1000 and SW6[4]=1 for boot from 8bit NAND flash
+  SW4[1:4]= 0110 and SW6[4]=0 for boot from SPI flash
+Note: 1 stands for 'on', 0 stands for 'off'
+
+
+Setting of hwconfig
+===================
+If FlexCAN or TDM is needed, please set "fsl_p1010mux:tdm_can=can" or
+"fsl_p1010mux:tdm_can=tdm" explicitly in u-booot prompt as below for example:
+setenv hwconfig "fsl_p1010mux:tdm_can=tdm;usb1:dr_mode=host,phy_type=utmi"
+By default, don't set fsl_p1010mux:tdm_can, in this case, spi chip selection
+is set to spi-flash instead of to SLIC/TDM/DAC and tdm_can_sel is set to TDM
+instead of to CAN/UART1.
+
+
+Build and burn u-boot to NOR flash
+==================================
+1. Build u-boot.bin image
+	export ARCH=powerpc
+	export CROSS_COMPILE=/your_path/powerpc-linux-gnu-
+	make P1010RDB_NOR
+
+2. Burn u-boot.bin into NOR flash
+	=> tftp $loadaddr $uboot
+	=> protect off eff80000 +$filesize
+	=> erase eff80000 +$filesize
+	=> cp.b $loadaddr eff80000 $filesize
+
+3. Check SW4[1:4]= 1111 and SW6[4]=0, then power on.
+
+
+Alternate NOR bank
+============================
+1. Burn u-boot.bin into alternate NOR bank
+	=> tftp $loadaddr $uboot
+	=> protect off eef80000 +$filesize
+	=> erase eef80000 +$filesize
+	=> cp.b $loadaddr eef80000 $filesize
+
+2. Switch to alternate NOR bank
+	=> mw.b ffb00009 1
+	=> reset
+	or set SW1[8]= ON
+
+SW1[8]= OFF: Upper bank used for booting start
+SW1[8]= ON:  Lower bank used for booting start
+CPLD NOR bank selection register address 0xFFB00009 Bit[0]:
+0 - boot from upper 4 sectors
+1 - boot from lower 4 sectors
+
+
+Build and burn u-boot to NAND flash
+===================================
+1. Build u-boot.bin image
+	export ARCH=powerpc
+	export CROSS_COMPILE=/your_path/powerpc-linux-gnu-
+	make P1010RDB_NAND
+
+2. Burn u-boot-nand.bin into NAND flash
+	=> tftp $loadaddr $uboot-nand
+	=> nand erase 0 $filesize
+	=> nand write $loadaddr 0 $filesize
+
+3. Check SW4[1:4]= 1000 and SW6[4]=1, then power on.
+
+
+
+Build and burn u-boot to SPI flash
+==================================
+1. Build u-boot-spi.bin image
+	make P1010RDB_SPIFLASH_config; make
+	Boot up kernel with rootfs.ext2.gz.uboot.p1010rdb
+	Download u-boot.bin to linux and you can find some config files
+	under /usr/share such as config_xx.dat. Do below command:
+	boot_format config_ddr3_1gb_p1010rdb_800M.dat u-boot.bin -spi \
+			u-boot-spi.bin
+	to generate u-boot-spi.bin.
+
+2. Burn u-boot-spi.bin into SPI flash
+	=> tftp $loadaddr $uboot-spi
+	=> sf erase 0 100000
+	=> sf write $loadaddr 0 $filesize
+
+3. Check SW4[1:4]= 0110 and SW6[4]=0, then power on.
+
+
+
+CPLD POR setting registers
+==========================
+1. Set POR switch selection register (addr 0xFFB00011) to 0.
+2. Write CPLD POR registers (BCSR0~BCSR3, addr 0xFFB00014~0xFFB00017) with
+   proper values.
+   If change boot ROM location to NOR or NAND flash, need write the IFC_CS0
+   switch command by I2C.
+3. Send reset command.
+   After reset, the new POR setting will be implemented.
+
+Two examples are given in below:
+Switch from NOR to NAND boot with default frequency:
+	=> i2c dev 0
+	=> i2c mw 18 1 f9
+	=> i2c mw 18 3 f0
+	=> mw.b ffb00011 0
+	=> mw.b ffb00017 1
+	=> reset
+Switch from NAND to NOR boot with Core/CCB/DDR (800/400/667 MHz):
+	=> i2c dev 0
+	=> i2c mw 18 1 f1
+	=> i2c mw 18 3 f0
+	=> mw.b ffb00011 0
+	=> mw.b ffb00014 2
+	=> mw.b ffb00015 5
+	=> mw.b ffb00016 3
+	=> mw.b ffb00017 f
+	=> reset
+
+
+
+Boot Linux from network using TFTP on P1010RDB
+==============================================
+Place uImage, p1010rdb.dtb and rootfs files in the TFTP disk area.
+	=> tftp 1000000 uImage
+	=> tftp 2000000 p1010rdb.dtb
+	=> tftp 3000000 rootfs.ext2.gz.uboot.p1010rdb
+	=> bootm 1000000 3000000 2000000
+
+
+Please contact your local field applications engineer or sales representative
+to obtain related documents, such as P1010-RDB User Guide for details.

+ 102 - 0
doc/README.ramboot-ppc85xx

@@ -0,0 +1,102 @@
+			RAMBOOT for MPC85xx Platforms
+			==============================
+
+RAMBOOT literally means boot from DDR. But since DDR is volatile memory some
+pre-mechanism is required to load the DDR with the bootloader binary.
+- In case of SD and SPI boot this is done by BootROM code inside the chip
+  itself.
+- In case of NAND boot FCM supports loading initial 4K code from NAND flash
+  which can initialize the DDR and get the complete bootloader copied to DDR.
+
+In addition to the above there could be some more methods to initialize the DDR
+and load it manually.
+Two of them are described below.There is also an explanation as to where these
+methods could be handy.
+1. Load the RAM based bootloader onto DDR via JTAG/BDI interface. And then
+   execute the bootloader from DDR.
+   This may be handy in the following cases:
+     - In very early stage of platform bringup where other boot options are not
+       functional because of various reasons.
+     - In case the support to program the flashes on the board is not available.
+
+2. Load the RAM based bootloader onto DDR using already existing bootloader on
+   the board.And then execute the bootloader from DDR.
+   Some usecases where this may be used:
+      - While developing some new feature of u-boot, for example USB driver or
+        SPI driver.
+        Suppose the board already has a working bootloader on it. And you would
+        prefer to keep it intact, at the same time want to test your bootloader.
+        In this case you can get your test bootloader binary into DDR via tftp
+        for example. Then execute the test bootloader.
+     - Suppose a platform already has a propreitery bootloader which does not
+       support for example AMP boot. In this case also RAM boot loader can be
+       utilized.
+
+   So basically when the original bootloader is required to be kept intact
+   RAM based bootloader can offer an updated bootloader on the system.
+
+Both the above Bootloaders are slight variants of SDcard or SPI Flash
+bootloader or for that matter even NAND bootloader.
+All of them define CONFIG_SYS_RAMBOOT.
+The main difference among all of them is the way the pre-environment is getting
+configured and who is doing that.
+- In case of SD card and SPI flash bootloader this is done by On Chip BootROM inside the Si itself.
+- In case of NAND boot SPL/TPL code does it with some support from Si itself.
+- In case of the pure RAM based bootloaders we have to do it by JTAG manually or already existing bootloader.
+
+How to use them:
+1. Using JTAG
+   Boot up in core hold off mode or stop the core after reset using JTAG
+   interface.
+   Preconfigure DDR/L2SRAM through JTAG interface.
+	- setup DDR controller registers.
+	- setup DDR LAWs
+	- setup DDR TLB
+   Load the RAM based boot loader to the proper location in DDR/L2SRAM.
+   set up IAR (Instruction counter properly)
+   Enable the core to execute.
+
+2. Using already existing bootloader.
+   get the rambased boot loader binary into DDR/L2SRAM via tftp.
+   execute the RAM based bootloader.
+      => tftp 11000000 u-boot-ram.bin
+      => go 1107f000
+
+Please note that L2SRAM can also be used instead of DDR if the SOC has
+sufficient size of L2SRAM.
+
+Necessary Code changes Required:
+=====================================
+Please note that below mentioned changes are for 85xx platforms.
+They have been tested on P1020/P2020/P1010 RDB.
+
+The main difference between the above two methods from technical perspective is
+that in 1st case SOC is just out of reset so it is in default configuration.
+(CCSRBAR is at 0xff700000).
+In the 2nd case bootloader has already re-located CCSRBAR to 0xffe00000
+
+1. File name-> boards.cfg
+   There can be added specific Make options for RAMBoot. We can keep different
+   options for the two cases mentioned above.
+   for example
+   P1020RDB_JTAG_RAMBOOT and P1020RDB_GO_RAMBOOT.
+
+2. platform config file
+   for example include/configs/P1_P2_RDB.h
+
+   #ifdef CONFIG_RAMBOOT
+   #define CONFIG_SDCARD
+   #endif
+
+   This will finally use the CONFIG_SYS_RAMBOOT.
+
+3. File name-> arch/powerpc/include/asm/config_mpc85xx.h
+   In the section of the particular SOC, for example P1020,
+
+   #if defined(CONFIG_GO)
+   #define CONFIG_SYS_CCSRBAR_DEFAULT	0xffe00000
+   #else
+   #define CONFIG_SYS_CCSRBAR_DEFAULT	0xff700000
+   #endif
+
+For JTAG  RAMBOOT this is not required because CCSRBAR is at ff700000.

+ 3 - 0
doc/README.watchdog

@@ -27,3 +27,6 @@ CONFIG_IMX_WATCHDOG
 	Available for i.mx31/35/5x/6x to service the watchdog. This is not
 	Available for i.mx31/35/5x/6x to service the watchdog. This is not
 	automatically set because some boards (vision2) still need to define
 	automatically set because some boards (vision2) still need to define
 	their own hw_watchdog_reset routine.
 	their own hw_watchdog_reset routine.
+
+CONFIG_XILINX_TB_WATCHDOG
+	Available for Xilinx Axi platforms to service timebase watchdog timer.

+ 7 - 12
doc/feature-removal-schedule.txt

@@ -7,20 +7,15 @@ file.
 
 
 ---------------------------
 ---------------------------
 
 
-What:	Remove CONFIG_CMD_MEMTEST from default list
-When:	Release v2013.07
+What:	Remove unused CONFIG_SYS_MEMTEST_START/END
+When:	Release v2013.10
 
 
-Why:	The "mtest" command is of little practical use (if any), and
-	experience has shown that a large number of board configu-
-	rations define useless or even dangerous start and end
-	addresses.  If not even the board maintainers are able to
-	figure out which memory range can be reliably tested, how can
-	we expect such from the end users?  As this problem comes up
-	repeatedly, we rather do not enable this command by default,
-	so only people who know what they are doing will be confronted
-	with it.
+Why:	As the 'mtest' command is no longer default, a number of platforms
+	have not opted to turn the command back on and thus provide unused
+	defines (which are likely to be propogated to new platforms from
+	copy/paste).  Remove these defines when unused.
 
 
-Who:	Wolfgang Denk <wd@denx.de>
+Who:	Tom Rini <trini@ti.com>
 
 
 ---------------------------
 ---------------------------
 
 

+ 2 - 1
doc/git-mailrc

@@ -34,6 +34,7 @@ alias sjg            Simon Glass <sjg@chromium.org>
 alias smcnutt        Scott McNutt <smcnutt@psyent.com>
 alias smcnutt        Scott McNutt <smcnutt@psyent.com>
 alias sonic          Sonic Zhang <sonic.adi@gmail.com>
 alias sonic          Sonic Zhang <sonic.adi@gmail.com>
 alias stroese        Stefan Roese <sr@denx.de>
 alias stroese        Stefan Roese <sr@denx.de>
+alias trini          Tom Rini <trini@ti.com>
 alias vapier         Mike Frysinger <vapier@gentoo.org>
 alias vapier         Mike Frysinger <vapier@gentoo.org>
 alias wd             Wolfgang Denk <wd@denx.de>
 alias wd             Wolfgang Denk <wd@denx.de>
 
 
@@ -54,7 +55,7 @@ alias s5pc           samsung
 alias samsung        uboot, prom
 alias samsung        uboot, prom
 alias tegra          uboot, sjg, Tom Warren <twarren@nvidia.com>, Stephen Warren <swarren@nvidia.com>
 alias tegra          uboot, sjg, Tom Warren <twarren@nvidia.com>, Stephen Warren <swarren@nvidia.com>
 alias tegra2         tegra
 alias tegra2         tegra
-alias ti             uboot, Tom Rini <trini@ti.com>
+alias ti             uboot, trini
 
 
 alias avr32          uboot, abiessmann
 alias avr32          uboot, abiessmann
 
 

+ 1 - 0
drivers/block/ata_piix.c

@@ -406,6 +406,7 @@ void sata_identify(int num, int dev)
 	/* assuming HD */
 	/* assuming HD */
 	sata_dev_desc[devno].type = DEV_TYPE_HARDDISK;
 	sata_dev_desc[devno].type = DEV_TYPE_HARDDISK;
 	sata_dev_desc[devno].blksz = ATA_BLOCKSIZE;
 	sata_dev_desc[devno].blksz = ATA_BLOCKSIZE;
+	sata_dev_desc[devno].log2blksz = LOG2(sata_dev_desc[devno].blksz);
 	sata_dev_desc[devno].lun = 0;	/* just to fill something in... */
 	sata_dev_desc[devno].lun = 0;	/* just to fill something in... */
 }
 }
 
 

+ 2 - 0
drivers/block/pata_bfin.c

@@ -897,6 +897,8 @@ static void bfin_ata_identify(struct ata_port *ap, int dev)
 	/* assuming HD */
 	/* assuming HD */
 	sata_dev_desc[ap->port_no].type = DEV_TYPE_HARDDISK;
 	sata_dev_desc[ap->port_no].type = DEV_TYPE_HARDDISK;
 	sata_dev_desc[ap->port_no].blksz = ATA_SECT_SIZE;
 	sata_dev_desc[ap->port_no].blksz = ATA_SECT_SIZE;
+	sata_dev_desc[ap->port_no].log2blksz =
+		LOG2(sata_dev_desc[ap->port_no].blksz);
 	sata_dev_desc[ap->port_no].lun = 0;	/* just to fill something in... */
 	sata_dev_desc[ap->port_no].lun = 0;	/* just to fill something in... */
 
 
 	printf("PATA device#%d %s is found on ata port#%d.\n",
 	printf("PATA device#%d %s is found on ata port#%d.\n",

+ 1 - 0
drivers/block/systemace.c

@@ -127,6 +127,7 @@ block_dev_desc_t *systemace_get_dev(int dev)
 		systemace_dev.part_type = PART_TYPE_UNKNOWN;
 		systemace_dev.part_type = PART_TYPE_UNKNOWN;
 		systemace_dev.type = DEV_TYPE_HARDDISK;
 		systemace_dev.type = DEV_TYPE_HARDDISK;
 		systemace_dev.blksz = 512;
 		systemace_dev.blksz = 512;
+		systemace_dev.log2blksz = LOG2(systemace_dev.blksz);
 		systemace_dev.removable = 1;
 		systemace_dev.removable = 1;
 		systemace_dev.block_read = systemace_read;
 		systemace_dev.block_read = systemace_read;
 
 

+ 14 - 12
drivers/mmc/mmc.c

@@ -601,7 +601,7 @@ static int mmc_send_ext_csd(struct mmc *mmc, u8 *ext_csd)
 
 
 	data.dest = (char *)ext_csd;
 	data.dest = (char *)ext_csd;
 	data.blocks = 1;
 	data.blocks = 1;
-	data.blocksize = 512;
+	data.blocksize = MMC_MAX_BLOCK_LEN;
 	data.flags = MMC_DATA_READ;
 	data.flags = MMC_DATA_READ;
 
 
 	err = mmc_send_cmd(mmc, &cmd, &data);
 	err = mmc_send_cmd(mmc, &cmd, &data);
@@ -634,7 +634,7 @@ static int mmc_switch(struct mmc *mmc, u8 set, u8 index, u8 value)
 
 
 static int mmc_change_freq(struct mmc *mmc)
 static int mmc_change_freq(struct mmc *mmc)
 {
 {
-	ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, 512);
+	ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, MMC_MAX_BLOCK_LEN);
 	char cardtype;
 	char cardtype;
 	int err;
 	int err;
 
 
@@ -899,8 +899,8 @@ static int mmc_startup(struct mmc *mmc)
 	uint mult, freq;
 	uint mult, freq;
 	u64 cmult, csize, capacity;
 	u64 cmult, csize, capacity;
 	struct mmc_cmd cmd;
 	struct mmc_cmd cmd;
-	ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, 512);
-	ALLOC_CACHE_ALIGN_BUFFER(u8, test_csd, 512);
+	ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, MMC_MAX_BLOCK_LEN);
+	ALLOC_CACHE_ALIGN_BUFFER(u8, test_csd, MMC_MAX_BLOCK_LEN);
 	int timeout = 1000;
 	int timeout = 1000;
 
 
 #ifdef CONFIG_MMC_SPI_CRC_ON
 #ifdef CONFIG_MMC_SPI_CRC_ON
@@ -1016,11 +1016,11 @@ static int mmc_startup(struct mmc *mmc)
 	mmc->capacity = (csize + 1) << (cmult + 2);
 	mmc->capacity = (csize + 1) << (cmult + 2);
 	mmc->capacity *= mmc->read_bl_len;
 	mmc->capacity *= mmc->read_bl_len;
 
 
-	if (mmc->read_bl_len > 512)
-		mmc->read_bl_len = 512;
+	if (mmc->read_bl_len > MMC_MAX_BLOCK_LEN)
+		mmc->read_bl_len = MMC_MAX_BLOCK_LEN;
 
 
-	if (mmc->write_bl_len > 512)
-		mmc->write_bl_len = 512;
+	if (mmc->write_bl_len > MMC_MAX_BLOCK_LEN)
+		mmc->write_bl_len = MMC_MAX_BLOCK_LEN;
 
 
 	/* Select the card, and put it into Transfer Mode */
 	/* Select the card, and put it into Transfer Mode */
 	if (!mmc_host_is_spi(mmc)) { /* cmd not supported in spi */
 	if (!mmc_host_is_spi(mmc)) { /* cmd not supported in spi */
@@ -1051,7 +1051,7 @@ static int mmc_startup(struct mmc *mmc)
 					| ext_csd[EXT_CSD_SEC_CNT + 1] << 8
 					| ext_csd[EXT_CSD_SEC_CNT + 1] << 8
 					| ext_csd[EXT_CSD_SEC_CNT + 2] << 16
 					| ext_csd[EXT_CSD_SEC_CNT + 2] << 16
 					| ext_csd[EXT_CSD_SEC_CNT + 3] << 24;
 					| ext_csd[EXT_CSD_SEC_CNT + 3] << 24;
-			capacity *= 512;
+			capacity *= MMC_MAX_BLOCK_LEN;
 			if ((capacity >> 20) > 2 * 1024)
 			if ((capacity >> 20) > 2 * 1024)
 				mmc->capacity = capacity;
 				mmc->capacity = capacity;
 		}
 		}
@@ -1079,10 +1079,11 @@ static int mmc_startup(struct mmc *mmc)
 		 * group size from ext_csd directly, or calculate
 		 * group size from ext_csd directly, or calculate
 		 * the group size from the csd value.
 		 * the group size from the csd value.
 		 */
 		 */
-		if (ext_csd[EXT_CSD_ERASE_GROUP_DEF])
+		if (ext_csd[EXT_CSD_ERASE_GROUP_DEF]) {
 			mmc->erase_grp_size =
 			mmc->erase_grp_size =
-			      ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] * 512 * 1024;
-		else {
+				ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] *
+					MMC_MAX_BLOCK_LEN * 1024;
+		} else {
 			int erase_gsz, erase_gmul;
 			int erase_gsz, erase_gmul;
 			erase_gsz = (mmc->csd[2] & 0x00007c00) >> 10;
 			erase_gsz = (mmc->csd[2] & 0x00007c00) >> 10;
 			erase_gmul = (mmc->csd[2] & 0x000003e0) >> 5;
 			erase_gmul = (mmc->csd[2] & 0x000003e0) >> 5;
@@ -1202,6 +1203,7 @@ static int mmc_startup(struct mmc *mmc)
 	mmc->block_dev.lun = 0;
 	mmc->block_dev.lun = 0;
 	mmc->block_dev.type = 0;
 	mmc->block_dev.type = 0;
 	mmc->block_dev.blksz = mmc->read_bl_len;
 	mmc->block_dev.blksz = mmc->read_bl_len;
+	mmc->block_dev.log2blksz = LOG2(mmc->block_dev.blksz);
 	mmc->block_dev.lba = lldiv(mmc->capacity, mmc->read_bl_len);
 	mmc->block_dev.lba = lldiv(mmc->capacity, mmc->read_bl_len);
 	sprintf(mmc->block_dev.vendor, "Man %06x Snr %04x%04x",
 	sprintf(mmc->block_dev.vendor, "Man %06x Snr %04x%04x",
 		mmc->cid[0] >> 24, (mmc->cid[2] & 0xffff),
 		mmc->cid[0] >> 24, (mmc->cid[2] & 0xffff),

+ 9 - 8
drivers/mmc/spl_mmc.c

@@ -34,8 +34,9 @@ DECLARE_GLOBAL_DATA_PTR;
 
 
 static void mmc_load_image_raw(struct mmc *mmc)
 static void mmc_load_image_raw(struct mmc *mmc)
 {
 {
-	u32 image_size_sectors, err;
-	const struct image_header *header;
+	unsigned long err;
+	u32 image_size_sectors;
+	struct image_header *header;
 
 
 	header = (struct image_header *)(CONFIG_SYS_TEXT_BASE -
 	header = (struct image_header *)(CONFIG_SYS_TEXT_BASE -
 						sizeof(struct image_header));
 						sizeof(struct image_header));
@@ -43,9 +44,9 @@ static void mmc_load_image_raw(struct mmc *mmc)
 	/* read image header to find the image size & load address */
 	/* read image header to find the image size & load address */
 	err = mmc->block_dev.block_read(0,
 	err = mmc->block_dev.block_read(0,
 			CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR, 1,
 			CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR, 1,
-			(void *)header);
+			header);
 
 
-	if (err <= 0)
+	if (err == 0)
 		goto end;
 		goto end;
 
 
 	spl_parse_image_header(header);
 	spl_parse_image_header(header);
@@ -60,8 +61,8 @@ static void mmc_load_image_raw(struct mmc *mmc)
 			image_size_sectors, (void *)spl_image.load_addr);
 			image_size_sectors, (void *)spl_image.load_addr);
 
 
 end:
 end:
-	if (err <= 0) {
-		printf("spl: mmc blk read err - %d\n", err);
+	if (err == 0) {
+		printf("spl: mmc blk read err - %lu\n", err);
 		hang();
 		hang();
 	}
 	}
 }
 }
@@ -69,7 +70,7 @@ end:
 #ifdef CONFIG_SPL_FAT_SUPPORT
 #ifdef CONFIG_SPL_FAT_SUPPORT
 static void mmc_load_image_fat(struct mmc *mmc)
 static void mmc_load_image_fat(struct mmc *mmc)
 {
 {
-	s32 err;
+	int err;
 	struct image_header *header;
 	struct image_header *header;
 
 
 	header = (struct image_header *)(CONFIG_SYS_TEXT_BASE -
 	header = (struct image_header *)(CONFIG_SYS_TEXT_BASE -
@@ -83,7 +84,7 @@ static void mmc_load_image_fat(struct mmc *mmc)
 	}
 	}
 
 
 	err = file_fat_read(CONFIG_SPL_FAT_LOAD_PAYLOAD_NAME,
 	err = file_fat_read(CONFIG_SPL_FAT_LOAD_PAYLOAD_NAME,
-				(u8 *)header, sizeof(struct image_header));
+				header, sizeof(struct image_header));
 	if (err <= 0)
 	if (err <= 0)
 		goto end;
 		goto end;
 
 

+ 2 - 0
drivers/mtd/nand/Makefile

@@ -34,6 +34,7 @@ NORMAL_DRIVERS=y
 endif
 endif
 
 
 COBJS-$(CONFIG_SPL_NAND_AM33XX_BCH) += am335x_spl_bch.o
 COBJS-$(CONFIG_SPL_NAND_AM33XX_BCH) += am335x_spl_bch.o
+COBJS-$(CONFIG_SPL_NAND_DOCG4) += docg4_spl.o
 COBJS-$(CONFIG_SPL_NAND_SIMPLE) += nand_spl_simple.o
 COBJS-$(CONFIG_SPL_NAND_SIMPLE) += nand_spl_simple.o
 COBJS-$(CONFIG_SPL_NAND_LOAD) += nand_spl_load.o
 COBJS-$(CONFIG_SPL_NAND_LOAD) += nand_spl_load.o
 COBJS-$(CONFIG_SPL_NAND_ECC) += nand_ecc.o
 COBJS-$(CONFIG_SPL_NAND_ECC) += nand_ecc.o
@@ -77,6 +78,7 @@ COBJS-$(CONFIG_NAND_SPEAR) += spr_nand.o
 COBJS-$(CONFIG_TEGRA_NAND) += tegra_nand.o
 COBJS-$(CONFIG_TEGRA_NAND) += tegra_nand.o
 COBJS-$(CONFIG_NAND_OMAP_GPMC) += omap_gpmc.o
 COBJS-$(CONFIG_NAND_OMAP_GPMC) += omap_gpmc.o
 COBJS-$(CONFIG_NAND_PLAT) += nand_plat.o
 COBJS-$(CONFIG_NAND_PLAT) += nand_plat.o
+COBJS-$(CONFIG_NAND_DOCG4) += docg4.o
 
 
 else  # minimal SPL drivers
 else  # minimal SPL drivers
 
 

+ 1028 - 0
drivers/mtd/nand/docg4.c

@@ -0,0 +1,1028 @@
+/*
+ * drivers/mtd/nand/docg4.c
+ *
+ * Copyright (C) 2013 Mike Dunn <mikedunn@newsguy.com>
+ *
+ * This file is released under the terms of GPL v2 and any later version.
+ * See the file COPYING in the root directory of the source tree for details.
+ *
+ * mtd nand driver for M-Systems DiskOnChip G4
+ *
+ * Tested on the Palm Treo 680.  The G4 is also present on Toshiba Portege, Asus
+ * P526, some HTC smartphones (Wizard, Prophet, ...), O2 XDA Zinc, maybe others.
+ * Should work on these as well.  Let me know!
+ *
+ * TODO:
+ *
+ *  Mechanism for management of password-protected areas
+ *
+ *  Hamming ecc when reading oob only
+ *
+ *  According to the M-Sys documentation, this device is also available in a
+ *  "dual-die" configuration having a 256MB capacity, but no mechanism for
+ *  detecting this variant is documented.  Currently this driver assumes 128MB
+ *  capacity.
+ *
+ *  Support for multiple cascaded devices ("floors").  Not sure which gadgets
+ *  contain multiple G4s in a cascaded configuration, if any.
+ *
+ */
+
+
+#include <common.h>
+#include <asm/arch/hardware.h>
+#include <asm/io.h>
+#include <asm/bitops.h>
+#include <asm/errno.h>
+#include <malloc.h>
+#include <nand.h>
+#include <linux/bch.h>
+#include <linux/bitrev.h>
+#include <linux/mtd/docg4.h>
+
+/*
+ * The device has a nop register which M-Sys claims is for the purpose of
+ * inserting precise delays.  But beware; at least some operations fail if the
+ * nop writes are replaced with a generic delay!
+ */
+static inline void write_nop(void __iomem *docptr)
+{
+	writew(0, docptr + DOC_NOP);
+}
+
+
+static int poll_status(void __iomem *docptr)
+{
+	/*
+	 * Busy-wait for the FLASHREADY bit to be set in the FLASHCONTROL
+	 * register.  Operations known to take a long time (e.g., block erase)
+	 * should sleep for a while before calling this.
+	 */
+
+	uint8_t flash_status;
+
+	/* hardware quirk requires reading twice initially */
+	flash_status = readb(docptr + DOC_FLASHCONTROL);
+
+	do {
+		flash_status = readb(docptr + DOC_FLASHCONTROL);
+	} while (!(flash_status & DOC_CTRL_FLASHREADY));
+
+	return 0;
+}
+
+static void write_addr(void __iomem *docptr, uint32_t docg4_addr)
+{
+	/* write the four address bytes packed in docg4_addr to the device */
+
+	writeb(docg4_addr & 0xff, docptr + DOC_FLASHADDRESS);
+	docg4_addr >>= 8;
+	writeb(docg4_addr & 0xff, docptr + DOC_FLASHADDRESS);
+	docg4_addr >>= 8;
+	writeb(docg4_addr & 0xff, docptr + DOC_FLASHADDRESS);
+	docg4_addr >>= 8;
+	writeb(docg4_addr & 0xff, docptr + DOC_FLASHADDRESS);
+}
+
+/*
+ * This is a module parameter in the linux kernel version of this driver.  It is
+ * hard-coded to 'off' for u-boot.  This driver uses oob to mark bad blocks.
+ * This can be problematic when dealing with data not intended for the mtd/nand
+ * subsystem.  For example, on boards that boot from the docg4 and use the IPL
+ * to load an spl + u-boot image, the blocks containing the image will be
+ * reported as "bad" because the oob of the first page of each block contains a
+ * magic number that the IPL looks for, which causes the badblock scan to
+ * erroneously add them to the bad block table.  To erase such a block, use
+ * u-boot's 'nand scrub'.  scrub is safe for the docg4.  The device does have a
+ * factory bad block table, but it is read-only, and is used in conjunction with
+ * oob bad block markers that are written by mtd/nand when a block is deemed to
+ * be bad.  To read data from "bad" blocks, use 'read.raw'.  Unfortunately,
+ * read.raw does not use ecc, which would still work fine on such misidentified
+ * bad blocks.  TODO: u-boot nand utilities need the ability to ignore bad
+ * blocks.
+ */
+static const int ignore_badblocks; /* remains false */
+
+struct docg4_priv {
+	int status;
+	struct {
+		unsigned int command;
+		int column;
+		int page;
+	} last_command;
+	uint8_t oob_buf[16];
+	uint8_t ecc_buf[7];
+	int oob_page;
+	struct bch_control *bch;
+};
+/*
+ * Oob bytes 0 - 6 are available to the user.
+ * Byte 7 is hamming ecc for first 7 bytes.  Bytes 8 - 14 are hw-generated ecc.
+ * Byte 15 (the last) is used by the driver as a "page written" flag.
+ */
+static struct nand_ecclayout docg4_oobinfo = {
+	.eccbytes = 9,
+	.eccpos = {7, 8, 9, 10, 11, 12, 13, 14, 15},
+	.oobavail = 7,
+	.oobfree = { {0, 7} }
+};
+
+static void reset(void __iomem *docptr)
+{
+	/* full device reset */
+
+	writew(DOC_ASICMODE_RESET | DOC_ASICMODE_MDWREN, docptr + DOC_ASICMODE);
+	writew(~(DOC_ASICMODE_RESET | DOC_ASICMODE_MDWREN),
+	       docptr + DOC_ASICMODECONFIRM);
+	write_nop(docptr);
+
+	writew(DOC_ASICMODE_NORMAL | DOC_ASICMODE_MDWREN,
+	       docptr + DOC_ASICMODE);
+	writew(~(DOC_ASICMODE_NORMAL | DOC_ASICMODE_MDWREN),
+	       docptr + DOC_ASICMODECONFIRM);
+
+	writew(DOC_ECCCONF1_ECC_ENABLE, docptr + DOC_ECCCONF1);
+
+	poll_status(docptr);
+}
+
+static void docg4_select_chip(struct mtd_info *mtd, int chip)
+{
+	/*
+	 * Select among multiple cascaded chips ("floors").  Multiple floors are
+	 * not yet supported, so the only valid non-negative value is 0.
+	 */
+	void __iomem *docptr = CONFIG_SYS_NAND_BASE;
+
+	if (chip < 0)
+		return;		/* deselected */
+
+	if (chip > 0)
+		printf("multiple floors currently unsupported\n");
+
+	writew(0, docptr + DOC_DEVICESELECT);
+}
+
+static void read_hw_ecc(void __iomem *docptr, uint8_t *ecc_buf)
+{
+	/* read the 7 hw-generated ecc bytes */
+
+	int i;
+	for (i = 0; i < 7; i++) { /* hw quirk; read twice */
+		ecc_buf[i] = readb(docptr + DOC_BCH_SYNDROM(i));
+		ecc_buf[i] = readb(docptr + DOC_BCH_SYNDROM(i));
+	}
+}
+
+static int correct_data(struct mtd_info *mtd, uint8_t *buf, int page)
+{
+	/*
+	 * Called after a page read when hardware reports bitflips.
+	 * Up to four bitflips can be corrected.
+	 */
+
+	struct nand_chip *nand = mtd->priv;
+	struct docg4_priv *doc = nand->priv;
+	void __iomem *docptr = CONFIG_SYS_NAND_BASE;
+	int i, numerrs;
+	unsigned int errpos[4];
+	const uint8_t blank_read_hwecc[8] = {
+		0xcf, 0x72, 0xfc, 0x1b, 0xa9, 0xc7, 0xb9, 0 };
+
+	read_hw_ecc(docptr, doc->ecc_buf); /* read 7 hw-generated ecc bytes */
+
+	/* check if read error is due to a blank page */
+	if (!memcmp(doc->ecc_buf, blank_read_hwecc, 7))
+		return 0;	/* yes */
+
+	/* skip additional check of "written flag" if ignore_badblocks */
+	if (!ignore_badblocks) {
+		/*
+		 * If the hw ecc bytes are not those of a blank page, there's
+		 * still a chance that the page is blank, but was read with
+		 * errors.  Check the "written flag" in last oob byte, which
+		 * is set to zero when a page is written.  If more than half
+		 * the bits are set, assume a blank page.  Unfortunately, the
+		 * bit flips(s) are not reported in stats.
+		 */
+
+		if (doc->oob_buf[15]) {
+			int bit, numsetbits = 0;
+			unsigned long written_flag = doc->oob_buf[15];
+
+			for (bit = 0; bit < 8; bit++) {
+				if (written_flag & 0x01)
+					numsetbits++;
+				written_flag >>= 1;
+			}
+			if (numsetbits > 4) { /* assume blank */
+				printf("errors in blank page at offset %08x\n",
+				       page * DOCG4_PAGE_SIZE);
+				return 0;
+			}
+		}
+	}
+
+	/*
+	 * The hardware ecc unit produces oob_ecc ^ calc_ecc.  The kernel's bch
+	 * algorithm is used to decode this.  However the hw operates on page
+	 * data in a bit order that is the reverse of that of the bch alg,
+	 * requiring that the bits be reversed on the result.  Thanks to Ivan
+	 * Djelic for his analysis!
+	 */
+	for (i = 0; i < 7; i++)
+		doc->ecc_buf[i] = bitrev8(doc->ecc_buf[i]);
+
+	numerrs = decode_bch(doc->bch, NULL, DOCG4_USERDATA_LEN, NULL,
+			     doc->ecc_buf, NULL, errpos);
+
+	if (numerrs == -EBADMSG) {
+		printf("uncorrectable errors at offset %08x\n",
+		       page * DOCG4_PAGE_SIZE);
+		return -EBADMSG;
+	}
+
+	BUG_ON(numerrs < 0);	/* -EINVAL, or anything other than -EBADMSG */
+
+	/* undo last step in BCH alg (modulo mirroring not needed) */
+	for (i = 0; i < numerrs; i++)
+		errpos[i] = (errpos[i] & ~7)|(7-(errpos[i] & 7));
+
+	/* fix the errors */
+	for (i = 0; i < numerrs; i++) {
+		/* ignore if error within oob ecc bytes */
+		if (errpos[i] > DOCG4_USERDATA_LEN * 8)
+			continue;
+
+		/* if error within oob area preceeding ecc bytes... */
+		if (errpos[i] > DOCG4_PAGE_SIZE * 8)
+			__change_bit(errpos[i] - DOCG4_PAGE_SIZE * 8,
+				     (unsigned long *)doc->oob_buf);
+
+		else    /* error in page data */
+			__change_bit(errpos[i], (unsigned long *)buf);
+	}
+
+	printf("%d error(s) corrected at offset %08x\n",
+	       numerrs, page * DOCG4_PAGE_SIZE);
+
+	return numerrs;
+}
+
+static int read_progstatus(struct docg4_priv *doc, void __iomem *docptr)
+{
+	/*
+	 * This apparently checks the status of programming.  Done after an
+	 * erasure, and after page data is written.  On error, the status is
+	 * saved, to be later retrieved by the nand infrastructure code.
+	 */
+
+	/* status is read from the I/O reg */
+	uint16_t status1 = readw(docptr + DOC_IOSPACE_DATA);
+	uint16_t status2 = readw(docptr + DOC_IOSPACE_DATA);
+	uint16_t status3 = readw(docptr + DOCG4_MYSTERY_REG);
+
+	MTDDEBUG(MTD_DEBUG_LEVEL3, "docg4: %s: %02x %02x %02x\n",
+	    __func__, status1, status2, status3);
+
+	if (status1 != DOCG4_PROGSTATUS_GOOD ||
+	    status2 != DOCG4_PROGSTATUS_GOOD_2 ||
+	    status3 != DOCG4_PROGSTATUS_GOOD_2) {
+		doc->status = NAND_STATUS_FAIL;
+		printf("read_progstatus failed: %02x, %02x, %02x\n",
+		       status1, status2, status3);
+		return -EIO;
+	}
+	return 0;
+}
+
+static int pageprog(struct mtd_info *mtd)
+{
+	/*
+	 * Final step in writing a page.  Writes the contents of its
+	 * internal buffer out to the flash array, or some such.
+	 */
+
+	struct nand_chip *nand = mtd->priv;
+	struct docg4_priv *doc = nand->priv;
+	void __iomem *docptr = CONFIG_SYS_NAND_BASE;
+	int retval = 0;
+
+	MTDDEBUG(MTD_DEBUG_LEVEL3, "docg4: %s\n", __func__);
+
+	writew(DOCG4_SEQ_PAGEPROG, docptr + DOC_FLASHSEQUENCE);
+	writew(DOC_CMD_PROG_CYCLE2, docptr + DOC_FLASHCOMMAND);
+	write_nop(docptr);
+	write_nop(docptr);
+
+	/* Just busy-wait; usleep_range() slows things down noticeably. */
+	poll_status(docptr);
+
+	writew(DOCG4_SEQ_FLUSH, docptr + DOC_FLASHSEQUENCE);
+	writew(DOCG4_CMD_FLUSH, docptr + DOC_FLASHCOMMAND);
+	writew(DOC_ECCCONF0_READ_MODE | 4, docptr + DOC_ECCCONF0);
+	write_nop(docptr);
+	write_nop(docptr);
+	write_nop(docptr);
+	write_nop(docptr);
+	write_nop(docptr);
+
+	retval = read_progstatus(doc, docptr);
+	writew(0, docptr + DOC_DATAEND);
+	write_nop(docptr);
+	poll_status(docptr);
+	write_nop(docptr);
+
+	return retval;
+}
+
+static void sequence_reset(void __iomem *docptr)
+{
+	/* common starting sequence for all operations */
+
+	writew(DOC_CTRL_UNKNOWN | DOC_CTRL_CE, docptr + DOC_FLASHCONTROL);
+	writew(DOC_SEQ_RESET, docptr + DOC_FLASHSEQUENCE);
+	writew(DOC_CMD_RESET, docptr + DOC_FLASHCOMMAND);
+	write_nop(docptr);
+	write_nop(docptr);
+	poll_status(docptr);
+	write_nop(docptr);
+}
+
+static void read_page_prologue(void __iomem *docptr, uint32_t docg4_addr)
+{
+	/* first step in reading a page */
+
+	sequence_reset(docptr);
+
+	writew(DOCG4_SEQ_PAGE_READ, docptr + DOC_FLASHSEQUENCE);
+	writew(DOCG4_CMD_PAGE_READ, docptr + DOC_FLASHCOMMAND);
+	write_nop(docptr);
+
+	write_addr(docptr, docg4_addr);
+
+	write_nop(docptr);
+	writew(DOCG4_CMD_READ2, docptr + DOC_FLASHCOMMAND);
+	write_nop(docptr);
+	write_nop(docptr);
+
+	poll_status(docptr);
+}
+
+static void write_page_prologue(void __iomem *docptr, uint32_t docg4_addr)
+{
+	/* first step in writing a page */
+
+	sequence_reset(docptr);
+	writew(DOCG4_SEQ_PAGEWRITE, docptr + DOC_FLASHSEQUENCE);
+	writew(DOCG4_CMD_PAGEWRITE, docptr + DOC_FLASHCOMMAND);
+	write_nop(docptr);
+	write_addr(docptr, docg4_addr);
+	write_nop(docptr);
+	write_nop(docptr);
+	poll_status(docptr);
+}
+
+static uint32_t mtd_to_docg4_address(int page, int column)
+{
+	/*
+	 * Convert mtd address to format used by the device, 32 bit packed.
+	 *
+	 * Some notes on G4 addressing... The M-Sys documentation on this device
+	 * claims that pages are 2K in length, and indeed, the format of the
+	 * address used by the device reflects that.  But within each page are
+	 * four 512 byte "sub-pages", each with its own oob data that is
+	 * read/written immediately after the 512 bytes of page data.  This oob
+	 * data contains the ecc bytes for the preceeding 512 bytes.
+	 *
+	 * Rather than tell the mtd nand infrastructure that page size is 2k,
+	 * with four sub-pages each, we engage in a little subterfuge and tell
+	 * the infrastructure code that pages are 512 bytes in size.  This is
+	 * done because during the course of reverse-engineering the device, I
+	 * never observed an instance where an entire 2K "page" was read or
+	 * written as a unit.  Each "sub-page" is always addressed individually,
+	 * its data read/written, and ecc handled before the next "sub-page" is
+	 * addressed.
+	 *
+	 * This requires us to convert addresses passed by the mtd nand
+	 * infrastructure code to those used by the device.
+	 *
+	 * The address that is written to the device consists of four bytes: the
+	 * first two are the 2k page number, and the second is the index into
+	 * the page.  The index is in terms of 16-bit half-words and includes
+	 * the preceeding oob data, so e.g., the index into the second
+	 * "sub-page" is 0x108, and the full device address of the start of mtd
+	 * page 0x201 is 0x00800108.
+	 */
+	int g4_page = page / 4;	                      /* device's 2K page */
+	int g4_index = (page % 4) * 0x108 + column/2; /* offset into page */
+	return (g4_page << 16) | g4_index;	      /* pack */
+}
+
+static void docg4_command(struct mtd_info *mtd, unsigned command, int column,
+			  int page_addr)
+{
+	/* handle standard nand commands */
+
+	struct nand_chip *nand = mtd->priv;
+	struct docg4_priv *doc = nand->priv;
+	uint32_t g4_addr = mtd_to_docg4_address(page_addr, column);
+
+	MTDDEBUG(MTD_DEBUG_LEVEL3, "%s %x, page_addr=%x, column=%x\n",
+	    __func__, command, page_addr, column);
+
+	/*
+	 * Save the command and its arguments.  This enables emulation of
+	 * standard flash devices, and also some optimizations.
+	 */
+	doc->last_command.command = command;
+	doc->last_command.column = column;
+	doc->last_command.page = page_addr;
+
+	switch (command) {
+	case NAND_CMD_RESET:
+		reset(CONFIG_SYS_NAND_BASE);
+		break;
+
+	case NAND_CMD_READ0:
+		read_page_prologue(CONFIG_SYS_NAND_BASE, g4_addr);
+		break;
+
+	case NAND_CMD_STATUS:
+		/* next call to read_byte() will expect a status */
+		break;
+
+	case NAND_CMD_SEQIN:
+		write_page_prologue(CONFIG_SYS_NAND_BASE, g4_addr);
+
+		/* hack for deferred write of oob bytes */
+		if (doc->oob_page == page_addr)
+			memcpy(nand->oob_poi, doc->oob_buf, 16);
+		break;
+
+	case NAND_CMD_PAGEPROG:
+		pageprog(mtd);
+		break;
+
+	/* we don't expect these, based on review of nand_base.c */
+	case NAND_CMD_READOOB:
+	case NAND_CMD_READID:
+	case NAND_CMD_ERASE1:
+	case NAND_CMD_ERASE2:
+		printf("docg4_command: unexpected nand command 0x%x\n",
+		       command);
+		break;
+	}
+}
+
+static void docg4_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
+{
+	int i;
+	struct nand_chip *nand = mtd->priv;
+	uint16_t *p = (uint16_t *)buf;
+	len >>= 1;
+
+	for (i = 0; i < len; i++)
+		p[i] = readw(nand->IO_ADDR_R);
+}
+
+static int docg4_read_oob(struct mtd_info *mtd, struct nand_chip *nand,
+			  int page, int sndcmd)
+{
+	struct docg4_priv *doc = nand->priv;
+	void __iomem *docptr = CONFIG_SYS_NAND_BASE;
+	uint16_t status;
+
+	MTDDEBUG(MTD_DEBUG_LEVEL3, "%s: page %x\n", __func__, page);
+
+	/*
+	 * Oob bytes are read as part of a normal page read.  If the previous
+	 * nand command was a read of the page whose oob is now being read, just
+	 * copy the oob bytes that we saved in a local buffer and avoid a
+	 * separate oob read.
+	 */
+	if (doc->last_command.command == NAND_CMD_READ0 &&
+	    doc->last_command.page == page) {
+		memcpy(nand->oob_poi, doc->oob_buf, 16);
+		return 0;
+	}
+
+	/*
+	 * Separate read of oob data only.
+	 */
+	docg4_command(mtd, NAND_CMD_READ0, nand->ecc.size, page);
+
+	writew(DOC_ECCCONF0_READ_MODE | DOCG4_OOB_SIZE, docptr + DOC_ECCCONF0);
+	write_nop(docptr);
+	write_nop(docptr);
+	write_nop(docptr);
+	write_nop(docptr);
+	write_nop(docptr);
+
+	/* the 1st byte from the I/O reg is a status; the rest is oob data */
+	status = readw(docptr + DOC_IOSPACE_DATA);
+	if (status & DOCG4_READ_ERROR) {
+		printf("docg4_read_oob failed: status = 0x%02x\n", status);
+		return -EIO;
+	}
+
+	MTDDEBUG(MTD_DEBUG_LEVEL3, "%s: status = 0x%x\n", __func__, status);
+
+	docg4_read_buf(mtd, nand->oob_poi, 16);
+
+	write_nop(docptr);
+	write_nop(docptr);
+	write_nop(docptr);
+	writew(0, docptr + DOC_DATAEND);
+	write_nop(docptr);
+
+	return 0;
+}
+
+static int docg4_write_oob(struct mtd_info *mtd, struct nand_chip *nand,
+			   int page)
+{
+	/*
+	 * Writing oob-only is not really supported, because MLC nand must write
+	 * oob bytes at the same time as page data.  Nonetheless, we save the
+	 * oob buffer contents here, and then write it along with the page data
+	 * if the same page is subsequently written.  This allows user space
+	 * utilities that write the oob data prior to the page data to work
+	 * (e.g., nandwrite).  The disdvantage is that, if the intention was to
+	 * write oob only, the operation is quietly ignored.  Also, oob can get
+	 * corrupted if two concurrent processes are running nandwrite.
+	 */
+
+	/* note that bytes 7..14 are hw generated hamming/ecc and overwritten */
+	struct docg4_priv *doc = nand->priv;
+	doc->oob_page = page;
+	memcpy(doc->oob_buf, nand->oob_poi, 16);
+	return 0;
+}
+
+static int docg4_block_neverbad(struct mtd_info *mtd, loff_t ofs, int getchip)
+{
+	/* only called when module_param ignore_badblocks is set */
+	return 0;
+}
+
+static void docg4_write_buf16(struct mtd_info *mtd, const uint8_t *buf, int len)
+{
+	int i;
+	struct nand_chip *nand = mtd->priv;
+	uint16_t *p = (uint16_t *)buf;
+	len >>= 1;
+
+	for (i = 0; i < len; i++)
+		writew(p[i], nand->IO_ADDR_W);
+}
+
+static void write_page(struct mtd_info *mtd, struct nand_chip *nand,
+		       const uint8_t *buf, int use_ecc)
+{
+	void __iomem *docptr = CONFIG_SYS_NAND_BASE;
+	uint8_t ecc_buf[8];
+
+	writew(DOC_ECCCONF0_ECC_ENABLE |
+	       DOC_ECCCONF0_UNKNOWN |
+	       DOCG4_BCH_SIZE,
+	       docptr + DOC_ECCCONF0);
+	write_nop(docptr);
+
+	/* write the page data */
+	docg4_write_buf16(mtd, buf, DOCG4_PAGE_SIZE);
+
+	/* oob bytes 0 through 5 are written to I/O reg */
+	docg4_write_buf16(mtd, nand->oob_poi, 6);
+
+	/* oob byte 6 written to a separate reg */
+	writew(nand->oob_poi[6], docptr + DOCG4_OOB_6_7);
+
+	write_nop(docptr);
+	write_nop(docptr);
+
+	/* write hw-generated ecc bytes to oob */
+	if (likely(use_ecc)) {
+		/* oob byte 7 is hamming code */
+		uint8_t hamming = readb(docptr + DOC_HAMMINGPARITY);
+		hamming = readb(docptr + DOC_HAMMINGPARITY); /* 2nd read */
+		writew(hamming, docptr + DOCG4_OOB_6_7);
+		write_nop(docptr);
+
+		/* read the 7 bch bytes from ecc regs */
+		read_hw_ecc(docptr, ecc_buf);
+		ecc_buf[7] = 0;         /* clear the "page written" flag */
+	}
+
+	/* write user-supplied bytes to oob */
+	else {
+		writew(nand->oob_poi[7], docptr + DOCG4_OOB_6_7);
+		write_nop(docptr);
+		memcpy(ecc_buf, &nand->oob_poi[8], 8);
+	}
+
+	docg4_write_buf16(mtd, ecc_buf, 8);
+	write_nop(docptr);
+	write_nop(docptr);
+	writew(0, docptr + DOC_DATAEND);
+	write_nop(docptr);
+}
+
+static void docg4_write_page_raw(struct mtd_info *mtd, struct nand_chip *nand,
+				 const uint8_t *buf)
+{
+	return write_page(mtd, nand, buf, 0);
+}
+
+static void docg4_write_page(struct mtd_info *mtd, struct nand_chip *nand,
+			     const uint8_t *buf)
+{
+	return write_page(mtd, nand, buf, 1);
+}
+
+static int read_page(struct mtd_info *mtd, struct nand_chip *nand,
+		     uint8_t *buf, int page, int use_ecc)
+{
+	struct docg4_priv *doc = nand->priv;
+	void __iomem *docptr = CONFIG_SYS_NAND_BASE;
+	uint16_t status, edc_err, *buf16;
+
+	writew(DOC_ECCCONF0_READ_MODE |
+	       DOC_ECCCONF0_ECC_ENABLE |
+	       DOC_ECCCONF0_UNKNOWN |
+	       DOCG4_BCH_SIZE,
+	       docptr + DOC_ECCCONF0);
+	write_nop(docptr);
+	write_nop(docptr);
+	write_nop(docptr);
+	write_nop(docptr);
+	write_nop(docptr);
+
+	/* the 1st byte from the I/O reg is a status; the rest is page data */
+	status = readw(docptr + DOC_IOSPACE_DATA);
+	if (status & DOCG4_READ_ERROR) {
+		printf("docg4_read_page: bad status: 0x%02x\n", status);
+		writew(0, docptr + DOC_DATAEND);
+		return -EIO;
+	}
+
+	docg4_read_buf(mtd, buf, DOCG4_PAGE_SIZE); /* read the page data */
+
+	/* first 14 oob bytes read from I/O reg */
+	docg4_read_buf(mtd, nand->oob_poi, 14);
+
+	/* last 2 read from another reg */
+	buf16 = (uint16_t *)(nand->oob_poi + 14);
+	*buf16 = readw(docptr + DOCG4_MYSTERY_REG);
+
+	/*
+	 * Diskonchips read oob immediately after a page read.  Mtd
+	 * infrastructure issues a separate command for reading oob after the
+	 * page is read.  So we save the oob bytes in a local buffer and just
+	 * copy it if the next command reads oob from the same page.
+	 */
+	memcpy(doc->oob_buf, nand->oob_poi, 16);
+
+	write_nop(docptr);
+
+	if (likely(use_ecc)) {
+		/* read the register that tells us if bitflip(s) detected  */
+		edc_err = readw(docptr + DOC_ECCCONF1);
+		edc_err = readw(docptr + DOC_ECCCONF1);
+
+		/* If bitflips are reported, attempt to correct with ecc */
+		if (edc_err & DOC_ECCCONF1_BCH_SYNDROM_ERR) {
+			int bits_corrected = correct_data(mtd, buf, page);
+			if (bits_corrected == -EBADMSG)
+				mtd->ecc_stats.failed++;
+			else
+				mtd->ecc_stats.corrected += bits_corrected;
+		}
+	}
+
+	writew(0, docptr + DOC_DATAEND);
+	return 0;
+}
+
+
+static int docg4_read_page_raw(struct mtd_info *mtd, struct nand_chip *nand,
+			       uint8_t *buf, int page)
+{
+	return read_page(mtd, nand, buf, page, 0);
+}
+
+static int docg4_read_page(struct mtd_info *mtd, struct nand_chip *nand,
+			   uint8_t *buf, int page)
+{
+	return read_page(mtd, nand, buf, page, 1);
+}
+
+static void docg4_erase_block(struct mtd_info *mtd, int page)
+{
+	struct nand_chip *nand = mtd->priv;
+	struct docg4_priv *doc = nand->priv;
+	void __iomem *docptr = CONFIG_SYS_NAND_BASE;
+	uint16_t g4_page;
+
+	MTDDEBUG(MTD_DEBUG_LEVEL3, "%s: page %04x\n", __func__, page);
+
+	sequence_reset(docptr);
+
+	writew(DOCG4_SEQ_BLOCKERASE, docptr + DOC_FLASHSEQUENCE);
+	writew(DOC_CMD_PROG_BLOCK_ADDR, docptr + DOC_FLASHCOMMAND);
+	write_nop(docptr);
+
+	/* only 2 bytes of address are written to specify erase block */
+	g4_page = (uint16_t)(page / 4);  /* to g4's 2k page addressing */
+	writeb(g4_page & 0xff, docptr + DOC_FLASHADDRESS);
+	g4_page >>= 8;
+	writeb(g4_page & 0xff, docptr + DOC_FLASHADDRESS);
+	write_nop(docptr);
+
+	/* start the erasure */
+	writew(DOC_CMD_ERASECYCLE2, docptr + DOC_FLASHCOMMAND);
+	write_nop(docptr);
+	write_nop(docptr);
+
+	poll_status(docptr);
+	writew(DOCG4_SEQ_FLUSH, docptr + DOC_FLASHSEQUENCE);
+	writew(DOCG4_CMD_FLUSH, docptr + DOC_FLASHCOMMAND);
+	writew(DOC_ECCCONF0_READ_MODE | 4, docptr + DOC_ECCCONF0);
+	write_nop(docptr);
+	write_nop(docptr);
+	write_nop(docptr);
+	write_nop(docptr);
+	write_nop(docptr);
+
+	read_progstatus(doc, docptr);
+
+	writew(0, docptr + DOC_DATAEND);
+	write_nop(docptr);
+	poll_status(docptr);
+	write_nop(docptr);
+}
+
+static int read_factory_bbt(struct mtd_info *mtd)
+{
+	/*
+	 * The device contains a read-only factory bad block table.  Read it and
+	 * update the memory-based bbt accordingly.
+	 */
+
+	struct nand_chip *nand = mtd->priv;
+	uint32_t g4_addr = mtd_to_docg4_address(DOCG4_FACTORY_BBT_PAGE, 0);
+	uint8_t *buf;
+	int i, block, status;
+
+	buf = kzalloc(DOCG4_PAGE_SIZE, GFP_KERNEL);
+	if (buf == NULL)
+		return -ENOMEM;
+
+	read_page_prologue(CONFIG_SYS_NAND_BASE, g4_addr);
+	status = docg4_read_page(mtd, nand, buf, DOCG4_FACTORY_BBT_PAGE);
+	if (status)
+		goto exit;
+
+	/*
+	 * If no memory-based bbt was created, exit.  This will happen if module
+	 * parameter ignore_badblocks is set.  Then why even call this function?
+	 * For an unknown reason, block erase always fails if it's the first
+	 * operation after device power-up.  The above read ensures it never is.
+	 * Ugly, I know.
+	 */
+	if (nand->bbt == NULL)  /* no memory-based bbt */
+		goto exit;
+
+	/*
+	 * Parse factory bbt and update memory-based bbt.  Factory bbt format is
+	 * simple: one bit per block, block numbers increase left to right (msb
+	 * to lsb).  Bit clear means bad block.
+	 */
+	for (i = block = 0; block < DOCG4_NUMBLOCKS; block += 8, i++) {
+		int bitnum;
+		uint8_t mask;
+		for (bitnum = 0, mask = 0x80;
+		     bitnum < 8; bitnum++, mask >>= 1) {
+			if (!(buf[i] & mask)) {
+				int badblock = block + bitnum;
+				nand->bbt[badblock / 4] |=
+					0x03 << ((badblock % 4) * 2);
+				mtd->ecc_stats.badblocks++;
+				printf("factory-marked bad block: %d\n",
+				       badblock);
+			}
+		}
+	}
+ exit:
+	kfree(buf);
+	return status;
+}
+
+static int docg4_block_markbad(struct mtd_info *mtd, loff_t ofs)
+{
+	/*
+	 * Mark a block as bad.  Bad blocks are marked in the oob area of the
+	 * first page of the block.  The default scan_bbt() in the nand
+	 * infrastructure code works fine for building the memory-based bbt
+	 * during initialization, as does the nand infrastructure function that
+	 * checks if a block is bad by reading the bbt.  This function replaces
+	 * the nand default because writes to oob-only are not supported.
+	 */
+
+	int ret, i;
+	uint8_t *buf;
+	struct nand_chip *nand = mtd->priv;
+	struct nand_bbt_descr *bbtd = nand->badblock_pattern;
+	int block = (int)(ofs >> nand->bbt_erase_shift);
+	int page = (int)(ofs >> nand->page_shift);
+	uint32_t g4_addr = mtd_to_docg4_address(page, 0);
+
+	MTDDEBUG(MTD_DEBUG_LEVEL3, "%s: %08llx\n", __func__, ofs);
+
+	if (unlikely(ofs & (DOCG4_BLOCK_SIZE - 1)))
+		printf("%s: ofs %llx not start of block!\n",
+		       __func__, ofs);
+
+	/* allocate blank buffer for page data */
+	buf = kzalloc(DOCG4_PAGE_SIZE, GFP_KERNEL);
+	if (buf == NULL)
+		return -ENOMEM;
+
+	/* update bbt in memory */
+	nand->bbt[block / 4] |= 0x01 << ((block & 0x03) * 2);
+
+	/* write bit-wise negation of pattern to oob buffer */
+	memset(nand->oob_poi, 0xff, mtd->oobsize);
+	for (i = 0; i < bbtd->len; i++)
+		nand->oob_poi[bbtd->offs + i] = ~bbtd->pattern[i];
+
+	/* write first page of block */
+	write_page_prologue(CONFIG_SYS_NAND_BASE, g4_addr);
+	docg4_write_page(mtd, nand, buf);
+	ret = pageprog(mtd);
+	if (!ret)
+		mtd->ecc_stats.badblocks++;
+
+	kfree(buf);
+
+	return ret;
+}
+
+static uint8_t docg4_read_byte(struct mtd_info *mtd)
+{
+	struct nand_chip *nand = mtd->priv;
+	struct docg4_priv *doc = nand->priv;
+
+	MTDDEBUG(MTD_DEBUG_LEVEL3, "%s\n", __func__);
+
+	if (doc->last_command.command == NAND_CMD_STATUS) {
+		int status;
+
+		/*
+		 * Previous nand command was status request, so nand
+		 * infrastructure code expects to read the status here.  If an
+		 * error occurred in a previous operation, report it.
+		 */
+		doc->last_command.command = 0;
+
+		if (doc->status) {
+			status = doc->status;
+			doc->status = 0;
+		}
+
+		/* why is NAND_STATUS_WP inverse logic?? */
+		else
+			status = NAND_STATUS_WP | NAND_STATUS_READY;
+
+		return status;
+	}
+
+	printf("unexpectd call to read_byte()\n");
+
+	return 0;
+}
+
+static int docg4_wait(struct mtd_info *mtd, struct nand_chip *nand)
+{
+	struct docg4_priv *doc = nand->priv;
+	int status = NAND_STATUS_WP;       /* inverse logic?? */
+	MTDDEBUG(MTD_DEBUG_LEVEL3, "%s...\n", __func__);
+
+	/* report any previously unreported error */
+	if (doc->status) {
+		status |= doc->status;
+		doc->status = 0;
+		return status;
+	}
+
+	status |= poll_status(CONFIG_SYS_NAND_BASE);
+	return status;
+}
+
+int docg4_nand_init(struct mtd_info *mtd, struct nand_chip *nand, int devnum)
+{
+	uint16_t id1, id2;
+	struct docg4_priv *docg4;
+	int retval;
+
+	docg4 = kzalloc(sizeof(*docg4), GFP_KERNEL);
+	if (!docg4)
+		return -1;
+
+	mtd->priv = nand;
+	nand->priv = docg4;
+
+	/* These must be initialized here because the docg4 is non-standard
+	 * and doesn't produce an id that the nand code can use to look up
+	 * these values (nand_scan_ident() not called).
+	 */
+	mtd->size = DOCG4_CHIP_SIZE;
+	mtd->name = "Msys_Diskonchip_G4";
+	mtd->writesize = DOCG4_PAGE_SIZE;
+	mtd->erasesize = DOCG4_BLOCK_SIZE;
+	mtd->oobsize = DOCG4_OOB_SIZE;
+
+	nand->IO_ADDR_R =
+		(void __iomem *)CONFIG_SYS_NAND_BASE + DOC_IOSPACE_DATA;
+	nand->IO_ADDR_W = nand->IO_ADDR_R;
+	nand->chipsize = DOCG4_CHIP_SIZE;
+	nand->chip_shift = DOCG4_CHIP_SHIFT;
+	nand->bbt_erase_shift = DOCG4_ERASE_SHIFT;
+	nand->phys_erase_shift = DOCG4_ERASE_SHIFT;
+	nand->chip_delay = 20;
+	nand->page_shift = DOCG4_PAGE_SHIFT;
+	nand->pagemask = 0x3ffff;
+	nand->badblockpos = NAND_LARGE_BADBLOCK_POS;
+	nand->badblockbits = 8;
+	nand->ecc.layout = &docg4_oobinfo;
+	nand->ecc.mode = NAND_ECC_HW_SYNDROME;
+	nand->ecc.size = DOCG4_PAGE_SIZE;
+	nand->ecc.prepad = 8;
+	nand->ecc.bytes	= 8;
+	nand->options =
+		NAND_BUSWIDTH_16 | NAND_NO_SUBPAGE_WRITE | NAND_NO_AUTOINCR;
+	nand->controller = &nand->hwcontrol;
+
+	/* methods */
+	nand->cmdfunc = docg4_command;
+	nand->waitfunc = docg4_wait;
+	nand->select_chip = docg4_select_chip;
+	nand->read_byte = docg4_read_byte;
+	nand->block_markbad = docg4_block_markbad;
+	nand->read_buf = docg4_read_buf;
+	nand->write_buf = docg4_write_buf16;
+	nand->scan_bbt = nand_default_bbt;
+	nand->erase_cmd = docg4_erase_block;
+	nand->ecc.read_page = docg4_read_page;
+	nand->ecc.write_page = docg4_write_page;
+	nand->ecc.read_page_raw = docg4_read_page_raw;
+	nand->ecc.write_page_raw = docg4_write_page_raw;
+	nand->ecc.read_oob = docg4_read_oob;
+	nand->ecc.write_oob = docg4_write_oob;
+
+	/*
+	 * The way the nand infrastructure code is written, a memory-based bbt
+	 * is not created if NAND_SKIP_BBTSCAN is set.  With no memory bbt,
+	 * nand->block_bad() is used.  So when ignoring bad blocks, we skip the
+	 * scan and define a dummy block_bad() which always returns 0.
+	 */
+	if (ignore_badblocks) {
+		nand->options |= NAND_SKIP_BBTSCAN;
+		nand->block_bad	= docg4_block_neverbad;
+	}
+
+	reset(CONFIG_SYS_NAND_BASE);
+
+	/* check for presence of g4 chip by reading id registers */
+	id1 = readw(CONFIG_SYS_NAND_BASE + DOC_CHIPID);
+	id1 = readw(CONFIG_SYS_NAND_BASE + DOCG4_MYSTERY_REG);
+	id2 = readw(CONFIG_SYS_NAND_BASE + DOC_CHIPID_INV);
+	id2 = readw(CONFIG_SYS_NAND_BASE + DOCG4_MYSTERY_REG);
+	if (id1 != DOCG4_IDREG1_VALUE || id2 != DOCG4_IDREG2_VALUE)
+		return -1;
+
+	/* initialize bch algorithm */
+	docg4->bch = init_bch(DOCG4_M, DOCG4_T, DOCG4_PRIMITIVE_POLY);
+	if (docg4->bch == NULL)
+		return -1;
+
+	retval = nand_scan_tail(mtd);
+	if (retval)
+		return -1;
+
+	/*
+	 * Scan for bad blocks and create bbt here, then add the factory-marked
+	 * bad blocks to the bbt.
+	 */
+	nand->scan_bbt(mtd);
+	nand->options |= NAND_BBT_SCANNED;
+	retval = read_factory_bbt(mtd);
+	if (retval)
+		return -1;
+
+	retval = nand_register(devnum);
+	if (retval)
+		return -1;
+
+	return 0;
+}

+ 222 - 0
drivers/mtd/nand/docg4_spl.c

@@ -0,0 +1,222 @@
+/*
+ * SPL driver for Diskonchip G4 nand flash
+ *
+ * Copyright (C) 2013 Mike Dunn <mikedunn@newsguy.com>
+ *
+ * This file is released under the terms of GPL v2 and any later version.
+ * See the file COPYING in the root directory of the source tree for details.
+ *
+ *
+ * This driver basically mimics the load functionality of a typical IPL (initial
+ * program loader) resident in the 2k NOR-like region of the docg4 that is
+ * mapped to the reset vector.  It allows the u-boot SPL to continue loading if
+ * the IPL loads a fixed number of flash blocks that is insufficient to contain
+ * the entire u-boot image.  In this case, a concatenated spl + u-boot image is
+ * written at the flash offset from which the IPL loads an image, and when the
+ * IPL jumps to the SPL, the SPL resumes loading where the IPL left off.  See
+ * the palmtreo680 for an example.
+ *
+ * This driver assumes that the data was written to the flash using the device's
+ * "reliable" mode, and also assumes that each 512 byte page is stored
+ * redundantly in the subsequent page.  This storage format is likely to be used
+ * by all boards that boot from the docg4.  The format compensates for the lack
+ * of ecc in the IPL.
+ *
+ * Reliable mode reduces the capacity of a block by half, and the redundant
+ * pages reduce it by half again.  As a result, the normal 256k capacity of a
+ * block is reduced to 64k for the purposes of the IPL/SPL.
+ */
+
+#include <asm/io.h>
+#include <linux/mtd/docg4.h>
+
+/* forward declarations */
+static inline void write_nop(void __iomem *docptr);
+static int poll_status(void __iomem *docptr);
+static void write_addr(void __iomem *docptr, uint32_t docg4_addr);
+static void address_sequence(unsigned int g4_page, unsigned int g4_index,
+			     void __iomem *docptr);
+static int docg4_load_block_reliable(uint32_t flash_offset, void *dest_addr);
+
+int nand_spl_load_image(uint32_t offs, unsigned int size, void *dst)
+{
+	void *load_addr = dst;
+	uint32_t flash_offset = offs;
+	const unsigned int block_count =
+		(size + DOCG4_BLOCK_CAPACITY_SPL - 1)
+		/ DOCG4_BLOCK_CAPACITY_SPL;
+	int i;
+
+	for (i = 0; i < block_count; i++) {
+		int ret = docg4_load_block_reliable(flash_offset, load_addr);
+		if (ret)
+			return ret;
+		load_addr += DOCG4_BLOCK_CAPACITY_SPL;
+		flash_offset += DOCG4_BLOCK_SIZE;
+	}
+	return 0;
+}
+
+static inline void write_nop(void __iomem *docptr)
+{
+	writew(0, docptr + DOC_NOP);
+}
+
+static int poll_status(void __iomem *docptr)
+{
+	/*
+	 * Busy-wait for the FLASHREADY bit to be set in the FLASHCONTROL
+	 * register.  Operations known to take a long time (e.g., block erase)
+	 * should sleep for a while before calling this.
+	 */
+
+	uint8_t flash_status;
+
+	/* hardware quirk requires reading twice initially */
+	flash_status = readb(docptr + DOC_FLASHCONTROL);
+
+	do {
+		flash_status = readb(docptr + DOC_FLASHCONTROL);
+	} while (!(flash_status & DOC_CTRL_FLASHREADY));
+
+	return 0;
+}
+
+static void write_addr(void __iomem *docptr, uint32_t docg4_addr)
+{
+	/* write the four address bytes packed in docg4_addr to the device */
+
+	writeb(docg4_addr & 0xff, docptr + DOC_FLASHADDRESS);
+	docg4_addr >>= 8;
+	writeb(docg4_addr & 0xff, docptr + DOC_FLASHADDRESS);
+	docg4_addr >>= 8;
+	writeb(docg4_addr & 0xff, docptr + DOC_FLASHADDRESS);
+	docg4_addr >>= 8;
+	writeb(docg4_addr & 0xff, docptr + DOC_FLASHADDRESS);
+}
+
+static void address_sequence(unsigned int g4_page, unsigned int g4_index,
+			     void __iomem *docptr)
+{
+	writew(DOCG4_SEQ_PAGE_READ, docptr + DOC_FLASHSEQUENCE);
+	writew(DOCG4_CMD_PAGE_READ, docptr + DOC_FLASHCOMMAND);
+	write_nop(docptr);
+	write_addr(docptr, ((uint32_t)g4_page << 16) | g4_index);
+	write_nop(docptr);
+}
+
+static int docg4_load_block_reliable(uint32_t flash_offset, void *dest_addr)
+{
+	void __iomem *docptr = (void *)CONFIG_SYS_NAND_BASE;
+	unsigned int g4_page = flash_offset >> 11; /* 2k page */
+	const unsigned int last_g4_page = g4_page + 0x80; /* last in block */
+	int g4_index = 0;
+	uint16_t flash_status;
+	uint16_t *buf;
+	uint16_t discard, magic_high, magic_low;
+
+	/* flash_offset must be aligned to the start of a block */
+	if (flash_offset & 0x3ffff)
+		return -1;
+
+	writew(DOC_SEQ_RESET, docptr + DOC_FLASHSEQUENCE);
+	writew(DOC_CMD_RESET, docptr + DOC_FLASHCOMMAND);
+	write_nop(docptr);
+	write_nop(docptr);
+	poll_status(docptr);
+	write_nop(docptr);
+	writew(0x45, docptr + DOC_FLASHSEQUENCE);
+	writew(0xa3, docptr + DOC_FLASHCOMMAND);
+	write_nop(docptr);
+	writew(0x22, docptr + DOC_FLASHCOMMAND);
+	write_nop(docptr);
+
+	/* read 1st 4 oob bytes of first subpage of block */
+	address_sequence(g4_page, 0x0100, docptr); /* index at oob */
+	write_nop(docptr);
+	flash_status = readw(docptr + DOC_FLASHCONTROL);
+	flash_status = readw(docptr + DOC_FLASHCONTROL);
+	if (flash_status & 0x06) /* sequence or protection errors */
+		return -1;
+	writew(DOCG4_CMD_READ2, docptr + DOC_FLASHCOMMAND);
+	write_nop(docptr);
+	write_nop(docptr);
+	poll_status(docptr);
+	writew(DOC_ECCCONF0_READ_MODE | 4, docptr + DOC_ECCCONF0);
+	write_nop(docptr);
+	write_nop(docptr);
+	write_nop(docptr);
+	write_nop(docptr);
+	write_nop(docptr);
+
+	/*
+	 * Here we read the first four oob bytes of the first page of the block.
+	 * The IPL on the palmtreo680 requires that this contain a 32 bit magic
+	 * number, or the load aborts.  We'll ignore it.
+	 */
+	discard = readw(docptr + 0x103c); /* hw quirk; 1st read discarded */
+	magic_low = readw(docptr + 0x103c);
+	magic_high = readw(docptr + DOCG4_MYSTERY_REG);
+	writew(0, docptr + DOC_DATAEND);
+	write_nop(docptr);
+	write_nop(docptr);
+
+	/* load contents of block to memory */
+	buf = (uint16_t *)dest_addr;
+	do {
+		int i;
+
+		address_sequence(g4_page, g4_index, docptr);
+		writew(DOCG4_CMD_READ2,
+		       docptr + DOC_FLASHCOMMAND);
+		write_nop(docptr);
+		write_nop(docptr);
+		poll_status(docptr);
+		writew(DOC_ECCCONF0_READ_MODE |
+		       DOC_ECCCONF0_ECC_ENABLE |
+		       DOCG4_BCH_SIZE,
+		       docptr + DOC_ECCCONF0);
+		write_nop(docptr);
+		write_nop(docptr);
+		write_nop(docptr);
+		write_nop(docptr);
+		write_nop(docptr);
+
+		/* read the 512 bytes of page data, 2 bytes at a time */
+		discard = readw(docptr + 0x103c);
+		for (i = 0; i < 256; i++)
+			*buf++ = readw(docptr + 0x103c);
+
+		/* read oob, but discard it */
+		for (i = 0; i < 7; i++)
+			discard = readw(docptr + 0x103c);
+		discard = readw(docptr + DOCG4_OOB_6_7);
+		discard = readw(docptr + DOCG4_OOB_6_7);
+
+		writew(0, docptr + DOC_DATAEND);
+		write_nop(docptr);
+		write_nop(docptr);
+
+		if (!(g4_index & 0x100)) {
+			/* not redundant subpage read; check for ecc error */
+			write_nop(docptr);
+			flash_status = readw(docptr + DOC_ECCCONF1);
+			flash_status = readw(docptr + DOC_ECCCONF1);
+			if (flash_status & 0x80) { /* ecc error */
+				g4_index += 0x108; /* read redundant subpage */
+				buf -= 256;        /* back up ram ptr */
+				continue;
+			} else                       /* no ecc error */
+				g4_index += 0x210; /* skip redundant subpage */
+		} else  /* redundant page was just read; skip ecc error check */
+			g4_index += 0x108;
+
+		if (g4_index == 0x420) { /* finished with 2k page */
+			g4_index = 0;
+			g4_page += 2; /* odd-numbered 2k pages skipped */
+		}
+
+	} while (g4_page != last_g4_page); /* while still on same block */
+
+	return 0;
+}

+ 0 - 9
drivers/mtd/nand/mxc_nand_spl.c

@@ -355,12 +355,3 @@ void nand_boot(void)
 		hang();
 		hang();
 	}
 	}
 }
 }
-
-/*
- * Called in case of an exception.
- */
-void hang(void)
-{
-	/* Loop forever */
-	while (1) ;
-}

+ 17 - 0
drivers/net/fm/memac.c

@@ -112,6 +112,23 @@ static void memac_set_interface_mode(struct fsl_enet_mac *mac,
 	/* Enable automatic speed selection */
 	/* Enable automatic speed selection */
 	if_mode |= IF_MODE_EN_AUTO;
 	if_mode |= IF_MODE_EN_AUTO;
 
 
+	if (type == PHY_INTERFACE_MODE_RGMII) {
+		if_mode &= ~IF_MODE_EN_AUTO;
+		if_mode &= ~IF_MODE_SETSP_MASK;
+		switch (speed) {
+		case SPEED_1000:
+			if_mode |= IF_MODE_SETSP_1000M;
+			break;
+		case SPEED_100:
+			if_mode |= IF_MODE_SETSP_100M;
+			break;
+		case SPEED_10:
+			if_mode |= IF_MODE_SETSP_10M;
+		default:
+			break;
+		}
+	}
+
 	debug(" %s, if_mode = %x\n", __func__,  if_mode);
 	debug(" %s, if_mode = %x\n", __func__,  if_mode);
 	debug(" %s, if_status = %x\n", __func__,  if_status);
 	debug(" %s, if_status = %x\n", __func__,  if_status);
 	out_be32(&regs->if_mode, if_mode);
 	out_be32(&regs->if_mode, if_mode);

部分文件因为文件数量过多而无法显示