Merge branch 'master' of git://git.denx.de/u-boot-mpc85xx
diff --git a/MAINTAINERS b/MAINTAINERS
index 24a55c2..e2a4ba9 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -427,12 +427,19 @@
 	ids8247		MPC8247
 	jupiter		MPC5200
 	kmeter1		MPC8360
+	kmsupx5		MPC8321
 	mgcoge		MPC8247
+	mgcoge2ne	MPC8247
+	mgcoge2un	ARM926EJS (Kirkwood SoC)
 	mucmc52		MPC5200
 	muas3001	MPC8270
 	municse		MPC5200
 	sc3		PPC405GP
 	suen3		ARM926EJS (Kirkwood SoC)
+	suen8		ARM926EJS (Kirkwood SoC)
+	suvd3		MPC8321
+	tuda1		MPC8321
+	tuxa1		MPC8321
 	uc101		MPC5200
 	ve8313		MPC8313
 
diff --git a/Makefile b/Makefile
index ada951e..384a59e 100644
--- a/Makefile
+++ b/Makefile
@@ -183,6 +183,7 @@
 LIBS  = lib/libgeneric.o
 LIBS += lib/lzma/liblzma.o
 LIBS += lib/lzo/liblzo.o
+LIBS += lib/zlib/libz.o
 LIBS += $(shell if [ -f board/$(VENDOR)/common/Makefile ]; then echo \
 	"board/$(VENDOR)/common/lib$(VENDOR).o"; fi)
 LIBS += $(CPUDIR)/lib$(CPU).o
diff --git a/README b/README
index 2754d1e..76b1500 100644
--- a/README
+++ b/README
@@ -1103,13 +1103,10 @@
 			CONFIG_VIDEO_LOGO
 			CONFIG_VIDEO_BMP_LOGO
 
-		The DIU driver will look for the 'monitor' environment variable,
-		and if defined, enable the DIU as a console during boot.  This
-		variable should be set to one of these values:
-
-			'0'	Output video to the DVI connector
-			'1'	Output video to the LVDS connector
-			'2'	Output video to the Dual-Link LVDS connector
+		The DIU driver will look for the 'video-mode' environment
+		variable, and if defined, enable the DIU as a console during
+		boot.  See the documentation file README.video for a
+		description of this variable.
 
 - Keyboard Support:
 		CONFIG_KEYBOARD
@@ -2761,6 +2758,14 @@
 		source code. It is used to make hardware dependant
 		initializations.
 
+- CONFIG_IDE_AHB:
+		Most IDE controllers were designed to be connected with PCI
+		interface. Only few of them were designed for AHB interface.
+		When software is doing ATA command and data transfer to
+		IDE devices through IDE-AHB controller, some additional
+		registers accessing to these kind of IDE-AHB controller
+		is requierd.
+
 - CONFIG_SYS_IMMR:	Physical address of the Internal Memory.
 		DO NOT CHANGE unless you know exactly what you're
 		doing! (11-4) [MPC8xx/82xx systems only]
diff --git a/arch/arm/config.mk b/arch/arm/config.mk
index fcc26a2..ec1b420 100644
--- a/arch/arm/config.mk
+++ b/arch/arm/config.mk
@@ -61,7 +61,6 @@
 PLATFORM_LIBS += $(OBJTREE)/arch/arm/lib/eabi_compat.o
 endif
 endif
-LDSCRIPT := $(SRCTREE)/$(CPUDIR)/u-boot.lds
 
 # needed for relocation
 ifndef CONFIG_NAND_SPL
diff --git a/arch/nios2/config.mk b/arch/nios2/config.mk
index d241a96..e58ea24 100644
--- a/arch/nios2/config.mk
+++ b/arch/nios2/config.mk
@@ -29,7 +29,5 @@
 PLATFORM_CPPFLAGS += -DCONFIG_NIOS2 -D__NIOS2__
 PLATFORM_CPPFLAGS += -G0
 
-LDSCRIPT ?= $(SRCTREE)/$(CPUDIR)/u-boot.lds
-
 LDFLAGS_FINAL += --gc-sections
 PLATFORM_RELFLAGS += -ffunction-sections -fdata-sections
diff --git a/arch/powerpc/config.mk b/arch/powerpc/config.mk
index e682071..a307154 100644
--- a/arch/powerpc/config.mk
+++ b/arch/powerpc/config.mk
@@ -29,17 +29,6 @@
 PLATFORM_CPPFLAGS += -DCONFIG_PPC -D__powerpc__
 PLATFORM_LDFLAGS  += -n
 
-ifdef CONFIG_SYS_LDSCRIPT
-# need to strip off double quotes
-LDSCRIPT := $(subst ",,$(CONFIG_SYS_LDSCRIPT))
-else ifdef CONFIG_NAND_SPL
-LDSCRIPT := $(SRCTREE)/$(CONFIG_BOARDDIR)/u-boot-nand.lds
-else
-ifneq ($(wildcard $(SRCTREE)/arch/powerpc/cpu/$(CPU)/u-boot.lds),)
-LDSCRIPT := $(SRCTREE)/arch/powerpc/cpu/$(CPU)/u-boot.lds
-endif
-endif
-
 #
 # When cross-compiling on NetBSD, we have to define __PPC__ or else we
 # will pick up a va_list declaration that is incompatible with the
diff --git a/arch/powerpc/cpu/mpc512x/diu.c b/arch/powerpc/cpu/mpc512x/diu.c
index c4108af..9dc1e48 100644
--- a/arch/powerpc/cpu/mpc512x/diu.c
+++ b/arch/powerpc/cpu/mpc512x/diu.c
@@ -51,20 +51,10 @@
 	debug("DIU: Modified value of CLKDVDR = 0x%08x\n", in_be32(clkdvdr));
 }
 
-int platform_diu_init(unsigned int *xres, unsigned int *yres)
+int platform_diu_init(unsigned int xres, unsigned int yres, const char *port)
 {
-	unsigned int pixel_format;
-
-#if defined(CONFIG_VIDEO_XRES) & defined(CONFIG_VIDEO_YRES)
-	*xres = CONFIG_VIDEO_XRES;
-	*yres = CONFIG_VIDEO_YRES;
-#else
-	*xres = 1024;
-	*yres = 768;
-#endif
-	pixel_format = 0x88883316;
+	unsigned int pixel_format = 0x88883316;
 
 	debug("mpc5121_diu_init\n");
-
-	return fsl_diu_init(*xres, pixel_format, 0);
+	return fsl_diu_init(xres, pixel_format, 0);
 }
diff --git a/arch/powerpc/cpu/mpc83xx/fdt.c b/arch/powerpc/cpu/mpc83xx/fdt.c
index daf73a6..028c8f0 100644
--- a/arch/powerpc/cpu/mpc83xx/fdt.c
+++ b/arch/powerpc/cpu/mpc83xx/fdt.c
@@ -32,7 +32,8 @@
 
 DECLARE_GLOBAL_DATA_PTR;
 
-#if defined(CONFIG_BOOTCOUNT_LIMIT) && defined(CONFIG_MPC8360)
+#if defined(CONFIG_BOOTCOUNT_LIMIT) && \
+	(defined(CONFIG_QE))
 #include <asm/immap_qe.h>
 
 void fdt_fixup_muram (void *blob)
diff --git a/arch/powerpc/lib/bootcount.c b/arch/powerpc/lib/bootcount.c
index 07ef28d..f9ce539 100644
--- a/arch/powerpc/lib/bootcount.c
+++ b/arch/powerpc/lib/bootcount.c
@@ -51,7 +51,7 @@
 #define CONFIG_SYS_BOOTCOUNT_ADDR	(CONFIG_SYS_IMMR + CPM_BOOTCOUNT_ADDR)
 #endif /* defined(CONFIG_MPC8260) */
 
-#if defined(CONFIG_MPC8360)
+#if defined(CONFIG_QE)
 #include <asm/immap_qe.h>
 
 #define CONFIG_SYS_BOOTCOUNT_ADDR	(CONFIG_SYS_IMMR + 0x110000 + \
diff --git a/arch/sh/config.mk b/arch/sh/config.mk
index af57307..07ff8b9 100644
--- a/arch/sh/config.mk
+++ b/arch/sh/config.mk
@@ -31,9 +31,3 @@
 PLATFORM_CPPFLAGS += -DCONFIG_SH -D__SH__
 PLATFORM_LDFLAGS += -e $(CONFIG_SYS_TEXT_BASE) --defsym reloc_dst=$(CONFIG_SYS_TEXT_BASE)
 LDFLAGS_FINAL = --gc-sections
-
-ifdef CONFIG_SYS_LDSCRIPT
-LDSCRIPT := $(subst ",,$(CONFIG_SYS_LDSCRIPT))
-else
-LDSCRIPT := $(SRCTREE)/$(CPUDIR)/u-boot.lds
-endif
diff --git a/arch/x86/config.mk b/arch/x86/config.mk
index e945201..ee23c9f 100644
--- a/arch/x86/config.mk
+++ b/arch/x86/config.mk
@@ -39,4 +39,3 @@
 PLATFORM_LDFLAGS += --emit-relocs -Bsymbolic -Bsymbolic-functions
 
 LDFLAGS_FINAL += --gc-sections -pie
-LDSCRIPT := $(SRCTREE)/$(CPUDIR)/u-boot.lds
diff --git a/board/actux1/config.mk b/board/actux1/config.mk
index 88634f7..9cb838b 100644
--- a/board/actux1/config.mk
+++ b/board/actux1/config.mk
@@ -2,5 +2,3 @@
 
 # include NPE ethernet driver
 BOARDLIBS = arch/arm/cpu/ixp/npe/libnpe.o
-
-LDSCRIPT := $(SRCTREE)/board/$(BOARDDIR)/u-boot.lds
diff --git a/board/actux2/config.mk b/board/actux2/config.mk
index 88634f7..9cb838b 100644
--- a/board/actux2/config.mk
+++ b/board/actux2/config.mk
@@ -2,5 +2,3 @@
 
 # include NPE ethernet driver
 BOARDLIBS = arch/arm/cpu/ixp/npe/libnpe.o
-
-LDSCRIPT := $(SRCTREE)/board/$(BOARDDIR)/u-boot.lds
diff --git a/board/actux3/config.mk b/board/actux3/config.mk
index 88634f7..9cb838b 100644
--- a/board/actux3/config.mk
+++ b/board/actux3/config.mk
@@ -2,5 +2,3 @@
 
 # include NPE ethernet driver
 BOARDLIBS = arch/arm/cpu/ixp/npe/libnpe.o
-
-LDSCRIPT := $(SRCTREE)/board/$(BOARDDIR)/u-boot.lds
diff --git a/board/altera/nios2-generic/config.mk b/board/altera/nios2-generic/config.mk
index 95e75af..00c16fc 100644
--- a/board/altera/nios2-generic/config.mk
+++ b/board/altera/nios2-generic/config.mk
@@ -30,5 +30,3 @@
 ifeq ($(debug),1)
 PLATFORM_CPPFLAGS += -DDEBUG
 endif
-
-LDSCRIPT := $(SRCTREE)/board/$(VENDOR)/$(BOARD)/u-boot.lds
diff --git a/board/amcc/acadia/config.mk b/board/amcc/acadia/config.mk
index 2f2787f..bfc0945 100644
--- a/board/amcc/acadia/config.mk
+++ b/board/amcc/acadia/config.mk
@@ -28,10 +28,3 @@
 ifeq ($(debug),1)
 PLATFORM_CPPFLAGS += -DDEBUG
 endif
-
-ifdef CONFIG_SYS_LDSCRIPT
-# need to strip off double quotes
-LDSCRIPT := $(subst ",,$(CONFIG_SYS_LDSCRIPT))
-else ifdef CONFIG_NAND_U_BOOT
-LDSCRIPT := $(TOPDIR)/board/$(BOARDDIR)/u-boot-nand.lds
-endif
diff --git a/board/amcc/bamboo/config.mk b/board/amcc/bamboo/config.mk
index 7ca16a0..24f74e1 100644
--- a/board/amcc/bamboo/config.mk
+++ b/board/amcc/bamboo/config.mk
@@ -30,10 +30,3 @@
 ifeq ($(dbcr),1)
 PLATFORM_CPPFLAGS += -DCONFIG_SYS_INIT_DBCR=0x8cff0000
 endif
-
-ifdef CONFIG_SYS_LDSCRIPT
-# need to strip off double quotes
-LDSCRIPT := $(subst ",,$(CONFIG_SYS_LDSCRIPT))
-else ifdef CONFIG_NAND_U_BOOT
-LDSCRIPT := $(TOPDIR)/board/$(BOARDDIR)/u-boot-nand.lds
-endif
diff --git a/board/amcc/canyonlands/config.mk b/board/amcc/canyonlands/config.mk
index abf2a26..d693a26 100644
--- a/board/amcc/canyonlands/config.mk
+++ b/board/amcc/canyonlands/config.mk
@@ -33,10 +33,3 @@
 ifeq ($(dbcr),1)
 PLATFORM_CPPFLAGS += -DCONFIG_SYS_INIT_DBCR=0x8cff0000
 endif
-
-ifdef CONFIG_SYS_LDSCRIPT
-# need to strip off double quotes
-LDSCRIPT := $(subst ",,$(CONFIG_SYS_LDSCRIPT))
-else ifdef CONFIG_NAND_U_BOOT
-LDSCRIPT := $(TOPDIR)/board/$(BOARDDIR)/u-boot-nand.lds
-endif
diff --git a/board/amcc/kilauea/config.mk b/board/amcc/kilauea/config.mk
index 4ae3ea9..003b8c3 100644
--- a/board/amcc/kilauea/config.mk
+++ b/board/amcc/kilauea/config.mk
@@ -24,10 +24,3 @@
 ifeq ($(debug),1)
 PLATFORM_CPPFLAGS += -DDEBUG
 endif
-
-ifdef CONFIG_SYS_LDSCRIPT
-# need to strip off double quotes
-LDSCRIPT := $(subst ",,$(CONFIG_SYS_LDSCRIPT))
-else ifdef CONFIG_NAND_U_BOOT
-LDSCRIPT := $(TOPDIR)/board/$(BOARDDIR)/u-boot-nand.lds
-endif
diff --git a/board/amcc/sequoia/config.mk b/board/amcc/sequoia/config.mk
index 73efe72..e0bf071 100644
--- a/board/amcc/sequoia/config.mk
+++ b/board/amcc/sequoia/config.mk
@@ -33,10 +33,3 @@
 ifeq ($(dbcr),1)
 PLATFORM_CPPFLAGS += -DCONFIG_SYS_INIT_DBCR=0x8cff0000
 endif
-
-ifdef CONFIG_SYS_LDSCRIPT
-# need to strip off double quotes
-LDSCRIPT := $(subst ",,$(CONFIG_SYS_LDSCRIPT))
-else ifdef CONFIG_NAND_U_BOOT
-LDSCRIPT := $(TOPDIR)/board/$(BOARDDIR)/u-boot-nand.lds
-endif
diff --git a/board/armltd/vexpress/ca9x4_ct_vxp.c b/board/armltd/vexpress/ca9x4_ct_vxp.c
index ce1be1e..3566b95 100644
--- a/board/armltd/vexpress/ca9x4_ct_vxp.c
+++ b/board/armltd/vexpress/ca9x4_ct_vxp.c
@@ -86,6 +86,15 @@
 	return rc;
 }
 
+int cpu_mmc_init(bd_t *bis)
+{
+	int rc = 0;
+#ifdef CONFIG_ARM_PL180_MMCI
+	rc = arm_pl180_mmci_init();
+#endif
+	return rc;
+}
+
 static void flash__init(void)
 {
 	/* Setup the sytem control register to allow writing to flash */
diff --git a/board/atmel/atstk1000/config.mk b/board/atmel/atstk1000/config.mk
index 8c03b77..284f7ff 100644
--- a/board/atmel/atstk1000/config.mk
+++ b/board/atmel/atstk1000/config.mk
@@ -1,4 +1,3 @@
 PLATFORM_RELFLAGS	+= -ffunction-sections -fdata-sections
 PLATFORM_LDFLAGS	+= --gc-sections
 CONFIG_SYS_TEXT_BASE		= 0x00000000
-LDSCRIPT		= $(src)board/atmel/atstk1000/u-boot.lds
diff --git a/board/avnet/fx12mm/config.mk b/board/avnet/fx12mm/config.mk
deleted file mode 100644
index 78dde62..0000000
--- a/board/avnet/fx12mm/config.mk
+++ /dev/null
@@ -1,29 +0,0 @@
-#
-# (C) Copyright 2008
-# Ricardo Ribalda-Universidad Autonoma de Madrid-ricardo.ribalda@uam.es
-# Work supported by Qtechnology http://www.qtec.com
-#
-# 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
-#
-#
-
-ifdef CONFIG_SYS_LDSCRIPT
-# need to strip off double quotes
-LDSCRIPT := $(subst ",,$(CONFIG_SYS_LDSCRIPT))
-endif
diff --git a/board/avnet/v5fx30teval/config.mk b/board/avnet/v5fx30teval/config.mk
deleted file mode 100644
index 78dde62..0000000
--- a/board/avnet/v5fx30teval/config.mk
+++ /dev/null
@@ -1,29 +0,0 @@
-#
-# (C) Copyright 2008
-# Ricardo Ribalda-Universidad Autonoma de Madrid-ricardo.ribalda@uam.es
-# Work supported by Qtechnology http://www.qtec.com
-#
-# 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
-#
-#
-
-ifdef CONFIG_SYS_LDSCRIPT
-# need to strip off double quotes
-LDSCRIPT := $(subst ",,$(CONFIG_SYS_LDSCRIPT))
-endif
diff --git a/board/cm5200/u-boot.lds b/board/cm5200/u-boot.lds
deleted file mode 100644
index cf73b11..0000000
--- a/board/cm5200/u-boot.lds
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * (C) Copyright 2003-2007
- * Wolfgang Denk, DENX Software Engineering, wd@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.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-
-OUTPUT_ARCH(powerpc)
-SECTIONS
-{
-  /* Read-only sections, merged into text segment: */
-  . = + SIZEOF_HEADERS;
-  .interp : { *(.interp) }
-  .hash          : { *(.hash)		}
-  .dynsym        : { *(.dynsym)		}
-  .dynstr        : { *(.dynstr)		}
-  .rel.text      : { *(.rel.text)		}
-  .rela.text     : { *(.rela.text)	}
-  .rel.data      : { *(.rel.data)		}
-  .rela.data     : { *(.rela.data)	}
-  .rel.rodata    : { *(.rel.rodata)	}
-  .rela.rodata   : { *(.rela.rodata)	}
-  .rel.got       : { *(.rel.got)		}
-  .rela.got      : { *(.rela.got)		}
-  .rel.ctors     : { *(.rel.ctors)	}
-  .rela.ctors    : { *(.rela.ctors)	}
-  .rel.dtors     : { *(.rel.dtors)	}
-  .rela.dtors    : { *(.rela.dtors)	}
-  .rel.bss       : { *(.rel.bss)		}
-  .rela.bss      : { *(.rela.bss)		}
-  .rel.plt       : { *(.rel.plt)		}
-  .rela.plt      : { *(.rela.plt)		}
-  .init          : { *(.init)	}
-  .plt : { *(.plt) }
-  .text      :
-  {
-    arch/powerpc/cpu/mpc5xxx/start.o	(.text)
-    *(.text)
-    *(.got1)
-    . = ALIGN(16);
-    *(.eh_frame)
-    *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*)))
-  }
-  .fini      : { *(.fini)    } =0
-  .ctors     : { *(.ctors)   }
-  .dtors     : { *(.dtors)   }
-
-  /* Read-write section, merged into data segment: */
-  . = (. + 0x0FFF) & 0xFFFFF000;
-  _erotext = .;
-  PROVIDE (erotext = .);
-  .reloc   :
-  {
-    *(.got)
-    _GOT2_TABLE_ = .;
-    *(.got2)
-    _FIXUP_TABLE_ = .;
-    *(.fixup)
-  }
-  __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >> 2;
-  __fixup_entries = (. - _FIXUP_TABLE_) >> 2;
-
-  .data    :
-  {
-    *(.data)
-    *(.data1)
-    *(.sdata)
-    *(.sdata2)
-    *(.dynamic)
-    CONSTRUCTORS
-  }
-  _edata  =  .;
-  PROVIDE (edata = .);
-
-  . = .;
-  __u_boot_cmd_start = .;
-  .u_boot_cmd : { *(.u_boot_cmd) }
-  __u_boot_cmd_end = .;
-
-
-  . = .;
-  __start___ex_table = .;
-  __ex_table : { *(__ex_table) }
-  __stop___ex_table = .;
-
-  . = ALIGN(4096);
-  __init_begin = .;
-  .text.init : { *(.text.init) }
-  .data.init : { *(.data.init) }
-  . = ALIGN(4096);
-  __init_end = .;
-
-  __bss_start = .;
-  .bss (NOLOAD)       :
-  {
-   *(.sbss) *(.scommon)
-   *(.dynbss)
-   *(.bss)
-   *(COMMON)
-   . = ALIGN(4);
-  }
-  __bss_end__ = . ;
-  PROVIDE (end = .);
-}
diff --git a/board/cogent/config.mk b/board/cogent/config.mk
index 78730db..12e2e7c 100644
--- a/board/cogent/config.mk
+++ b/board/cogent/config.mk
@@ -26,5 +26,3 @@
 #
 
 PLATFORM_CPPFLAGS += -I$(TOPDIR)
-
-LDSCRIPT := $(SRCTREE)/board/cogent/u-boot.lds
diff --git a/board/earthlcd/favr-32-ezkit/config.mk b/board/earthlcd/favr-32-ezkit/config.mk
index f8bc88d..284f7ff 100644
--- a/board/earthlcd/favr-32-ezkit/config.mk
+++ b/board/earthlcd/favr-32-ezkit/config.mk
@@ -1,4 +1,3 @@
 PLATFORM_RELFLAGS	+= -ffunction-sections -fdata-sections
 PLATFORM_LDFLAGS	+= --gc-sections
 CONFIG_SYS_TEXT_BASE		= 0x00000000
-LDSCRIPT		= $(src)board/earthlcd/favr-32-ezkit/u-boot.lds
diff --git a/board/freescale/mpc8610hpcd/mpc8610hpcd_diu.c b/board/freescale/mpc8610hpcd/mpc8610hpcd_diu.c
index 81e53e7..3011bb80 100644
--- a/board/freescale/mpc8610hpcd/mpc8610hpcd_diu.c
+++ b/board/freescale/mpc8610hpcd/mpc8610hpcd_diu.c
@@ -1,6 +1,7 @@
 /*
- * Copyright 2007 Freescale Semiconductor, Inc.
- * York Sun <yorksun@freescale.com>
+ * Copyright 2007-2011 Freescale Semiconductor, Inc.
+ * Authors: York Sun <yorksun@freescale.com>
+ *          Timur Tabi <timur@freescale.com>
  *
  * FSL DIU Framebuffer driver
  *
@@ -27,6 +28,10 @@
 #include <command.h>
 #include <asm/io.h>
 #include <fsl_diu_fb.h>
+#include "../common/pixis.h"
+
+#define PX_BRDCFG0_DLINK	0x10
+#define PX_BRDCFG0_DVISEL	0x08
 
 void diu_set_pixel_clock(unsigned int pixclock)
 {
@@ -49,50 +54,34 @@
 	debug("DIU: Modified value of CLKDVDR = 0x%08x\n", *guts_clkdvdr);
 }
 
-int platform_diu_init(unsigned int *xres, unsigned int *yres)
+int platform_diu_init(unsigned int xres, unsigned int yres, const char *port)
 {
-	char *monitor_port;
-	int gamma_fix;
-	unsigned int pixel_format;
-	unsigned char tmp_val;
-	unsigned char pixis_arch;
-	u8 *pixis_base = (u8 *)PIXIS_BASE;
+	const char *name;
+	int gamma_fix = 0;
+	u32 pixel_format = 0x88883316;
+	u8 temp;
 
-	tmp_val = in_8(pixis_base + PIXIS_BRDCFG0);
-	pixis_arch = in_8(pixis_base + PIXIS_VER);
+	temp = in_8(&pixis->brdcfg0);
 
-	monitor_port = getenv("monitor");
-	if (!strncmp(monitor_port, "0", 1)) {	/* 0 - DVI */
-		*xres = 1280;
-		*yres = 1024;
-		if (pixis_arch == 0x01)
-			pixel_format = 0x88882317;
-		else
-			pixel_format = 0x88883316;
-		gamma_fix = 0;
-		out_8(pixis_base + PIXIS_BRDCFG0, tmp_val | 0x08);
-
-	} else if (!strncmp(monitor_port, "1", 1)) { /* 1 - Single link LVDS */
-		*xres = 1024;
-		*yres = 768;
-		pixel_format = 0x88883316;
-		gamma_fix = 0;
-		out_8(pixis_base + PIXIS_BRDCFG0, (tmp_val & 0xf7) | 0x10);
-
-	} else if (!strncmp(monitor_port, "2", 1)) { /* 2 - Double link LVDS */
-		*xres = 1280;
-		*yres = 1024;
-		pixel_format = 0x88883316;
+	if (strncmp(port, "dlvds", 5) == 0) {
+		/* Dual link LVDS */
 		gamma_fix = 1;
-		out_8(pixis_base + PIXIS_BRDCFG0, tmp_val & 0xe7);
-
-	} else {	/* DVI */
-		*xres = 1280;
-		*yres = 1024;
-		pixel_format = 0x88882317;
-		gamma_fix = 0;
-		out_8(pixis_base + PIXIS_BRDCFG0, tmp_val | 0x08);
+		temp &= ~(PX_BRDCFG0_DLINK | PX_BRDCFG0_DVISEL);
+		name = "Dual-Link LVDS";
+	} else if (strncmp(port, "lvds", 4) == 0) {
+		/* Single link LVDS */
+		temp = (temp & ~PX_BRDCFG0_DVISEL) | PX_BRDCFG0_DLINK;
+		name = "Single-Link LVDS";
+	} else {
+		/* DVI */
+		if (in_8(&pixis->ver) == 1)	/* Board version */
+			pixel_format = 0x88882317;
+		temp |= PX_BRDCFG0_DVISEL;
+		name = "DVI";
 	}
 
-	return fsl_diu_init(*xres, pixel_format, gamma_fix);
+	printf("DIU:   Switching to %s monitor @ %ux%u\n", name, xres, yres);
+	out_8(&pixis->brdcfg0, temp);
+
+	return fsl_diu_init(xres, pixel_format, gamma_fix);
 }
diff --git a/board/freescale/mx31ads/config.mk b/board/freescale/mx31ads/config.mk
index 2303f30..0131edf 100644
--- a/board/freescale/mx31ads/config.mk
+++ b/board/freescale/mx31ads/config.mk
@@ -1,3 +1 @@
 CONFIG_SYS_TEXT_BASE = 0x87f00000
-
-LDSCRIPT := $(SRCTREE)/board/$(BOARDDIR)/u-boot.lds
diff --git a/board/freescale/p1022ds/diu.c b/board/freescale/p1022ds/diu.c
index b37e0e2..7d1f6aa 100644
--- a/board/freescale/p1022ds/diu.c
+++ b/board/freescale/p1022ds/diu.c
@@ -12,6 +12,7 @@
 
 #include <common.h>
 #include <command.h>
+#include <linux/ctype.h>
 #include <asm/io.h>
 #include <stdio_dev.h>
 #include <video_fb.h>
@@ -81,10 +82,10 @@
 	out_be32(&gur->clkdvdr, temp | 0x80000000 | ((pixval & 0x1F) << 16));
 }
 
-int platform_diu_init(unsigned int *xres, unsigned int *yres)
+int platform_diu_init(unsigned int xres, unsigned int yres, const char *port)
 {
 	ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
-	char *monitor_port;
+	const char *name;
 	u32 pixel_format;
 	u8 temp;
 
@@ -100,21 +101,23 @@
 
 	temp = in_8(&pixis->brdcfg1);
 
-	monitor_port = getenv("monitor");
-	if (!strncmp(monitor_port, "1", 1)) { /* 1 - Single link LVDS */
-		*xres = 1024;
-		*yres = 768;
-		/* Enable the DFP port, disable the DVI and the backlight */
-		temp &= ~(PX_BRDCFG1_DVIEN | PX_BRDCFG1_BACKLIGHT);
-		temp |= PX_BRDCFG1_DFPEN;
+	if (strncmp(port, "lvds", 4) == 0) {
+		/* Single link LVDS */
+		temp &= ~PX_BRDCFG1_DVIEN;
+		/*
+		 * LVDS also needs backlight enabled, otherwise the display
+		 * will be blank.
+		 */
+		temp |= (PX_BRDCFG1_DFPEN | PX_BRDCFG1_BACKLIGHT);
+		name = "Single-Link LVDS";
 	} else {	/* DVI */
-		*xres = 1280;
-		*yres = 1024;
 		/* Enable the DVI port, disable the DFP and the backlight */
 		temp &= ~(PX_BRDCFG1_DFPEN | PX_BRDCFG1_BACKLIGHT);
 		temp |= PX_BRDCFG1_DVIEN;
+		name = "DVI";
 	}
 
+	printf("DIU:   Switching to %s monitor @ %ux%u\n", name, xres, yres);
 	out_8(&pixis->brdcfg1, temp);
 
 	/*
@@ -136,7 +139,7 @@
 	clrsetbits_be32(&gur->pmuxcr, PMUXCR_ELBCDIU_MASK, PMUXCR_ELBCDIU_DIU);
 	pmuxcr = in_be32(&gur->pmuxcr);
 
-	return fsl_diu_init(*xres, pixel_format, 0);
+	return fsl_diu_init(xres, pixel_format, 0);
 }
 
 /*
diff --git a/board/hymod/config.mk b/board/hymod/config.mk
index ae766bc..ea64004 100644
--- a/board/hymod/config.mk
+++ b/board/hymod/config.mk
@@ -28,5 +28,3 @@
 PLATFORM_CPPFLAGS += -I$(TOPDIR)
 
 OBJCFLAGS = --remove-section=.ppcenv
-
-LDSCRIPT := $(SRCTREE)/board/hymod/u-boot.lds
diff --git a/board/keymile/common/common.c b/board/keymile/common/common.c
index 7b4eefd..4883fe5 100644
--- a/board/keymile/common/common.c
+++ b/board/keymile/common/common.c
@@ -22,13 +22,14 @@
  */
 
 #include <common.h>
-#if defined(CONFIG_MGCOGE)
+#if defined(CONFIG_MGCOGE) || defined(CONFIG_MGCOGE2NE)
 #include <mpc8260.h>
 #endif
 #include <ioports.h>
 #include <malloc.h>
 #include <hush.h>
 #include <net.h>
+#include <netdev.h>
 #include <asm/io.h>
 
 #if defined(CONFIG_OF_BOARD_SETUP) && defined(CONFIG_OF_LIBFDT)
@@ -39,9 +40,11 @@
 #if defined(CONFIG_HARD_I2C) || defined(CONFIG_SOFT_I2C)
 #include <i2c.h>
 
-extern int i2c_soft_read_pin (void);
+static void i2c_write_start_seq(void);
+static int i2c_make_abort(void);
+DECLARE_GLOBAL_DATA_PTR;
 
-int ivm_calc_crc (unsigned char *buf, int len)
+int ivm_calc_crc(unsigned char *buf, int len)
 {
 	const unsigned short crc_tab[16] = {
 		0x0000, 0xCC01, 0xD801, 0x1400,
@@ -71,20 +74,55 @@
 	return crc;
 }
 
-static int  ivm_set_value (char *name, char *value)
+/*
+ * Set Keymile specific environment variables
+ * Currently only some memory layout variables are calculated here
+ * ... ------------------------------------------------
+ * ... |@rootfsaddr |@pnvramaddr |@varaddr |@reserved |@END_OF_RAM
+ * ... |<------------------- pram ------------------->|
+ * ... ------------------------------------------------
+ * @END_OF_RAM: denotes the RAM size
+ * @pnvramaddr: Startadress of pseudo non volatile RAM in hex
+ * @pram      : preserved ram size in k
+ * @varaddr   : startadress for /var mounted into RAM
+ */
+int set_km_env(void)
+{
+	uchar buf[32];
+	unsigned int pnvramaddr;
+	unsigned int pram;
+	unsigned int varaddr;
+
+	pnvramaddr = gd->ram_size - CONFIG_KM_RESERVED_PRAM - CONFIG_KM_PHRAM
+			- CONFIG_KM_PNVRAM;
+	sprintf((char *)buf, "0x%x", pnvramaddr);
+	setenv("pnvramaddr", (char *)buf);
+
+	pram = (CONFIG_KM_RESERVED_PRAM + CONFIG_KM_PHRAM + CONFIG_KM_PNVRAM) /
+		0x400;
+	sprintf((char *)buf, "0x%x", pram);
+	setenv("pram", (char *)buf);
+
+	varaddr = gd->ram_size - CONFIG_KM_RESERVED_PRAM - CONFIG_KM_PHRAM;
+	sprintf((char *)buf, "0x%x", varaddr);
+	setenv("varaddr", (char *)buf);
+	return 0;
+}
+
+static int ivm_set_value(char *name, char *value)
 {
 	char tempbuf[256];
 
 	if (value != NULL) {
-		sprintf (tempbuf, "%s=%s", name, value);
-		return set_local_var (tempbuf, 0);
+		sprintf(tempbuf, "%s=%s", name, value);
+		return set_local_var(tempbuf, 0);
 	} else {
-		unset_local_var (name);
+		unset_local_var(name);
 	}
 	return 0;
 }
 
-static int ivm_get_value (unsigned char *buf, int len, char *name, int off,
+static int ivm_get_value(unsigned char *buf, int len, char *name, int off,
 				int check)
 {
 	unsigned short	val;
@@ -92,21 +130,21 @@
 
 	if ((buf[off + 0] != buf[off + 2]) &&
 	    (buf[off + 2] != buf[off + 4])) {
-		printf ("%s Error corrupted %s\n", __FUNCTION__, name);
+		printf("%s Error corrupted %s\n", __func__, name);
 		val = -1;
 	} else {
 		val = buf[off + 0] + (buf[off + 1] << 8);
 		if ((val == 0) && (check == 1))
 			val = -1;
 	}
-	sprintf ((char *)valbuf, "%x", val);
-	ivm_set_value (name, (char *)valbuf);
+	sprintf((char *)valbuf, "%x", val);
+	ivm_set_value(name, (char *)valbuf);
 	return val;
 }
 
-#define INVENTORYBLOCKSIZE	0x100
-#define INVENTORYDATAADDRESS	0x21
-#define INVENTORYDATASIZE	(INVENTORYBLOCKSIZE - INVENTORYDATAADDRESS - 3)
+#define INV_BLOCKSIZE		0x100
+#define INV_DATAADDRESS		0x21
+#define INVENTORYDATASIZE	(INV_BLOCKSIZE - INV_DATAADDRESS - 3)
 
 #define IVM_POS_SHORT_TEXT		0
 #define IVM_POS_MANU_ID			1
@@ -121,19 +159,19 @@
 #define IVM_POS_HISTORY			10
 #define IVM_POS_SYMBOL_ONLY		11
 
-static char convert_char (char c)
+static char convert_char(char c)
 {
 	return (c < ' ' || c > '~') ? '.' : c;
 }
 
-static int ivm_findinventorystring (int type,
+static int ivm_findinventorystring(int type,
 					unsigned char* const string,
 					unsigned long maxlen,
 					unsigned char *buf)
 {
 	int xcode = 0;
 	unsigned long cr = 0;
-	unsigned long addr = INVENTORYDATAADDRESS;
+	unsigned long addr = INV_DATAADDRESS;
 	unsigned long size = 0;
 	unsigned long nr = type;
 	int stop = 0; 	/* stop on semicolon */
@@ -157,8 +195,10 @@
 		addr++;
 	}
 
-	/* the expected number of CR was found until the end of the IVM
-	 *  content --> fill string */
+	/*
+	 * the expected number of CR was found until the end of the IVM
+	 *  content --> fill string
+	 */
 	if (addr < INVENTORYDATASIZE) {
 		/* Copy the IVM string in the corresponding string */
 		for (; (buf[addr] != '\r')			&&
@@ -170,64 +210,75 @@
 						convert_char (buf[addr]));
 		}
 
-		/* copy phase is done: check if everything is ok. If not,
+		/*
+		 * copy phase is done: check if everything is ok. If not,
 		 * the inventory data is most probably corrupted: tell
-		 * the world there is a problem! */
+		 * the world there is a problem!
+		 */
 		if (addr == INVENTORYDATASIZE) {
 			xcode = -1;
-			printf ("Error end of string not found\n");
+			printf("Error end of string not found\n");
 		} else if ((size >= (maxlen - 1)) &&
 			   (buf[addr] != '\r')) {
 			xcode = -1;
-			printf ("string too long till next CR\n");
+			printf("string too long till next CR\n");
 		}
 	} else {
-		/* some CR are missing...
-		 * the inventory data is most probably corrupted */
+		/*
+		 * some CR are missing...
+		 * the inventory data is most probably corrupted
+		 */
 		xcode = -1;
-		printf ("not enough cr found\n");
+		printf("not enough cr found\n");
 	}
 	return xcode;
 }
 
 #define GET_STRING(name, which, len) \
-	if (ivm_findinventorystring (which, valbuf, len, buf) == 0) { \
-		ivm_set_value (name, (char *)valbuf); \
+	if (ivm_findinventorystring(which, valbuf, len, buf) == 0) { \
+		ivm_set_value(name, (char *)valbuf); \
 	}
 
-static int ivm_check_crc (unsigned char *buf, int block)
+static int ivm_check_crc(unsigned char *buf, int block)
 {
 	unsigned long	crc;
 	unsigned long	crceeprom;
 
-	crc = ivm_calc_crc (buf, CONFIG_SYS_IVM_EEPROM_PAGE_LEN - 2);
+	crc = ivm_calc_crc(buf, CONFIG_SYS_IVM_EEPROM_PAGE_LEN - 2);
 	crceeprom = (buf[CONFIG_SYS_IVM_EEPROM_PAGE_LEN - 1] + \
 			buf[CONFIG_SYS_IVM_EEPROM_PAGE_LEN - 2] * 256);
 	if (crc != crceeprom) {
 		if (block == 0)
-			printf ("Error CRC Block: %d EEprom: calculated: \
+			printf("Error CRC Block: %d EEprom: calculated: \
 			%lx EEprom: %lx\n", block, crc, crceeprom);
 		return -1;
 	}
 	return 0;
 }
 
-static int ivm_analyze_block2 (unsigned char *buf, int len)
+static int ivm_analyze_block2(unsigned char *buf, int len)
 {
 	unsigned char	valbuf[CONFIG_SYS_IVM_EEPROM_PAGE_LEN];
 	unsigned long	count;
 
 	/* IVM_MacAddress */
-	sprintf ((char *)valbuf, "%02X:%02X:%02X:%02X:%02X:%02X",
-			buf[1],
-			buf[2],
-			buf[3],
-			buf[4],
-			buf[5],
-			buf[6]);
-	ivm_set_value ("IVM_MacAddress", (char *)valbuf);
-	if (getenv ("ethaddr") == NULL)
-		setenv ((char *)"ethaddr", (char *)valbuf);
+	sprintf((char *)valbuf, "%pM", buf);
+	ivm_set_value("IVM_MacAddress", (char *)valbuf);
+	/* if an offset is defined, add it */
+#if defined(CONFIG_PIGGY_MAC_ADRESS_OFFSET)
+	if (CONFIG_PIGGY_MAC_ADRESS_OFFSET > 0) {
+		unsigned long val = (buf[4] << 16) + (buf[5] << 8) + buf[6];
+
+		val += CONFIG_PIGGY_MAC_ADRESS_OFFSET;
+		buf[4] = (val >> 16) & 0xff;
+		buf[5] = (val >> 8) & 0xff;
+		buf[6] = val & 0xff;
+		sprintf((char *)valbuf, "%pM", buf);
+	}
+#endif
+	if (getenv("ethaddr") == NULL)
+		setenv((char *)"ethaddr", (char *)valbuf);
+
 	/* IVM_MacCount */
 	count = (buf[10] << 24) +
 		   (buf[11] << 16) +
@@ -235,48 +286,52 @@
 		    buf[13];
 	if (count == 0xffffffff)
 		count = 1;
-	sprintf ((char *)valbuf, "%lx", count);
-	ivm_set_value ("IVM_MacCount", (char *)valbuf);
+	sprintf((char *)valbuf, "%lx", count);
+	ivm_set_value("IVM_MacCount", (char *)valbuf);
 	return 0;
 }
 
-int ivm_analyze_eeprom (unsigned char *buf, int len)
+int ivm_analyze_eeprom(unsigned char *buf, int len)
 {
 	unsigned short	val;
 	unsigned char	valbuf[CONFIG_SYS_IVM_EEPROM_PAGE_LEN];
 	unsigned char	*tmp;
 
-	if (ivm_check_crc (buf, 0) != 0)
+	if (ivm_check_crc(buf, 0) != 0)
 		return -1;
 
-	ivm_get_value (buf, CONFIG_SYS_IVM_EEPROM_PAGE_LEN, "IVM_BoardId", 0, 1);
-	val = ivm_get_value (buf, CONFIG_SYS_IVM_EEPROM_PAGE_LEN, "IVM_HWKey", 6, 1);
+	ivm_get_value(buf, CONFIG_SYS_IVM_EEPROM_PAGE_LEN,
+			"IVM_BoardId", 0, 1);
+	val = ivm_get_value(buf, CONFIG_SYS_IVM_EEPROM_PAGE_LEN,
+			"IVM_HWKey", 6, 1);
 	if (val != 0xffff) {
-		sprintf ((char *)valbuf, "%x", ((val /100) % 10));
-		ivm_set_value ("IVM_HWVariant", (char *)valbuf);
-		sprintf ((char *)valbuf, "%x", (val % 100));
-		ivm_set_value ("IVM_HWVersion", (char *)valbuf);
+		sprintf((char *)valbuf, "%x", ((val / 100) % 10));
+		ivm_set_value("IVM_HWVariant", (char *)valbuf);
+		sprintf((char *)valbuf, "%x", (val % 100));
+		ivm_set_value("IVM_HWVersion", (char *)valbuf);
 	}
-	ivm_get_value (buf, CONFIG_SYS_IVM_EEPROM_PAGE_LEN, "IVM_Functions", 12, 0);
+	ivm_get_value(buf, CONFIG_SYS_IVM_EEPROM_PAGE_LEN,
+		"IVM_Functions", 12, 0);
 
 	GET_STRING("IVM_Symbol", IVM_POS_SYMBOL_ONLY, 8)
 	GET_STRING("IVM_DeviceName", IVM_POS_SHORT_TEXT, 64)
 	tmp = (unsigned char *) getenv("IVM_DeviceName");
 	if (tmp) {
-		int	len = strlen ((char *)tmp);
+		int	len = strlen((char *)tmp);
 		int	i = 0;
 
 		while (i < len) {
 			if (tmp[i] == ';') {
-				ivm_set_value ("IVM_ShortText", (char *)&tmp[i + 1]);
+				ivm_set_value("IVM_ShortText",
+					(char *)&tmp[i + 1]);
 				break;
 			}
 			i++;
 		}
 		if (i >= len)
-			ivm_set_value ("IVM_ShortText", NULL);
+			ivm_set_value("IVM_ShortText", NULL);
 	} else {
-		ivm_set_value ("IVM_ShortText", NULL);
+		ivm_set_value("IVM_ShortText", NULL);
 	}
 	GET_STRING("IVM_ManufacturerID", IVM_POS_MANU_ID, 32)
 	GET_STRING("IVM_ManufacturerSerialNumber", IVM_POS_MANU_SERIAL, 20)
@@ -288,14 +343,15 @@
 	GET_STRING("IVM_CustomerID", IVM_POS_CUSTOMER_ID, 32)
 	GET_STRING("IVM_CustomerProductID", IVM_POS_CUSTOMER_PROD_ID, 32)
 
-	if (ivm_check_crc (&buf[CONFIG_SYS_IVM_EEPROM_PAGE_LEN * 2], 2) != 0)
+	if (ivm_check_crc(&buf[CONFIG_SYS_IVM_EEPROM_PAGE_LEN * 2], 2) != 0)
 		return 0;
-	ivm_analyze_block2 (&buf[CONFIG_SYS_IVM_EEPROM_PAGE_LEN * 2], CONFIG_SYS_IVM_EEPROM_PAGE_LEN);
+	ivm_analyze_block2(&buf[CONFIG_SYS_IVM_EEPROM_PAGE_LEN * 2],
+		CONFIG_SYS_IVM_EEPROM_PAGE_LEN);
 
 	return 0;
 }
 
-int ivm_read_eeprom (void)
+int ivm_read_eeprom(void)
 {
 #if defined(CONFIG_I2C_MUX)
 	I2C_MUX_DEVICE *dev = NULL;
@@ -303,176 +359,241 @@
 	uchar i2c_buffer[CONFIG_SYS_IVM_EEPROM_MAX_LEN];
 	uchar	*buf;
 	unsigned dev_addr = CONFIG_SYS_IVM_EEPROM_ADR;
+	int ret;
 
 #if defined(CONFIG_I2C_MUX)
 	/* First init the Bus, select the Bus */
 #if defined(CONFIG_SYS_I2C_IVM_BUS)
-	dev = i2c_mux_ident_muxstring ((uchar *)CONFIG_SYS_I2C_IVM_BUS);
+	dev = i2c_mux_ident_muxstring((uchar *)CONFIG_SYS_I2C_IVM_BUS);
 #else
-	buf = (unsigned char *) getenv ("EEprom_ivm");
+	buf = (unsigned char *) getenv("EEprom_ivm");
 	if (buf != NULL)
-		dev = i2c_mux_ident_muxstring (buf);
+		dev = i2c_mux_ident_muxstring(buf);
 #endif
 	if (dev == NULL) {
-		printf ("Error couldnt add Bus for IVM\n");
+		printf("Error couldnt add Bus for IVM\n");
 		return -1;
 	}
-	i2c_set_bus_num (dev->busid);
+	i2c_set_bus_num(dev->busid);
 #endif
 
-	buf = (unsigned char *) getenv ("EEprom_ivm_addr");
+	buf = (unsigned char *) getenv("EEprom_ivm_addr");
 	if (buf != NULL)
-		dev_addr = simple_strtoul ((char *)buf, NULL, 16);
+		dev_addr = simple_strtoul((char *)buf, NULL, 16);
 
-	if (i2c_read(dev_addr, 0, 1, i2c_buffer, CONFIG_SYS_IVM_EEPROM_MAX_LEN) != 0) {
+	/* add deblocking here */
+	i2c_make_abort();
+
+	ret = i2c_read(dev_addr, 0, 1, i2c_buffer,
+		CONFIG_SYS_IVM_EEPROM_MAX_LEN);
+	if (ret != 0) {
 		printf ("Error reading EEprom\n");
 		return -2;
 	}
 
-	return ivm_analyze_eeprom (i2c_buffer, CONFIG_SYS_IVM_EEPROM_MAX_LEN);
+	return ivm_analyze_eeprom(i2c_buffer, CONFIG_SYS_IVM_EEPROM_MAX_LEN);
 }
 
 #if defined(CONFIG_SYS_I2C_INIT_BOARD)
-#define DELAY_ABORT_SEQ		62
+#define DELAY_ABORT_SEQ		62  /* @200kHz 9 clocks = 44us, 62us is ok */
 #define DELAY_HALF_PERIOD	(500 / (CONFIG_SYS_I2C_SPEED / 1000))
 
-#if defined(CONFIG_MGCOGE)
+#if defined(CONFIG_MGCOGE) || defined(CONFIG_MGCOGE2NE)
 #define SDA_MASK	0x00010000
 #define SCL_MASK	0x00020000
-static void set_pin (int state, unsigned long mask)
+static void set_pin(int state, unsigned long mask)
 {
-	volatile ioport_t *iop = ioport_addr ((immap_t *)CONFIG_SYS_IMMR, 3);
+	ioport_t *iop = ioport_addr((immap_t *)CONFIG_SYS_IMMR, 3);
 
 	if (state)
-		iop->pdat |= (mask);
+		setbits_be32(&iop->pdat, mask);
 	else
-		iop->pdat &= ~(mask);
+		clrbits_be32(&iop->pdat, mask);
 
-	iop->pdir |= (mask);
+	setbits_be32(&iop->pdir, mask);
 }
 
-static int get_pin (unsigned long mask)
+static int get_pin(unsigned long mask)
 {
-	volatile ioport_t *iop = ioport_addr ((immap_t *)CONFIG_SYS_IMMR, 3);
+	ioport_t *iop = ioport_addr((immap_t *)CONFIG_SYS_IMMR, 3);
 
-	iop->pdir &= ~(mask);
-	return (0 != (iop->pdat & (mask)));
+	clrbits_be32(&iop->pdir, mask);
+	return 0 != (in_be32(&iop->pdat) & mask);
 }
 
-static void set_sda (int state)
+static void set_sda(int state)
 {
-	set_pin (state, SDA_MASK);
+	set_pin(state, SDA_MASK);
 }
 
-static void set_scl (int state)
+static void set_scl(int state)
 {
-	set_pin (state, SCL_MASK);
+	set_pin(state, SCL_MASK);
 }
 
-static int get_sda (void)
+static int get_sda(void)
 {
-	return get_pin (SDA_MASK);
+	return get_pin(SDA_MASK);
 }
 
-static int get_scl (void)
+static int get_scl(void)
 {
-	return get_pin (SCL_MASK);
+	return get_pin(SCL_MASK);
 }
 
 #if defined(CONFIG_HARD_I2C)
-static void setports (int gpio)
+static void setports(int gpio)
 {
-	volatile ioport_t *iop = ioport_addr ((immap_t *)CONFIG_SYS_IMMR, 3);
+	ioport_t *iop = ioport_addr((immap_t *)CONFIG_SYS_IMMR, 3);
 
 	if (gpio) {
-		iop->ppar &= ~(SDA_MASK | SCL_MASK);
-		iop->podr &= ~(SDA_MASK | SCL_MASK);
+		clrbits_be32(&iop->ppar, (SDA_MASK | SCL_MASK));
+		clrbits_be32(&iop->podr, (SDA_MASK | SCL_MASK));
 	} else {
-		iop->ppar |= (SDA_MASK | SCL_MASK);
-		iop->pdir &= ~(SDA_MASK | SCL_MASK);
-		iop->podr |= (SDA_MASK | SCL_MASK);
+		setbits_be32(&iop->ppar, (SDA_MASK | SCL_MASK));
+		clrbits_be32(&iop->pdir, (SDA_MASK | SCL_MASK));
+		setbits_be32(&iop->podr, (SDA_MASK | SCL_MASK));
 	}
 }
 #endif
 #endif
 
-#if defined(CONFIG_KM8XX)
-static void set_sda (int state)
+#if !defined(CONFIG_MPC83xx)
+static void i2c_write_start_seq(void)
 {
-	I2C_SDA(state);
+	set_sda(1);
+	udelay(DELAY_HALF_PERIOD);
+	set_scl(1);
+	udelay(DELAY_HALF_PERIOD);
+	set_sda(0);
+	udelay(DELAY_HALF_PERIOD);
+	set_scl(0);
+	udelay(DELAY_HALF_PERIOD);
 }
 
-static void set_scl (int state)
+/*
+ * I2C is a synchronous protocol and resets of the processor in the middle
+ * of an access can block the I2C Bus until a powerdown of the full unit is
+ * done. This function toggles the SCL until the SCL and SCA line are
+ * released, but max. 16 times, after this a I2C start-sequence is sent.
+ * This I2C Deblocking mechanism was developed by Keymile in association
+ * with Anatech and Atmel in 1998.
+ */
+static int i2c_make_abort(void)
 {
-	I2C_SCL(state);
-}
 
-static int get_sda (void)
-{
-	return I2C_READ;
-}
+#if defined(CONFIG_HARD_I2C) && !defined(MACH_TYPE_KM_KIRKWOOD)
+	immap_t *immap = (immap_t *)CONFIG_SYS_IMMR ;
+	i2c8260_t *i2c	= (i2c8260_t *)&immap->im_i2c;
 
-static int get_scl (void)
-{
-	int	val;
+	/*
+	 * disable I2C controller first, otherwhise it thinks we want to
+	 * talk to the slave port...
+	 */
+	clrbits_8(&i2c->i2c_i2mod, 0x01);
 
-	*(unsigned short *)(I2C_BASE_DIR) &=  ~SCL_CONF;
-	udelay (1);
-	val = *(unsigned char *)(I2C_BASE_PORT);
-
-	return ((val & SCL_BIT) == SCL_BIT);
-}
+	/* Set the PortPins to GPIO */
+	setports(1);
 #endif
 
-#if !defined(CONFIG_KMETER1)
-static void writeStartSeq (void)
-{
-	set_sda (1);
-	udelay (DELAY_HALF_PERIOD);
-	set_scl (1);
-	udelay (DELAY_HALF_PERIOD);
-	set_sda (0);
-	udelay (DELAY_HALF_PERIOD);
-	set_scl (0);
-	udelay (DELAY_HALF_PERIOD);
-}
-
-/* I2C is a synchronous protocol and resets of the processor in the middle
-   of an access can block the I2C Bus until a powerdown of the full unit is
-   done. This function toggles the SCL until the SCL and SCA line are
-   released, but max. 16 times, after this a I2C start-sequence is sent.
-   This I2C Deblocking mechanism was developed by Keymile in association
-   with Anatech and Atmel in 1998.
- */
-static int i2c_make_abort (void)
-{
 	int	scl_state = 0;
 	int	sda_state = 0;
 	int	i = 0;
 	int	ret = 0;
 
-	if (!get_sda ()) {
+	if (!get_sda()) {
 		ret = -1;
 		while (i < 16) {
 			i++;
-			set_scl (0);
-			udelay (DELAY_ABORT_SEQ);
-			set_scl (1);
-			udelay (DELAY_ABORT_SEQ);
-			scl_state = get_scl ();
-			sda_state = get_sda ();
+			set_scl(0);
+			udelay(DELAY_ABORT_SEQ);
+			set_scl(1);
+			udelay(DELAY_ABORT_SEQ);
+			scl_state = get_scl();
+			sda_state = get_sda();
 			if (scl_state && sda_state) {
 				ret = 0;
 				break;
 			}
 		}
 	}
-	if (ret == 0) {
-		for (i =0; i < 5; i++) {
-			writeStartSeq ();
-		}
+	if (ret == 0)
+		for (i = 0; i < 5; i++)
+			i2c_write_start_seq();
+
+	/* respect stop setup time */
+	udelay(DELAY_ABORT_SEQ);
+	set_scl(1);
+	udelay(DELAY_ABORT_SEQ);
+	set_sda(1);
+	get_sda();
+
+#if defined(CONFIG_HARD_I2C)
+	/* Set the PortPins back to use for I2C */
+	setports(0);
+#endif
+	return ret;
+}
+#endif
+
+#if defined(CONFIG_MPC83xx)
+static void i2c_write_start_seq(void)
+{
+	struct fsl_i2c *dev;
+	dev = (struct fsl_i2c *) (CONFIG_SYS_IMMR + CONFIG_SYS_I2C_OFFSET);
+	udelay(DELAY_ABORT_SEQ);
+	out_8(&dev->cr, (I2C_CR_MEN | I2C_CR_MSTA));
+	udelay(DELAY_ABORT_SEQ);
+	out_8(&dev->cr, (I2C_CR_MEN));
+}
+
+static int i2c_make_abort(void)
+{
+	struct fsl_i2c *dev;
+	dev = (struct fsl_i2c *) (CONFIG_SYS_IMMR + CONFIG_SYS_I2C_OFFSET);
+	uchar	dummy;
+	uchar   last;
+	int     nbr_read = 0;
+	int     i = 0;
+	int	    ret = 0;
+
+	/* wait after each operation to finsh with a delay */
+	out_8(&dev->cr, (I2C_CR_MSTA));
+	udelay(DELAY_ABORT_SEQ);
+	out_8(&dev->cr, (I2C_CR_MEN | I2C_CR_MSTA));
+	udelay(DELAY_ABORT_SEQ);
+	dummy = in_8(&dev->dr);
+	udelay(DELAY_ABORT_SEQ);
+	last = in_8(&dev->dr);
+	nbr_read++;
+
+	/*
+	 * do read until the last bit is 1, but stop if the full eeprom is
+	 * read.
+	 */
+	while (((last & 0x01) != 0x01) &&
+		(nbr_read < CONFIG_SYS_IVM_EEPROM_MAX_LEN)) {
+		udelay(DELAY_ABORT_SEQ);
+		last = in_8(&dev->dr);
+		nbr_read++;
 	}
-	get_sda ();
+	if ((last & 0x01) != 0x01)
+		ret = -2;
+	if ((last != 0xff) || (nbr_read > 1))
+		printf("[INFO] i2c abort after %d bytes (0x%02x)\n",
+			nbr_read, last);
+	udelay(DELAY_ABORT_SEQ);
+	out_8(&dev->cr, (I2C_CR_MEN));
+	udelay(DELAY_ABORT_SEQ);
+	/* clear status reg */
+	out_8(&dev->sr, 0);
+
+	for (i = 0; i < 5; i++)
+		i2c_write_start_seq();
+	if (ret != 0)
+		printf("[ERROR] i2c abort failed after %d bytes (0x%02x)\n",
+			nbr_read, last);
+
 	return ret;
 }
 #endif
@@ -483,49 +604,14 @@
  */
 void i2c_init_board(void)
 {
-#if defined(CONFIG_KMETER1)
-	struct fsl_i2c *dev;
-	dev = (struct fsl_i2c *) (CONFIG_SYS_IMMR + CONFIG_SYS_I2C_OFFSET);
-	uchar	dummy;
-
-	out_8 (&dev->cr, (I2C_CR_MSTA));
-	out_8 (&dev->cr, (I2C_CR_MEN | I2C_CR_MSTA));
-	dummy = in_8(&dev->dr);
-	dummy = in_8(&dev->dr);
-	if (dummy != 0xff) {
-		dummy = in_8(&dev->dr);
-	}
-	out_8 (&dev->cr, (I2C_CR_MEN));
-	out_8 (&dev->cr, 0x00);
-	out_8 (&dev->cr, (I2C_CR_MEN));
-
-#else
-#if defined(CONFIG_HARD_I2C) && !defined(CONFIG_MACH_SUEN3)
-	volatile immap_t *immap = (immap_t *)CONFIG_SYS_IMMR ;
-	volatile i2c8260_t *i2c	= (i2c8260_t *)&immap->im_i2c;
-
-	/* disable I2C controller first, otherwhise it thinks we want to    */
-	/* talk to the slave port...                                        */
-	i2c->i2c_i2mod &= ~0x01;
-
-	/* Set the PortPins to GPIO */
-	setports (1);
-#endif
-
 	/* Now run the AbortSequence() */
-	i2c_make_abort ();
-
-#if defined(CONFIG_HARD_I2C)
-	/* Set the PortPins back to use for I2C */
-	setports (0);
-#endif
-#endif
+	i2c_make_abort();
 }
 #endif
 #endif
 
 #if defined(CONFIG_OF_BOARD_SETUP) && defined(CONFIG_OF_LIBFDT)
-int fdt_set_node_and_value (void *blob,
+int fdt_set_node_and_value(void *blob,
 				char *nodename,
 				char *regname,
 				void *var,
@@ -534,21 +620,22 @@
 	int ret = 0;
 	int nodeoffset = 0;
 
-	nodeoffset = fdt_path_offset (blob, nodename);
+	nodeoffset = fdt_path_offset(blob, nodename);
 	if (nodeoffset >= 0) {
-		ret = fdt_setprop (blob, nodeoffset, regname, var,
+		ret = fdt_setprop(blob, nodeoffset, regname, var,
 					size);
 		if (ret < 0)
 			printf("ft_blob_update(): cannot set %s/%s "
 				"property err:%s\n", nodename, regname,
-				fdt_strerror (ret));
+				fdt_strerror(ret));
 	} else {
 		printf("ft_blob_update(): cannot find %s node "
-			"err:%s\n", nodename, fdt_strerror (nodeoffset));
+			"err:%s\n", nodename, fdt_strerror(nodeoffset));
 	}
 	return ret;
 }
-int fdt_get_node_and_value (void *blob,
+
+int fdt_get_node_and_value(void *blob,
 				char *nodename,
 				char *propname,
 				void **var)
@@ -556,42 +643,45 @@
 	int len;
 	int nodeoffset = 0;
 
-	nodeoffset = fdt_path_offset (blob, nodename);
+	nodeoffset = fdt_path_offset(blob, nodename);
 	if (nodeoffset >= 0) {
-		*var = (void *)fdt_getprop (blob, nodeoffset, propname, &len);
+		*var = (void *)fdt_getprop(blob, nodeoffset, propname, &len);
 		if (len == 0) {
 			/* no value */
-			printf ("%s no value\n", __FUNCTION__);
+			printf("%s no value\n", __func__);
 			return -1;
 		} else if (len > 0) {
 			return len;
 		} else {
-			printf ("libfdt fdt_getprop(): %s\n",
+			printf("libfdt fdt_getprop(): %s\n",
 				fdt_strerror(len));
 			return -2;
 		}
 	} else {
-		printf("%s: cannot find %s node err:%s\n", __FUNCTION__,
-			nodename, fdt_strerror (nodeoffset));
+		printf("%s: cannot find %s node err:%s\n", __func__,
+			nodename, fdt_strerror(nodeoffset));
 		return -3;
 	}
 }
 #endif
 
-#if !defined(CONFIG_MACH_SUEN3)
-int ethernet_present (void)
+#if !defined(MACH_TYPE_KM_KIRKWOOD)
+int ethernet_present(void)
 {
-	return (in_8((u8 *)CONFIG_SYS_PIGGY_BASE + CONFIG_SYS_SLOT_ID_OFF) & 0x80);
+	struct km_bec_fpga *base =
+		(struct km_bec_fpga *)CONFIG_SYS_KMBEC_FPGA_BASE;
+
+	return in_8(&base->bprth) & PIGGY_PRESENT;
 }
 #endif
 
-int board_eth_init (bd_t *bis)
+int board_eth_init(bd_t *bis)
 {
 #ifdef CONFIG_KEYMILE_HDLC_ENET
-	(void)keymile_hdlc_enet_initialize (bis);
+	(void)keymile_hdlc_enet_initialize(bis);
 #endif
-	if (ethernet_present ()) {
-		return -1;
-	}
-	return 0;
+	if (ethernet_present())
+		return cpu_eth_init(bis);
+
+	return -1;
 }
diff --git a/board/keymile/common/common.h b/board/keymile/common/common.h
index a38c727..099de98 100644
--- a/board/keymile/common/common.h
+++ b/board/keymile/common/common.h
@@ -11,20 +11,55 @@
 #ifndef __KEYMILE_COMMON_H
 #define __KEYMILE_COMMON_H
 
-int ethernet_present (void);
-int ivm_read_eeprom (void);
+#define WRG_RESET	0x80
+#define H_OPORTS_14	0x40
+#define WRG_LED		0x02
+#define WRL_BOOT	0x01
 
-#ifdef CONFIG_KEYMILE_HDLC_ENET
-int keymile_hdlc_enet_initialize (bd_t *bis);
+#define H_OPORTS_SCC4_ENA	0x10
+#define H_OPORTS_SCC4_FD_ENA	0x04
+#define H_OPORTS_FCC1_PW_DWN	0x01
+
+#define PIGGY_PRESENT	0x80
+
+struct km_bec_fpga {
+	unsigned char	id;
+	unsigned char	rev;
+	unsigned char	oprth;
+	unsigned char	oprtl;
+	unsigned char	res1[3];
+	unsigned char	bprth;
+	unsigned char	bprtl;
+	unsigned char	res2[6];
+	unsigned char	prst;
+	unsigned char	res3[0xfff0];
+	unsigned char	pgy_id;
+	unsigned char	pgy_rev;
+	unsigned char	pgy_outputs;
+	unsigned char	pgy_eth;
+};
+
+#if !defined(CONFIG_PIGGY_MAC_ADRESS_OFFSET)
+#define CONFIG_PIGGY_MAC_ADRESS_OFFSET	0
 #endif
 
-int fdt_set_node_and_value (void *blob,
+int ethernet_present(void);
+int ivm_read_eeprom(void);
+
+#ifdef CONFIG_KEYMILE_HDLC_ENET
+int keymile_hdlc_enet_initialize(bd_t *bis);
+#endif
+
+int set_km_env(void);
+int fdt_set_node_and_value(void *blob,
 			char *nodename,
 			char *regname,
 			void *var,
 			int size);
-int fdt_get_node_and_value (void *blob,
+int fdt_get_node_and_value(void *blob,
 				char *nodename,
 				char *propname,
 				void **var);
+
+int i2c_soft_read_pin(void);
 #endif /* __KEYMILE_COMMON_H */
diff --git a/board/keymile/kmeter1/Makefile b/board/keymile/km83xx/Makefile
similarity index 100%
rename from board/keymile/kmeter1/Makefile
rename to board/keymile/km83xx/Makefile
diff --git a/board/keymile/km83xx/km83xx.c b/board/keymile/km83xx/km83xx.c
new file mode 100644
index 0000000..17560c8
--- /dev/null
+++ b/board/keymile/km83xx/km83xx.c
@@ -0,0 +1,288 @@
+/*
+ * Copyright (C) 2006 Freescale Semiconductor, Inc.
+ *                    Dave Liu <daveliu@freescale.com>
+ *
+ * Copyright (C) 2007 Logic Product Development, Inc.
+ *                    Peter Barada <peterb@logicpd.com>
+ *
+ * Copyright (C) 2007 MontaVista Software, Inc.
+ *                    Anton Vorontsov <avorontsov@ru.mvista.com>
+ *
+ * (C) Copyright 2008 - 2010
+ * Heiko Schocher, DENX Software Engineering, hs@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.
+ */
+
+#include <common.h>
+#include <ioports.h>
+#include <mpc83xx.h>
+#include <i2c.h>
+#include <miiphy.h>
+#include <asm/io.h>
+#include <asm/mmu.h>
+#include <asm/processor.h>
+#include <pci.h>
+#include <libfdt.h>
+
+#include "../common/common.h"
+
+const qe_iop_conf_t qe_iop_conf_tab[] = {
+	/* port pin dir open_drain assign */
+#if defined(CONFIG_KMETER1)
+	/* MDIO */
+	{0,  1, 3, 0, 2}, /* MDIO */
+	{0,  2, 1, 0, 1}, /* MDC */
+
+	/* UCC4 - UEC */
+	{1, 14, 1, 0, 1}, /* TxD0 */
+	{1, 15, 1, 0, 1}, /* TxD1 */
+	{1, 20, 2, 0, 1}, /* RxD0 */
+	{1, 21, 2, 0, 1}, /* RxD1 */
+	{1, 18, 1, 0, 1}, /* TX_EN */
+	{1, 26, 2, 0, 1}, /* RX_DV */
+	{1, 27, 2, 0, 1}, /* RX_ER */
+	{1, 24, 2, 0, 1}, /* COL */
+	{1, 25, 2, 0, 1}, /* CRS */
+	{2, 15, 2, 0, 1}, /* TX_CLK - CLK16 */
+	{2, 16, 2, 0, 1}, /* RX_CLK - CLK17 */
+
+	/* DUART - UART2 */
+	{5,  0, 1, 0, 2}, /* UART2_SOUT */
+	{5,  2, 1, 0, 1}, /* UART2_RTS */
+	{5,  3, 2, 0, 2}, /* UART2_SIN */
+	{5,  1, 2, 0, 3}, /* UART2_CTS */
+#else
+	/* Local Bus */
+	{0, 16, 1, 0, 3}, /* LA00 */
+	{0, 17, 1, 0, 3}, /* LA01 */
+	{0, 18, 1, 0, 3}, /* LA02 */
+	{0, 19, 1, 0, 3}, /* LA03 */
+	{0, 20, 1, 0, 3}, /* LA04 */
+	{0, 21, 1, 0, 3}, /* LA05 */
+	{0, 22, 1, 0, 3}, /* LA06 */
+	{0, 23, 1, 0, 3}, /* LA07 */
+	{0, 24, 1, 0, 3}, /* LA08 */
+	{0, 25, 1, 0, 3}, /* LA09 */
+	{0, 26, 1, 0, 3}, /* LA10 */
+	{0, 27, 1, 0, 3}, /* LA11 */
+	{0, 28, 1, 0, 3}, /* LA12 */
+	{0, 29, 1, 0, 3}, /* LA13 */
+	{0, 30, 1, 0, 3}, /* LA14 */
+	{0, 31, 1, 0, 3}, /* LA15 */
+
+	/* MDIO */
+	{3,  4, 3, 0, 2}, /* MDIO */
+	{3,  5, 1, 0, 2}, /* MDC */
+
+	/* UCC4 - UEC */
+	{1, 18, 1, 0, 1}, /* TxD0 */
+	{1, 19, 1, 0, 1}, /* TxD1 */
+	{1, 22, 2, 0, 1}, /* RxD0 */
+	{1, 23, 2, 0, 1}, /* RxD1 */
+	{1, 26, 2, 0, 1}, /* RxER */
+	{1, 28, 2, 0, 1}, /* Rx_DV */
+	{1, 30, 1, 0, 1}, /* TxEN */
+	{1, 31, 2, 0, 1}, /* CRS */
+	{3, 10, 2, 0, 3}, /* TxCLK->CLK17 */
+#endif
+
+	/* END of table */
+	{0,  0, 0, 0, QE_IOP_TAB_END},
+};
+
+static int board_init_i2c_busses(void)
+{
+	I2C_MUX_DEVICE *dev = NULL;
+	uchar	*buf;
+
+	/* Set up the Bus for the DTTs */
+	buf = (unsigned char *) getenv("dtt_bus");
+	if (buf != NULL)
+		dev = i2c_mux_ident_muxstring(buf);
+	if (dev == NULL) {
+		printf("Error couldn't add Bus for DTT\n");
+		printf("please setup dtt_bus to where your\n");
+		printf("DTT is found.\n");
+	}
+	return 0;
+}
+
+#if defined(CONFIG_SUVD3)
+const uint upma_table[] = {
+	0x1ffedc00, 0x0ffcdc80, 0x0ffcdc80, 0x0ffcdc04, /* Words 0 to 3 */
+	0x0ffcdc00, 0xffffcc00, 0xffffcc01, 0xfffffc01, /* Words 4 to 7 */
+	0xfffffc01, 0xfffffc01, 0xfffffc01, 0xfffffc01, /* Words 8 to 11 */
+	0xfffffc01, 0xfffffc01, 0xfffffc01, 0xfffffc01, /* Words 12 to 15 */
+	0xfffffc01, 0xfffffc01, 0xfffffc01, 0xfffffc01, /* Words 16 to 19 */
+	0xfffffc01, 0xfffffc01, 0xfffffc01, 0xfffffc01, /* Words 20 to 23 */
+	0x9cfffc00, 0x00fffc80, 0x00fffc80, 0x00fffc00, /* Words 24 to 27 */
+	0xffffec04, 0xffffec01, 0xfffffc01, 0xfffffc01, /* Words 28 to 31 */
+	0xfffffc01, 0xfffffc01, 0xfffffc01, 0xfffffc01, /* Words 32 to 35 */
+	0xfffffc01, 0xfffffc01, 0xfffffc01, 0xfffffc01, /* Words 36 to 39 */
+	0xfffffc01, 0xfffffc01, 0xfffffc01, 0xfffffc01, /* Words 40 to 43 */
+	0xfffffc01, 0xfffffc01, 0xfffffc01, 0xfffffc01, /* Words 44 to 47 */
+	0xfffffc01, 0xfffffc01, 0xfffffc01, 0xfffffc01, /* Words 48 to 51 */
+	0xfffffc01, 0xfffffc01, 0xfffffc01, 0xfffffc01, /* Words 52 to 55 */
+	0xfffffc01, 0xfffffc01, 0xfffffc01, 0xfffffc01, /* Words 56 to 59 */
+	0xfffffc01, 0xfffffc01, 0xfffffc01, 0xfffffc01  /* Words 60 to 63 */
+};
+#endif
+
+int board_early_init_r(void)
+{
+	struct km_bec_fpga *base =
+		(struct km_bec_fpga *)CONFIG_SYS_KMBEC_FPGA_BASE;
+#if defined(CONFIG_SUVD3)
+	immap_t *immap = (immap_t *) CONFIG_SYS_IMMR;
+	fsl_lbc_t *lbc = &immap->im_lbc;
+	u32 *mxmr = &lbc->mamr;
+#endif
+
+#if defined(CONFIG_MPC8360)
+	unsigned short	svid;
+	/*
+	 * Because of errata in the UCCs, we have to write to the reserved
+	 * registers to slow the clocks down.
+	 */
+	svid =  SVR_REV(mfspr(SVR));
+	switch (svid) {
+	case 0x0020:
+		/*
+		 * MPC8360ECE.pdf QE_ENET10 table 4:
+		 * IMMR + 0x14A8[4:5] = 11 (clk delay for UCC 2)
+		 * IMMR + 0x14A8[18:19] = 11 (clk delay for UCC 1)
+		 */
+		setbits_be32((void *)(CONFIG_SYS_IMMR + 0x14a8), 0x0c003000);
+		break;
+	case 0x0021:
+		/*
+		 * MPC8360ECE.pdf QE_ENET10 table 4:
+		 * IMMR + 0x14AC[24:27] = 1010
+		 */
+		clrsetbits_be32((void *)(CONFIG_SYS_IMMR + 0x14ac),
+			0x00000050, 0x000000a0);
+		break;
+	}
+#endif
+
+	/* enable the PHY on the PIGGY */
+	setbits_8(&base->pgy_eth, 0x01);
+	/* enable the Unit LED (green) */
+	setbits_8(&base->oprth, WRL_BOOT);
+
+#if defined(CONFIG_SUVD3)
+	/* configure UPMA for APP1 */
+	upmconfig(UPMA, (uint *) upma_table,
+		sizeof(upma_table) / sizeof(uint));
+	out_be32(mxmr, CONFIG_SYS_MAMR);
+#endif
+	return 0;
+}
+
+int misc_init_r(void)
+{
+	/* add board specific i2c busses */
+	board_init_i2c_busses();
+	return 0;
+}
+
+int last_stage_init(void)
+{
+	set_km_env();
+	return 0;
+}
+
+int fixed_sdram(void)
+{
+	immap_t *im = (immap_t *)CONFIG_SYS_IMMR;
+	u32 msize = 0;
+	u32 ddr_size;
+	u32 ddr_size_log2;
+
+	out_be32(&im->sysconf.ddrlaw[0].ar, (LAWAR_EN | 0x1e));
+	out_be32(&im->ddr.csbnds[0].csbnds, CONFIG_SYS_DDR_CS0_BNDS);
+	out_be32(&im->ddr.cs_config[0], CONFIG_SYS_DDR_CS0_CONFIG);
+	out_be32(&im->ddr.timing_cfg_0, CONFIG_SYS_DDR_TIMING_0);
+	out_be32(&im->ddr.timing_cfg_1, CONFIG_SYS_DDR_TIMING_1);
+	out_be32(&im->ddr.timing_cfg_2, CONFIG_SYS_DDR_TIMING_2);
+	out_be32(&im->ddr.timing_cfg_3, CONFIG_SYS_DDR_TIMING_3);
+	out_be32(&im->ddr.sdram_cfg, CONFIG_SYS_DDR_SDRAM_CFG);
+	out_be32(&im->ddr.sdram_cfg2, CONFIG_SYS_DDR_SDRAM_CFG2);
+	out_be32(&im->ddr.sdram_mode, CONFIG_SYS_DDR_MODE);
+	out_be32(&im->ddr.sdram_mode2, CONFIG_SYS_DDR_MODE2);
+	out_be32(&im->ddr.sdram_interval, CONFIG_SYS_DDR_INTERVAL);
+	out_be32(&im->ddr.sdram_clk_cntl, CONFIG_SYS_DDR_CLK_CNTL);
+	udelay(200);
+	out_be32(&im->ddr.sdram_cfg, SDRAM_CFG_MEM_EN);
+
+	msize = CONFIG_SYS_DDR_SIZE << 20;
+	disable_addr_trans();
+	msize = get_ram_size(CONFIG_SYS_DDR_BASE, msize);
+	enable_addr_trans();
+	msize /= (1024 * 1024);
+	if (CONFIG_SYS_DDR_SIZE != msize) {
+		for (ddr_size = msize << 20, ddr_size_log2 = 0;
+			(ddr_size > 1);
+			ddr_size = ddr_size >> 1, ddr_size_log2++)
+			if (ddr_size & 1)
+				return -1;
+		out_be32(&im->sysconf.ddrlaw[0].ar,
+			(LAWAR_EN | ((ddr_size_log2 - 1) & LAWAR_SIZE)));
+		out_be32(&im->ddr.csbnds[0].csbnds,
+			(((msize / 16) - 1) & 0xff));
+	}
+
+	return msize;
+}
+
+phys_size_t initdram(int board_type)
+{
+	immap_t *im = (immap_t *)CONFIG_SYS_IMMR;
+	u32 msize = 0;
+
+	if ((in_be32(&im->sysconf.immrbar) & IMMRBAR_BASE_ADDR) != (u32)im)
+		return -1;
+
+	out_be32(&im->sysconf.ddrlaw[0].bar,
+		CONFIG_SYS_DDR_BASE & LAWBAR_BAR);
+	msize = fixed_sdram();
+
+#if defined(CONFIG_DDR_ECC) && !defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER)
+	/*
+	 * Initialize DDR ECC byte
+	 */
+	ddr_enable_ecc(msize * 1024 * 1024);
+#endif
+
+	/* return total bus SDRAM size(bytes)  -- DDR */
+	return msize * 1024 * 1024;
+}
+
+int checkboard(void)
+{
+	puts("Board: Keymile " CONFIG_KM_BOARD_NAME);
+
+	if (ethernet_present())
+		puts(" with PIGGY.");
+	puts("\n");
+	return 0;
+}
+
+#if defined(CONFIG_OF_BOARD_SETUP)
+void ft_board_setup(void *blob, bd_t *bd)
+{
+	ft_cpu_setup(blob, bd);
+}
+#endif
+
+#if defined(CONFIG_HUSH_INIT_VAR)
+int hush_init_var(void)
+{
+	ivm_read_eeprom();
+	return 0;
+}
+#endif
diff --git a/board/keymile/km_arm/km_arm.c b/board/keymile/km_arm/km_arm.c
index dcf0f42..c772ee2 100644
--- a/board/keymile/km_arm/km_arm.c
+++ b/board/keymile/km_arm/km_arm.c
@@ -93,7 +93,7 @@
 	MPP41_GPIO,		/* Piggy3 LED[4] */
 	MPP42_GPIO,		/* Piggy3 LED[5] */
 	MPP43_GPIO,		/* Piggy3 LED[6] */
-	MPP44_GPIO,		/* Piggy3 LED[7] */
+	MPP44_GPIO,		/* Piggy3 LED[7], BIST_EN_L */
 	MPP45_GPIO,		/* Piggy3 LED[8] */
 	MPP46_GPIO,		/* Reserved */
 	MPP47_GPIO,		/* Reserved */
@@ -108,15 +108,43 @@
 	int	ret = 0;
 
 	if (i2c_read(0x10, 2, 1, &buf, 1) != 0) {
-		printf ("%s: Error reading Boco\n", __FUNCTION__);
+		printf("%s: Error reading Boco\n", __func__);
 		return -1;
 	}
-	if ((buf & 0x40) == 0x40) {
+	if ((buf & 0x40) == 0x40)
 		ret = 1;
-	}
+
 	return ret;
 }
 
+int initialize_unit_leds(void)
+{
+	/*
+	 * init the unit LEDs
+	 * per default they all are
+	 * ok apart from bootstat
+	 * LED connected through BOCO
+	 * BOCO	lies at the address  0x10
+	 * LEDs are in the block CTRL_H	(addr 0x02)
+	 * BOOTSTAT LED is the first 0x01
+	 */
+	#define BOCO        0x10
+	#define CTRL_H      0x02
+	#define APPLEDMASK  0x01
+	uchar buf;
+
+	if (i2c_read(BOCO, CTRL_H, 1, &buf, 1) != 0) {
+		printf("%s: Error reading Boco\n", __func__);
+		return -1;
+	}
+	buf |= APPLEDMASK;
+	if (i2c_write(BOCO, CTRL_H, 1, &buf, 1) != 0) {
+		printf("%s: Error writing Boco\n", __func__);
+		return -1;
+	}
+	return 0;
+}
+
 int misc_init_r(void)
 {
 	char *str;
@@ -133,6 +161,9 @@
 		printf("Overwriting MACH_TYPE with %d!!!\n", mach_type);
 		gd->bd->bi_arch_number = mach_type;
 	}
+
+	initialize_unit_leds();
+
 	return 0;
 }
 
@@ -155,14 +186,14 @@
 
 #if defined(CONFIG_SOFT_I2C)
 	/* init the GPIO for I2C Bitbang driver */
-	kw_gpio_set_valid(SUEN3_SDA_PIN, 1);
-	kw_gpio_set_valid(SUEN3_SCL_PIN, 1);
-	kw_gpio_direction_output(SUEN3_SDA_PIN, 0);
-	kw_gpio_direction_output(SUEN3_SCL_PIN, 0);
+	kw_gpio_set_valid(KM_KIRKWOOD_SDA_PIN, 1);
+	kw_gpio_set_valid(KM_KIRKWOOD_SCL_PIN, 1);
+	kw_gpio_direction_output(KM_KIRKWOOD_SDA_PIN, 0);
+	kw_gpio_direction_output(KM_KIRKWOOD_SCL_PIN, 0);
 #endif
 #if defined(CONFIG_SYS_EEPROM_WREN)
-	kw_gpio_set_valid(SUEN3_ENV_WP, 38);
-	kw_gpio_direction_output(SUEN3_ENV_WP, 1);
+	kw_gpio_set_valid(KM_KIRKWOOD_ENV_WP, 38);
+	kw_gpio_direction_output(KM_KIRKWOOD_ENV_WP, 1);
 #endif
 
 	return 0;
@@ -173,7 +204,7 @@
 	/*
 	 * arch number of board
 	 */
-	gd->bd->bi_arch_number = MACH_TYPE_SUEN3;
+	gd->bd->bi_arch_number = MACH_TYPE_KM_KIRKWOOD;
 
 	/* address of boot parameters */
 	gd->bd->bi_boot_params = kw_sdram_bar(0) + 0x100;
@@ -181,6 +212,12 @@
 	return 0;
 }
 
+int last_stage_init(void)
+{
+	set_km_env();
+	return 0;
+}
+
 #if defined(CONFIG_CMD_SF)
 int do_spi_toggle(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 {
@@ -239,7 +276,6 @@
 
 	for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
 		gd->bd->bi_dram[i].start = kw_sdram_bar(i);
-		gd->bd->bi_dram[i].size = kw_sdram_bs(i);
 		gd->bd->bi_dram[i].size = get_ram_size((long *)kw_sdram_bar(i),
 						       kw_sdram_bs(i));
 	}
@@ -258,15 +294,15 @@
 }
 
 #if defined(CONFIG_HUSH_INIT_VAR)
-int hush_init_var (void)
+int hush_init_var(void)
 {
-	ivm_read_eeprom ();
+	ivm_read_eeprom();
 	return 0;
 }
 #endif
 
 #if defined(CONFIG_BOOTCOUNT_LIMIT)
-void bootcount_store (ulong a)
+void bootcount_store(ulong a)
 {
 	volatile ulong *save_addr;
 	volatile ulong size = 0;
@@ -279,7 +315,7 @@
 	writel(BOOTCOUNT_MAGIC, &save_addr[1]);
 }
 
-ulong bootcount_load (void)
+ulong bootcount_load(void)
 {
 	volatile ulong *save_addr;
 	volatile ulong size = 0;
@@ -296,34 +332,34 @@
 #endif
 
 #if defined(CONFIG_SOFT_I2C)
-void set_sda (int state)
+void set_sda(int state)
 {
 	I2C_ACTIVE;
 	I2C_SDA(state);
 }
 
-void set_scl (int state)
+void set_scl(int state)
 {
 	I2C_SCL(state);
 }
 
-int get_sda (void)
+int get_sda(void)
 {
 	I2C_TRISTATE;
 	return I2C_READ;
 }
 
-int get_scl (void)
+int get_scl(void)
 {
-	return (kw_gpio_get_value(SUEN3_SCL_PIN) ? 1 : 0);
+	return kw_gpio_get_value(KM_KIRKWOOD_SCL_PIN) ? 1 : 0;
 }
 #endif
 
 #if defined(CONFIG_SYS_EEPROM_WREN)
-int eeprom_write_enable (unsigned dev_addr, int state)
+int eeprom_write_enable(unsigned dev_addr, int state)
 {
-	kw_gpio_set_value(SUEN3_ENV_WP, !state);
+	kw_gpio_set_value(KM_KIRKWOOD_ENV_WP, !state);
 
-	return !kw_gpio_get_value(SUEN3_ENV_WP);
+	return !kw_gpio_get_value(KM_KIRKWOOD_ENV_WP);
 }
 #endif
diff --git a/board/keymile/km_arm/kwbimage.cfg b/board/keymile/km_arm/kwbimage.cfg
index 26d6aa0..b2f5193 100644
--- a/board/keymile/km_arm/kwbimage.cfg
+++ b/board/keymile/km_arm/kwbimage.cfg
@@ -27,16 +27,18 @@
 # Boot Media configurations
 BOOT_FROM	spi	# Boot from SPI flash
 
-DATA 0xFFD10000 0x01111111	# MPP Control 0 Register
-# bit 3-0:   MPPSel0	1, NF_IO[2]
-# bit 7-4:   MPPSel1	1, NF_IO[3]
-# bit 12-8:  MPPSel2	1, NF_IO[4]
-# bit 15-12: MPPSel3	1, NF_IO[5]
+DATA 0xFFD10000 0x01112222	# MPP Control 0 Register
+# bit 3-0:   MPPSel0	2, NF_IO[2]
+# bit 7-4:   MPPSel1	2, NF_IO[3]
+# bit 12-8:  MPPSel2	2, NF_IO[4]
+# bit 15-12: MPPSel3	2, NF_IO[5]
 # bit 19-16: MPPSel4	1, NF_IO[6]
 # bit 23-20: MPPSel5	1, NF_IO[7]
 # bit 27-24: MPPSel6	1, SYSRST_O
 # bit 31-28: MPPSel7	0, GPO[7]
 
+DATA 0xFFD10004 0x03303300
+
 DATA 0xFFD10008 0x00001100	# MPP Control 2 Register
 # bit 3-0:   MPPSel16	0, GPIO[16]
 # bit 7-4:   MPPSel17	0, GPIO[17]
@@ -48,8 +50,8 @@
 # bit 31-28: MPPSel23	0, GPIO[23]
 
 DATA 0xFFD100E0 0x1B1B1B1B	# IO Configuration 0 Register
-DATA 0xFFD20134 0xBBBBBBBB	# L2 RAM Timing 0 Register
-DATA 0xFFD20138 0x00BBBBBB	# L2 RAM Timing 1 Register
+DATA 0xFFD20134 0x66666666	# L2 RAM Timing 0 Register
+DATA 0xFFD20138 0x66666666	# L2 RAM Timing 1 Register
 DATA 0xFFD20154 0x00000200	# CPU RAM Management Control3 Register
 DATA 0xFFD2014C 0x00001C00	# CPU RAM Management Control1 Register
 DATA 0xFFD20148 0x00000001	# CPU RAM Management Control0 Register
@@ -63,7 +65,7 @@
 # bit29-26: zero
 # bit31-30: 01
 
-DATA 0xFFD01404 0x36343000	# DDR Controller Control Low
+DATA 0xFFD01404 0x39543000	# DDR Controller Control Low
 # bit 3-0:  0 reserved
 # bit 4:    0=addr/cmd in smame cycle
 # bit 5:    0=clk is driven during self refresh, we don't care for APX
@@ -75,7 +77,7 @@
 # bit30-28: 3 required
 # bit31:    0=no additional STARTBURST delay
 
-DATA 0xFFD01408 0x2302544B	# DDR Timing (Low) (active cycles value +1)
+DATA 0xFFD01408 0x34136552	# DDR Timing (Low) (active cycles value +1)
 # bit3-0:   TRAS lsbs
 # bit7-4:   TRCD
 # bit11- 8: TRP
@@ -86,7 +88,7 @@
 # bit27-24: TRRD
 # bit31-28: TRTP
 
-DATA 0xFFD0140C 0x00000032	#  DDR Timing (High)
+DATA 0xFFD0140C 0x00000033	#  DDR Timing (High)
 # bit6-0:   TRFC
 # bit8-7:   TR2R
 # bit10-9:  TR2W
@@ -116,8 +118,8 @@
 # bit3-0:   0x0, DDR cmd
 # bit31-4:  0 required
 
-DATA 0xFFD0141C 0x00000642	#  DDR Mode
-DATA 0xFFD01420 0x00000040	#  DDR Extended Mode
+DATA 0xFFD0141C 0x00000652	#  DDR Mode
+DATA 0xFFD01420 0x00000044	#  DDR Extended Mode
 # bit0:    0,  DDR DLL enabled
 # bit1:    0,  DDR drive strenght normal
 # bit2:    1,  DDR ODT control lsd disabled
@@ -140,6 +142,8 @@
 # bit11 :  0  , 1/4 clock cycle skew disabled for write mesh
 # bit15-12: 1111 required
 # bit31-16: 0    required
+DATA 0xFFD01428 0x00074510
+DATA 0xFFD0147c 0x00007451
 
 DATA 0xFFD01500 0x00000000	# CS[0]n Base address to 0x0
 DATA 0xFFD01504 0x07FFFFF1	# CS[0]n Size
@@ -153,7 +157,7 @@
 DATA 0xFFD01514 0x00000000	# CS[2]n Size, window disabled
 DATA 0xFFD0151C 0x00000000	# CS[3]n Size, window disabled
 
-DATA 0xFFD01494 0x00000000	#  DDR ODT Control (Low)
+DATA 0xFFD01494 0x00010001	#  DDR ODT Control (Low)
 # bit3-0:  0, ODT0Rd, MODT[0] asserted during read from DRAM CS0
 # bit19-16:0, ODT0Wr, MODT[0] asserted during write to DRAM CS0
 
@@ -162,7 +166,7 @@
 # bit3-2:  00, ODT1 controlled by register
 # bit31-4: zero, required
 
-DATA 0xFFD0149C 0x0000E90F	# CPU ODT Control
+DATA 0xFFD0149C 0x0000FC11	# CPU ODT Control
 # bit3-0:  F, ODT0Rd, Internal ODT asserted during read from DRAM bank0
 # bit7-4:  0, ODT0Wr, Internal ODT asserted during write to DRAM bank0
 # bit9-8:  1, ODTEn, never active
diff --git a/board/keymile/kmeter1/kmeter1.c b/board/keymile/kmeter1/kmeter1.c
deleted file mode 100644
index bbcaf5d..0000000
--- a/board/keymile/kmeter1/kmeter1.c
+++ /dev/null
@@ -1,217 +0,0 @@
-/*
- * Copyright (C) 2006 Freescale Semiconductor, Inc.
- *                    Dave Liu <daveliu@freescale.com>
- *
- * Copyright (C) 2007 Logic Product Development, Inc.
- *                    Peter Barada <peterb@logicpd.com>
- *
- * Copyright (C) 2007 MontaVista Software, Inc.
- *                    Anton Vorontsov <avorontsov@ru.mvista.com>
- *
- * (C) Copyright 2008
- * Heiko Schocher, DENX Software Engineering, hs@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.
- */
-
-#include <common.h>
-#include <ioports.h>
-#include <mpc83xx.h>
-#include <i2c.h>
-#include <miiphy.h>
-#include <asm/io.h>
-#include <asm/mmu.h>
-#include <asm/processor.h>
-#include <pci.h>
-#include <libfdt.h>
-
-#include "../common/common.h"
-
-extern void disable_addr_trans (void);
-extern void enable_addr_trans (void);
-const qe_iop_conf_t qe_iop_conf_tab[] = {
-	/* port pin dir open_drain assign */
-
-	/* MDIO */
-	{0,  1, 3, 0, 2}, /* MDIO */
-	{0,  2, 1, 0, 1}, /* MDC */
-
-	/* UCC4 - UEC */
-	{1, 14, 1, 0, 1}, /* TxD0 */
-	{1, 15, 1, 0, 1}, /* TxD1 */
-	{1, 20, 2, 0, 1}, /* RxD0 */
-	{1, 21, 2, 0, 1}, /* RxD1 */
-	{1, 18, 1, 0, 1}, /* TX_EN */
-	{1, 26, 2, 0, 1}, /* RX_DV */
-	{1, 27, 2, 0, 1}, /* RX_ER */
-	{1, 24, 2, 0, 1}, /* COL */
-	{1, 25, 2, 0, 1}, /* CRS */
-	{2, 15, 2, 0, 1}, /* TX_CLK - CLK16 */
-	{2, 16, 2, 0, 1}, /* RX_CLK - CLK17 */
-
-	/* DUART - UART2 */
-	{5,  0, 1, 0, 2}, /* UART2_SOUT */
-	{5,  2, 1, 0, 1}, /* UART2_RTS */
-	{5,  3, 2, 0, 2}, /* UART2_SIN */
-	{5,  1, 2, 0, 3}, /* UART2_CTS */
-
-	/* END of table */
-	{0,  0, 0, 0, QE_IOP_TAB_END},
-};
-
-static int board_init_i2c_busses (void)
-{
-	I2C_MUX_DEVICE *dev = NULL;
-	uchar	*buf;
-
-	/* Set up the Bus for the DTTs */
-	buf = (unsigned char *) getenv ("dtt_bus");
-	if (buf != NULL)
-		dev = i2c_mux_ident_muxstring (buf);
-	if (dev == NULL) {
-		printf ("Error couldn't add Bus for DTT\n");
-		printf ("please setup dtt_bus to where your\n");
-		printf ("DTT is found.\n");
-	}
-	return 0;
-}
-
-int board_early_init_r (void)
-{
-	unsigned short	svid;
-
-	/*
-	 * Because of errata in the UCCs, we have to write to the reserved
-	 * registers to slow the clocks down.
-	 */
-	svid =  SVR_REV(mfspr (SVR));
-	switch (svid) {
-	case 0x0020:
-		setbits_be32((void *)(CONFIG_SYS_IMMR + 0x14a8), 0x0c003000);
-		break;
-	case 0x0021:
-		clrsetbits_be32((void *)(CONFIG_SYS_IMMR + 0x14ac),
-			0x00000050, 0x000000a0);
-		break;
-	}
-	/* enable the PHY on the PIGGY */
-	setbits (8, (void *)(CONFIG_SYS_PIGGY_BASE + 0x10003), 0x01);
-	/* enable the Unit LED (green) */
-	setbits (8, (void *)(CONFIG_SYS_PIGGY_BASE + 0x00002), 0x01);
-	/* take FE/GbE PHYs out of reset */
-	setbits (8, (void *)(CONFIG_SYS_PIGGY_BASE + 0x0000f), 0x1c);
-
-	return 0;
-}
-
-int misc_init_r (void)
-{
-	/* add board specific i2c busses */
-	board_init_i2c_busses ();
-	return 0;
-}
-
-int fixed_sdram(void)
-{
-	volatile immap_t *im = (immap_t *)CONFIG_SYS_IMMR;
-	u32 msize = 0;
-	u32 ddr_size;
-	u32 ddr_size_log2;
-
-	im->sysconf.ddrlaw[0].ar = LAWAR_EN | 0x1e;
-	im->ddr.csbnds[0].csbnds = CONFIG_SYS_DDR_CS0_BNDS;
-	im->ddr.cs_config[0] = CONFIG_SYS_DDR_CS0_CONFIG;
-	im->ddr.timing_cfg_0 = CONFIG_SYS_DDR_TIMING_0;
-	im->ddr.timing_cfg_1 = CONFIG_SYS_DDR_TIMING_1;
-	im->ddr.timing_cfg_2 = CONFIG_SYS_DDR_TIMING_2;
-	im->ddr.timing_cfg_3 = CONFIG_SYS_DDR_TIMING_3;
-	im->ddr.sdram_cfg = CONFIG_SYS_DDR_SDRAM_CFG;
-	im->ddr.sdram_cfg2 = CONFIG_SYS_DDR_SDRAM_CFG2;
-	im->ddr.sdram_mode = CONFIG_SYS_DDR_MODE;
-	im->ddr.sdram_mode2 = CONFIG_SYS_DDR_MODE2;
-	im->ddr.sdram_interval = CONFIG_SYS_DDR_INTERVAL;
-	im->ddr.sdram_clk_cntl = CONFIG_SYS_DDR_CLK_CNTL;
-	udelay (200);
-	im->ddr.sdram_cfg |= SDRAM_CFG_MEM_EN;
-
-	msize = CONFIG_SYS_DDR_SIZE << 20;
-	disable_addr_trans ();
-	msize = get_ram_size (CONFIG_SYS_DDR_BASE, msize);
-	enable_addr_trans ();
-	msize /= (1024 * 1024);
-	if (CONFIG_SYS_DDR_SIZE != msize) {
-		for (ddr_size = msize << 20, ddr_size_log2 = 0;
-		     (ddr_size > 1); ddr_size = ddr_size >> 1, ddr_size_log2++)
-			if (ddr_size & 1)
-				return -1;
-		im->sysconf.ddrlaw[0].ar =
-		    LAWAR_EN | ((ddr_size_log2 - 1) & LAWAR_SIZE);
-		im->ddr.csbnds[0].csbnds = (((msize / 16) - 1) & 0xff);
-	}
-
-	return msize;
-}
-
-phys_size_t initdram (int board_type)
-{
-#if defined(CONFIG_DDR_ECC) && !defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER)
-	extern void ddr_enable_ecc (unsigned int dram_size);
-#endif
-	volatile immap_t *im = (immap_t *)CONFIG_SYS_IMMR;
-	u32 msize = 0;
-
-	if ((im->sysconf.immrbar & IMMRBAR_BASE_ADDR) != (u32)im)
-		return -1;
-
-	/* DDR SDRAM - Main SODIMM */
-	im->sysconf.ddrlaw[0].bar = CONFIG_SYS_DDR_BASE & LAWBAR_BAR;
-	msize = fixed_sdram ();
-
-#if defined(CONFIG_DDR_ECC) && !defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER)
-	/*
-	 * Initialize DDR ECC byte
-	 */
-	ddr_enable_ecc (msize * 1024 * 1024);
-#endif
-
-	/* return total bus SDRAM size(bytes)  -- DDR */
-	return (msize * 1024 * 1024);
-}
-
-int checkboard (void)
-{
-	puts ("Board: Keymile kmeter1");
-	if (ethernet_present ())
-		puts (" with PIGGY.");
-	puts ("\n");
-	return 0;
-}
-
-#if defined(CONFIG_OF_BOARD_SETUP)
-/*
- * update property in the blob
- */
-void ft_blob_update (void *blob, bd_t *bd)
-{
-  /* no board specific update */
-}
-
-
-void ft_board_setup (void *blob, bd_t *bd)
-{
-	ft_cpu_setup (blob, bd);
-	ft_blob_update (blob, bd);
-}
-#endif
-
-#if defined(CONFIG_HUSH_INIT_VAR)
-extern int ivm_read_eeprom (void);
-int hush_init_var (void)
-{
-	ivm_read_eeprom ();
-	return 0;
-}
-#endif
diff --git a/board/keymile/mgcoge/mgcoge.c b/board/keymile/mgcoge/mgcoge.c
index 5dcdf37..7b34684 100644
--- a/board/keymile/mgcoge/mgcoge.c
+++ b/board/keymile/mgcoge/mgcoge.c
@@ -195,33 +195,30 @@
     }
 };
 
-/* Try SDRAM initialization with P/LSDMR=sdmr and ORx=orx
+/*
+ * Try SDRAM initialization with P/LSDMR=sdmr and ORx=orx
  *
  * This routine performs standard 8260 initialization sequence
  * and calculates the available memory size. It may be called
  * several times to try different SDRAM configurations on both
  * 60x and local buses.
  */
-static long int try_init (volatile memctl8260_t * memctl, ulong sdmr,
-						  ulong orx, volatile uchar * base)
+static long int try_init(memctl8260_t *memctl, ulong sdmr,
+				  ulong orx, uchar *base)
 {
-	volatile uchar c = 0xff;
-	volatile uint *sdmr_ptr;
-	volatile uint *orx_ptr;
+	uchar c = 0xff;
 	ulong maxsize, size;
 	int i;
 
-	/* We must be able to test a location outsize the maximum legal size
+	/*
+	 * We must be able to test a location outsize the maximum legal size
 	 * to find out THAT we are outside; but this address still has to be
 	 * mapped by the controller. That means, that the initial mapping has
 	 * to be (at least) twice as large as the maximum expected size.
 	 */
 	maxsize = (1 + (~orx | 0x7fff))/* / 2*/;
 
-	sdmr_ptr = &memctl->memc_psdmr;
-	orx_ptr = &memctl->memc_or1;
-
-	*orx_ptr = orx;
+	out_be32(&memctl->memc_or1, orx);
 
 	/*
 	 * Quote from 8260 UM (10.4.2 SDRAM Power-On Initialization, 10-35):
@@ -243,53 +240,58 @@
 	 * get here. The SDRAM can be accessed at the address CONFIG_SYS_SDRAM_BASE.
 	 */
 
-	*sdmr_ptr = sdmr | PSDMR_OP_PREA;
-	*base = c;
+	out_be32(&memctl->memc_psdmr, sdmr | PSDMR_OP_PREA);
+	out_8(base, c);
 
-	*sdmr_ptr = sdmr | PSDMR_OP_CBRR;
+	out_be32(&memctl->memc_psdmr, sdmr | PSDMR_OP_CBRR);
 	for (i = 0; i < 8; i++)
-		*base = c;
+		out_8(base, c);
 
-	*sdmr_ptr = sdmr | PSDMR_OP_MRW;
-	*(base + CONFIG_SYS_MRS_OFFS) = c;	/* setting MR on address lines */
+	out_be32(&memctl->memc_psdmr, sdmr | PSDMR_OP_MRW);
+	/* setting MR on address lines */
+	out_8((uchar *)(base + CONFIG_SYS_MRS_OFFS), c);
 
-	*sdmr_ptr = sdmr | PSDMR_OP_NORM | PSDMR_RFEN;
-	*base = c;
+	out_be32(&memctl->memc_psdmr, sdmr | PSDMR_OP_NORM | PSDMR_RFEN);
+	out_8(base, c);
 
-	size = get_ram_size ((long *)base, maxsize);
-	*orx_ptr = orx | ~(size - 1);
+	size = get_ram_size((long *)base, maxsize);
+	out_be32(&memctl->memc_or1, orx | ~(size - 1));
 
 	return (size);
 }
 
-phys_size_t initdram (int board_type)
+phys_size_t initdram(int board_type)
 {
-	volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR;
-	volatile memctl8260_t *memctl = &immap->im_memctl;
+	immap_t *immap = (immap_t *) CONFIG_SYS_IMMR;
+	memctl8260_t *memctl = &immap->im_memctl;
 
 	long psize;
 
-	memctl->memc_psrt = CONFIG_SYS_PSRT;
-	memctl->memc_mptpr = CONFIG_SYS_MPTPR;
+	out_8(&memctl->memc_psrt, CONFIG_SYS_PSRT);
+	out_be16(&memctl->memc_mptpr, CONFIG_SYS_MPTPR);
 
 #ifndef CONFIG_SYS_RAMBOOT
 	/* 60x SDRAM setup:
 	 */
-	psize = try_init (memctl, CONFIG_SYS_PSDMR, CONFIG_SYS_OR1,
-						  (uchar *) CONFIG_SYS_SDRAM_BASE);
+	psize = try_init(memctl, CONFIG_SYS_PSDMR, CONFIG_SYS_OR1,
+				  (uchar *) CONFIG_SYS_SDRAM_BASE);
 #endif /* CONFIG_SYS_RAMBOOT */
 
-	icache_enable ();
+	icache_enable();
 
 	return (psize);
 }
 
 int checkboard(void)
 {
-	puts ("Board: Keymile mgcoge");
-	if (ethernet_present ())
-		puts (" with PIGGY.");
-	puts ("\n");
+#if defined(CONFIG_MGCOGE)
+	puts("Board: Keymile mgcoge");
+#else
+	puts("Board: Keymile mgcoge2ne");
+#endif
+	if (ethernet_present())
+		puts(" with PIGGY.");
+	puts("\n");
 	return 0;
 }
 
@@ -308,31 +310,37 @@
 		puts("DIP:   Enabled\n");
 		setenv("actual_bank", "0");
 	}
+	set_km_env();
 	return 0;
 }
 
 /*
  * Early board initalization.
  */
-int board_early_init_r (void)
+int board_early_init_r(void)
 {
+	struct km_bec_fpga *base =
+		(struct km_bec_fpga *)CONFIG_SYS_KMBEC_FPGA_BASE;
+
 	/* setup the UPIOx */
 	/* General Unit Reset disabled, Flash Bank enabled, UnitLed on */
-	out_8((u8 *)(CONFIG_SYS_PIGGY_BASE + 0x02), 0xc2);
+	out_8(&base->oprth, (WRG_RESET | H_OPORTS_14 | WRG_LED));
 	/* SCC4 enable, halfduplex, FCC1 powerdown */
-	out_8((u8 *)(CONFIG_SYS_PIGGY_BASE + 0x03), 0x15);
+	out_8(&base->oprtl, (H_OPORTS_SCC4_ENA | H_OPORTS_SCC4_FD_ENA |
+		H_OPORTS_FCC1_PW_DWN));
+
 	return 0;
 }
 
-int hush_init_var (void)
+int hush_init_var(void)
 {
-	ivm_read_eeprom ();
+	ivm_read_eeprom();
 	return 0;
 }
 
 #if defined(CONFIG_OF_BOARD_SETUP) && defined(CONFIG_OF_LIBFDT)
-void ft_board_setup (void *blob, bd_t *bd)
+void ft_board_setup(void *blob, bd_t *bd)
 {
-	ft_cpu_setup (blob, bd);
+	ft_cpu_setup(blob, bd);
 }
 #endif /* defined(CONFIG_OF_BOARD_SETUP) && defined(CONFIG_OF_LIBFDT) */
diff --git a/board/munices/u-boot.lds b/board/munices/u-boot.lds
deleted file mode 100644
index 99576bf..0000000
--- a/board/munices/u-boot.lds
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * (C) Copyright 2007
- * Heiko Schocher, DENX Software Engineering, hs@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.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-
-OUTPUT_ARCH(powerpc)
-/* Do we need any of these for elf?
-   __DYNAMIC = 0;    */
-SECTIONS
-{
-  /* Read-only sections, merged into text segment: */
-  . = + SIZEOF_HEADERS;
-  .interp : { *(.interp) }
-  .hash          : { *(.hash)		}
-  .dynsym        : { *(.dynsym)		}
-  .dynstr        : { *(.dynstr)		}
-  .rel.text      : { *(.rel.text)		}
-  .rela.text     : { *(.rela.text)	}
-  .rel.data      : { *(.rel.data)		}
-  .rela.data     : { *(.rela.data)	}
-  .rel.rodata    : { *(.rel.rodata)	}
-  .rela.rodata   : { *(.rela.rodata)	}
-  .rel.got       : { *(.rel.got)		}
-  .rela.got      : { *(.rela.got)		}
-  .rel.ctors     : { *(.rel.ctors)	}
-  .rela.ctors    : { *(.rela.ctors)	}
-  .rel.dtors     : { *(.rel.dtors)	}
-  .rela.dtors    : { *(.rela.dtors)	}
-  .rel.bss       : { *(.rel.bss)		}
-  .rela.bss      : { *(.rela.bss)		}
-  .rel.plt       : { *(.rel.plt)		}
-  .rela.plt      : { *(.rela.plt)		}
-  .init          : { *(.init)	}
-  .plt : { *(.plt) }
-  .text      :
-  {
-    arch/powerpc/cpu/mpc5xxx/start.o	(.text)
-    *(.text)
-    *(.got1)
-    . = ALIGN(16);
-    *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*)))
-  }
-  .fini      : { *(.fini)    } =0
-  .ctors     : { *(.ctors)   }
-  .dtors     : { *(.dtors)   }
-
-  /* Read-write section, merged into data segment: */
-  . = (. + 0x0FFF) & 0xFFFFF000;
-  _erotext = .;
-  PROVIDE (erotext = .);
-  .reloc   :
-  {
-    *(.got)
-    _GOT2_TABLE_ = .;
-    *(.got2)
-    _FIXUP_TABLE_ = .;
-    *(.fixup)
-  }
-  __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >> 2;
-  __fixup_entries = (. - _FIXUP_TABLE_) >> 2;
-
-  .data    :
-  {
-    *(.data)
-    *(.data1)
-    *(.sdata)
-    *(.sdata2)
-    *(.dynamic)
-    CONSTRUCTORS
-  }
-  _edata  =  .;
-  PROVIDE (edata = .);
-
-  . = .;
-  __u_boot_cmd_start = .;
-  .u_boot_cmd : { *(.u_boot_cmd) }
-  __u_boot_cmd_end = .;
-
-
-  __start___ex_table = .;
-  __ex_table : { *(__ex_table) }
-  __stop___ex_table = .;
-
-  . = ALIGN(4096);
-  __init_begin = .;
-  .text.init : { *(.text.init) }
-  .data.init : { *(.data.init) }
-  . = ALIGN(4096);
-  __init_end = .;
-
-  __bss_start = .;
-  .bss (NOLOAD)       :
-  {
-   *(.sbss) *(.scommon)
-   *(.dynbss)
-   *(.bss)
-   *(COMMON)
-   . = ALIGN(4);
-  }
-  __bss_end__ = . ;
-  PROVIDE (end = .);
-}
diff --git a/board/samsung/smdk6400/config.mk b/board/samsung/smdk6400/config.mk
index 90cbcf2..6f04c2f 100644
--- a/board/samsung/smdk6400/config.mk
+++ b/board/samsung/smdk6400/config.mk
@@ -28,5 +28,3 @@
 else
 CONFIG_SYS_TEXT_BASE = 0
 endif
-
-LDSCRIPT := $(SRCTREE)/board/$(BOARDDIR)/u-boot-nand.lds
diff --git a/board/sc3/u-boot.lds b/board/sc3/u-boot.lds
deleted file mode 100644
index 4db46ca..0000000
--- a/board/sc3/u-boot.lds
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * (C) Copyright 2000
- * Wolfgang Denk, DENX Software Engineering, wd@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.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-
-OUTPUT_ARCH(powerpc)
-/* Do we need any of these for elf?
-   __DYNAMIC = 0;    */
-SECTIONS
-{
-  .resetvec 0xFFFFFFFC :
-  {
-    *(.resetvec)
-  } = 0xffff
-
-  /* Read-only sections, merged into text segment: */
-  . = + SIZEOF_HEADERS;
-  .interp : { *(.interp) }
-  .hash          : { *(.hash)		}
-  .dynsym        : { *(.dynsym)		}
-  .dynstr        : { *(.dynstr)		}
-  .rel.text      : { *(.rel.text)		}
-  .rela.text     : { *(.rela.text)	}
-  .rel.data      : { *(.rel.data)		}
-  .rela.data     : { *(.rela.data)	}
-  .rel.rodata    : { *(.rel.rodata)	}
-  .rela.rodata   : { *(.rela.rodata)	}
-  .rel.got       : { *(.rel.got)		}
-  .rela.got      : { *(.rela.got)		}
-  .rel.ctors     : { *(.rel.ctors)	}
-  .rela.ctors    : { *(.rela.ctors)	}
-  .rel.dtors     : { *(.rel.dtors)	}
-  .rela.dtors    : { *(.rela.dtors)	}
-  .rel.bss       : { *(.rel.bss)		}
-  .rela.bss      : { *(.rela.bss)		}
-  .rel.plt       : { *(.rel.plt)		}
-  .rela.plt      : { *(.rela.plt)		}
-  .init          : { *(.init)	}
-  .plt : { *(.plt) }
-  .text      :
-  {
-    /* WARNING - the following is hand-optimized to fit within	*/
-    /* the sector layout of our flash chips!	XXX FIXME XXX	*/
-
-    arch/powerpc/cpu/ppc4xx/start.o	(.text)
-    board/sc3/init.o	(.text)
-    arch/powerpc/cpu/ppc4xx/kgdb.o	(.text)
-    arch/powerpc/cpu/ppc4xx/traps.o	(.text)
-    arch/powerpc/cpu/ppc4xx/interrupts.o	(.text)
-    arch/powerpc/cpu/ppc4xx/4xx_uart.o	(.text)
-    arch/powerpc/cpu/ppc4xx/cpu_init.o	(.text)
-    arch/powerpc/cpu/ppc4xx/speed.o	(.text)
-    common/dlmalloc.o	(.text)
-    lib/crc32.o		(.text)
-    arch/powerpc/lib/extable.o	(.text)
-    lib/zlib.o		(.text)
-
-/*    . = env_offset;*/
-/*    common/env_embedded.o(.text)*/
-
-    *(.text)
-    *(.got1)
-  }
-  _etext = .;
-  PROVIDE (etext = .);
-  .rodata    :
-  {
-    *(.eh_frame)
-    *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*)))
-  }
-  .fini      : { *(.fini)    } =0
-  .ctors     : { *(.ctors)   }
-  .dtors     : { *(.dtors)   }
-
-  /* Read-write section, merged into data segment: */
-  . = (. + 0x00FF) & 0xFFFFFF00;
-  _erotext = .;
-  PROVIDE (erotext = .);
-  .reloc   :
-  {
-    _GOT2_TABLE_ = .;
-    *(.got2)
-    *(.got)
-    PROVIDE(_GLOBAL_OFFSET_TABLE_ = . + 4);
-    _FIXUP_TABLE_ = .;
-    *(.fixup)
-  }
-  __got2_entries = ((_GLOBAL_OFFSET_TABLE_ - _GOT2_TABLE_) >> 2) - 1;
-  __fixup_entries = (. - _FIXUP_TABLE_)>>2;
-
-  .data    :
-  {
-    *(.data)
-    *(.data1)
-    *(.sdata)
-    *(.sdata2)
-    *(.dynamic)
-    CONSTRUCTORS
-  }
-  _edata  =  .;
-  PROVIDE (edata = .);
-
-  . = .;
-  __u_boot_cmd_start = .;
-  .u_boot_cmd : { *(.u_boot_cmd) }
-  __u_boot_cmd_end = .;
-
-  __start___ex_table = .;
-  __ex_table : { *(__ex_table) }
-  __stop___ex_table = .;
-
-  . = ALIGN(256);
-  __init_begin = .;
-  .text.init : { *(.text.init) }
-  .data.init : { *(.data.init) }
-  . = ALIGN(256);
-  __init_end = .;
-
-  __bss_start = .;
-  .bss (NOLOAD)       :
-  {
-   *(.sbss) *(.scommon)
-   *(.dynbss)
-   *(.bss)
-   *(COMMON)
-   . = ALIGN(4);
-  }
-  __bss_end__ = . ;
-  PROVIDE (end = .);
-}
diff --git a/board/trab/config.mk b/board/trab/config.mk
index a349b8c..367f0b7 100644
--- a/board/trab/config.mk
+++ b/board/trab/config.mk
@@ -24,5 +24,3 @@
 ifndef CONFIG_SYS_TEXT_BASE
 CONFIG_SYS_TEXT_BASE = 0x0DF40000
 endif
-
-LDSCRIPT := $(SRCTREE)/board/$(BOARDDIR)/u-boot.lds
diff --git a/board/xilinx/ml507/config.mk b/board/xilinx/ml507/config.mk
deleted file mode 100644
index 4df1d9c..0000000
--- a/board/xilinx/ml507/config.mk
+++ /dev/null
@@ -1,4 +0,0 @@
-# need to strip off double quotes
-ifneq ($(CONFIG_SYS_LDSCRIPT),)
-LDSCRIPT := $(subst ",,$(CONFIG_SYS_LDSCRIPT))
-endif
diff --git a/board/xilinx/ppc405-generic/config.mk b/board/xilinx/ppc405-generic/config.mk
deleted file mode 100644
index 4df1d9c..0000000
--- a/board/xilinx/ppc405-generic/config.mk
+++ /dev/null
@@ -1,4 +0,0 @@
-# need to strip off double quotes
-ifneq ($(CONFIG_SYS_LDSCRIPT),)
-LDSCRIPT := $(subst ",,$(CONFIG_SYS_LDSCRIPT))
-endif
diff --git a/board/xilinx/ppc440-generic/config.mk b/board/xilinx/ppc440-generic/config.mk
deleted file mode 100644
index 4df1d9c..0000000
--- a/board/xilinx/ppc440-generic/config.mk
+++ /dev/null
@@ -1,4 +0,0 @@
-# need to strip off double quotes
-ifneq ($(CONFIG_SYS_LDSCRIPT),)
-LDSCRIPT := $(subst ",,$(CONFIG_SYS_LDSCRIPT))
-endif
diff --git a/boards.cfg b/boards.cfg
index 18a4494..2b0900a 100644
--- a/boards.cfg
+++ b/boards.cfg
@@ -104,6 +104,8 @@
 davinci_sffsdr               arm         arm926ejs   sffsdr              davinci        davinci
 davinci_sonata               arm         arm926ejs   sonata              davinci        davinci
 suen3                        arm         arm926ejs   km_arm              keymile        kirkwood
+suen8                        arm         arm926ejs   km_arm              keymile        kirkwood
+mgcoge2un                    arm         arm926ejs   km_arm              keymile        kirkwood
 guruplug                     arm         arm926ejs   -                   Marvell        kirkwood
 mv88f6281gtw_ge              arm         arm926ejs   -                   Marvell        kirkwood
 openrd_base                  arm         arm926ejs   -                   Marvell        kirkwood
@@ -438,6 +440,7 @@
 PQ2FADS-ZU_lowboot           powerpc     mpc8260     mpc8260ads          freescale      -           MPC8260ADS:ADSTYPE=CONFIG_SYS_PQ2FADS,SYS_TEXT_BASE=0xFF800000
 VoVPN-GW_66MHz               powerpc     mpc8260     vovpn-gw            funkwerk       -           VoVPN-GW:CLKIN_66MHz
 mgcoge                       powerpc     mpc8260     -                   keymile
+mgcoge2ne                    powerpc     mpc8260     mgcoge              keymile
 SCM                          powerpc     mpc8260     -                   siemens
 TQM8255_AA                   powerpc     mpc8260     tqm8260             tqc            -           TQM8260:MPC8255,300MHz
 TQM8260_AA                   powerpc     mpc8260     tqm8260             tqc            -           TQM8260:MPC8260,200MHz
@@ -486,11 +489,15 @@
 MPC837XEMDS                  powerpc     mpc83xx     mpc837xemds         freescale      -           MPC837XEMDS
 MPC837XEMDS_HOST             powerpc     mpc83xx     mpc837xemds         freescale      -           MPC837XEMDS:PCI
 MPC837XERDB                  powerpc     mpc83xx     mpc837xerdb         freescale
-kmeter1                      powerpc     mpc83xx     kmeter1             keymile
+kmeter1                      powerpc     mpc83xx     km83xx              keymile
 MVBLM7                       powerpc     mpc83xx     mvblm7              matrix_vision
 SIMPC8313_LP                 powerpc     mpc83xx     simpc8313           sheldon        -           SIMPC8313:NAND_LP
 SIMPC8313_SP                 powerpc     mpc83xx     simpc8313           sheldon        -           SIMPC8313:NAND_SP
+kmsupx5                      powerpc     mpc83xx     km83xx              keymile
+suvd3                        powerpc     mpc83xx     km83xx              keymile
 TQM834x                      powerpc     mpc83xx     tqm834x             tqc
+tuda1                        powerpc     mpc83xx     km83xx              keymile
+tuxa1                        powerpc     mpc83xx     km83xx              keymile
 sbc8540                      powerpc     mpc85xx     sbc8560             -              -           SBC8540
 sbc8540_33                   powerpc     mpc85xx     sbc8560             -              -           SBC8540
 sbc8540_66                   powerpc     mpc85xx     sbc8560             -              -           SBC8540
diff --git a/common/cmd_i2c.c b/common/cmd_i2c.c
index c272b0d..d913e13 100644
--- a/common/cmd_i2c.c
+++ b/common/cmd_i2c.c
@@ -132,6 +132,14 @@
 
 #define DISP_LINE_LEN	16
 
+/* implement possible board specific board init */
+void __def_i2c_init_board(void)
+{
+	return;
+}
+void i2c_init_board(void)
+	__attribute__((weak, alias("__def_i2c_init_board")));
+
 /* TODO: Implement architecture-specific get/set functions */
 unsigned int __def_i2c_get_bus_speed(void)
 {
@@ -1541,6 +1549,8 @@
 
 	mux = dev->mux;
 	while (mux != NULL) {
+		/* do deblocking on each level of mux, before mux config */
+		i2c_init_board();
 		if (i2c_write(mux->chip, 0, 0, &mux->channel, 1) != 0) {
 			printf ("Error setting Mux: chip:%x channel: \
 				%x\n", mux->chip, mux->channel);
@@ -1548,6 +1558,8 @@
 		}
 		mux = mux->next;
 	}
+	/* do deblocking on each level of mux and after mux config */
+	i2c_init_board();
 	return 0;
 }
 #endif /* CONFIG_I2C_MUX */
diff --git a/common/cmd_ide.c b/common/cmd_ide.c
index a1f7e57..e7952ff 100644
--- a/common/cmd_ide.c
+++ b/common/cmd_ide.c
@@ -517,8 +517,20 @@
 {
 	debug ("ide_outb (dev= %d, port= 0x%x, val= 0x%02x) : @ 0x%08lx\n",
 		dev, port, val, (ATA_CURR_BASE(dev)+CONFIG_SYS_ATA_PORT_ADDR(port)));
+
+#if defined(CONFIG_IDE_AHB)
+	if (port) {
+		/* write command */
+		ide_write_register(dev, port, val);
+	} else {
+		/* write data */
+		outb(val, (ATA_CURR_BASE(dev)));
+	}
+#else
 	outb(val, (ATA_CURR_BASE(dev)+CONFIG_SYS_ATA_PORT_ADDR(port)));
+#endif
 }
+
 void ide_outb (int dev, int port, unsigned char val)
 		__attribute__((weak, alias("__ide_outb")));
 
@@ -526,7 +538,13 @@
 __ide_inb(int dev, int port)
 {
 	uchar val;
+
+#if defined(CONFIG_IDE_AHB)
+	val = ide_read_register(dev, port);
+#else
 	val = inb((ATA_CURR_BASE(dev)+CONFIG_SYS_ATA_PORT_ADDR(port)));
+#endif
+
 	debug ("ide_inb (dev= %d, port= 0x%x) : @ 0x%08lx -> 0x%02x\n",
 		dev, port, (ATA_CURR_BASE(dev)+CONFIG_SYS_ATA_PORT_ADDR(port)), val);
 	return val;
@@ -695,6 +713,7 @@
 		ide_dev_desc[i].blksz=0;
 		ide_dev_desc[i].lba=0;
 		ide_dev_desc[i].block_read=ide_read;
+		ide_dev_desc[i].block_write = ide_write;
 		if (!ide_bus_ok[IDE_BUS(i)])
 			continue;
 		ide_led (led, 1);		/* LED on	*/
@@ -902,7 +921,11 @@
 static void
 output_data(int dev, ulong *sect_buf, int words)
 {
-	outsw(ATA_CURR_BASE(dev)+ATA_DATA_REG, sect_buf, words<<1);
+#if defined(CONFIG_IDE_AHB)
+	ide_write_data(dev, sect_buf, words);
+#else
+	outsw(ATA_CURR_BASE(dev)+ATA_DATA_REG, sect_buf, words << 1);
+#endif
 }
 #endif	/* CONFIG_IDE_SWAP_IO */
 
@@ -960,7 +983,11 @@
 static void
 input_data(int dev, ulong *sect_buf, int words)
 {
+#if defined(CONFIG_IDE_AHB)
+	ide_read_data(dev, sect_buf, words);
+#else
 	insw(ATA_CURR_BASE(dev)+ATA_DATA_REG, sect_buf, words << 1);
+#endif
 }
 
 #endif	/* CONFIG_IDE_SWAP_IO */
diff --git a/common/cmd_mmc_spi.c b/common/cmd_mmc_spi.c
index 63fe313..cfd0fb1 100644
--- a/common/cmd_mmc_spi.c
+++ b/common/cmd_mmc_spi.c
@@ -74,6 +74,7 @@
 	}
 	printf("%s: %d at %u:%u hz %u mode %u\n", mmc->name, mmc->block_dev.dev,
 	       bus, cs, speed, mode);
+	mmc_init(mmc);
 	return 0;
 
 usage:
diff --git a/common/cmd_nvedit.c b/common/cmd_nvedit.c
index 817f39b..aa9de3a 100644
--- a/common/cmd_nvedit.c
+++ b/common/cmd_nvedit.c
@@ -56,16 +56,16 @@
 
 DECLARE_GLOBAL_DATA_PTR;
 
-#if !defined(CONFIG_ENV_IS_IN_EEPROM)	&& \
-    !defined(CONFIG_ENV_IS_IN_FLASH)	&& \
-    !defined(CONFIG_ENV_IS_IN_DATAFLASH)	&& \
-    !defined(CONFIG_ENV_IS_IN_MG_DISK)	&& \
-    !defined(CONFIG_ENV_IS_IN_MMC)  && \
-    !defined(CONFIG_ENV_IS_IN_NAND)	&& \
-    !defined(CONFIG_ENV_IS_IN_NVRAM)	&& \
-    !defined(CONFIG_ENV_IS_IN_ONENAND)	&& \
-    !defined(CONFIG_ENV_IS_IN_SPI_FLASH)	&& \
-    !defined(CONFIG_ENV_IS_NOWHERE)
+#if	!defined(CONFIG_ENV_IS_IN_EEPROM)	&& \
+	!defined(CONFIG_ENV_IS_IN_FLASH)	&& \
+	!defined(CONFIG_ENV_IS_IN_DATAFLASH)	&& \
+	!defined(CONFIG_ENV_IS_IN_MG_DISK)	&& \
+	!defined(CONFIG_ENV_IS_IN_MMC)		&& \
+	!defined(CONFIG_ENV_IS_IN_NAND)		&& \
+	!defined(CONFIG_ENV_IS_IN_NVRAM)	&& \
+	!defined(CONFIG_ENV_IS_IN_ONENAND)	&& \
+	!defined(CONFIG_ENV_IS_IN_SPI_FLASH)	&& \
+	!defined(CONFIG_ENV_IS_NOWHERE)
 # error Define one of CONFIG_ENV_IS_IN_{EEPROM|FLASH|DATAFLASH|ONENAND|\
 SPI_FLASH|MG_DISK|NVRAM|MMC} or CONFIG_ENV_IS_NOWHERE
 #endif
@@ -95,7 +95,7 @@
  */
 static int env_id = 1;
 
-int get_env_id (void)
+int get_env_id(void)
 {
 	return env_id;
 }
@@ -118,7 +118,7 @@
 		hsearch_r(e, FIND, &ep, &env_htab);
 		if (ep == NULL)
 			return 0;
-		len = printf ("%s=%s\n", ep->key, ep->data);
+		len = printf("%s=%s\n", ep->key, ep->data);
 		return len;
 	}
 
@@ -209,7 +209,7 @@
 	name = argv[1];
 
 	if (strchr(name, '=')) {
-		printf ("## Error: illegal character '=' in variable name \"%s\"\n", name);
+		printf("## Error: illegal character '=' in variable name \"%s\"\n", name);
 		return 1;
 	}
 
@@ -222,13 +222,12 @@
 	hsearch_r(e, FIND, &ep, &env_htab);
 
 	/* Check for console redirection */
-	if (strcmp(name,"stdin") == 0) {
+	if (strcmp(name, "stdin") == 0)
 		console = stdin;
-	} else if (strcmp(name,"stdout") == 0) {
+	else if (strcmp(name, "stdout") == 0)
 		console = stdout;
-	} else if (strcmp(name,"stderr") == 0) {
+	else if (strcmp(name, "stderr") == 0)
 		console = stderr;
-	}
 
 	if (console != -1) {
 		if (argc < 3) {		/* Cannot delete it! */
@@ -242,11 +241,11 @@
 			return i;
 #else
 		/* Try assigning specified device */
-		if (console_assign (console, argv[2]) < 0)
+		if (console_assign(console, argv[2]) < 0)
 			return 1;
 
 #ifdef CONFIG_SERIAL_MULTI
-		if (serial_assign (argv[2]) < 0)
+		if (serial_assign(argv[2]) < 0)
 			return 1;
 #endif
 #endif /* CONFIG_CONSOLE_MUX */
@@ -258,28 +257,28 @@
 	 */
 	if (ep) {		/* variable exists */
 #ifndef CONFIG_ENV_OVERWRITE
-		if ((strcmp (name, "serial#") == 0) ||
-		    ((strcmp (name, "ethaddr") == 0)
+		if ((strcmp(name, "serial#") == 0) ||
+		    ((strcmp(name, "ethaddr") == 0)
 #if defined(CONFIG_OVERWRITE_ETHADDR_ONCE) && defined(CONFIG_ETHADDR)
-		     && (strcmp (ep->data,MK_STR(CONFIG_ETHADDR)) != 0)
+		     && (strcmp(ep->data, MK_STR(CONFIG_ETHADDR)) != 0)
 #endif	/* CONFIG_OVERWRITE_ETHADDR_ONCE && CONFIG_ETHADDR */
 		    ) ) {
-			printf ("Can't overwrite \"%s\"\n", name);
+			printf("Can't overwrite \"%s\"\n", name);
 			return 1;
 		}
 #endif
 		/*
 		 * Switch to new baudrate if new baudrate is supported
 		 */
-		if (strcmp(name,"baudrate") == 0) {
+		if (strcmp(name, "baudrate") == 0) {
 			int baudrate = simple_strtoul(argv[2], NULL, 10);
 			int i;
-			for (i=0; i<N_BAUDRATES; ++i) {
+			for (i = 0; i < N_BAUDRATES; ++i) {
 				if (baudrate == baudrate_table[i])
 					break;
 			}
 			if (i == N_BAUDRATES) {
-				printf ("## Baudrate %d bps not supported\n",
+				printf("## Baudrate %d bps not supported\n",
 					baudrate);
 				return 1;
 			}
@@ -291,11 +290,11 @@
 			gd->bd->bi_baudrate = baudrate;
 #endif
 
-			serial_setbrg ();
+			serial_setbrg();
 			udelay(50000);
 			for (;;) {
 				if (getc() == '\r')
-				      break;
+					break;
 			}
 		}
 	}
@@ -309,14 +308,15 @@
 	/*
 	 * Insert / replace new value
 	 */
-	for (i=2,len=0; i<argc; ++i) {
+	for (i = 2, len = 0; i < argc; ++i)
 		len += strlen(argv[i]) + 1;
-	}
-	if ((value = malloc(len)) == NULL) {
+
+	value = malloc(len);
+	if (value == NULL) {
 		printf("## Can't malloc %d bytes\n", len);
 		return 1;
 	}
-	for (i=2,s=value; i<argc; ++i) {
+	for (i = 2, s = value; i < argc; ++i) {
 		char *v = argv[i];
 
 		while ((*s++ = *v++) != '\0')
@@ -341,12 +341,12 @@
 	 * entry in the environment is changed
 	 */
 
-	if (strcmp(name,"ipaddr") == 0) {
+	if (strcmp(name, "ipaddr") == 0) {
 		char *s = argv[2];	/* always use only one arg */
 		char *e;
 		unsigned long addr;
 		bd->bi_ip_addr = 0;
-		for (addr=0, i=0; i<4; ++i) {
+		for (addr = 0, i = 0; i < 4; ++i) {
 			ulong val = s ? simple_strtoul(s, &e, 10) : 0;
 			addr <<= 8;
 			addr  |= (val & 0xFF);
@@ -354,20 +354,20 @@
 		}
 		bd->bi_ip_addr = htonl(addr);
 		return 0;
-	} else if (strcmp(argv[1],"loadaddr") == 0) {
+	} else if (strcmp(argv[1], "loadaddr") == 0) {
 		load_addr = simple_strtoul(argv[2], NULL, 16);
 		return 0;
 	}
 #if defined(CONFIG_CMD_NET)
-	else if (strcmp(argv[1],"bootfile") == 0) {
-		copy_filename (BootFile, argv[2], sizeof(BootFile));
+	else if (strcmp(argv[1], "bootfile") == 0) {
+		copy_filename(BootFile, argv[2], sizeof(BootFile));
 		return 0;
 	}
 #endif
 	return 0;
 }
 
-int setenv (char *varname, char *varvalue)
+int setenv(char *varname, char *varvalue)
 {
 	char * const argv[4] = { "setenv", varname, varvalue, NULL };
 	if ((varvalue == NULL) || (varvalue[0] == '\0'))
@@ -376,7 +376,7 @@
 		return _do_env_set(0, 3, argv);
 }
 
-int do_env_set (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+int do_env_set(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 {
 	if (argc < 2)
 		return cmd_usage(cmdtp);
@@ -388,7 +388,7 @@
  * Prompt for environment variable
  */
 #if defined(CONFIG_CMD_ASKENV)
-int do_env_ask ( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+int do_env_ask(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 {
 	extern char console_buffer[CONFIG_SYS_CBSIZE];
 	char message[CONFIG_SYS_CBSIZE];
@@ -416,10 +416,10 @@
 		break;
 
 	default:	/* env_ask envname message1 ... messagen size */
-		for (i=2,pos=0; i < argc - 1; i++) {
-			if (pos) {
+		for (i = 2, pos = 0; i < argc - 1; i++) {
+			if (pos)
 				message[pos++] = ' ';
-			}
+
 			strcpy(message+pos, argv[i]);
 			pos += strlen(argv[i]);
 		}
@@ -482,7 +482,7 @@
  * return address of storage for that variable,
  * or NULL if not found
  */
-char *getenv (char *name)
+char *getenv(char *name)
 {
 	if (gd->flags & GD_FLG_ENV_READY) {	/* after import into hashtable */
 		ENTRY e, *ep;
@@ -493,7 +493,7 @@
 		e.data = NULL;
 		hsearch_r(e, FIND, &ep, &env_htab);
 
-		return (ep ? ep->data : NULL);
+		return ep ? ep->data : NULL;
 	}
 
 	/* restricted capabilities before import */
@@ -507,23 +507,24 @@
 /*
  * Look up variable from environment for restricted C runtime env.
  */
-int getenv_f (char *name, char *buf, unsigned len)
+int getenv_f(char *name, char *buf, unsigned len)
 {
 	int i, nxt;
 
-	for (i=0; env_get_char(i) != '\0'; i=nxt+1) {
+	for (i = 0; env_get_char(i) != '\0'; i = nxt+1) {
 		int val, n;
 
-		for (nxt=i; env_get_char(nxt) != '\0'; ++nxt) {
-			if (nxt >= CONFIG_ENV_SIZE) {
-				return (-1);
-			}
+		for (nxt = i; env_get_char(nxt) != '\0'; ++nxt) {
+			if (nxt >= CONFIG_ENV_SIZE)
+				return -1;
 		}
-		if ((val=envmatch((uchar *)name, i)) < 0)
+
+		val = envmatch((uchar *)name, i);
+		if (val < 0)
 			continue;
 
 		/* found; copy out */
-		for (n=0; n<len; ++n, ++buf) {
+		for (n = 0; n < len; ++n, ++buf) {
 			if ((*buf = env_get_char(val++)) == '\0')
 				return n;
 		}
@@ -535,18 +536,18 @@
 
 		return n;
 	}
-	return (-1);
+	return -1;
 }
 
 #if defined(CONFIG_CMD_SAVEENV) && !defined(CONFIG_ENV_IS_NOWHERE)
 
-int do_env_save (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+int do_env_save(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 {
-	extern char * env_name_spec;
+	extern char *env_name_spec;
 
-	printf ("Saving Environment to %s...\n", env_name_spec);
+	printf("Saving Environment to %s...\n", env_name_spec);
 
-	return (saveenv() ? 1 : 0);
+	return saveenv() ? 1 : 0;
 }
 
 U_BOOT_CMD(
@@ -566,27 +567,26 @@
  * If the names match, return the index for the value2, else NULL.
  */
 
-int envmatch (uchar *s1, int i2)
+int envmatch(uchar *s1, int i2)
 {
-
 	while (*s1 == env_get_char(i2++))
 		if (*s1++ == '=')
-			return(i2);
+			return i2;
 	if (*s1 == '\0' && env_get_char(i2-1) == '=')
-		return(i2);
-	return(-1);
+		return i2;
+	return -1;
 }
 
-static int do_env_default(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
+static int do_env_default(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 {
-	if ((argc != 2) || (strcmp(argv[1], "-f") != 0)) {
+	if ((argc != 2) || (strcmp(argv[1], "-f") != 0))
 		return cmd_usage(cmdtp);
-	}
+
 	set_default_env("## Resetting to default environment\n");
 	return 0;
 }
 
-static int do_env_delete(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
+static int do_env_delete(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 {
 	printf("Not implemented yet\n");
 	return 0;
@@ -673,9 +673,8 @@
 		}
 	}
 
-	if (argc < 1) {
+	if (argc < 1)
 		return cmd_usage(cmdtp);
-	}
 
 	addr = (char *)simple_strtoul(argv[0], NULL, 16);
 
@@ -719,7 +718,7 @@
 		envp->flags = ACTIVE_FLAG;
 #endif
 	}
-	sprintf(buf, "%zX", (size_t)(len + offsetof(env_t,data)));
+	sprintf(buf, "%zX", (size_t)(len + offsetof(env_t, data)));
 	setenv("filesize", buf);
 
 	return 0;
@@ -744,7 +743,7 @@
  *	size:	length of input data; if missing, proper '\0'
  *		termination is mandatory
  */
-static int do_env_import(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
+static int do_env_import(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 {
 	char	*cmd, *addr;
 	char	sep = '\n';
@@ -784,9 +783,8 @@
 		}
 	}
 
-	if (argc < 1) {
+	if (argc < 1)
 		return cmd_usage(cmdtp);
-	}
 
 	if (!fmt)
 		printf("## Warning: defaulting to text format\n");
@@ -844,7 +842,7 @@
 #endif
 
 #if defined(CONFIG_CMD_RUN)
-extern int do_run (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
+extern int do_run(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
 #endif
 
 /*
@@ -885,7 +883,7 @@
 }
 #endif
 
-static int do_env (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+static int do_env(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 {
 	cmd_tbl_t *cp;
 
diff --git a/config.mk b/config.mk
index fa46ff1..7ce554e 100644
--- a/config.mk
+++ b/config.mk
@@ -153,14 +153,37 @@
 RELFLAGS= $(PLATFORM_RELFLAGS)
 DBGFLAGS= -g # -DDEBUG
 OPTFLAGS= -Os #-fomit-frame-pointer
+
+# If board code explicitly specified LDSCRIPT or CONFIG_SYS_LDSCRIPT, use
+# that (or fail if absent).  Otherwise, search for a linker script in a
+# standard location.
+
 ifndef LDSCRIPT
-#LDSCRIPT := $(TOPDIR)/board/$(BOARDDIR)/u-boot.lds.debug
-ifeq ($(CONFIG_NAND_U_BOOT),y)
-LDSCRIPT := $(TOPDIR)/board/$(BOARDDIR)/u-boot-nand.lds
-else
-LDSCRIPT := $(TOPDIR)/board/$(BOARDDIR)/u-boot.lds
+	#LDSCRIPT := $(TOPDIR)/board/$(BOARDDIR)/u-boot.lds.debug
+	ifdef CONFIG_SYS_LDSCRIPT
+		# need to strip off double quotes
+		LDSCRIPT := $(subst ",,$(CONFIG_SYS_LDSCRIPT))
+	endif
 endif
+
+ifndef LDSCRIPT
+	ifeq ($(CONFIG_NAND_U_BOOT),y)
+		LDSCRIPT := $(TOPDIR)/board/$(BOARDDIR)/u-boot-nand.lds
+		ifeq ($(wildcard $(LDSCRIPT)),)
+			LDSCRIPT := $(TOPDIR)/$(CPUDIR)/u-boot-nand.lds
+		endif
+	endif
+	ifeq ($(wildcard $(LDSCRIPT)),)
+		LDSCRIPT := $(TOPDIR)/board/$(BOARDDIR)/u-boot.lds
+	endif
+	ifeq ($(wildcard $(LDSCRIPT)),)
+		LDSCRIPT := $(TOPDIR)/$(CPUDIR)/u-boot.lds
+	endif
+	ifeq ($(wildcard $(LDSCRIPT)),)
+$(error could not find linker script)
+	endif
 endif
+
 OBJCFLAGS += --gap-fill=0xff
 
 gccincdir := $(shell $(CC) -print-file-name=include)
diff --git a/doc/README.video b/doc/README.video
index 34e199c..0c04bea 100644
--- a/doc/README.video
+++ b/doc/README.video
@@ -28,3 +28,22 @@
 
 - MPC823FADS with AD7176 on a PAL TV (YCbYCr)	- arsenio@tin.it
 - GENIETV    with AD7177 on a PAL TV (YCbYCr)	- arsenio@tin.it
+
+
+"video-mode" environment variable
+===============================
+
+The 'video-mode' environment variable can be used to enable and configure
+some video drivers.  The format matches the video= command-line option used
+for Linux:
+
+	video-mode=<driver>:<xres>x<yres>-<depth>@<freq><,option=string>
+
+	<driver>	The video driver name, ignored by U-Boot
+	<xres>		The X resolution (in pixels) to use.
+	<yres>		The Y resolution (in pixels) to use.
+	<depth>		The color depth (in bits) to use.
+	<freq>		The frequency (in Hz) to use.
+	<options>	A comma-separated list of device-specific options
+
+Example: video-mode=fslfb:1280x1024-32@60,monitor=dvi
diff --git a/drivers/i2c/soft_i2c.c b/drivers/i2c/soft_i2c.c
index 69b5f42..9b02e89 100644
--- a/drivers/i2c/soft_i2c.c
+++ b/drivers/i2c/soft_i2c.c
@@ -286,6 +286,7 @@
 		int	ret;
 
 		ret = i2x_mux_select_mux(bus);
+		i2c_init_board();
 		if (ret == 0)
 			i2c_bus_num = bus;
 		else
diff --git a/drivers/mmc/Makefile b/drivers/mmc/Makefile
index 9aca3a2..a8fe17a 100644
--- a/drivers/mmc/Makefile
+++ b/drivers/mmc/Makefile
@@ -32,6 +32,7 @@
 COBJS-$(CONFIG_GENERIC_MMC) += mmc.o
 COBJS-$(CONFIG_GENERIC_ATMEL_MCI) += gen_atmel_mci.o
 COBJS-$(CONFIG_MMC_SPI) += mmc_spi.o
+COBJS-$(CONFIG_ARM_PL180_MMCI) += arm_pl180_mmci.o
 COBJS-$(CONFIG_MXC_MMC) += mxcmmc.o
 COBJS-$(CONFIG_OMAP3_MMC) += omap3_mmc.o
 COBJS-$(CONFIG_OMAP_HSMMC) += omap_hsmmc.o
diff --git a/drivers/mmc/arm_pl180_mmci.c b/drivers/mmc/arm_pl180_mmci.c
new file mode 100644
index 0000000..ed296ee
--- /dev/null
+++ b/drivers/mmc/arm_pl180_mmci.c
@@ -0,0 +1,443 @@
+/*
+ * ARM PrimeCell MultiMedia Card Interface - PL180
+ *
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * Author: Ulf Hansson <ulf.hansson@stericsson.com>
+ * Author: Martin Lundholm <martin.xa.lundholm@stericsson.com>
+ * Ported to drivers/mmc/ by: Matt Waddel <matt.waddel@linaro.org>
+ *
+ * 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
+ */
+
+/* #define DEBUG */
+
+#include <asm/io.h>
+#include "common.h"
+#include <errno.h>
+#include <mmc.h>
+#include "arm_pl180_mmci.h"
+#include <malloc.h>
+
+struct mmc_host {
+	struct sdi_registers *base;
+};
+
+static int wait_for_command_end(struct mmc *dev, struct mmc_cmd *cmd)
+{
+	u32 hoststatus, statusmask;
+	struct mmc_host *host = dev->priv;
+
+	statusmask = SDI_STA_CTIMEOUT | SDI_STA_CCRCFAIL;
+	if ((cmd->resp_type & MMC_RSP_PRESENT))
+		statusmask |= SDI_STA_CMDREND;
+	else
+		statusmask |= SDI_STA_CMDSENT;
+
+	do
+		hoststatus = readl(&host->base->status) & statusmask;
+	while (!hoststatus);
+
+	writel(statusmask, &host->base->status_clear);
+	if (hoststatus & SDI_STA_CTIMEOUT) {
+		printf("CMD%d time out\n", cmd->cmdidx);
+		return -ETIMEDOUT;
+	} else if ((hoststatus & SDI_STA_CCRCFAIL) &&
+		   (cmd->flags & MMC_RSP_CRC)) {
+		printf("CMD%d CRC error\n", cmd->cmdidx);
+		return -EILSEQ;
+	}
+
+	if (cmd->resp_type & MMC_RSP_PRESENT) {
+		cmd->response[0] = readl(&host->base->response0);
+		cmd->response[1] = readl(&host->base->response1);
+		cmd->response[2] = readl(&host->base->response2);
+		cmd->response[3] = readl(&host->base->response3);
+		debug("CMD%d response[0]:0x%08X, response[1]:0x%08X, "
+			"response[2]:0x%08X, response[3]:0x%08X\n",
+			cmd->cmdidx, cmd->response[0], cmd->response[1],
+			cmd->response[2], cmd->response[3]);
+	}
+
+	return 0;
+}
+
+/* send command to the mmc card and wait for results */
+static int do_command(struct mmc *dev, struct mmc_cmd *cmd)
+{
+	int result;
+	u32 sdi_cmd = 0;
+	struct mmc_host *host = dev->priv;
+
+	sdi_cmd = ((cmd->cmdidx & SDI_CMD_CMDINDEX_MASK) | SDI_CMD_CPSMEN);
+
+	if (cmd->resp_type) {
+		sdi_cmd |= SDI_CMD_WAITRESP;
+		if (cmd->resp_type & MMC_RSP_136)
+			sdi_cmd |= SDI_CMD_LONGRESP;
+	}
+
+	writel((u32)cmd->cmdarg, &host->base->argument);
+	udelay(COMMAND_REG_DELAY);
+	writel(sdi_cmd, &host->base->command);
+	result = wait_for_command_end(dev, cmd);
+
+	/* After CMD2 set RCA to a none zero value. */
+	if ((result == 0) && (cmd->cmdidx == MMC_CMD_ALL_SEND_CID))
+		dev->rca = 10;
+
+	/* After CMD3 open drain is switched off and push pull is used. */
+	if ((result == 0) && (cmd->cmdidx == MMC_CMD_SET_RELATIVE_ADDR)) {
+		u32 sdi_pwr = readl(&host->base->power) & ~SDI_PWR_OPD;
+		writel(sdi_pwr, &host->base->power);
+	}
+
+	return result;
+}
+
+static int read_bytes(struct mmc *dev, u32 *dest, u32 blkcount, u32 blksize)
+{
+	u32 *tempbuff = dest;
+	int i;
+	u64 xfercount = blkcount * blksize;
+	struct mmc_host *host = dev->priv;
+	u32 status, status_err;
+
+	debug("read_bytes: blkcount=%u blksize=%u\n", blkcount, blksize);
+
+	status = readl(&host->base->status);
+	status_err = status & (SDI_STA_DCRCFAIL | SDI_STA_DTIMEOUT |
+			       SDI_STA_RXOVERR);
+	while (!status_err &&
+	       (xfercount >= SDI_FIFO_BURST_SIZE * sizeof(u32))) {
+		if (status & SDI_STA_RXFIFOBR) {
+			for (i = 0; i < SDI_FIFO_BURST_SIZE; i++)
+				*(tempbuff + i) = readl(&host->base->fifo);
+			tempbuff += SDI_FIFO_BURST_SIZE;
+			xfercount -= SDI_FIFO_BURST_SIZE * sizeof(u32);
+		}
+		status = readl(&host->base->status);
+		status_err = status &
+			(SDI_STA_DCRCFAIL | SDI_STA_DTIMEOUT | SDI_STA_RXOVERR);
+	}
+
+	if (status & SDI_STA_DTIMEOUT) {
+		printf("Read data timed out, xfercount: %llu, status: 0x%08X\n",
+			xfercount, status);
+		return -ETIMEDOUT;
+	} else if (status & SDI_STA_DCRCFAIL) {
+		printf("Read data blk CRC error: 0x%x\n", status);
+		return -EILSEQ;
+	} else if (status & SDI_STA_RXOVERR) {
+		printf("Read data RX overflow error\n");
+		return -EIO;
+	}
+
+	while ((!status_err) && (xfercount >= sizeof(u32))) {
+		if (status & SDI_STA_RXDAVL) {
+			*(tempbuff) = readl(&host->base->fifo);
+			tempbuff++;
+			xfercount -= sizeof(u32);
+		}
+		status = readl(&host->base->status);
+		status_err = status & (SDI_STA_DCRCFAIL | SDI_STA_DTIMEOUT |
+				       SDI_STA_RXOVERR);
+	}
+
+	status_err = status &
+		(SDI_STA_DCRCFAIL | SDI_STA_DTIMEOUT | SDI_STA_DBCKEND |
+		 SDI_STA_RXOVERR);
+	while (!status_err) {
+		status = readl(&host->base->status);
+		status_err = status &
+			(SDI_STA_DCRCFAIL | SDI_STA_DTIMEOUT | SDI_STA_DBCKEND |
+			 SDI_STA_RXOVERR);
+	}
+
+	if (status & SDI_STA_DTIMEOUT) {
+		printf("Read data timed out, xfercount: %llu, status: 0x%08X\n",
+			xfercount, status);
+		return -ETIMEDOUT;
+	} else if (status & SDI_STA_DCRCFAIL) {
+		printf("Read data bytes CRC error: 0x%x\n", status);
+		return -EILSEQ;
+	} else if (status & SDI_STA_RXOVERR) {
+		printf("Read data RX overflow error\n");
+		return -EIO;
+	}
+
+	writel(SDI_ICR_MASK, &host->base->status_clear);
+
+	if (xfercount) {
+		printf("Read data error, xfercount: %llu\n", xfercount);
+		return -ENOBUFS;
+	}
+
+	return 0;
+}
+
+static int write_bytes(struct mmc *dev, u32 *src, u32 blkcount, u32 blksize)
+{
+	u32 *tempbuff = src;
+	int i;
+	u64 xfercount = blkcount * blksize;
+	struct mmc_host *host = dev->priv;
+	u32 status, status_err;
+
+	debug("write_bytes: blkcount=%u blksize=%u\n", blkcount, blksize);
+
+	status = readl(&host->base->status);
+	status_err = status & (SDI_STA_DCRCFAIL | SDI_STA_DTIMEOUT);
+	while (!status_err && xfercount) {
+		if (status & SDI_STA_TXFIFOBW) {
+			if (xfercount >= SDI_FIFO_BURST_SIZE * sizeof(u32)) {
+				for (i = 0; i < SDI_FIFO_BURST_SIZE; i++)
+					writel(*(tempbuff + i),
+						&host->base->fifo);
+				tempbuff += SDI_FIFO_BURST_SIZE;
+				xfercount -= SDI_FIFO_BURST_SIZE * sizeof(u32);
+			} else {
+				while (xfercount >= sizeof(u32)) {
+					writel(*(tempbuff), &host->base->fifo);
+					tempbuff++;
+					xfercount -= sizeof(u32);
+				}
+			}
+		}
+		status = readl(&host->base->status);
+		status_err = status & (SDI_STA_DCRCFAIL | SDI_STA_DTIMEOUT);
+	}
+
+	status_err = status &
+		(SDI_STA_DCRCFAIL | SDI_STA_DTIMEOUT | SDI_STA_DBCKEND);
+	while (!status_err) {
+		status = readl(&host->base->status);
+		status_err = status &
+			(SDI_STA_DCRCFAIL | SDI_STA_DTIMEOUT | SDI_STA_DBCKEND);
+	}
+
+	if (status & SDI_STA_DTIMEOUT) {
+		printf("Write data timed out, xfercount:%llu,status:0x%08X\n",
+		       xfercount, status);
+		return -ETIMEDOUT;
+	} else if (status & SDI_STA_DCRCFAIL) {
+		printf("Write data CRC error\n");
+		return -EILSEQ;
+	}
+
+	writel(SDI_ICR_MASK, &host->base->status_clear);
+
+	if (xfercount) {
+		printf("Write data error, xfercount:%llu", xfercount);
+		return -ENOBUFS;
+	}
+
+	return 0;
+}
+
+static int do_data_transfer(struct mmc *dev,
+			    struct mmc_cmd *cmd,
+			    struct mmc_data *data)
+{
+	int error = -ETIMEDOUT;
+	struct mmc_host *host = dev->priv;
+	u32 blksz = 0;
+	u32 data_ctrl = 0;
+	u32 data_len = (u32) (data->blocks * data->blocksize);
+
+	blksz = (ffs(data->blocksize) - 1);
+	data_ctrl |= ((blksz << 4) & SDI_DCTRL_DBLKSIZE_MASK);
+	data_ctrl |= SDI_DCTRL_DTEN;
+
+	writel(SDI_DTIMER_DEFAULT, &host->base->datatimer);
+	writel(data_len, &host->base->datalength);
+	udelay(DATA_REG_DELAY);
+
+	if (data->flags & MMC_DATA_READ) {
+		data_ctrl |= SDI_DCTRL_DTDIR_IN;
+		writel(data_ctrl, &host->base->datactrl);
+
+		error = do_command(dev, cmd);
+		if (error)
+			return error;
+
+		error = read_bytes(dev, (u32 *)data->dest, (u32)data->blocks,
+				   (u32)data->blocksize);
+	} else if (data->flags & MMC_DATA_WRITE) {
+		error = do_command(dev, cmd);
+		if (error)
+			return error;
+
+		writel(data_ctrl, &host->base->datactrl);
+		error = write_bytes(dev, (u32 *)data->src, (u32)data->blocks,
+				    (u32)data->blocksize);
+	}
+
+	return error;
+}
+
+static int host_request(struct mmc *dev,
+			struct mmc_cmd *cmd,
+			struct mmc_data *data)
+{
+	int result;
+
+	if (data)
+		result = do_data_transfer(dev, cmd, data);
+	else
+		result = do_command(dev, cmd);
+
+	return result;
+}
+
+/* MMC uses open drain drivers in the enumeration phase */
+static int mmc_host_reset(struct mmc *dev)
+{
+	struct mmc_host *host = dev->priv;
+	u32 sdi_u32 = SDI_PWR_OPD | SDI_PWR_PWRCTRL_ON;
+
+	writel(sdi_u32, &host->base->power);
+
+	return 0;
+}
+
+static void host_set_ios(struct mmc *dev)
+{
+	struct mmc_host *host = dev->priv;
+	u32 sdi_clkcr;
+
+	sdi_clkcr = readl(&host->base->clock);
+
+	/* Ramp up the clock rate */
+	if (dev->clock) {
+		u32 clkdiv = 0;
+
+		if (dev->clock >= dev->f_max)
+			dev->clock = dev->f_max;
+
+		clkdiv = ((ARM_MCLK / dev->clock) / 2) - 1;
+
+		if (clkdiv > SDI_CLKCR_CLKDIV_MASK)
+			clkdiv = SDI_CLKCR_CLKDIV_MASK;
+
+		sdi_clkcr &= ~(SDI_CLKCR_CLKDIV_MASK);
+		sdi_clkcr |= clkdiv;
+	}
+
+	/* Set the bus width */
+	if (dev->bus_width) {
+		u32 buswidth = 0;
+
+		switch (dev->bus_width) {
+		case 1:
+			buswidth |= SDI_CLKCR_WIDBUS_1;
+			break;
+		case 4:
+			buswidth |= SDI_CLKCR_WIDBUS_4;
+			break;
+		default:
+			printf("Invalid bus width\n");
+			break;
+		}
+		sdi_clkcr &= ~(SDI_CLKCR_WIDBUS_MASK);
+		sdi_clkcr |= buswidth;
+	}
+
+	writel(sdi_clkcr, &host->base->clock);
+	udelay(CLK_CHANGE_DELAY);
+}
+
+struct mmc *alloc_mmc_struct(void)
+{
+	struct mmc_host *host = NULL;
+	struct mmc *mmc_device = NULL;
+
+	host = malloc(sizeof(struct mmc_host));
+	if (!host)
+		return NULL;
+
+	mmc_device = malloc(sizeof(struct mmc));
+	if (!mmc_device)
+		goto err;
+
+	mmc_device->priv = host;
+	return mmc_device;
+
+err:
+	free(host);
+	return NULL;
+}
+
+/*
+ * mmc_host_init - initialize the mmc controller.
+ * Set initial clock and power for mmc slot.
+ * Initialize mmc struct and register with mmc framework.
+ */
+static int arm_pl180_mmci_host_init(struct mmc *dev)
+{
+	struct mmc_host *host = dev->priv;
+	u32 sdi_u32;
+
+	host->base = (struct sdi_registers *)CONFIG_ARM_PL180_MMCI_BASE;
+
+	/* Initially set power-on, full voltage & MMCI read */
+	sdi_u32 = INIT_PWR;
+	writel(sdi_u32, &host->base->power);
+
+	/* setting clk freq 505KHz */
+	sdi_u32 = SDI_CLKCR_CLKDIV_INIT | SDI_CLKCR_CLKEN;
+	writel(sdi_u32, &host->base->clock);
+	udelay(CLK_CHANGE_DELAY);
+
+	/* Disable mmc interrupts */
+	sdi_u32 = readl(&host->base->mask0) & ~SDI_MASK0_MASK;
+	writel(sdi_u32, &host->base->mask0);
+
+	sprintf(dev->name, "MMC");
+	dev->clock = ARM_MCLK / (2 * (SDI_CLKCR_CLKDIV_INIT + 1));
+	dev->send_cmd = host_request;
+	dev->set_ios = host_set_ios;
+	dev->init = mmc_host_reset;
+	dev->host_caps = 0;
+	dev->voltages = VOLTAGE_WINDOW_MMC;
+	dev->f_min = dev->clock;
+	dev->f_max = CONFIG_ARM_PL180_MMCI_CLOCK_FREQ;
+
+	return 0;
+}
+
+int arm_pl180_mmci_init(void)
+{
+	int error;
+	struct mmc *dev;
+
+	dev = alloc_mmc_struct();
+	if (!dev)
+		return -1;
+
+	error = arm_pl180_mmci_host_init(dev);
+	if (error) {
+		printf("mmci_host_init error - %d\n", error);
+		return -1;
+	}
+
+	dev->b_max = 0;
+
+	mmc_register(dev);
+	debug("registered mmc interface number is:%d\n", dev->block_dev.dev);
+
+	return 0;
+}
diff --git a/drivers/mmc/arm_pl180_mmci.h b/drivers/mmc/arm_pl180_mmci.h
new file mode 100644
index 0000000..42fbe3e
--- /dev/null
+++ b/drivers/mmc/arm_pl180_mmci.h
@@ -0,0 +1,183 @@
+/*
+ * ARM PrimeCell MultiMedia Card Interface - PL180
+ *
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * Author: Ulf Hansson <ulf.hansson@stericsson.com>
+ * Author: Martin Lundholm <martin.xa.lundholm@stericsson.com>
+ * Ported to drivers/mmc/ by: Matt Waddel <matt.waddel@linaro.org>
+ *
+ * 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
+ */
+
+#ifndef __ARM_PL180_MMCI_H__
+#define __ARM_PL180_MMCI_H__
+
+int arm_pl180_mmci_init(void);
+
+#define COMMAND_REG_DELAY	300
+#define DATA_REG_DELAY		1000
+#define CLK_CHANGE_DELAY	2000
+
+#define INIT_PWR		0xBF /* Power on, full power, not open drain */
+#define ARM_MCLK		(100*1000*1000)
+
+/* SDI Power Control register bits */
+#define SDI_PWR_PWRCTRL_MASK	0x00000003
+#define SDI_PWR_PWRCTRL_ON	0x00000003
+#define SDI_PWR_PWRCTRL_OFF	0x00000000
+#define SDI_PWR_DAT2DIREN	0x00000004
+#define SDI_PWR_CMDDIREN	0x00000008
+#define SDI_PWR_DAT0DIREN	0x00000010
+#define SDI_PWR_DAT31DIREN	0x00000020
+#define SDI_PWR_OPD		0x00000040
+#define SDI_PWR_FBCLKEN		0x00000080
+#define SDI_PWR_DAT74DIREN	0x00000100
+#define SDI_PWR_RSTEN		0x00000200
+
+#define VOLTAGE_WINDOW_MMC	0x00FF8080
+#define VOLTAGE_WINDOW_SD	0x80010000
+
+/* SDI clock control register bits */
+#define SDI_CLKCR_CLKDIV_MASK	0x000000FF
+#define SDI_CLKCR_CLKEN		0x00000100
+#define SDI_CLKCR_PWRSAV	0x00000200
+#define SDI_CLKCR_BYPASS	0x00000400
+#define SDI_CLKCR_WIDBUS_MASK	0x00001800
+#define SDI_CLKCR_WIDBUS_1	0x00000000
+#define SDI_CLKCR_WIDBUS_4	0x00000800
+
+#define SDI_CLKCR_CLKDIV_INIT	0x000000C6 /* MCLK/(2*(0xC6+1)) => 505KHz */
+
+/* SDI command register bits */
+#define SDI_CMD_CMDINDEX_MASK	0x000000FF
+#define SDI_CMD_WAITRESP	0x00000040
+#define SDI_CMD_LONGRESP	0x00000080
+#define SDI_CMD_WAITINT		0x00000100
+#define SDI_CMD_WAITPEND	0x00000200
+#define SDI_CMD_CPSMEN		0x00000400
+#define SDI_CMD_SDIOSUSPEND	0x00000800
+#define SDI_CMD_ENDCMDCOMPL	0x00001000
+#define SDI_CMD_NIEN		0x00002000
+#define SDI_CMD_CE_ATACMD	0x00004000
+#define SDI_CMD_CBOOTMODEEN	0x00008000
+
+#define SDI_DTIMER_DEFAULT	0xFFFF0000
+
+/* SDI Status register bits */
+#define SDI_STA_CCRCFAIL	0x00000001
+#define SDI_STA_DCRCFAIL	0x00000002
+#define SDI_STA_CTIMEOUT	0x00000004
+#define SDI_STA_DTIMEOUT	0x00000008
+#define SDI_STA_TXUNDERR	0x00000010
+#define SDI_STA_RXOVERR		0x00000020
+#define SDI_STA_CMDREND		0x00000040
+#define SDI_STA_CMDSENT		0x00000080
+#define SDI_STA_DATAEND		0x00000100
+#define SDI_STA_STBITERR	0x00000200
+#define SDI_STA_DBCKEND		0x00000400
+#define SDI_STA_CMDACT		0x00000800
+#define SDI_STA_TXACT		0x00001000
+#define SDI_STA_RXACT		0x00002000
+#define SDI_STA_TXFIFOBW	0x00004000
+#define SDI_STA_RXFIFOBR	0x00008000
+#define SDI_STA_TXFIFOF		0x00010000
+#define SDI_STA_RXFIFOF		0x00020000
+#define SDI_STA_TXFIFOE		0x00040000
+#define SDI_STA_RXFIFOE		0x00080000
+#define SDI_STA_TXDAVL		0x00100000
+#define SDI_STA_RXDAVL		0x00200000
+#define SDI_STA_SDIOIT		0x00400000
+#define SDI_STA_CEATAEND	0x00800000
+#define SDI_STA_CARDBUSY	0x01000000
+#define SDI_STA_BOOTMODE	0x02000000
+#define SDI_STA_BOOTACKERR	0x04000000
+#define SDI_STA_BOOTACKTIMEOUT	0x08000000
+#define SDI_STA_RSTNEND		0x10000000
+
+/* SDI Interrupt Clear register bits */
+#define SDI_ICR_MASK		0x1DC007FF
+#define SDI_ICR_CCRCFAILC	0x00000001
+#define SDI_ICR_DCRCFAILC	0x00000002
+#define SDI_ICR_CTIMEOUTC	0x00000004
+#define SDI_ICR_DTIMEOUTC	0x00000008
+#define SDI_ICR_TXUNDERRC	0x00000010
+#define SDI_ICR_RXOVERRC	0x00000020
+#define SDI_ICR_CMDRENDC	0x00000040
+#define SDI_ICR_CMDSENTC	0x00000080
+#define SDI_ICR_DATAENDC	0x00000100
+#define SDI_ICR_STBITERRC	0x00000200
+#define SDI_ICR_DBCKENDC	0x00000400
+#define SDI_ICR_SDIOITC		0x00400000
+#define SDI_ICR_CEATAENDC	0x00800000
+#define SDI_ICR_BUSYENDC	0x01000000
+#define SDI_ICR_BOOTACKERRC	0x04000000
+#define SDI_ICR_BOOTACKTIMEOUTC	0x08000000
+#define SDI_ICR_RSTNENDC	0x10000000
+
+#define SDI_MASK0_MASK		0x1FFFFFFF
+
+/* SDI Data control register bits */
+#define SDI_DCTRL_DTEN		0x00000001
+#define SDI_DCTRL_DTDIR_IN	0x00000002
+#define SDI_DCTRL_DTMODE_STREAM	0x00000004
+#define SDI_DCTRL_DMAEN		0x00000008
+#define SDI_DCTRL_DBLKSIZE_MASK	0x000000F0
+#define SDI_DCTRL_RWSTART	0x00000100
+#define SDI_DCTRL_RWSTOP	0x00000200
+#define SDI_DCTRL_RWMOD		0x00000200
+#define SDI_DCTRL_SDIOEN	0x00000800
+#define SDI_DCTRL_DMAREQCTL	0x00001000
+#define SDI_DCTRL_DBOOTMODEEN	0x00002000
+#define SDI_DCTRL_BUSYMODE	0x00004000
+#define SDI_DCTRL_DDR_MODE	0x00008000
+
+#define SDI_FIFO_BURST_SIZE	8
+
+struct sdi_registers {
+	u32 power;		/* 0x00*/
+	u32 clock;		/* 0x04*/
+	u32 argument;		/* 0x08*/
+	u32 command;		/* 0x0c*/
+	u32 respcommand;	/* 0x10*/
+	u32 response0;		/* 0x14*/
+	u32 response1;		/* 0x18*/
+	u32 response2;		/* 0x1c*/
+	u32 response3;		/* 0x20*/
+	u32 datatimer;		/* 0x24*/
+	u32 datalength;		/* 0x28*/
+	u32 datactrl;		/* 0x2c*/
+	u32 datacount;		/* 0x30*/
+	u32 status;		/* 0x34*/
+	u32 status_clear;	/* 0x38*/
+	u32 mask0;		/* 0x3c*/
+	u32 mask1;		/* 0x40*/
+	u32 card_select;	/* 0x44*/
+	u32 fifo_count;		/* 0x48*/
+	u32 padding1[(0x80-0x4C)>>2];
+	u32 fifo;		/* 0x80*/
+	u32 padding2[(0xFE0-0x84)>>2];
+	u32 periph_id0;		/* 0xFE0 mmc Peripheral Identifcation Register*/
+	u32 periph_id1;		/* 0xFE4*/
+	u32 periph_id2;		/* 0xFE8*/
+	u32 periph_id3;		/* 0xFEC*/
+	u32 pcell_id0;		/* 0xFF0*/
+	u32 pcell_id1;		/* 0xFF4*/
+	u32 pcell_id2;		/* 0xFF8*/
+	u32 pcell_id3;		/* 0xFFC*/
+};
+
+#endif
diff --git a/drivers/mmc/bfin_sdh.c b/drivers/mmc/bfin_sdh.c
index 31b6459..bc9057f 100644
--- a/drivers/mmc/bfin_sdh.c
+++ b/drivers/mmc/bfin_sdh.c
@@ -257,6 +257,8 @@
 	mmc->f_min = mmc->f_max >> 9;
 	mmc->block_dev.part_type = PART_TYPE_DOS;
 
+	mmc->b_max = 0;
+
 	mmc_register(mmc);
 
 	return 0;
diff --git a/drivers/mmc/davinci_mmc.c b/drivers/mmc/davinci_mmc.c
index d5d19eb..5d918e6 100644
--- a/drivers/mmc/davinci_mmc.c
+++ b/drivers/mmc/davinci_mmc.c
@@ -394,9 +394,8 @@
 	mmc->voltages = host->voltages;
 	mmc->host_caps = host->host_caps;
 
-#ifdef CONFIG_MMC_MBLOCK
 	mmc->b_max = DAVINCI_MAX_BLOCKS;
-#endif
+
 	mmc_register(mmc);
 
 	return 0;
diff --git a/drivers/mmc/fsl_esdhc.c b/drivers/mmc/fsl_esdhc.c
index 2838795..d2355be 100644
--- a/drivers/mmc/fsl_esdhc.c
+++ b/drivers/mmc/fsl_esdhc.c
@@ -99,6 +99,10 @@
 	else if (cmd->resp_type & MMC_RSP_PRESENT)
 		xfertyp |= XFERTYP_RSPTYP_48;
 
+#ifdef CONFIG_MX53
+	if (cmd->cmdidx == MMC_CMD_STOP_TRANSMISSION)
+		xfertyp |= XFERTYP_CMDTYP_ABORT;
+#endif
 	return XFERTYP_CMD(cmd->cmdidx) | xfertyp;
 }
 
diff --git a/drivers/mmc/gen_atmel_mci.c b/drivers/mmc/gen_atmel_mci.c
index 2984d64..6577925 100644
--- a/drivers/mmc/gen_atmel_mci.c
+++ b/drivers/mmc/gen_atmel_mci.c
@@ -348,6 +348,8 @@
 	mmc->f_min = get_mci_clk_rate() / (2*256);
 	mmc->f_max = get_mci_clk_rate() / (2*1);
 
+	mmc->b_max = 0;
+
 	mmc_register(mmc);
 
 	return 0;
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index f27b7c7..f6d31f5 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -243,8 +243,7 @@
 		return 0;
 
 	do {
-		cur = (blocks_todo > CONFIG_SYS_MMC_MAX_BLK_COUNT) ?
-		       CONFIG_SYS_MMC_MAX_BLK_COUNT : blocks_todo;
+		cur = (blocks_todo > mmc->b_max) ?  mmc->b_max : blocks_todo;
 		if(mmc_write_blocks(mmc, start, cur, src) != cur)
 			return 0;
 		blocks_todo -= cur;
@@ -320,8 +319,7 @@
 		return 0;
 
 	do {
-		cur = (blocks_todo > CONFIG_SYS_MMC_MAX_BLK_COUNT) ?
-		       CONFIG_SYS_MMC_MAX_BLK_COUNT : blocks_todo;
+		cur = (blocks_todo > mmc->b_max) ?  mmc->b_max : blocks_todo;
 		if(mmc_read_blocks(mmc, dst, start, cur) != cur)
 			return 0;
 		blocks_todo -= cur;
@@ -1029,6 +1027,8 @@
 	mmc->block_dev.removable = 1;
 	mmc->block_dev.block_read = mmc_bread;
 	mmc->block_dev.block_write = mmc_bwrite;
+	if (!mmc->b_max)
+		mmc->b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT;
 
 	INIT_LIST_HEAD (&mmc->link);
 
diff --git a/drivers/mmc/mxcmmc.c b/drivers/mmc/mxcmmc.c
index 5963953..ab1fc82 100644
--- a/drivers/mmc/mxcmmc.c
+++ b/drivers/mmc/mxcmmc.c
@@ -511,6 +511,8 @@
 	mmc->f_min = imx_get_perclk2() >> 7;
 	mmc->f_max = imx_get_perclk2() >> 1;
 
+	mmc->b_max = 0;
+
 	mmc_register(mmc);
 
 	return 0;
diff --git a/drivers/mmc/omap_hsmmc.c b/drivers/mmc/omap_hsmmc.c
index 6f2280a..957b987 100644
--- a/drivers/mmc/omap_hsmmc.c
+++ b/drivers/mmc/omap_hsmmc.c
@@ -465,6 +465,16 @@
 	mmc->f_min = 400000;
 	mmc->f_max = 52000000;
 
+	mmc->b_max = 0;
+
+#if defined(CONFIG_OMAP34XX)
+	/*
+	 * Silicon revs 2.1 and older do not support multiblock transfers.
+	 */
+	if ((get_cpu_family() == CPU_OMAP34XX) && (get_cpu_rev() <= CPU_3XX_ES21))
+		mmc->b_max = 1;
+#endif
+
 	mmc_register(mmc);
 
 	return 0;
diff --git a/drivers/mmc/s5p_mmc.c b/drivers/mmc/s5p_mmc.c
index 0323800..668c28b 100644
--- a/drivers/mmc/s5p_mmc.c
+++ b/drivers/mmc/s5p_mmc.c
@@ -466,6 +466,7 @@
 
 	mmc_host[dev_index].clock = 0;
 	mmc_host[dev_index].reg = s5p_get_base_mmc(dev_index);
+	mmc->m_bmax = 0;
 	mmc_register(mmc);
 
 	return 0;
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
index 74f1293..a9b1ca4 100644
--- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile
@@ -35,6 +35,7 @@
 COBJS-$(CONFIG_MPC52XX_SPI) += mpc52xx_spi.o
 COBJS-$(CONFIG_MPC8XXX_SPI) += mpc8xxx_spi.o
 COBJS-$(CONFIG_MXC_SPI) += mxc_spi.o
+COBJS-$(CONFIG_OC_TINY_SPI) += oc_tiny_spi.o
 COBJS-$(CONFIG_OMAP3_SPI) += omap3_spi.o
 COBJS-$(CONFIG_SOFT_SPI) += soft_spi.o
 COBJS-$(CONFIG_SH_SPI) += sh_spi.o
diff --git a/drivers/spi/oc_tiny_spi.c b/drivers/spi/oc_tiny_spi.c
new file mode 100644
index 0000000..fc01fb8
--- /dev/null
+++ b/drivers/spi/oc_tiny_spi.c
@@ -0,0 +1,248 @@
+/*
+ * Opencore tiny_spi driver
+ *
+ * http://opencores.org/project,tiny_spi
+ *
+ * based on bfin_spi.c
+ * Copyright (c) 2005-2008 Analog Devices Inc.
+ * Copyright (C) 2010 Thomas Chou <thomas@wytron.com.tw>
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <malloc.h>
+#include <spi.h>
+#include <asm/gpio.h>
+
+#define TINY_SPI_STATUS_TXE 0x1
+#define TINY_SPI_STATUS_TXR 0x2
+
+struct tiny_spi_regs {
+	unsigned rxdata;	/* Rx data reg */
+	unsigned txdata;	/* Tx data reg */
+	unsigned status;	/* Status reg */
+	unsigned control;	/* Control reg */
+	unsigned baud;		/* Baud reg */
+};
+
+struct tiny_spi_host {
+	uint base;
+	uint freq;
+	uint baudwidth;
+};
+static const struct tiny_spi_host tiny_spi_host_list[] =
+	CONFIG_SYS_TINY_SPI_LIST;
+
+struct tiny_spi_slave {
+	struct spi_slave slave;
+	const struct tiny_spi_host *host;
+	uint mode;
+	uint baud;
+	uint flg;
+};
+#define to_tiny_spi_slave(s) container_of(s, struct tiny_spi_slave, slave)
+
+int spi_cs_is_valid(unsigned int bus, unsigned int cs)
+{
+	return bus < ARRAY_SIZE(tiny_spi_host_list) && gpio_is_valid(cs);
+}
+
+void spi_cs_activate(struct spi_slave *slave)
+{
+	struct tiny_spi_slave *tiny_spi = to_tiny_spi_slave(slave);
+	unsigned int cs = slave->cs;
+
+	gpio_set_value(cs, tiny_spi->flg);
+	debug("%s: SPI_CS_GPIO:%x\n", __func__, gpio_get_value(cs));
+}
+
+void spi_cs_deactivate(struct spi_slave *slave)
+{
+	struct tiny_spi_slave *tiny_spi = to_tiny_spi_slave(slave);
+	unsigned int cs = slave->cs;
+
+	gpio_set_value(cs, !tiny_spi->flg);
+	debug("%s: SPI_CS_GPIO:%x\n", __func__, gpio_get_value(cs));
+}
+
+void spi_set_speed(struct spi_slave *slave, uint hz)
+{
+	struct tiny_spi_slave *tiny_spi = to_tiny_spi_slave(slave);
+	const struct tiny_spi_host *host = tiny_spi->host;
+
+	tiny_spi->baud = min(DIV_ROUND_UP(host->freq, hz * 2),
+			     (1 << host->baudwidth)) - 1;
+	debug("%s: speed %u actual %u\n", __func__, hz,
+	      host->freq / ((tiny_spi->baud + 1) * 2));
+}
+
+void spi_init(void)
+{
+}
+
+struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
+				  unsigned int hz, unsigned int mode)
+{
+	struct tiny_spi_slave *tiny_spi;
+
+	if (!spi_cs_is_valid(bus, cs) || gpio_request(cs, "tiny_spi"))
+		return NULL;
+
+	tiny_spi = malloc(sizeof(*tiny_spi));
+	if (!tiny_spi)
+		return NULL;
+	memset(tiny_spi, 0, sizeof(*tiny_spi));
+
+	tiny_spi->slave.bus = bus;
+	tiny_spi->slave.cs = cs;
+	tiny_spi->host = &tiny_spi_host_list[bus];
+	tiny_spi->mode = mode & (SPI_CPOL | SPI_CPHA);
+	tiny_spi->flg = mode & SPI_CS_HIGH ? 1 : 0;
+	spi_set_speed(&tiny_spi->slave, hz);
+
+	debug("%s: bus:%i cs:%i base:%lx\n", __func__,
+		bus, cs, tiny_spi->host->base);
+	return &tiny_spi->slave;
+}
+
+void spi_free_slave(struct spi_slave *slave)
+{
+	struct tiny_spi_slave *tiny_spi = to_tiny_spi_slave(slave);
+
+	gpio_free(slave->cs);
+	free(tiny_spi);
+}
+
+int spi_claim_bus(struct spi_slave *slave)
+{
+	struct tiny_spi_slave *tiny_spi = to_tiny_spi_slave(slave);
+	struct tiny_spi_regs *regs = (void *)tiny_spi->host->base;
+
+	debug("%s: bus:%i cs:%i\n", __func__, slave->bus, slave->cs);
+	gpio_direction_output(slave->cs, !tiny_spi->flg);
+	writel(tiny_spi->mode, &regs->control);
+	writel(tiny_spi->baud, &regs->baud);
+	return 0;
+}
+
+void spi_release_bus(struct spi_slave *slave)
+{
+	debug("%s: bus:%i cs:%i\n", __func__, slave->bus, slave->cs);
+}
+
+#ifndef CONFIG_TINY_SPI_IDLE_VAL
+# define CONFIG_TINY_SPI_IDLE_VAL 0xff
+#endif
+
+int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout,
+	     void *din, unsigned long flags)
+{
+	struct tiny_spi_slave *tiny_spi = to_tiny_spi_slave(slave);
+	struct tiny_spi_regs *regs = (void *)tiny_spi->host->base;
+	const u8 *txp = dout;
+	u8 *rxp = din;
+	uint bytes = bitlen / 8;
+	uint i;
+
+	debug("%s: bus:%i cs:%i bitlen:%i bytes:%i flags:%lx\n", __func__,
+		slave->bus, slave->cs, bitlen, bytes, flags);
+	if (bitlen == 0)
+		goto done;
+
+	/* assume to do 8 bits transfers */
+	if (bitlen % 8) {
+		flags |= SPI_XFER_END;
+		goto done;
+	}
+
+	if (flags & SPI_XFER_BEGIN)
+		spi_cs_activate(slave);
+
+	/* we need to tighten the transfer loop */
+	if (txp && rxp) {
+		writeb(*txp++, &regs->txdata);
+		if (bytes > 1) {
+			writeb(*txp++, &regs->txdata);
+			for (i = 2; i < bytes; i++) {
+				u8 rx, tx = *txp++;
+				while (!(readb(&regs->status) &
+					 TINY_SPI_STATUS_TXR))
+					;
+				rx = readb(&regs->txdata);
+				writeb(tx, &regs->txdata);
+				*rxp++ = rx;
+			}
+			while (!(readb(&regs->status) &
+				 TINY_SPI_STATUS_TXR))
+				;
+			*rxp++ = readb(&regs->txdata);
+		}
+		while (!(readb(&regs->status) &
+			 TINY_SPI_STATUS_TXE))
+			;
+		*rxp++ = readb(&regs->rxdata);
+	} else if (rxp) {
+		writeb(CONFIG_TINY_SPI_IDLE_VAL, &regs->txdata);
+		if (bytes > 1) {
+			writeb(CONFIG_TINY_SPI_IDLE_VAL,
+			       &regs->txdata);
+			for (i = 2; i < bytes; i++) {
+				u8 rx;
+				while (!(readb(&regs->status) &
+					 TINY_SPI_STATUS_TXR))
+					;
+				rx = readb(&regs->txdata);
+				writeb(CONFIG_TINY_SPI_IDLE_VAL,
+				       &regs->txdata);
+				*rxp++ = rx;
+			}
+			while (!(readb(&regs->status) &
+				 TINY_SPI_STATUS_TXR))
+				;
+			*rxp++ = readb(&regs->txdata);
+		}
+		while (!(readb(&regs->status) &
+			 TINY_SPI_STATUS_TXE))
+			;
+		*rxp++ = readb(&regs->rxdata);
+	} else if (txp) {
+		writeb(*txp++, &regs->txdata);
+		if (bytes > 1) {
+			writeb(*txp++, &regs->txdata);
+			for (i = 2; i < bytes; i++) {
+				u8 tx = *txp++;
+				while (!(readb(&regs->status) &
+					 TINY_SPI_STATUS_TXR))
+					;
+				writeb(tx, &regs->txdata);
+			}
+		}
+		while (!(readb(&regs->status) &
+			 TINY_SPI_STATUS_TXE))
+			;
+	} else {
+		writeb(CONFIG_TINY_SPI_IDLE_VAL, &regs->txdata);
+		if (bytes > 1) {
+			writeb(CONFIG_TINY_SPI_IDLE_VAL,
+			       &regs->txdata);
+			for (i = 2; i < bytes; i++) {
+				while (!(readb(&regs->status) &
+					 TINY_SPI_STATUS_TXR))
+					;
+				writeb(CONFIG_TINY_SPI_IDLE_VAL,
+				       &regs->txdata);
+			}
+		}
+		while (!(readb(&regs->status) &
+			 TINY_SPI_STATUS_TXE))
+			;
+	}
+
+ done:
+	if (flags & SPI_XFER_END)
+		spi_cs_deactivate(slave);
+
+	return 0;
+}
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index 2c53a6f..086dc05 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -28,7 +28,7 @@
 COBJS-$(CONFIG_ATI_RADEON_FB) += ati_radeon_fb.o videomodes.o
 COBJS-$(CONFIG_ATMEL_LCD) += atmel_lcdfb.o
 COBJS-$(CONFIG_CFB_CONSOLE) += cfb_console.o
-COBJS-$(CONFIG_FSL_DIU_FB) += fsl_diu_fb.o
+COBJS-$(CONFIG_FSL_DIU_FB) += fsl_diu_fb.o videomodes.o
 COBJS-$(CONFIG_S6E63D6) += s6e63d6.o
 COBJS-$(CONFIG_VIDEO_AMBA) += amba.o
 COBJS-$(CONFIG_VIDEO_CT69000) += ct69000.o videomodes.o
diff --git a/drivers/video/cfb_console.c b/drivers/video/cfb_console.c
index dd849c2..b427c84 100644
--- a/drivers/video/cfb_console.c
+++ b/drivers/video/cfb_console.c
@@ -882,6 +882,8 @@
 	struct palette p[256];
 	bmp_color_table_entry_t cte;
 	int green_shift, red_off;
+	int limit = VIDEO_COLS * VIDEO_ROWS;
+	int pixels = 0;
 
 	x = 0;
 	y = __le32_to_cpu(img->header.height) - 1;
@@ -962,6 +964,10 @@
 				/* unencoded run */
 				cnt = bm[1];
 				runlen = cnt;
+				pixels += cnt;
+				if (pixels > limit)
+					goto error;
+
 				bm += 2;
 				if (y < height) {
 					if (x >= width) {
@@ -970,7 +976,6 @@
 					}
 					if (x + runlen > width)
 						cnt = width - x;
-
 					draw_bitmap (&fbp, bm, p, cnt, 0);
 					x += runlen;
 				}
@@ -982,9 +987,13 @@
 			break;
 		default:
 			/* encoded run */
+			cnt = bm[0];
+			runlen = cnt;
+			pixels += cnt;
+			if (pixels > limit)
+				goto error;
+
 			if (y < height) { /* only draw into visible area */
-				cnt = bm[0];
-				runlen = cnt;
 				if (x >= width) {
 					x += runlen;
 					bm += 2;
@@ -992,7 +1001,6 @@
 				}
 				if (x + runlen > width)
 					cnt = width - x;
-
 				draw_bitmap (&fbp, bm, p, cnt, 1);
 				x += runlen;
 			}
@@ -1001,6 +1009,9 @@
 		}
 	}
 	return 0;
+error:
+	printf("Error: Too much encoded pixel data, validate your bitmap\n");
+	return -1;
 }
 #endif
 
diff --git a/drivers/video/fsl_diu_fb.c b/drivers/video/fsl_diu_fb.c
index 35ed938..0709849 100644
--- a/drivers/video/fsl_diu_fb.c
+++ b/drivers/video/fsl_diu_fb.c
@@ -1,6 +1,7 @@
 /*
- * Copyright 2007, 2010 Freescale Semiconductor, Inc.
- * York Sun <yorksun@freescale.com>
+ * Copyright 2007, 2010-2011 Freescale Semiconductor, Inc.
+ * Authors: York Sun <yorksun@freescale.com>
+ *          Timur Tabi <timur@freescale.com>
  *
  * FSL DIU Framebuffer driver
  *
@@ -24,12 +25,42 @@
  */
 
 #include <common.h>
-#include <i2c.h>
 #include <malloc.h>
 #include <asm/io.h>
 
+#include "videomodes.h"
+#include <video_fb.h>
 #include <fsl_diu_fb.h>
 
+struct fb_var_screeninfo {
+	unsigned int xres;		/* visible resolution		*/
+	unsigned int yres;
+
+	unsigned int bits_per_pixel;	/* guess what			*/
+
+	/* Timing: All values in pixclocks, except pixclock (of course) */
+	unsigned int pixclock;		/* pixel clock in ps (pico seconds) */
+	unsigned int left_margin;	/* time from sync to picture	*/
+	unsigned int right_margin;	/* time from picture to sync	*/
+	unsigned int upper_margin;	/* time from sync to picture	*/
+	unsigned int lower_margin;
+	unsigned int hsync_len;		/* length of horizontal sync	*/
+	unsigned int vsync_len;		/* length of vertical sync	*/
+	unsigned int sync;		/* see FB_SYNC_*		*/
+	unsigned int vmode;		/* see FB_VMODE_*		*/
+	unsigned int rotate;		/* angle we rotate counter clockwise */
+};
+
+struct fb_info {
+	struct fb_var_screeninfo var;	/* Current var */
+	unsigned int smem_len;		/* Length of frame buffer mem */
+	unsigned int type;		/* see FB_TYPE_*		*/
+	unsigned int line_length;	/* length of a line in bytes    */
+
+	void *screen_base;
+	unsigned long screen_size;
+};
+
 struct fb_videomode {
 	const char *name;	/* optional */
 	unsigned int refresh;		/* optional */
@@ -53,6 +84,7 @@
 
 /* This setting is used for the ifm pdm360ng with PRIMEVIEW PM070WL3 */
 static struct fb_videomode fsl_diu_mode_800 = {
+	.name		= "800x600-60",
 	.refresh	= 60,
 	.xres		= 800,
 	.yres		= 480,
@@ -74,6 +106,7 @@
  * hsync 31.5kHz, vsync 60Hz
  */
 static struct fb_videomode fsl_diu_mode_1024 = {
+	.name		= "1024x768-60",
 	.refresh	= 60,
 	.xres		= 1024,
 	.yres		= 768,
@@ -109,120 +142,137 @@
  */
 struct diu_ad {
 	/* Word 0(32-bit) in DDR memory */
-	unsigned int pix_fmt; /* hard coding pixel format */
+	__le32 pix_fmt; /* hard coding pixel format */
 	/* Word 1(32-bit) in DDR memory */
-	unsigned int addr;
+	__le32 addr;
 	/* Word 2(32-bit) in DDR memory */
-	unsigned int src_size_g_alpha;
+	__le32 src_size_g_alpha;
 	/* Word 3(32-bit) in DDR memory */
-	unsigned int aoi_size;
+	__le32 aoi_size;
 	/* Word 4(32-bit) in DDR memory */
-	unsigned int offset_xyi;
+	__le32 offset_xyi;
 	/* Word 5(32-bit) in DDR memory */
-	unsigned int offset_xyd;
+	__le32 offset_xyd;
 	/* Word 6(32-bit) in DDR memory */
-	unsigned int ckmax_r:8;
-	unsigned int ckmax_g:8;
-	unsigned int ckmax_b:8;
-	unsigned int res9:8;
+	__le32 ckmax_r:8;
+	__le32 ckmax_g:8;
+	__le32 ckmax_b:8;
+	__le32 res9:8;
 	/* Word 7(32-bit) in DDR memory */
-	unsigned int ckmin_r:8;
-	unsigned int ckmin_g:8;
-	unsigned int ckmin_b:8;
-	unsigned int res10:8;
+	__le32 ckmin_r:8;
+	__le32 ckmin_g:8;
+	__le32 ckmin_b:8;
+	__le32 res10:8;
 	/* Word 8(32-bit) in DDR memory */
-	unsigned int next_ad;
+	__le32 next_ad;
 	/* Word 9(32-bit) in DDR memory, just for 64-bit aligned */
-	unsigned int res1;
-	unsigned int res2;
-	unsigned int res3;
-}__attribute__ ((packed));
+	__le32 res[3];
+} __attribute__ ((packed));
 
 /*
  * DIU register map
  */
 struct diu {
-	unsigned int desc[3];
-	unsigned int gamma;
-	unsigned int pallete;
-	unsigned int cursor;
-	unsigned int curs_pos;
-	unsigned int diu_mode;
-	unsigned int bgnd;
-	unsigned int bgnd_wb;
-	unsigned int disp_size;
-	unsigned int wb_size;
-	unsigned int wb_mem_addr;
-	unsigned int hsyn_para;
-	unsigned int vsyn_para;
-	unsigned int syn_pol;
-	unsigned int thresholds;
-	unsigned int int_status;
-	unsigned int int_mask;
-	unsigned int colorbar[8];
-	unsigned int filling;
-	unsigned int plut;
+	__be32 desc[3];
+	__be32 gamma;
+	__be32 pallete;
+	__be32 cursor;
+	__be32 curs_pos;
+	__be32 diu_mode;
+	__be32 bgnd;
+	__be32 bgnd_wb;
+	__be32 disp_size;
+	__be32 wb_size;
+	__be32 wb_mem_addr;
+	__be32 hsyn_para;
+	__be32 vsyn_para;
+	__be32 syn_pol;
+	__be32 thresholds;
+	__be32 int_status;
+	__be32 int_mask;
+	__be32 colorbar[8];
+	__be32 filling;
+	__be32 plut;
 } __attribute__ ((packed));
 
-struct diu_hw {
-	struct diu *diu_reg;
-	volatile unsigned int mode;		/* DIU operation mode */
+struct diu_addr {
+	void *vaddr;		/* Virtual address */
+	u32 paddr;		/* 32-bit physical address */
+	unsigned int offset;	/* Alignment offset */
 };
 
-struct diu_addr {
-	unsigned char  *  paddr;	/* Virtual address */
-	unsigned int	   offset;
-};
+static struct fb_info info;
 
 /*
- * Modes of operation of DIU
+ * Align to 64-bit(8-byte), 32-byte, etc.
  */
-#define MFB_MODE0	0	/* DIU off */
-#define MFB_MODE1	1	/* All three planes output to display */
-#define MFB_MODE2	2	/* Plane 1 to display,
-				 * planes 2+3 written back to memory */
-#define MFB_MODE3	3	/* All three planes written back to memory */
-#define MFB_MODE4	4	/* Color bar generation */
+static int allocate_buf(struct diu_addr *buf, u32 size, u32 bytes_align)
+{
+	u32 offset, ssize;
+	u32 mask;
 
-#define MAX_CURS		32
+	ssize = size + bytes_align;
+	buf->vaddr = malloc(ssize);
+	if (!buf->vaddr)
+		return -1;
 
-static struct fb_info fsl_fb_info;
-static struct diu_addr gamma, cursor;
-static struct diu_ad fsl_diu_fb_ad __attribute__ ((aligned(32)));
-static struct diu_ad dummy_ad __attribute__ ((aligned(32)));
-static unsigned char *dummy_fb;
-static struct diu_hw dr = {
-	.mode = MFB_MODE1,
-};
+	memset(buf->vaddr, 0, ssize);
+	mask = bytes_align - 1;
+	offset = (u32)buf->vaddr & mask;
+	if (offset) {
+		buf->offset = bytes_align - offset;
+		buf->vaddr += offset;
+	} else
+		buf->offset = 0;
 
-int fb_enabled = 0;
-int fb_initialized = 0;
-const int default_xres = 1280;
-const int default_pixel_format = 0x88882317;
+	buf->paddr = virt_to_phys(buf->vaddr);
+	return 0;
+}
 
-static int map_video_memory(struct fb_info *info, unsigned long bytes_align);
-static void enable_lcdc(void);
-static void disable_lcdc(void);
-static int fsl_diu_enable_panel(struct fb_info *info);
-static int fsl_diu_disable_panel(struct fb_info *info);
-static int allocate_buf(struct diu_addr *buf, u32 size, u32 bytes_align);
-void diu_set_pixel_clock(unsigned int pixclock);
+/*
+ * Allocate a framebuffer and an Area Descriptor that points to it.  Both
+ * are created in the same memory block.  The Area Descriptor is updated to
+ * point to the framebuffer memory. Memory is aligned as needed.
+ */
+static struct diu_ad *allocate_fb(unsigned int xres, unsigned int yres,
+				  unsigned int depth, void **fb)
+{
+	unsigned long size = xres * yres * depth;
+	struct diu_addr addr;
+	struct diu_ad *ad;
+	size_t ad_size = roundup(sizeof(struct diu_ad), 32);
 
-int fsl_diu_init(int xres, unsigned int pixel_format, int gamma_fix)
+	/*
+	 * Allocate a memory block that holds the Area Descriptor and the
+	 * frame buffer right behind it.  To keep the code simple, everything
+	 * is aligned on a 32-byte address.
+	 */
+	if (allocate_buf(&addr, ad_size + size, 32) < 0)
+		return NULL;
+
+	ad = addr.vaddr;
+	ad->addr = cpu_to_le32(addr.paddr + ad_size);
+	ad->aoi_size = cpu_to_le32((yres << 16) | xres);
+	ad->src_size_g_alpha = cpu_to_le32((yres << 12) | xres);
+	ad->offset_xyi = 0;
+	ad->offset_xyd = 0;
+
+	if (fb)
+		*fb = addr.vaddr + ad_size;
+
+	return ad;
+}
+
+int fsl_diu_init(int xres, u32 pixel_format, int gamma_fix)
 {
 	struct fb_videomode *fsl_diu_mode_db;
-	struct diu_ad *ad = &fsl_diu_fb_ad;
-	struct diu *hw;
-	struct fb_info *info = &fsl_fb_info;
-	struct fb_var_screeninfo *var = &info->var;
-	unsigned char *gamma_table_base;
+	struct diu_ad *ad;
+	struct diu *hw = (struct diu *)CONFIG_SYS_DIU_ADDR;
+	u8 *gamma_table_base;
 	unsigned int i, j;
-
-	debug("Enter fsl_diu_init\n");
-	dr.diu_reg = (struct diu *) (CONFIG_SYS_DIU_ADDR);
-	hw = (struct diu *) dr.diu_reg;
-
-	disable_lcdc();
+	struct diu_ad *dummy_ad;
+	struct diu_addr gamma;
+	struct diu_addr cursor;
 
 	switch (xres) {
 	case 800:
@@ -235,65 +285,40 @@
 		fsl_diu_mode_db = &fsl_diu_mode_1024;
 	}
 
-	if (0 == fb_initialized) {
-		allocate_buf(&gamma, 768, 32);
-		debug("gamma is allocated @ 0x%x\n",
-			(unsigned int)gamma.paddr);
-		allocate_buf(&cursor, MAX_CURS * MAX_CURS * 2, 32);
-		debug("curosr is allocated @ 0x%x\n",
-			(unsigned int)cursor.paddr);
-
-		/* create a dummy fb and dummy ad */
-		dummy_fb = malloc(64);
-		if (NULL == dummy_fb) {
-			printf("Cannot allocate dummy fb\n");
-			return -1;
-		}
-		dummy_ad.addr = cpu_to_le32((unsigned int)dummy_fb);
-		dummy_ad.pix_fmt = 0x88882317;
-		dummy_ad.src_size_g_alpha = 0x04400000;	/* alpha = 0 */
-		dummy_ad.aoi_size = 0x02000400;
-		dummy_ad.offset_xyi = 0;
-		dummy_ad.offset_xyd = 0;
-		dummy_ad.next_ad = 0;
-		/* Memory allocation for framebuffer */
-		if (map_video_memory(info, 32)) {
-			printf("Unable to allocate fb memory 1\n");
-			return -1;
-		}
+	/* The AD struct for the dummy framebuffer and the FB itself */
+	dummy_ad = allocate_fb(2, 4, 4, NULL);
+	if (!dummy_ad) {
+		printf("DIU:   Out of memory\n");
+		return -1;
 	}
-
-	memset(info->screen_base, 0, info->smem_len);
-
-	out_be32(&dr.diu_reg->desc[0], (int)&dummy_ad);
-	out_be32(&dr.diu_reg->desc[1], (int)&dummy_ad);
-	out_be32(&dr.diu_reg->desc[2], (int)&dummy_ad);
-	debug("dummy dr.diu_reg->desc[0] = 0x%x\n", dr.diu_reg->desc[0]);
-	debug("dummy desc[0] = 0x%x\n", hw->desc[0]);
+	dummy_ad->pix_fmt = 0x88883316;
 
 	/* read mode info */
-	var->xres = fsl_diu_mode_db->xres;
-	var->yres = fsl_diu_mode_db->yres;
-	var->bits_per_pixel = 32;
-	var->pixclock = fsl_diu_mode_db->pixclock;
-	var->left_margin = fsl_diu_mode_db->left_margin;
-	var->right_margin = fsl_diu_mode_db->right_margin;
-	var->upper_margin = fsl_diu_mode_db->upper_margin;
-	var->lower_margin = fsl_diu_mode_db->lower_margin;
-	var->hsync_len = fsl_diu_mode_db->hsync_len;
-	var->vsync_len = fsl_diu_mode_db->vsync_len;
-	var->sync = fsl_diu_mode_db->sync;
-	var->vmode = fsl_diu_mode_db->vmode;
-	info->line_length = var->xres * var->bits_per_pixel / 8;
+	info.var.xres = fsl_diu_mode_db->xres;
+	info.var.yres = fsl_diu_mode_db->yres;
+	info.var.bits_per_pixel = 32;
+	info.var.pixclock = fsl_diu_mode_db->pixclock;
+	info.var.left_margin = fsl_diu_mode_db->left_margin;
+	info.var.right_margin = fsl_diu_mode_db->right_margin;
+	info.var.upper_margin = fsl_diu_mode_db->upper_margin;
+	info.var.lower_margin = fsl_diu_mode_db->lower_margin;
+	info.var.hsync_len = fsl_diu_mode_db->hsync_len;
+	info.var.vsync_len = fsl_diu_mode_db->vsync_len;
+	info.var.sync = fsl_diu_mode_db->sync;
+	info.var.vmode = fsl_diu_mode_db->vmode;
+	info.line_length = info.var.xres * info.var.bits_per_pixel / 8;
+
+	/* Memory allocation for framebuffer */
+	info.smem_len =
+		info.var.xres * info.var.yres * (info.var.bits_per_pixel / 8);
+	ad = allocate_fb(info.var.xres, info.var.yres,
+			 info.var.bits_per_pixel / 8, &info.screen_base);
+	if (!ad) {
+		printf("DIU:   Out of memory\n");
+		return -1;
+	}
 
 	ad->pix_fmt = pixel_format;
-	ad->addr    = cpu_to_le32((unsigned int)info->screen_base);
-	ad->src_size_g_alpha
-			= cpu_to_le32((var->yres << 12) | var->xres);
-	/* fix me. AOI should not be greater than display size */
-	ad->aoi_size	= cpu_to_le32(( var->yres << 16) |  var->xres);
-	ad->offset_xyi = 0;
-	ad->offset_xyd = 0;
 
 	/* Disable chroma keying function */
 	ad->ckmax_r = 0;
@@ -304,195 +329,91 @@
 	ad->ckmin_g = 255;
 	ad->ckmin_b = 255;
 
-	gamma_table_base = gamma.paddr;
-	debug("gamma_table_base is allocated @ 0x%x\n",
-		(unsigned int)gamma_table_base);
-
-	/* Prep for DIU init  - gamma table */
-
+	/* Initialize the gamma table */
+	if (allocate_buf(&gamma, 256 * 3, 32) < 0) {
+		printf("DIU:   Out of memory\n");
+		return -1;
+	}
+	gamma_table_base = gamma.vaddr;
 	for (i = 0; i <= 2; i++)
-		for (j = 0; j <= 255; j++)
+		for (j = 0; j < 256; j++)
 			*gamma_table_base++ = j;
 
 	if (gamma_fix == 1) {	/* fix the gamma */
-		debug("Fix gamma table\n");
-		gamma_table_base = gamma.paddr;
-		for (i = 0; i < 256*3; i++) {
+		gamma_table_base = gamma.vaddr;
+		for (i = 0; i < 256 * 3; i++) {
 			gamma_table_base[i] = (gamma_table_base[i] << 2)
 				| ((gamma_table_base[i] >> 6) & 0x03);
 		}
 	}
 
-	debug("update-lcdc: HW - %p\n Disabling DIU\n", hw);
+	/* Initialize the cursor */
+	if (allocate_buf(&cursor, 32 * 32 * 2, 32) < 0) {
+		printf("DIU:   Can't alloc cursor data\n");
+		return -1;
+	}
 
 	/* Program DIU registers */
+	out_be32(&hw->diu_mode, 0);	/* Temporarily disable the DIU */
 
-	out_be32(&hw->gamma, (int)gamma.paddr);
-	out_be32(&hw->cursor, (int)cursor.paddr);
+	out_be32(&hw->gamma, gamma.paddr);
+	out_be32(&hw->cursor, cursor.paddr);
 	out_be32(&hw->bgnd, 0x007F7F7F);
-	out_be32(&hw->bgnd_wb, 0);				/* BGND_WB */
-	out_be32(&hw->disp_size, var->yres << 16 | var->xres);	/* DISP SIZE */
-	out_be32(&hw->wb_size, 0);				/* WB SIZE */
-	out_be32(&hw->wb_mem_addr, 0);				/* WB MEM ADDR */
-	out_be32(&hw->hsyn_para, var->left_margin << 22 |	/* BP_H */
-			var->hsync_len << 11   |	/* PW_H */
-			var->right_margin);		/* FP_H */
+	out_be32(&hw->bgnd_wb, 0);
+	out_be32(&hw->disp_size, info.var.yres << 16 | info.var.xres);
+	out_be32(&hw->wb_size, 0);
+	out_be32(&hw->wb_mem_addr, 0);
+	out_be32(&hw->hsyn_para, info.var.left_margin << 22 |
+			info.var.hsync_len << 11 |
+			info.var.right_margin);
 
-	out_be32(&hw->vsyn_para, var->upper_margin << 22 |	/* BP_V */
-			var->vsync_len << 11    |	/* PW_V  */
-			var->lower_margin);		/* FP_V  */
+	out_be32(&hw->vsyn_para, info.var.upper_margin << 22 |
+			info.var.vsync_len << 11 |
+			info.var.lower_margin);
 
-	out_be32(&hw->syn_pol, 0);			/* SYNC SIGNALS POLARITY */
-	out_be32(&hw->thresholds, 0x00037800);		/* The Thresholds */
-	out_be32(&hw->int_status, 0);			/* INTERRUPT STATUS */
-	out_be32(&hw->int_mask, 0);			/* INT MASK */
+	out_be32(&hw->syn_pol, 0);
+	out_be32(&hw->thresholds, 0x00037800);
+	out_be32(&hw->int_status, 0);
+	out_be32(&hw->int_mask, 0);
 	out_be32(&hw->plut, 0x01F5F666);
 	/* Pixel Clock configuration */
-	debug("DIU pixclock in ps - %d\n", var->pixclock);
-	diu_set_pixel_clock(var->pixclock);
+	diu_set_pixel_clock(info.var.pixclock);
 
-	fb_initialized = 1;
+	/* Set the frame buffers */
+	out_be32(&hw->desc[0], virt_to_phys(ad));
+	out_be32(&hw->desc[1], virt_to_phys(dummy_ad));
+	out_be32(&hw->desc[2], virt_to_phys(dummy_ad));
 
-	/* Enable the DIU */
-	fsl_diu_enable_panel(info);
-	enable_lcdc();
+	/* Enable the DIU, set display to all three planes */
+	out_be32(&hw->diu_mode, 1);
 
 	return 0;
 }
 
-char *fsl_fb_open(struct fb_info **info)
-{
-	*info = &fsl_fb_info;
-	return fsl_fb_info.screen_base;
-}
-
-void fsl_diu_close(void)
-{
-	struct fb_info *info = &fsl_fb_info;
-	fsl_diu_disable_panel(info);
-}
-
-static int fsl_diu_enable_panel(struct fb_info *info)
-{
-	struct diu *hw = dr.diu_reg;
-	struct diu_ad *ad = &fsl_diu_fb_ad;
-
-	debug("Entered: enable_panel\n");
-	if (in_be32(&hw->desc[0]) != (unsigned)ad)
-		out_be32(&hw->desc[0], (unsigned)ad);
-	debug("desc[0] = 0x%x\n", hw->desc[0]);
-	return 0;
-}
-
-static int fsl_diu_disable_panel(struct fb_info *info)
-{
-	struct diu *hw = dr.diu_reg;
-
-	debug("Entered: disable_panel\n");
-	if (in_be32(&hw->desc[0]) != (unsigned)&dummy_ad)
-		out_be32(&hw->desc[0], (unsigned)&dummy_ad);
-	return 0;
-}
-
-static int map_video_memory(struct fb_info *info, unsigned long bytes_align)
-{
-	unsigned long offset;
-	unsigned long mask;
-
-	debug("Entered: map_video_memory\n");
-	/* allocate maximum 1280*1024 with 32bpp */
-	info->smem_len = 1280 * 4 *1024 + bytes_align;
-	debug("MAP_VIDEO_MEMORY: smem_len = %d\n", info->smem_len);
-	info->screen_base = malloc(info->smem_len);
-	if (info->screen_base == NULL) {
-		printf("Unable to allocate fb memory\n");
-		return -1;
-	}
-	info->smem_start = (unsigned int) info->screen_base;
-	mask = bytes_align - 1;
-	offset = (unsigned long)info->screen_base & mask;
-	if (offset) {
-		info->screen_base += (bytes_align - offset);
-		info->smem_len = info->smem_len - (bytes_align - offset);
-	} else
-		info->smem_len = info->smem_len - bytes_align;
-
-	info->screen_size = info->smem_len;
-
-	debug("Allocated fb @ 0x%08lx, size=%d.\n",
-		info->smem_start, info->smem_len);
-
-	return 0;
-}
-
-static void enable_lcdc(void)
-{
-	struct diu *hw = dr.diu_reg;
-
-	debug("Entered: enable_lcdc, fb_enabled = %d\n", fb_enabled);
-	if (!fb_enabled) {
-		out_be32(&hw->diu_mode, dr.mode);
-		fb_enabled++;
-	}
-	debug("diu_mode = %d\n", hw->diu_mode);
-}
-
-static void disable_lcdc(void)
-{
-	struct diu *hw = dr.diu_reg;
-
-	debug("Entered: disable_lcdc, fb_enabled = %d\n", fb_enabled);
-	if (fb_enabled) {
-		out_be32(&hw->diu_mode, 0);
-		fb_enabled = 0;
-	}
-}
-
-/*
- * Align to 64-bit(8-byte), 32-byte, etc.
- */
-static int allocate_buf(struct diu_addr *buf, u32 size, u32 bytes_align)
-{
-	u32 offset, ssize;
-	u32 mask;
-
-	debug("Entered: allocate_buf\n");
-	ssize = size + bytes_align;
-	buf->paddr = malloc(ssize);
-	if (!buf->paddr)
-		return -1;
-
-	memset(buf->paddr, 0, ssize);
-	mask = bytes_align - 1;
-	offset = (u32)buf->paddr & mask;
-	if (offset) {
-		buf->offset = bytes_align - offset;
-		buf->paddr = (unsigned char *) ((u32)buf->paddr + offset);
-	} else
-		buf->offset = 0;
-	return 0;
-}
-
-#if defined(CONFIG_VIDEO) || defined(CONFIG_CFB_CONSOLE)
-#include <stdio_dev.h>
-#include <video_fb.h>
-/*
- * The Graphic Device
- */
-static GraphicDevice ctfb;
-
 void *video_hw_init(void)
 {
-	struct fb_info *info;
+	static GraphicDevice ctfb;
+	const char *options;
+	unsigned int depth = 0, freq = 0;
 
-	if (platform_diu_init(&ctfb.winSizeX, &ctfb.winSizeY) < 0)
+	if (!video_get_video_mode(&ctfb.winSizeX, &ctfb.winSizeY, &depth, &freq,
+				  &options))
+		return NULL;
+
+	/* Find the monitor port, which is a required option */
+	if (!options)
+		return NULL;
+	if (strncmp(options, "monitor=", 8) != 0)
+		return NULL;
+
+	if (platform_diu_init(ctfb.winSizeX, ctfb.winSizeY, options + 8) < 0)
 		return NULL;
 
 	/* fill in Graphic device struct */
 	sprintf(ctfb.modeIdent, "%ix%ix%i %ikHz %iHz",
-		ctfb.winSizeX, ctfb.winSizeY, 32, 64, 60);
+		ctfb.winSizeX, ctfb.winSizeY, depth, 64, freq);
 
-	ctfb.frameAdrs = (unsigned int)fsl_fb_open(&info);
+	ctfb.frameAdrs = (unsigned int)info.screen_base;
 	ctfb.plnSizeX = ctfb.winSizeX;
 	ctfb.plnSizeY = ctfb.winSizeY;
 
@@ -501,7 +422,7 @@
 
 	ctfb.isaBase = 0;
 	ctfb.pciBase = 0;
-	ctfb.memSize = info->screen_size;
+	ctfb.memSize = info.screen_size;
 
 	/* Cursor Start Address */
 	ctfb.dprBase = 0;
@@ -510,4 +431,3 @@
 
 	return &ctfb;
 }
-#endif /* defined(CONFIG_VIDEO) || defined(CONFIG_CFB_CONSOLE) */
diff --git a/drivers/video/videomodes.c b/drivers/video/videomodes.c
index d27ce1d..6fe5811 100644
--- a/drivers/video/videomodes.c
+++ b/drivers/video/videomodes.c
@@ -1,6 +1,7 @@
 /*
  * (C) Copyright 2004
  * Pierre Aubert, Staubli Faverges , <p.aubert@staubli.com>
+ * Copyright 2011 Freescale Semiconductor, Inc.
  *
  * See file CREDITS for list of people who contributed to this
  * project.
@@ -73,6 +74,8 @@
 ****************************************************************************/
 
 #include <common.h>
+#include <linux/ctype.h>
+
 #include "videomodes.h"
 
 const struct ctfb_vesa_modes vesa_modes[VESA_MODES_COUNT] = {
@@ -206,3 +209,64 @@
 	}
 	return bpp;
 }
+
+/*
+ * Parse the 'video-mode' environment variable
+ *
+ * Example: "video-mode=fslfb:1280x1024-32@60,monitor=dvi".  See
+ * doc/README.video for more information on how to set the variable.
+ *
+ * @xres: returned value of X-resolution
+ * @yres: returned value of Y-resolution
+ * @depth: returned value of color depth
+ * @freq: returned value of monitor frequency
+ * @options: pointer to any remaining options, or NULL
+ *
+ * Returns 1 if valid values were found, 0 otherwise
+ */
+int video_get_video_mode(unsigned int *xres, unsigned int *yres,
+	unsigned int *depth, unsigned int *freq, const char **options)
+{
+	char *p = getenv("video-mode");
+	if (!p)
+		return 0;
+
+	/* Skip over the driver name, which we don't care about. */
+	p = strchr(p, ':');
+	if (!p)
+		return 0;
+
+	/* Get the X-resolution*/
+	while (*p && !isdigit(*p))
+		p++;
+	*xres = simple_strtoul(p, &p, 10);
+	if (!*xres)
+		return 0;
+
+	/* Get the Y-resolution */
+	while (*p && !isdigit(*p))
+		p++;
+	*yres = simple_strtoul(p, &p, 10);
+	if (!*yres)
+		return 0;
+
+	/* Get the depth */
+	while (*p && !isdigit(*p))
+		p++;
+	*depth = simple_strtoul(p, &p, 10);
+	if (!*depth)
+		return 0;
+
+	/* Get the frequency */
+	while (*p && !isdigit(*p))
+		p++;
+	*freq = simple_strtoul(p, &p, 10);
+	if (!*freq)
+		return 0;
+
+	/* Find the extra options, if any */
+	p = strchr(p, ',');
+	*options = p ? p + 1 : NULL;
+
+	return 1;
+}
diff --git a/drivers/video/videomodes.h b/drivers/video/videomodes.h
index 0d7c335..e546ab4 100644
--- a/drivers/video/videomodes.h
+++ b/drivers/video/videomodes.h
@@ -86,3 +86,6 @@
 extern const struct ctfb_res_modes res_mode_init[];
 
 int video_get_params (struct ctfb_res_modes *pPar, char *penv);
+
+int video_get_video_mode(unsigned int *xres, unsigned int *yres,
+	unsigned int *depth, unsigned int *freq, const char **options);
diff --git a/include/common.h b/include/common.h
index 21c05db..00e266e 100644
--- a/include/common.h
+++ b/include/common.h
@@ -449,6 +449,11 @@
 #if defined (CONFIG_MPC83xx)
 void		ppcDWload(unsigned int *addr, unsigned int *ret);
 void		ppcDWstore(unsigned int *addr, unsigned int *value);
+void disable_addr_trans(void);
+void enable_addr_trans(void);
+#if defined(CONFIG_DDR_ECC) && !defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER)
+void ddr_enable_ecc(unsigned int dram_size);
+#endif
 #endif
 
 /* $(CPU)/cpu.c */
diff --git a/include/configs/MPC8610HPCD.h b/include/configs/MPC8610HPCD.h
index efe0313..31dbc3b 100644
--- a/include/configs/MPC8610HPCD.h
+++ b/include/configs/MPC8610HPCD.h
@@ -1,5 +1,5 @@
 /*
- * Copyright 2007, 2010 Freescale Semiconductor, Inc.
+ * Copyright 2007-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
@@ -23,6 +23,8 @@
 
 
 /* video */
+#define CONFIG_FSL_DIU_FB
+
 #ifdef CONFIG_FSL_DIU_FB
 #define CONFIG_SYS_DIU_ADDR	(CONFIG_SYS_CCSRBAR + 0x2c000)
 #define CONFIG_VIDEO
@@ -625,8 +627,6 @@
  "diuregs=md e002c000 1d\0" \
  "dium=mw e002c01c\0" \
  "diuerr=md e002c014 1\0" \
- "othbootargs=diufb=15M video=fslfb:1280x1024-32@60,monitor=0 debug\0" \
- "monitor=0-DVI\0" \
  "pmregs=md e00e1000 2b\0" \
  "lawregs=md e0000c08 4b\0" \
  "lbcregs=md e0005000 36\0" \
@@ -646,9 +646,7 @@
  "ramdiskfile=8610hpcd/ramdisk.uboot\0"                         \
  "fdtaddr=c00000\0"                                             \
  "fdtfile=8610hpcd/mpc8610_hpcd.dtb\0"                          \
- "bdev=sda3\0"							\
- "othbootargs=diufb=15M video=fslfb:1280x1024-32@60,monitor=0\0"\
- "monitor=0-DVI\0"
+ "bdev=sda3\0"
 #endif
 
 #define CONFIG_NFSBOOTCOMMAND					\
diff --git a/include/configs/P1022DS.h b/include/configs/P1022DS.h
index 362abe8..a118975 100644
--- a/include/configs/P1022DS.h
+++ b/include/configs/P1022DS.h
@@ -204,6 +204,8 @@
 #define CONFIG_SYS_PROMPT_HUSH_PS2 "> "
 
 /* Video */
+#define CONFIG_FSL_DIU_FB
+
 #ifdef CONFIG_FSL_DIU_FB
 #define CONFIG_SYS_DIU_ADDR	(CONFIG_SYS_CCSRBAR + 0x10000)
 #define CONFIG_VIDEO
@@ -221,7 +223,7 @@
 #undef CONFIG_SYS_FLASH_EMPTY_INFO
 #endif
 
-#ifndef CONFIG_DIU
+#ifndef CONFIG_FSL_DIU_FB
 #define CONFIG_ATI
 #endif
 
@@ -522,9 +524,7 @@
 	"diuregs=md e002c000 1d\0"			 		\
 	"dium=mw e002c01c\0" 						\
 	"diuerr=md e002c014 1\0" 					\
-	"othbootargs=diufb=15M video=fslfb:1280x1024-32@60,monitor=0 tty0\0" \
-	"hwconfig=esdhc;audclk:12\0"					\
-	"monitor=0-DVI\0"
+	"hwconfig=esdhc;audclk:12\0"
 
 #define CONFIG_HDBOOT					\
 	"setenv bootargs root=/dev/$bdev rw "		\
diff --git a/include/configs/a320evb.h b/include/configs/a320evb.h
index 4b297f0..0527822 100644
--- a/include/configs/a320evb.h
+++ b/include/configs/a320evb.h
@@ -197,7 +197,6 @@
 	{ FTSMC020_BANK0_CONFIG, FTSMC020_BANK0_TIMING, },	\
 	{ FTSMC020_BANK1_CONFIG, FTSMC020_BANK1_TIMING, },	\
 }
-#endif /* CONFIG_FTSMC020 */
 
 /*-----------------------------------------------------------------------
  * FLASH and environment organization
diff --git a/include/configs/ca9x4_ct_vxp.h b/include/configs/ca9x4_ct_vxp.h
index 2a87a79..7f83249 100644
--- a/include/configs/ca9x4_ct_vxp.h
+++ b/include/configs/ca9x4_ct_vxp.h
@@ -44,6 +44,8 @@
 #define CONFIG_L2_OFF			1
 #define CONFIG_INITRD_TAG		1
 
+#define CONFIG_OF_LIBFDT		1
+
 /* Size of malloc() pool */
 #define CONFIG_SYS_MALLOC_LEN		(CONFIG_ENV_SIZE + 128 * 1024)
 
@@ -87,6 +89,10 @@
 #define CONFIG_MMC			1
 #define CONFIG_CMD_MMC
 #define CONFIG_GENERIC_MMC
+#define CONFIG_ARM_PL180_MMCI
+#define CONFIG_ARM_PL180_MMCI_BASE	0x10005000
+#define CONFIG_SYS_MMC_MAX_BLK_COUNT	127
+#define CONFIG_ARM_PL180_MMCI_CLOCK_FREQ 6250000
 
 /* BOOTP options */
 #define CONFIG_BOOTP_BOOTFILESIZE
diff --git a/include/configs/devkit8000.h b/include/configs/devkit8000.h
index 4ba3d91..e02793d 100644
--- a/include/configs/devkit8000.h
+++ b/include/configs/devkit8000.h
@@ -61,6 +61,8 @@
 #define CONFIG_INITRD_TAG		1
 #define CONFIG_REVISION_TAG		1
 
+#define CONFIG_OF_LIBFDT		1
+
 /* Size of malloc() pool */
 #define CONFIG_ENV_SIZE			(128 << 10)	/* 128 KiB */
 						/* Sector */
diff --git a/include/configs/efikamx.h b/include/configs/efikamx.h
index 1424347..571c3cb 100644
--- a/include/configs/efikamx.h
+++ b/include/configs/efikamx.h
@@ -66,6 +66,8 @@
 #define CONFIG_SETUP_MEMORY_TAGS
 #define CONFIG_INITRD_TAG
 
+#define CONFIG_OF_LIBFDT		1
+
 /*
  * Size of malloc() pool
  */
diff --git a/include/configs/igep0020.h b/include/configs/igep0020.h
index fc15a9c..5af9bec 100644
--- a/include/configs/igep0020.h
+++ b/include/configs/igep0020.h
@@ -53,6 +53,8 @@
 #define CONFIG_INITRD_TAG		1
 #define CONFIG_REVISION_TAG		1
 
+#define CONFIG_OF_LIBFDT		1
+
 /*
  * NS16550 Configuration
  */
diff --git a/include/configs/igep0030.h b/include/configs/igep0030.h
index 713b1b9..92144af 100644
--- a/include/configs/igep0030.h
+++ b/include/configs/igep0030.h
@@ -53,6 +53,8 @@
 #define CONFIG_INITRD_TAG		1
 #define CONFIG_REVISION_TAG		1
 
+#define CONFIG_OF_LIBFDT		1
+
 /*
  * NS16550 Configuration
  */
diff --git a/include/configs/keymile-common.h b/include/configs/keymile-common.h
index e3bd264..cb6d0fb 100644
--- a/include/configs/keymile-common.h
+++ b/include/configs/keymile-common.h
@@ -1,5 +1,5 @@
 /*
- * (C) Copyright 2008
+ * (C) Copyright 2008-2011
  * Heiko Schocher, DENX Software Engineering, hs@denx.de.
  *
  * See file CREDITS for list of people who contributed to this
@@ -25,7 +25,8 @@
 #define __CONFIG_KEYMILE_H
 
 /* Do boardspecific init for all boards */
-#define CONFIG_BOARD_EARLY_INIT_R       1
+#define CONFIG_BOARD_EARLY_INIT_R
+#define CONFIG_LAST_STAGE_INIT
 
 #define CONFIG_BOOTCOUNT_LIMIT
 
@@ -39,13 +40,6 @@
 #endif /* CONFIG_SYS_KWD_CONFIG */
 
 /*
- * CONFIG_SYS_TEXT_BASE can be defined in board specific header file, if needed
- */
-#ifndef CONFIG_SYS_TEXT_BASE
-#define	CONFIG_SYS_TEXT_BASE	0x00400000
-#endif /* CONFIG_SYS_TEXT_BASE */
-
-/*
  * Command line configuration.
  */
 #include <config_cmd_default.h>
@@ -56,51 +50,46 @@
 #define CONFIG_CMD_IMMAP
 #define CONFIG_CMD_MII
 #define CONFIG_CMD_PING
-#define CONFIG_CMD_DTT
 #define CONFIG_CMD_EEPROM
 #define CONFIG_CMD_I2C
 #define CONFIG_CMD_JFFS2
-#define CONFIG_JFFS2_CMDLINE
 #define CONFIG_CMD_MTDPARTS
+#define CONFIG_CMD_SETEXPR
 
-#undef	CONFIG_WATCHDOG			/* disable platform specific watchdog */
+#undef	CONFIG_WATCHDOG		/* disable platform specific watchdog */
 
-#define CONFIG_BOOTDELAY	5	/* autoboot after 5 seconds */
-#undef	CONFIG_BOOTARGS			/* the boot command will set bootargs */
+#define CONFIG_BOOTDELAY	2 /* autoboot after 2 seconds */
+#undef	CONFIG_BOOTARGS		/* the boot command will set bootargs */
 
 /*
  * Miscellaneous configurable options
  */
 #define CONFIG_SYS_HUSH_PARSER
 #define CONFIG_SYS_PROMPT_HUSH_PS2	"> "
-#define CONFIG_SYS_LONGHELP			/* undef to save memory	    */
-#define CONFIG_SYS_PROMPT		"=> "	/* Monitor Command Prompt   */
+#define CONFIG_SYS_LONGHELP			/* undef to save memory	  */
+#define CONFIG_SYS_PROMPT		"=> "	/* Monitor Command Prompt */
 #if defined(CONFIG_CMD_KGDB)
-#define CONFIG_SYS_CBSIZE		1024	/* Console I/O Buffer Size  */
+#define CONFIG_SYS_CBSIZE		1024	/* Console I/O Buffer Size */
 #else
-#define CONFIG_SYS_CBSIZE		256	/* Console I/O Buffer Size  */
+#define CONFIG_SYS_CBSIZE		512	/* Console I/O Buffer Size  */
 #endif
-#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE+sizeof(CONFIG_SYS_PROMPT)+16)	/* Print Buffer Size  */
-#define CONFIG_SYS_MAXARGS		16	/* max number of command args */
-#define CONFIG_SYS_BARGSIZE		CONFIG_SYS_CBSIZE	/* Boot Argument Buffer Size  */
-#define CONFIG_CMDLINE_EDITING		1	/* add command line history     */
-#define CONFIG_AUTO_COMPLETE		/* add autocompletion support	*/
+#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE+sizeof(CONFIG_SYS_PROMPT)+16)
+#define CONFIG_SYS_MAXARGS		32 /* max number of command args */
+#define CONFIG_SYS_BARGSIZE		CONFIG_SYS_CBSIZE
+#define CONFIG_CMDLINE_EDITING
+#define CONFIG_AUTO_COMPLETE
 
-#define CONFIG_HUSH_INIT_VAR	1
+#define CONFIG_HUSH_INIT_VAR
 
 #define CONFIG_SYS_ALT_MEMTEST		/* memory test, takes time */
-#define CONFIG_SYS_MEMTEST_START	0x00100000	/* memtest works on */
-#define CONFIG_SYS_MEMTEST_END		0x00f00000	/* 1 ... 15 MB in DRAM	*/
 
-#define CONFIG_SYS_LOAD_ADDR		0x100000	/* default load address */
+#define CONFIG_SYS_HZ			1000	/* decr. freq: 1 ms ticks */
 
-#define CONFIG_SYS_HZ			1000	/* decrementer freq: 1 ms ticks */
-
-#define CONFIG_BAUDRATE		115200
+#define CONFIG_BAUDRATE			115200
 #define CONFIG_SYS_BAUDRATE_TABLE	{ 9600, 19200, 38400, 57600, 115200, 230400 }
 
-#define CONFIG_LOADS_ECHO	1	/* echo on for serial download */
-#define CONFIG_SYS_LOADS_BAUD_CHANGE	1	/* allow baudrate change */
+#define CONFIG_LOADS_ECHO
+#define CONFIG_SYS_LOADS_BAUD_CHANGE
 #define CONFIG_SYS_BOARD_DRAM_INIT	/* Used board specific dram_init */
 
 /*
@@ -108,28 +97,28 @@
  * to modify in a centralized location.  This is used in the HDLC
  * driver to set the MAC.
 */
-#define CONFIG_CHECK_ETHERNET_PRESENT	1
-#define CONFIG_SYS_SLOT_ID_BASE		CONFIG_SYS_PIGGY_BASE
+#define CONFIG_CHECK_ETHERNET_PRESENT
+#define CONFIG_SYS_SLOT_ID_BASE		CONFIG_SYS_KMBEC_FPGA_BASE
 #define CONFIG_SYS_SLOT_ID_OFF		(0x07)	/* register offset */
 #define CONFIG_SYS_SLOT_ID_MASK		(0x3f)	/* mask for slot ID bits */
 
-#define CONFIG_I2C_MULTI_BUS	1
+#define CONFIG_I2C_MULTI_BUS
 #define CONFIG_SYS_MAX_I2C_BUS		1
-#define CONFIG_SYS_I2C_INIT_BOARD	1
-#define CONFIG_I2C_MUX		1
+#define CONFIG_SYS_I2C_INIT_BOARD
+#define CONFIG_I2C_MUX
 
 /* EEprom support */
-#define CONFIG_SYS_I2C_MULTI_EEPROMS	1
+#define CONFIG_SYS_I2C_MULTI_EEPROMS
 #define CONFIG_SYS_EEPROM_PAGE_WRITE_ENABLE
-#define CONFIG_SYS_EEPROM_PAGE_WRITE_BITS 3
-#define CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS 10
+#define CONFIG_SYS_EEPROM_PAGE_WRITE_BITS	3
+#define CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS	10
 
 /* Support the IVM EEprom */
 #define	CONFIG_SYS_IVM_EEPROM_ADR	0x50
 #define CONFIG_SYS_IVM_EEPROM_MAX_LEN	0x400
 #define CONFIG_SYS_IVM_EEPROM_PAGE_LEN	0x100
 
-#define	CONFIG_SYS_FLASH_PROTECTION 1
+#define	CONFIG_SYS_FLASH_PROTECTION
 
 /*
  * BOOTP options
@@ -139,139 +128,325 @@
 #define CONFIG_BOOTP_GATEWAY
 #define CONFIG_BOOTP_HOSTNAME
 
-#define CONFIG_ENV_SIZE		0x04000 /* Size of Environment */
-
-#define CONFIG_SYS_MALLOC_LEN	(4 * 1024 * 1024)
+#define CONFIG_SYS_MALLOC_LEN		(4 * 1024 * 1024)
 
 /* UBI Support for all Keymile boards */
 #define CONFIG_CMD_UBI
 #define CONFIG_RBTREE
 #define CONFIG_MTD_PARTITIONS
-#define CONFIG_FLASH_CFI_MTD
 #define CONFIG_MTD_DEVICE
 #define CONFIG_MTD_CONCAT
 
-/* define this to use the keymile's io muxing feature */
-/*#define CONFIG_IO_MUXING */
-
-#ifdef CONFIG_IO_MUXING
-#define	CONFIG_KM_DEF_ENV_IOMUX \
-	"nc=setenv ethact HDLC \0" \
-	"nce=setenv ethact SCC \0"	\
-	"stderr=serial,nc \0"	\
-	"stdin=serial,nc \0" \
-	"stdout=serial,nc \0" \
-	"tftpsrcp=69 \0" \
-	"tftpdstp=69 \0"
-#else
-#define	CONFIG_KM_DEF_ENV_IOMUX \
-	"stderr=serial \0" \
-	"stdin=serial \0"	 \
-	"stdout=serial \0"
+/* common powerpc specific env settings */
+#ifndef CONFIG_KM_DEF_ENV_BOOTPARAMS
+#define CONFIG_KM_DEF_ENV_BOOTPARAMS \
+	"bootparams=empty\0"	\
+	"initial_boot_bank=0\0"
 #endif
 
-#ifndef CONFIG_KM_DEF_ENV_PRIVATE
-#define	CONFIG_KM_DEF_ENV_PRIVATE \
-	"kmprivate=empty\0"
+#ifndef CONFIG_KM_DEF_NETDEV
+#define CONFIG_KM_DEF_NETDEV	\
+	"netdev=eth0\0"
+#endif
+
+#ifndef CONFIG_KM_UBI_PARTITION_NAME
+#define CONFIG_KM_UBI_PARTITION_NAME	"ubi0"
+#endif
+#ifndef CONFIG_KM_UBI_LINUX_MTD_NAME
+#define CONFIG_KM_UBI_LINUX_MTD_NAME	"ubi0"
 #endif
 
 #define xstr(s)	str(s)
 #define str(s)	#s
 
+/*
+ * bootrunner
+ * - run all commands in 'subbootcmds'
+ * - on error, stop running the remaing commands
+ */
+#define CONFIG_KM_DEF_ENV_BOOTRUNNER					\
+	"bootrunner="							\
+		"break=0; "						\
+		"for subbootcmd in ${subbootcmds}; do "			\
+		"if test ${break} -eq 0; then; "			\
+		"echo \"[INFO] running \\c\"; "				\
+		"print ${subbootcmd}; "					\
+		"run ${subbootcmd} || break=1; "			\
+		"if test ${break} -eq 1; then; "			\
+		"echo \"[ERR] failed \\c\"; "				\
+		"print ${subbootcmd}; "					\
+		"fi; "							\
+		"fi; "							\
+		"done\0"						\
+	""
+
+/*
+ * boottargets
+ * - set 'subbootcmds' for the bootrunner
+ * - set 'bootcmd' and 'altbootcmd'
+ * available targets:
+ * - 'release': for a standalone system		kernel/rootfs from flash
+ * - 'develop': for development			kernel(tftp)/rootfs(NFS)
+ * - 'ramfs': rootfilesystem in RAM		kernel(tftp)/rootfs(RAM)
+ *
+ * - 'commonargs': bootargs common to all targets
+ */
+#define CONFIG_KM_DEF_ENV_BOOTTARGETS					\
+	"commonargs="							\
+		"addip "						\
+		"addtty "						\
+		"addmem "						\
+		"addinit "						\
+		"addvar "						\
+		"addmtdparts "						\
+		"addbootcount "						\
+		"\0"							\
+	"develop="							\
+		"setenv subbootcmds \""					\
+		"tftpfdt tftpkernel "					\
+		"nfsargs ${commonargs} "				\
+		"printbootargs boot "					\
+		"\" && "						\
+		"setenv bootcmd \'"					\
+		"run bootrunner"					\
+		"\' && "						\
+		"setenv altbootcmd \'"					\
+		"run bootcmd"						\
+		"\' && "						\
+		"run setboardid && "					\
+		"saveenv && "						\
+		"reset\0"						\
+	"ramfs="							\
+		"setenv actual_bank -1 && "				\
+		"setenv subbootcmds \""					\
+		"tftpfdt tftpkernel "					\
+		"setrootfsaddr tftpramfs "				\
+		"flashargs ${commonargs} "				\
+		"addpanic addramfs "					\
+		"printbootargs boot "					\
+		"\" && "						\
+		"setenv bootcmd \'"					\
+		"run bootrunner"					\
+		"\' && "						\
+		"setenv altbootcmd \'"					\
+		"run bootcmd"						\
+		"\' && "						\
+		"run setboardid && "					\
+		"run setramfspram && "					\
+		"saveenv && "						\
+		"reset\0"						\
+	"release="							\
+		"setenv actual_bank ${initial_boot_bank} && "		\
+		"setenv subbootcmds \""					\
+		"checkboardidlist "					\
+		"checkboardid "						\
+		"ubiattach ubicopy "					\
+		"cramfsloadfdt cramfsloadkernel "			\
+		"flashargs ${commonargs} "				\
+		"addpanic "						\
+		"printbootargs boot "					\
+		"\" && "						\
+		"setenv bootcmd \'"					\
+		"run bootrunner; reset"					\
+		"\' && "						\
+		"setenv altbootcmd \'"					\
+		"run actual0 bootcmd; reset"				\
+		"\' && "						\
+		"saveenv && "						\
+		"reset\0"						\
+	""
+
+/*
+ * bootargs
+ * - modify 'bootargs'
+ *
+ * - 'addip': add ip configuration
+ * - 'addmem': limit kernel memory mem=
+ * - 'addpanic': add kernel panic options
+ * - 'addramfs': add phram device for the rootfilesysten in ram
+ * - 'addtty': add console=...
+ * - 'addvar': add phram device for /var
+ * - 'nfsargs': default arguments for nfs boot
+ * - 'flashargs': defaults arguments for flash base boot
+ *
+ * processor specific settings
+ * - 'addbootcount': add boot counter
+ * - 'addmtdparts': add mtd partition information
+ */
+#define CONFIG_KM_DEF_ENV_BOOTARGS					\
+	"addinit="							\
+		"setenv bootargs ${bootargs} init=${init}\0"		\
+	"addip="							\
+		"setenv bootargs ${bootargs} "				\
+		"ip=${ipaddr}:${serverip}:${gatewayip}:${netmask}"	\
+		":${hostname}:${netdev}:off\0"				\
+	"addmem="							\
+		"setenv bootargs ${bootargs} mem=0x${pnvramaddr}\0"	\
+	"addpanic="							\
+		"setenv bootargs ${bootargs} "				\
+		"panic=1 panic_on_oops=1\0"				\
+	"addramfs="							\
+		"setenv bootargs \""					\
+		"${bootargs} phram.phram="				\
+		"rootfs${actual_bank},${rootfsaddr},${rootfssize}\"\0"	\
+	"addtty="							\
+		"setenv bootargs ${bootargs}"				\
+		" console=" CONFIG_KM_CONSOLE_TTY ",${baudrate}\0"	\
+	"addvar="							\
+		"setenv bootargs ${bootargs} phram.phram=phvar,"	\
+		"${varaddr},0x" xstr(CONFIG_KM_PHRAM) "\0"		\
+	"nfsargs="							\
+		"setenv bootargs "					\
+		"ubi.mtd=" CONFIG_KM_UBI_LINUX_MTD_NAME " "		\
+		"root=/dev/nfs rw "					\
+		"nfsroot=${serverip}:${rootpath}\0"			\
+	"flashargs="							\
+		"setenv bootargs "					\
+		"ubi.mtd=" CONFIG_KM_UBI_LINUX_MTD_NAME " "		\
+		"root=mtdblock:rootfs${actual_bank} "			\
+		"rootfstype=squashfs ro\0"				\
+	""
+
+/*
+ * compute_addr
+ * - compute addresses and sizes
+ * - addresses are calculated form the end of memory 'memsize'
+ *
+ * - 'setramfspram': compute PRAM size for ramfs target
+ * - 'setrootfsaddr': compute rootfilesystem address for phram
+ */
+#define CONFIG_KM_DEF_ENV_COMPUTE_ADDR					\
+	"setboardid="							\
+		"if test \"x${boardId}\" = \"x\"; then; "		\
+		"setenv boardId ${IVM_BoardId} && "			\
+		"setenv hwKey ${IVM_HWKey}; "				\
+		"else; "						\
+		"echo \\\\c; "						\
+		"fi\0"							\
+	"setramfspram="							\
+		"setexpr value ${rootfssize} / 0x400 && "		\
+		"setexpr value 0x${value} + ${pram} && "		\
+		"setenv pram 0x${value}\0"				\
+	"setrootfsaddr="						\
+		"setexpr value ${pnvramaddr} - ${rootfssize} && "	\
+		"setenv rootfsaddr 0x${value}\0"			\
+	""
+
+/*
+ * flash_boot
+ * - commands for booting from flash
+ *
+ * - 'cramfsaddr': address to the cramfs (in ram)
+ * - 'cramfsloadkernel': copy kernel from a cramfs to ram
+ * - 'ubiattach': attach ubi partition
+ * - 'ubicopy': copy ubi volume to ram
+ *              - volume names: bootfs0, bootfs1, bootfs2, ...
+ * - 'ubiparition': mtd parition name for ubi
+ *
+ * processor specific settings
+ * - 'cramfsloadfdt': copy fdt from a cramfs to ram
+ */
+#define CONFIG_KM_DEF_ENV_FLASH_BOOT					\
+	"cramfsaddr="xstr(CONFIG_KM_CRAMFS_ADDR) "\0"			\
+	"cramfsloadkernel="						\
+		"cramfsload ${kernel_addr_r} uImage && "		\
+		"setenv actual_kernel_addr ${kernel_addr_r}\0"		\
+	"ubiattach=ubi part ${ubipartition}\0"				\
+	"ubicopy=ubi read ${cramfsaddr} bootfs${actual_bank}\0"		\
+	"ubipartition=" CONFIG_KM_UBI_PARTITION_NAME "\0"		\
+	""
+
+/*
+ * net_boot
+ * - commands for booting over the network
+ *
+ * - 'tftpkernel': load a kernel with tftp into ram
+ * - 'tftpramfs': load rootfs with tftp into ram
+ *
+ * processor specific settings
+ * - 'tftpfdt': load fdt with tftp into ram
+ */
+#define CONFIG_KM_DEF_ENV_NET_BOOT					\
+	"tftpkernel="							\
+		"tftpboot ${kernel_addr_r} ${kernel_file} && "		\
+		"setenv actual_kernel_addr ${kernel_addr_r}\0"		\
+	"tftpramfs="							\
+		"tftpboot ${rootfsaddr} \"\\\"${rootfsfile}\\\"\" && "	\
+		"setenv loadaddr\0"					\
+	""
+
+/*
+ * constants
+ * - KM specific constants and commands
+ *
+ * - 'default': setup default environment
+ */
+#define CONFIG_KM_DEF_ENV_CONSTANTS					\
+	"actual=setenv actual_bank ${initial_boot_bank}\0"		\
+	"actual0=setenv actual_bank 0\0"				\
+	"actual_bank=${initial_boot_bank}\0"				\
+	"default="							\
+		"setenv default 'run newenv; reset' &&  "		\
+		"run release && saveenv; reset\0"			\
+	"checkboardidlist="						\
+		"if test \"x${boardIdListHex}\" != \"x\"; then "	\
+		"IVMbidhwk=${IVM_BoardId}_${IVM_HWKey}; "		\
+		"found=0; "						\
+		"for bidhwk in \"${boardIdListHex}\"; do "		\
+		"echo trying $bidhwk ...; "				\
+		"if test \"x$bidhwk\" = \"x$IVMbidhwk\"; then "		\
+		"found=1; "						\
+		"echo match found for $bidhwk; "			\
+		"if test \"x$bidhwk\" != \"x${boardId}_${hwKey}\";then "\
+			"setenv boardid ${IVM_BoardId}; "		\
+			"setenv boardId ${IVM_BoardId}; "		\
+			"setenv hwkey ${IVM_HWKey}; "			\
+			"setenv hwKey ${IVM_HWKey}; "			\
+			"echo \"boardId set to ${boardId}\"; "		\
+			"echo \"hwKey   set to ${hwKey}\"; "		\
+			"saveenv; "					\
+		"fi; "							\
+		"fi; "							\
+		"done; "						\
+		"else "							\
+			"echo \"boardIdListHex not set, not checked\"; "\
+			"found=1; "					\
+		"fi; "							\
+		"test \"$found\" = 1 \0"				\
+	"checkboardid="							\
+		"test \"x${boardId}\" = \"x${IVM_BoardId}\" && "	\
+		"test \"x${hwKey}\" = \"x${IVM_HWKey}\"\0"		\
+	"printbootargs=print bootargs\0"				\
+	"rootfsfile="xstr(CONFIG_HOSTNAME) "/rootfsImage\0"		\
+	""
+
 #ifndef CONFIG_KM_DEF_ENV
 #define CONFIG_KM_DEF_ENV	\
-	"netdev=eth0\0"							\
-	"u-boot_addr_r=100000\0"					\
-	"kernel_addr_r=200000\0"					\
-	"fdt_addr_r=600000\0"						\
-	"ram_ws=800000 \0"						\
-	"script_ws=780000 \0"						\
-	"fdt_file=" xstr(CONFIG_HOSTNAME) "/" 				\
-		xstr(CONFIG_HOSTNAME) ".dtb\0"				\
-	"u-boot=" xstr(CONFIG_HOSTNAME) "/u-boot.bin \0" 		\
-	"kernel_file=" xstr(CONFIG_HOSTNAME) "/uImage \0" 		\
-	"load=tftp ${u-boot_addr_r} ${u-boot}\0"			\
-	"update=protect off " xstr(BOOTFLASH_START) " +${filesize};"	\
-		"erase " xstr(BOOTFLASH_START) "  +${filesize};"	\
-		"cp.b ${u-boot_addr_r} " xstr(BOOTFLASH_START) 		\
-		"  ${filesize};"					\
-		"protect on " xstr(BOOTFLASH_START) "  +${filesize}\0"	\
-	"load_fdt=tftp ${fdt_addr_r} ${fdt_file}; "			\
-		"setenv actual_fdt_addr ${fdt_addr_r} \0" 		\
-	"load_kernel=tftp ${kernel_addr_r} ${kernel_file}; " 		\
-		"setenv actual_kernel_addr ${kernel_addr_r} \0" 	\
-	"ramargs=setenv bootargs root=/dev/ram rw\0"			\
-	"nfsargs=setenv bootargs root=/dev/nfs rw "			\
-		"nfsroot=${serverip}:${rootpath}\0"			\
-	"mtdargs=setenv bootargs root=${actual_rootfs} rw "		\
-		"rootfstype=jffs2 \0" 					\
-	"altmtdargs=setenv bootargs root=${backup_rootfs} rw "		\
-		"rootfstype=jffs2 \0" 					\
-	"addmtd=setenv bootargs ${bootargs} ${mtdparts}\0"		\
-	"addip=setenv bootargs ${bootargs} "				\
-		"ip=${ipaddr}:${serverip}:${gatewayip}:${netmask}"	\
-		":${hostname}:${netdev}:off panic=1\0"			\
-	"addboardid=setenv bootargs ${bootargs} " 			\
-		"hwKey=${IVM_HWKey} boardId=0x${IVM_BoardId} \0" 	\
-	"addpram=setenv bootargs ${bootargs} "				\
-		"mem=${mem} pram=${pram}\0"				\
-	"pram=" xstr(CONFIG_PRAM) "k\0"					\
-	"net_nfs=tftp ${kernel_addr_r} ${kernel_file}; "		\
-		"tftp ${fdt_addr_r} ${fdt_file}; "			\
-		"run nfsargs addip addcon addboardid addpram;"		\
-		"bootm ${kernel_addr_r} - ${fdt_addr_r}\0"		\
-	"net_self=tftp ${kernel_addr_r} ${kernel_file}; "		\
-		"tftp ${fdt_addr_r} ${fdt_file}; "			\
-		"tftp ${ramdisk_addr} ${ramdisk_file}; "		\
-		"run ramargs addip addboardid addpram; "		\
-		"bootm ${kernel_addr_r} ${ramdisk_addr} ${fdt_addr_r}\0"\
-	"flash_nfs=run nfsargs addip addcon;"				\
-		"bootm ${kernel_addr} - ${fdt_addr}\0"			\
-	"flash_self=run ramargs addip addcon addboardid addpram;"	\
-		"bootm ${kernel_addr} ${ramdisk_addr} ${fdt_addr}\0"	\
-	"bootcmd=run mtdargs addip addcon addboardid addpram; "		\
-		"bootm ${actual_kernel_addr} - ${actual_fdt_addr} \0"	\
-	"altbootcmd=run altmtdargs addip addcon addboardid addpram; "	\
-		"bootm ${backup_kernel_addr} - ${backup_fdt_addr} \0"	\
-	"actual0=setenv actual_bank 0; setenv actual_kernel_addr "	\
-		"${bank0_kernel_addr}; "				\
-		"setenv actual_fdt_addr ${bank0_fdt_addr}; "		\
-		"setenv actual_rootfs ${bank0_rootfs} \0" 		\
-	"actual1=setenv actual_bank 1; setenv actual_kernel_addr "	\
-		"${bank1_kernel_addr}; "				\
-		"setenv actual_fdt_addr ${bank1_fdt_addr}; "		\
-		"setenv actual_rootfs ${bank1_rootfs} \0" 		\
-	"backup0=setenv backup_bank 0; setenv backup_kernel_addr " 	\
-		"${bank0_kernel_addr}; "				\
-		"setenv backup_fdt_addr ${bank0_fdt_addr}; "		\
-		"setenv backup_rootfs ${bank0_rootfs} \0"		\
-	"backup1=setenv backup_bank 1; setenv backup_kernel_addr "	\
-		"${bank1_kernel_addr}; "				\
-		"setenv backup_fdt_addr ${bank1_fdt_addr}; " 		\
-		"setenv backup_rootfs ${bank1_rootfs} \0" 		\
-	"setbank0=run actual0 backup1 \0" 				\
-	"setbank1=run actual1 backup0 \0" 				\
-	"release=setenv bootcmd "					\
-		"\'run mtdargs addip addcon addboardid addpram;" 	\
-		"bootm ${actual_kernel_addr} - ${actual_fdt_addr} \'; "	\
-		"saveenv \0"						\
-	"develop=setenv bootcmd "					\
-		"\'run nfsargs addip addcon addboardid addpram;" 	\
-		"bootm ${actual_kernel_addr} - ${actual_fdt_addr} \'; "	\
-		"saveenv \0"						\
-	"developall=setenv bootcmd "					\
-		"\'run load_fdt load_kernel nfsargs "			\
-		"addip addcon addboardid addpram; "			\
-		"bootm ${actual_kernel_addr} - ${actual_fdt_addr} \'; "	\
-		"saveenv \0"						\
-	"set_new_esw_script=setenv new_esw_script "			\
-		"new_esw_0x${IVM_BoardId}_0x${IVM_HWKey}.scr \0"	\
-	"new_esw=run set_new_esw_script; "				\
-		"tftp ${script_ws} ${new_esw_script}; "			\
-		"iminfo ${script_ws}; source ${script_ws} \0"		\
-	"bootlimit=0 \0" 						\
-	CONFIG_KM_DEF_ENV_IOMUX						\
-	CONFIG_KM_DEF_ENV_PRIVATE					\
+	CONFIG_KM_DEF_ENV_BOOTPARAMS					\
+	CONFIG_KM_DEF_NETDEV						\
+	CONFIG_KM_DEF_ENV_CPU						\
+	CONFIG_KM_DEF_ENV_BOOTRUNNER					\
+	CONFIG_KM_DEF_ENV_BOOTTARGETS					\
+	CONFIG_KM_DEF_ENV_BOOTARGS					\
+	CONFIG_KM_DEF_ENV_COMPUTE_ADDR					\
+	CONFIG_KM_DEF_ENV_FLASH_BOOT					\
+	CONFIG_KM_DEF_ENV_NET_BOOT					\
+	CONFIG_KM_DEF_ENV_CONSTANTS					\
+	"altbootcmd=run bootcmd\0"					\
+	"bootcmd=run default\0"						\
+	"bootlimit=2\0"							\
+	"init=/sbin/init-overlay.sh\0"					\
+	"kernel_addr_r="xstr(CONFIG_KM_KERNEL_ADDR) "\0"		\
+	"kernel_file="xstr(CONFIG_HOSTNAME) "/uImage\0"			\
+	"kernel_name=uImage\0"						\
+	"load=tftpboot ${u-boot_addr_r} ${u-boot}\0"			\
+	"mtdids=" MTDIDS_DEFAULT "\0"					\
+	"mtdparts=" MTDPARTS_DEFAULT "\0"				\
+	"stderr=serial\0"						\
+	"stdin=serial\0"						\
+	"stdout=serial\0"						\
+	"u-boot="xstr(CONFIG_HOSTNAME) "/u-boot.bin\0"			\
+	"u-boot_addr_r="xstr(CONFIG_KM_KERNEL_ADDR) "\0"		\
 	""
 #endif /* CONFIG_KM_DEF_ENV */
 
diff --git a/include/configs/km-powerpc.h b/include/configs/km-powerpc.h
new file mode 100644
index 0000000..3351609
--- /dev/null
+++ b/include/configs/km-powerpc.h
@@ -0,0 +1,92 @@
+/*
+ * (C) Copyright 2011
+ * Heiko Schocher, DENX Software Engineering, hs@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.
+ *
+ * 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
+ */
+
+#ifndef __CONFIG_KEYMILE_POWERPC_H
+#define __CONFIG_KEYMILE_POWERPC_H
+
+#define CONFIG_BOOTCOUNT_LIMIT
+
+#define CONFIG_CMD_DTT
+#define CONFIG_JFFS2_CMDLINE
+
+#define CONFIG_ENV_SIZE		0x04000		/* Size of Environment */
+#define CONFIG_FLASH_CFI_MTD
+
+#define CONFIG_SYS_MEMTEST_START 0x00100000	/* memtest works on */
+
+#define CONFIG_SYS_MEMTEST_END	0x00f00000	/* 1 ... 15 MB in DRAM	*/
+
+#define CONFIG_SYS_LOAD_ADDR	0x100000	/* default load address */
+
+/******************************************************************************
+ * (PRAM usage)
+ * ... -------------------------------------------------------
+ * ... |ROOTFSSIZE | PNVRAM |PHRAM |RESERVED_PRAM | END_OF_RAM
+ * ... |<------------------- pram -------------------------->|
+ * ... -------------------------------------------------------
+ * @END_OF_RAM:
+ * @CONFIG_KM_RESERVED_PRAM: reserved pram for special purpose
+ * @CONFIG_KM_PHRAM: address for /var
+ * @CONFIG_KM_PNVRAM: address for PNVRAM (for the application)
+ * @CONFIG_KM_ROOTFSSIZE: address for rootfilesystem in RAM
+ */
+
+/* size of rootfs in RAM */
+#define CONFIG_KM_ROOTFSSIZE	0x0
+/* pseudo-non volatile RAM [hex] */
+#define CONFIG_KM_PNVRAM	0x80000
+/* physical RAM MTD size [hex] */
+#define CONFIG_KM_PHRAM		0x100000
+/* resereved pram area at the end of memroy [hex] */
+#define CONFIG_KM_RESERVED_PRAM	0x0
+/* enable protected RAM */
+#define CONFIG_PRAM		0
+
+#define CONFIG_KM_CRAMFS_ADDR	0x800000
+#define CONFIG_KM_KERNEL_ADDR	0x400000	/* 3968Kbytes */
+#define CONFIG_KM_FDT_ADDR	0x7E0000	/* 128Kbytes */
+
+#define CONFIG_KM_DEF_ENV_CPU						\
+	"addbootcount=echo \\\\c\0"					\
+	"addmtdparts=echo \\\\c\0"					\
+	"boot=bootm ${actual_kernel_addr} - ${actual_fdt_addr}\0"	\
+	"cramfsloadfdt="						\
+		"cramfsload ${fdt_addr_r} "				\
+		"fdt_0x${IVM_BoardId}_0x${IVM_HWKey}.dtb && "		\
+		"setenv actual_fdt_addr ${fdt_addr_r}\0"		\
+	"fdt_addr_r=" xstr(CONFIG_KM_FDT_ADDR) "\0"			\
+	"fdt_file="							\
+		xstr(CONFIG_HOSTNAME) "/"				\
+		xstr(CONFIG_HOSTNAME) ".dtb\0"				\
+	"tftpfdt="							\
+		"tftpboot ${fdt_addr_r} ${fdt_file} && "		\
+		"setenv actual_fdt_addr ${fdt_addr_r} \0"		\
+	"update="							\
+		"protect off " xstr(BOOTFLASH_START) " +${filesize} && "\
+		"erase " xstr(BOOTFLASH_START) "  +${filesize} && "	\
+		"cp.b ${u-boot_addr_r} " xstr(BOOTFLASH_START)		\
+		"  ${filesize} && "					\
+		"protect on " xstr(BOOTFLASH_START) "  +${filesize}\0"  \
+	""
+
+#endif /* __CONFIG_KEYMILE_POWERPC_H */
diff --git a/include/configs/km82xx-common.h b/include/configs/km82xx-common.h
new file mode 100644
index 0000000..345212c
--- /dev/null
+++ b/include/configs/km82xx-common.h
@@ -0,0 +1,336 @@
+/*
+ * (C) Copyright 2007-2010
+ * Heiko Schocher, DENX Software Engineering, hs@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.
+ *
+ * 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
+ */
+
+#ifndef __KM82XX_COMMON
+#define __KM82XX_COMMON
+
+/*
+ * Select serial console configuration
+ *
+ * If either CONFIG_CONS_ON_SMC or CONFIG_CONS_ON_SCC is selected, then
+ * CONFIG_CONS_INDEX must be set to the channel number (1-2 for SMC, 1-4
+ * for SCC).
+ */
+#define	CONFIG_CONS_ON_SMC		/* Console is on SMC         */
+#undef  CONFIG_CONS_ON_SCC		/* It's not on SCC           */
+#undef	CONFIG_CONS_NONE		/* It's not on external UART */
+#define CONFIG_CONS_INDEX	2	/* SMC2 is used for console  */
+#define CONFIG_SYS_SMC_RXBUFLEN	128
+#define CONFIG_SYS_MAXIDLE	10
+
+/*
+ * Select ethernet configuration
+ *
+ * If either CONFIG_ETHER_ON_SCC or CONFIG_ETHER_ON_FCC is selected,
+ * then CONFIG_ETHER_INDEX must be set to the channel number (1-4 for
+ * SCC, 1-3 for FCC)
+ *
+ * If CONFIG_ETHER_NONE is defined, then either the ethernet routines
+ * must be defined elsewhere (as for the console), or CONFIG_CMD_NET
+ * must be unset.
+ */
+#define	CONFIG_ETHER_ON_SCC		/* Ethernet is on SCC */
+#undef	CONFIG_ETHER_ON_FCC		/* Ethernet is not on FCC     */
+#undef	CONFIG_ETHER_NONE		/* No external Ethernet   */
+#define CONFIG_NET_MULTI
+
+#define CONFIG_ETHER_INDEX	4
+#define CONFIG_HAS_ETH0
+#define CONFIG_SYS_SCC_TOUT_LOOP	10000000
+
+#define CONFIG_SYS_CMXSCR_VALUE	(CMXSCR_RS4CS_CLK7 | CMXSCR_TS4CS_CLK8)
+
+#ifndef CONFIG_8260_CLKIN
+#define CONFIG_8260_CLKIN	66000000	/* in Hz */
+#endif
+
+#define BOOTFLASH_START		0xFE000000
+
+#define CONFIG_KM_CONSOLE_TTY	"ttyCPM0"
+
+#define MTDPARTS_DEFAULT	"mtdparts="				\
+	"app:"								\
+		"768k(u-boot),"						\
+		"128k(env),"						\
+		"128k(envred),"						\
+		"3072k(free),"						\
+		"-(" CONFIG_KM_UBI_PARTITION_NAME ")"
+
+/*
+ * Default environment settings
+ */
+#define	CONFIG_EXTRA_ENV_SETTINGS					\
+	CONFIG_KM_DEF_ENV						\
+	"EEprom_ivm=pca9544a:70:4 \0"					\
+	"unlock=yes\0"							\
+	"newenv="							\
+		"prot off 0xFE0C0000 +0x40000 && "			\
+		"era 0xFE0C0000 +0x40000\0"				\
+	"rootpath=/opt/eldk/ppc_82xx\0"					\
+	""
+
+#define CONFIG_SYS_MONITOR_BASE	CONFIG_SYS_TEXT_BASE
+#if (CONFIG_SYS_MONITOR_BASE < CONFIG_SYS_FLASH_BASE)
+#define CONFIG_SYS_RAMBOOT
+#endif
+
+#define CONFIG_SYS_MONITOR_LEN		(768 << 10)
+
+#define CONFIG_ENV_IS_IN_FLASH
+
+#ifdef CONFIG_ENV_IS_IN_FLASH
+#define CONFIG_ENV_SECT_SIZE	0x20000
+#define CONFIG_ENV_ADDR		(CONFIG_SYS_MONITOR_BASE + \
+					CONFIG_SYS_MONITOR_LEN)
+#define CONFIG_ENV_OFFSET	CONFIG_SYS_MONITOR_LEN
+
+/* Address and size of Redundant Environment Sector	*/
+#define CONFIG_ENV_OFFSET_REDUND	(CONFIG_ENV_OFFSET + \
+						CONFIG_ENV_SECT_SIZE)
+#define CONFIG_ENV_SIZE_REDUND		(CONFIG_ENV_SIZE)
+#endif /* CONFIG_ENV_IS_IN_FLASH */
+
+/* enable I2C and select the hardware/software driver */
+#undef	CONFIG_HARD_I2C			/* I2C with hardware support	*/
+#define	CONFIG_SOFT_I2C			/* I2C bit-banged		*/
+#define CONFIG_SYS_I2C_SPEED		50000	/* I2C speed */
+#define CONFIG_SYS_I2C_SLAVE		0x7F	/* I2C slave address */
+
+/*
+ * Software (bit-bang) I2C driver configuration
+ */
+
+#define I2C_PORT	3		/* Port A=0, B=1, C=2, D=3 */
+#define I2C_ACTIVE	(iop->pdir |=  0x00010000)
+#define I2C_TRISTATE	(iop->pdir &= ~0x00010000)
+#define I2C_READ	((iop->pdat & 0x00010000) != 0)
+#define I2C_SDA(bit)	do { \
+				if (bit) \
+					iop->pdat |=  0x00010000; \
+				else \
+					iop->pdat &= ~0x00010000; \
+			} while (0)
+#define I2C_SCL(bit)	do { \
+				if (bit) \
+					iop->pdat |=  0x00020000; \
+				else \
+					iop->pdat &= ~0x00020000; \
+			} while (0)
+#define I2C_DELAY	udelay(5)	/* 1/4 I2C clock duration */
+
+/* I2C SYSMON (LM75, AD7414 is almost compatible)			*/
+#define CONFIG_DTT_LM75			/* ON Semi's LM75		*/
+#define CONFIG_DTT_SENSORS	{0}	/* Sensor addresses		*/
+#define CONFIG_SYS_DTT_MAX_TEMP	70
+#define CONFIG_SYS_DTT_LOW_TEMP	-30
+#define CONFIG_SYS_DTT_HYSTERESIS	3
+#define CONFIG_SYS_DTT_BUS_NUM		(CONFIG_SYS_MAX_I2C_BUS)
+
+#define CONFIG_SYS_I2C_EEPROM_ADDR_LEN	1
+
+#define CONFIG_SYS_IMMR		0xF0000000
+
+#define CONFIG_SYS_INIT_RAM_ADDR	CONFIG_SYS_IMMR
+#define CONFIG_SYS_INIT_RAM_SIZE	0x2000 /* used size in DPRAM */
+#define CONFIG_SYS_GBL_DATA_OFFSET	(CONFIG_SYS_INIT_RAM_SIZE - \
+						GENERATED_GBL_DATA_SIZE)
+#define CONFIG_SYS_INIT_SP_OFFSET	CONFIG_SYS_GBL_DATA_OFFSET
+
+/* Hard reset configuration word */
+#define CONFIG_SYS_HRCW_MASTER		0x0604b211
+
+/* No slaves */
+#define CONFIG_SYS_HRCW_SLAVE1		0
+#define CONFIG_SYS_HRCW_SLAVE2		0
+#define CONFIG_SYS_HRCW_SLAVE3		0
+#define CONFIG_SYS_HRCW_SLAVE4		0
+#define CONFIG_SYS_HRCW_SLAVE5		0
+#define CONFIG_SYS_HRCW_SLAVE6		0
+#define CONFIG_SYS_HRCW_SLAVE7		0
+
+/* Initial Memory map for Linux */
+#define CONFIG_SYS_BOOTMAPSZ		(8 << 20)
+
+#define CONFIG_SYS_CACHELINE_SIZE	32	/* For MPC8260 CPUs */
+#if defined(CONFIG_CMD_KGDB)
+#  define CONFIG_SYS_CACHELINE_SHIFT	5 /* log base 2 of the above value */
+#endif
+
+#define CONFIG_SYS_HID0_INIT		0
+#define CONFIG_SYS_HID0_FINAL		(HID0_ICE | HID0_IFEM | HID0_ABE)
+
+#define CONFIG_SYS_HID2		0
+
+#define CONFIG_SYS_SIUMCR		0x4020c200
+#define CONFIG_SYS_SYPCR		0xFFFFFFC3
+#define CONFIG_SYS_BCR			0x10000000
+#define CONFIG_SYS_SCCR		(SCCR_PCI_MODE | SCCR_PCI_MODCK)
+
+/*
+ *-----------------------------------------------------------------------
+ * RMR - Reset Mode Register                                     5-5
+ *-----------------------------------------------------------------------
+ * turn on Checkstop Reset Enable
+ */
+#define CONFIG_SYS_RMR         0
+
+/*
+ *-----------------------------------------------------------------------
+ * TMCNTSC - Time Counter Status and Control                     4-40
+ *-----------------------------------------------------------------------
+ * Clear once per Second and Alarm Interrupt Status, Set 32KHz timersclk,
+ * and enable Time Counter
+ */
+#define CONFIG_SYS_TMCNTSC     (TMCNTSC_SEC|TMCNTSC_ALR|TMCNTSC_TCF|TMCNTSC_TCE)
+
+/*
+ *-----------------------------------------------------------------------
+ * PISCR - Periodic Interrupt Status and Control                 4-42
+ *-----------------------------------------------------------------------
+ * Clear Periodic Interrupt Status, Set 32KHz timersclk, and enable
+ * Periodic timer
+ */
+#define CONFIG_SYS_PISCR       (PISCR_PS|PISCR_PTF|PISCR_PTE)
+
+/*
+ *-----------------------------------------------------------------------
+ * RCCR - RISC Controller Configuration                         13-7
+ *-----------------------------------------------------------------------
+ */
+#define CONFIG_SYS_RCCR        0
+
+/*
+ * Init Memory Controller:
+ *
+ * Bank Bus     Machine PortSz  Device
+ * ---- ---     ------- ------  ------
+ *  0   60x     GPCM     8 bit  FLASH
+ *  1   60x     SDRAM   32 bit  SDRAM
+ *  3   60x     GPCM     8 bit  GPIO/PIGGY
+ *  5   60x     GPCM    16 bit  CFG-Flash
+ *
+ */
+/* Bank 0 - FLASH
+ */
+#define CONFIG_SYS_BR0_PRELIM  ((CONFIG_SYS_FLASH_BASE & BRx_BA_MSK)	|\
+			 BRx_PS_8			|\
+			 BRx_MS_GPCM_P			|\
+			 BRx_V)
+
+#define CONFIG_SYS_OR0_PRELIM  (MEG_TO_AM(CONFIG_SYS_FLASH_SIZE)	|\
+			 ORxG_CSNT			|\
+			 ORxG_ACS_DIV2			|\
+			 ORxG_SCY_5_CLK			|\
+			 ORxG_TRLX)
+
+
+/*
+ * Bank 1 - 60x bus SDRAM
+ */
+#define SDRAM_MAX_SIZE	0x08000000	/* max. 128 MB		*/
+#define CONFIG_SYS_GLOBAL_SDRAM_LIMIT	(256 << 20)	/* less than 256 MB */
+
+#define CONFIG_SYS_MPTPR       0x1800
+
+/*
+ *-----------------------------------------------------------------------------
+ * Address for Mode Register Set (MRS) command
+ *-----------------------------------------------------------------------------
+ */
+#define CONFIG_SYS_MRS_OFFS	0x00000110
+#define CONFIG_SYS_PSRT        0x0e
+
+#define CONFIG_SYS_BR1_PRELIM ((CONFIG_SYS_SDRAM_BASE & BRx_BA_MSK) |\
+			 BRx_PS_64		|\
+			 BRx_MS_SDRAM_P		|\
+			 BRx_V)
+
+#define CONFIG_SYS_OR1_PRELIM	CONFIG_SYS_OR1
+
+/*
+ *  SDRAM initialization values
+ */
+
+#define CONFIG_SYS_OR1 ((~(CONFIG_SYS_GLOBAL_SDRAM_LIMIT-1) & ORxS_SDAM_MSK) |\
+			 ORxS_BPD_8			|\
+			 ORxS_ROWST_PBI0_A7		|\
+			 ORxS_NUMR_13)
+
+#define CONFIG_SYS_PSDMR (PSDMR_SDAM_A14_IS_A5	|\
+			 PSDMR_BSMA_A14_A16	|\
+			 PSDMR_SDA10_PBI0_A9	|\
+			 PSDMR_RFRC_5_CLK	|\
+			 PSDMR_PRETOACT_2W	|\
+			 PSDMR_ACTTORW_2W	|\
+			 PSDMR_LDOTOPRE_1C	|\
+			 PSDMR_WRC_1C		|\
+			 PSDMR_CL_2)
+
+/*
+ * UPIO FPGA (GPIO/PIGGY) on CS3 initialization values
+ */
+#define CONFIG_SYS_KMBEC_FPGA_BASE	0x30000000
+#define CONFIG_SYS_KMBEC_FPGA_SIZE	128
+
+#define CONFIG_SYS_BR3_PRELIM	((CONFIG_SYS_KMBEC_FPGA_BASE & BRx_BA_MSK) |\
+			 BRx_PS_8 | BRx_MS_GPCM_P | BRx_V)
+
+#define CONFIG_SYS_OR3_PRELIM	(MEG_TO_AM(CONFIG_SYS_KMBEC_FPGA_SIZE) |\
+			 ORxG_CSNT | ORxG_ACS_DIV2 |\
+			 ORxG_SCY_3_CLK | ORxG_TRLX)
+
+/*
+ * BFTICU board FPGA on CS4 initialization values
+ */
+#define CONFIG_SYS_FPGA_BASE	0x40000000
+#define CONFIG_SYS_FPGA_SIZE	1 /*1KB*/
+
+#define CONFIG_SYS_BR4_PRELIM ((CONFIG_SYS_FPGA_BASE & BRx_BA_MSK) |\
+			BRx_PS_8 | BRx_MS_GPCM_P | BRx_V)
+
+#define CONFIG_SYS_OR4_PRELIM (P2SZ_TO_AM(CONFIG_SYS_FPGA_SIZE << 10) |\
+			 ORxG_CSNT | ORxG_ACS_DIV2 |\
+			 ORxG_SCY_3_CLK | ORxG_TRLX)
+
+/*
+ * CFG-Flash on CS5 initialization values
+ */
+#define CONFIG_SYS_BR5_PRELIM	((CONFIG_SYS_FLASH_BASE_1 & BRx_BA_MSK) |\
+			 BRx_PS_16 | BRx_MS_GPCM_P | BRx_V)
+
+#define CONFIG_SYS_OR5_PRELIM	(MEG_TO_AM(CONFIG_SYS_FLASH_SIZE_1 + \
+				 CONFIG_SYS_FLASH_SIZE_2) |\
+				 ORxG_CSNT | ORxG_ACS_DIV2 |\
+				 ORxG_SCY_5_CLK | ORxG_TRLX)
+
+#define	CONFIG_SYS_RESET_ADDRESS 0xFDFFFFFC	/* "bad" address */
+
+/* pass open firmware flat tree */
+#define CONFIG_FIT		1
+#define CONFIG_OF_LIBFDT	1
+#define CONFIG_OF_BOARD_SETUP	1
+
+#define OF_TBCLK		(bd->bi_busfreq / 4)
+#define OF_STDOUT_PATH		"/soc/cpm/serial@11a90"
+
+#endif /* __KM82XX_COMMON */
diff --git a/include/configs/km8321-common.h b/include/configs/km8321-common.h
new file mode 100644
index 0000000..6fab45e
--- /dev/null
+++ b/include/configs/km8321-common.h
@@ -0,0 +1,137 @@
+/*
+ * Copyright (C) 2006 Freescale Semiconductor, Inc.
+ *                    Dave Liu <daveliu@freescale.com>
+ *
+ * Copyright (C) 2007 Logic Product Development, Inc.
+ *                    Peter Barada <peterb@logicpd.com>
+ *
+ * Copyright (C) 2007 MontaVista Software, Inc.
+ *                    Anton Vorontsov <avorontsov@ru.mvista.com>
+ *
+ * (C) Copyright 2008
+ * Heiko Schocher, DENX Software Engineering, hs@denx.de.
+ *
+ * (C) Copyright 2010
+ * Lukas Roggli, KEYMILE Ltd, lukas.roggli@keymile.com
+ *
+ * (C) Copyright 2010-2011
+ * Thomas Reufer, KEYMILE Ltd, thomas.reufer@keymile.com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ */
+
+#ifndef __CONFIG_KM8321_COMMON_H
+#define __CONFIG_KM8321_COMMON_H
+
+/*
+ * High Level Configuration Options
+ */
+#define CONFIG_QE	/* Has QE */
+#define CONFIG_MPC832x	/* MPC832x CPU specific */
+#define CONFIG_KM8321	/* Keymile PBEC8321 board specific */
+
+#define CONFIG_KM_DEF_ROOTPATH		\
+	"rootpath=/opt/eldk/ppc_8xx\0"
+
+/* include common defines/options for all 83xx Keymile boards */
+#include "km83xx-common.h"
+
+#define CONFIG_MISC_INIT_R
+
+/*
+ * System IO Config
+ */
+#define CONFIG_SYS_SICRL	SICRL_IRQ_CKS
+
+/*
+ * Hardware Reset Configuration Word
+ */
+#define CONFIG_SYS_HRCW_LOW (\
+	HRCWL_LCL_BUS_TO_SCB_CLK_1X1 | \
+	HRCWL_DDR_TO_SCB_CLK_2X1 | \
+	HRCWL_CSB_TO_CLKIN_2X1 | \
+	HRCWL_CORE_TO_CSB_2_5X1 | \
+	HRCWL_CE_PLL_VCO_DIV_2 | \
+	HRCWL_CE_TO_PLL_1X3)
+
+#define CONFIG_SYS_HRCW_HIGH (\
+	HRCWH_PCI_AGENT | \
+	HRCWH_PCI_ARBITER_DISABLE | \
+	HRCWH_CORE_ENABLE | \
+	HRCWH_FROM_0X00000100 | \
+	HRCWH_BOOTSEQ_DISABLE | \
+	HRCWH_SW_WATCHDOG_DISABLE | \
+	HRCWH_ROM_LOC_LOCAL_16BIT | \
+	HRCWH_BIG_ENDIAN | \
+	HRCWH_LALE_NORMAL)
+
+#define CONFIG_SYS_DDR_CS0_BNDS		0x0000007f
+#define CONFIG_SYS_DDR_SDRAM_CFG	(SDRAM_CFG_SDRAM_TYPE_DDR2 | \
+					 SDRAM_CFG_32_BE | \
+					 SDRAM_CFG_SREN)
+
+#define CONFIG_SYS_DDR_SDRAM_CFG2	0x00401000
+#define CONFIG_SYS_DDR_CLK_CNTL		(DDR_SDRAM_CLK_CNTL_CLK_ADJUST_05)
+#define CONFIG_SYS_DDR_INTERVAL	((0x064 << SDRAM_INTERVAL_BSTOPRE_SHIFT) | \
+				 (0x200 << SDRAM_INTERVAL_REFINT_SHIFT))
+
+#define CONFIG_SYS_DDR_CS0_CONFIG	(CSCONFIG_EN | CSCONFIG_AP | \
+					 CSCONFIG_ODT_WR_CFG | \
+					 CSCONFIG_ROW_BIT_13 | \
+					 CSCONFIG_COL_BIT_10)
+
+#define CONFIG_SYS_DDR_MODE	0x47860252
+#define CONFIG_SYS_DDR_MODE2	0x8080c000
+
+#define CONFIG_SYS_DDR_TIMING_0	((2 << TIMING_CFG0_MRS_CYC_SHIFT) | \
+				 (8 << TIMING_CFG0_ODT_PD_EXIT_SHIFT) | \
+				 (2 << TIMING_CFG0_PRE_PD_EXIT_SHIFT) | \
+				 (2 << TIMING_CFG0_ACT_PD_EXIT_SHIFT) | \
+				 (0 << TIMING_CFG0_WWT_SHIFT) | \
+				 (0 << TIMING_CFG0_RRT_SHIFT) | \
+				 (0 << TIMING_CFG0_WRT_SHIFT) | \
+				 (0 << TIMING_CFG0_RWT_SHIFT))
+
+#define CONFIG_SYS_DDR_TIMING_1	((TIMING_CFG1_CASLAT_50) | \
+				 (2 << TIMING_CFG1_WRTORD_SHIFT) | \
+				 (2 << TIMING_CFG1_ACTTOACT_SHIFT) | \
+				 (2 << TIMING_CFG1_WRREC_SHIFT) | \
+				 (6 << TIMING_CFG1_REFREC_SHIFT) | \
+				 (2 << TIMING_CFG1_ACTTORW_SHIFT) | \
+				 (6 << TIMING_CFG1_ACTTOPRE_SHIFT) | \
+				 (2 << TIMING_CFG1_PRETOACT_SHIFT))
+
+#define CONFIG_SYS_DDR_TIMING_2	((8 << TIMING_CFG2_FOUR_ACT_SHIFT) | \
+				 (3 << TIMING_CFG2_CKE_PLS_SHIFT) | \
+				 (2 << TIMING_CFG2_WR_DATA_DELAY_SHIFT) | \
+				 (2 << TIMING_CFG2_RD_TO_PRE_SHIFT) | \
+				 (4 << TIMING_CFG2_WR_LAT_DELAY_SHIFT) | \
+				 (0 << TIMING_CFG2_ADD_LAT_SHIFT) | \
+				 (5 << TIMING_CFG2_CPO_SHIFT))
+
+#define CONFIG_SYS_DDR_TIMING_3	0x00000000
+
+#define CONFIG_SYS_KMBEC_FPGA_BASE	0xE8000000
+#define	CONFIG_SYS_KMBEC_FPGA_SIZE	128
+
+/* EEprom support */
+#define CONFIG_SYS_I2C_EEPROM_ADDR_LEN	1
+
+/*
+ * Local Bus Configuration & Clock Setup
+ */
+#define CONFIG_SYS_LCRR		(LCRR_DBYP | LCRR_EADC_1 | LCRR_CLKDIV_2)
+#define CONFIG_SYS_LBC_LBCR	0x00000000
+
+/*
+ * MMU Setup
+ */
+#define CONFIG_SYS_IBAT7L	(0)
+#define CONFIG_SYS_IBAT7U	(0)
+#define CONFIG_SYS_DBAT7L	CONFIG_SYS_IBAT7L
+#define CONFIG_SYS_DBAT7U	CONFIG_SYS_IBAT7U
+
+#endif /* __CONFIG_KM8321_COMMON_H */
diff --git a/include/configs/km83xx-common.h b/include/configs/km83xx-common.h
new file mode 100644
index 0000000..85b6ed2
--- /dev/null
+++ b/include/configs/km83xx-common.h
@@ -0,0 +1,325 @@
+/*
+ * (C) Copyright 2010
+ * Heiko Schocher, DENX Software Engineering, hs@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.
+ */
+
+#ifndef __CONFIG_KM83XX_H
+#define __CONFIG_KM83XX_H
+
+/* include common defines/options for all Keymile boards */
+#include "keymile-common.h"
+#include "km-powerpc.h"
+
+#define MTDIDS_DEFAULT		"nor0=boot"
+#define MTDPARTS_DEFAULT	"mtdparts="			\
+	"boot:"							\
+		"768k(u-boot),"					\
+		"128k(env),"					\
+		"128k(envred),"					\
+		"-(" CONFIG_KM_UBI_PARTITION_NAME ")"
+
+#define CONFIG_MISC_INIT_R
+/*
+ * System Clock Setup
+ */
+#define CONFIG_83XX_CLKIN		66000000
+#define CONFIG_SYS_CLK_FREQ		66000000
+#define CONFIG_83XX_PCICLK		66000000
+
+/*
+ * IMMR new address
+ */
+#define CONFIG_SYS_IMMR		0xE0000000
+
+/*
+ * Bus Arbitration Configuration Register (ACR)
+ */
+#define CONFIG_SYS_ACR_PIPE_DEP 3       /* pipeline depth 4 transactions */
+#define CONFIG_SYS_ACR_RPTCNT   3       /* 4 consecutive transactions */
+#define CONFIG_SYS_ACR_APARK    0       /* park bus to master (below) */
+#define CONFIG_SYS_ACR_PARKM    3       /* parking master = QuiccEngine */
+
+/*
+ * DDR Setup
+ */
+#define CONFIG_SYS_DDR_BASE		0x00000000 /* DDR is system memory */
+#define CONFIG_SYS_SDRAM_BASE		CONFIG_SYS_DDR_BASE
+#define CONFIG_SYS_DDR_SDRAM_BASE	CONFIG_SYS_DDR_BASE
+#define CONFIG_SYS_DDR_SDRAM_CLK_CNTL	(DDR_SDRAM_CLK_CNTL_SS_EN | \
+					DDR_SDRAM_CLK_CNTL_CLK_ADJUST_05)
+
+#define CFG_83XX_DDR_USES_CS0
+
+/*
+ * Manually set up DDR parameters
+ */
+#define CONFIG_DDR_II
+#define CONFIG_SYS_DDR_SIZE		2048 /* MB */
+
+/*
+ * The reserved memory
+ */
+#define CONFIG_SYS_MONITOR_BASE	CONFIG_SYS_TEXT_BASE /* start of monitor */
+#define CONFIG_SYS_FLASH_BASE		0xF0000000
+
+#if (CONFIG_SYS_MONITOR_BASE < CONFIG_SYS_FLASH_BASE)
+#define CONFIG_SYS_RAMBOOT
+#endif
+
+/* Reserve 768 kB for Mon */
+#define CONFIG_SYS_MONITOR_LEN		(768 * 1024)
+
+/*
+ * Initial RAM Base Address Setup
+ */
+#define CONFIG_SYS_INIT_RAM_LOCK
+#define CONFIG_SYS_INIT_RAM_ADDR	0xE6000000 /* Initial RAM address */
+#define CONFIG_SYS_INIT_RAM_SIZE	0x1000 /* End of used area in RAM */
+#define CONFIG_SYS_GBL_DATA_SIZE	0x100 /* num bytes initial data */
+#define CONFIG_SYS_GBL_DATA_OFFSET	(CONFIG_SYS_INIT_RAM_SIZE - \
+						GENERATED_GBL_DATA_SIZE)
+
+/*
+ * Init Local Bus Memory Controller:
+ *
+ * Bank Bus     Machine PortSz  Size  Device
+ * ---- ---     ------- ------  -----  ------
+ *  0   Local   GPCM    16 bit  256MB FLASH
+ *  1   Local   GPCM     8 bit  128MB GPIO/PIGGY
+ *
+ */
+/*
+ * FLASH on the Local Bus
+ */
+#define CONFIG_SYS_FLASH_CFI		/* use the Common Flash Interface */
+#define CONFIG_FLASH_CFI_DRIVER		/* use the CFI driver */
+#define CONFIG_SYS_FLASH_SIZE		256 /* max FLASH size is 256M */
+#define CONFIG_SYS_FLASH_PROTECTION
+#define CONFIG_SYS_FLASH_USE_BUFFER_WRITE
+
+#define CONFIG_SYS_LBLAWBAR0_PRELIM	CONFIG_SYS_FLASH_BASE
+#define CONFIG_SYS_LBLAWAR0_PRELIM	0x8000001b /* 256MB window size */
+
+#define CONFIG_SYS_BR0_PRELIM	(CONFIG_SYS_FLASH_BASE | \
+				(2 << BR_PS_SHIFT) | /* 16 bit port size */ \
+				BR_V)
+
+#define CONFIG_SYS_OR0_PRELIM	(MEG_TO_AM(CONFIG_SYS_FLASH_SIZE) | \
+				OR_GPCM_CSNT | OR_GPCM_ACS_DIV2 | \
+				OR_GPCM_SCY_5 | \
+				OR_GPCM_TRLX | OR_GPCM_EAD)
+
+#define CONFIG_SYS_MAX_FLASH_BANKS	1   /* max num of flash banks	*/
+#define CONFIG_SYS_MAX_FLASH_SECT	512 /* max num of sects on one chip */
+#define CONFIG_SYS_FLASH_BANKS_LIST { CONFIG_SYS_FLASH_BASE }
+
+/*
+ * PRIO1/PIGGY on the local bus CS1
+ */
+/* Window base at flash base */
+#define CONFIG_SYS_LBLAWBAR1_PRELIM	CONFIG_SYS_KMBEC_FPGA_BASE
+#define CONFIG_SYS_LBLAWAR1_PRELIM	0x8000001A /* 128MB window size */
+
+#define CONFIG_SYS_BR1_PRELIM	(CONFIG_SYS_KMBEC_FPGA_BASE | \
+				(1 << BR_PS_SHIFT) | /* 8 bit port size */ \
+				BR_V)
+#define CONFIG_SYS_OR1_PRELIM	(MEG_TO_AM(CONFIG_SYS_KMBEC_FPGA_SIZE) | \
+				OR_GPCM_CSNT | OR_GPCM_ACS_DIV2 | \
+				OR_GPCM_SCY_2 | \
+				OR_GPCM_TRLX | OR_GPCM_EAD)
+
+/*
+ * Serial Port
+ */
+#define CONFIG_CONS_INDEX	1
+#define CONFIG_SYS_NS16550
+#define CONFIG_SYS_NS16550_SERIAL
+#define CONFIG_SYS_NS16550_REG_SIZE	1
+#define CONFIG_SYS_NS16550_CLK		get_bus_freq(0)
+
+#define CONFIG_SYS_NS16550_COM1	(CONFIG_SYS_IMMR+0x4500)
+#define CONFIG_SYS_NS16550_COM2	(CONFIG_SYS_IMMR+0x4600)
+
+/* Pass open firmware flat tree */
+#define CONFIG_OF_LIBFDT
+#define CONFIG_OF_BOARD_SETUP
+#define CONFIG_OF_STDOUT_VIA_ALIAS
+
+#ifndef CONFIG_NET_MULTI
+#define CONFIG_NET_MULTI
+#endif
+/*
+ * QE UEC ethernet configuration
+ */
+#define CONFIG_UEC_ETH
+#define CONFIG_ETHPRIME		"UEC0"
+
+#define CONFIG_UEC_ETH1		/* GETH1 */
+#define UEC_VERBOSE_DEBUG	1
+
+#ifdef CONFIG_UEC_ETH1
+#define CONFIG_SYS_UEC1_UCC_NUM	3	/* UCC4 */
+#define CONFIG_SYS_UEC1_RX_CLK		QE_CLK_NONE /* not used in RMII Mode */
+#define CONFIG_SYS_UEC1_TX_CLK		QE_CLK17
+#define CONFIG_SYS_UEC1_ETH_TYPE	FAST_ETH
+#define CONFIG_SYS_UEC1_PHY_ADDR	0
+#define CONFIG_SYS_UEC1_INTERFACE_TYPE	PHY_INTERFACE_MODE_RMII
+#define CONFIG_SYS_UEC1_INTERFACE_SPEED	100
+#endif
+
+/*
+ * Environment
+ */
+
+#ifndef CONFIG_SYS_RAMBOOT
+#define CONFIG_ENV_IS_IN_FLASH
+#define CONFIG_ENV_ADDR		(CONFIG_SYS_MONITOR_BASE + \
+					CONFIG_SYS_MONITOR_LEN)
+#define CONFIG_ENV_SECT_SIZE	0x20000 /* 128K(one sector) for env */
+#define CONFIG_ENV_OFFSET	(CONFIG_SYS_MONITOR_LEN)
+
+/* Address and size of Redundant Environment Sector	*/
+#define CONFIG_ENV_OFFSET_REDUND	(CONFIG_ENV_OFFSET + \
+						CONFIG_ENV_SECT_SIZE)
+#define CONFIG_ENV_SIZE_REDUND	(CONFIG_ENV_SIZE)
+
+#else /* CFG_SYS_RAMBOOT */
+#define CONFIG_SYS_NO_FLASH		/* Flash is not usable now */
+#define CONFIG_ENV_IS_NOWHERE		/* Store ENV in memory only */
+#define CONFIG_ENV_ADDR		(CONFIG_SYS_MONITOR_BASE - 0x1000)
+#define CONFIG_ENV_SIZE		0x2000
+#endif /* CFG_SYS_RAMBOOT */
+
+/* I2C */
+#define CONFIG_HARD_I2C		/* I2C with hardware support */
+#define CONFIG_FSL_I2C
+#define CONFIG_SYS_I2C_SPEED	200000	/* I2C speed and slave address */
+#define CONFIG_SYS_I2C_SLAVE	0x7F
+#define CONFIG_SYS_I2C_OFFSET	0x3000
+
+/* I2C SYSMON (LM75, AD7414 is almost compatible) */
+#define CONFIG_DTT_LM75		/* ON Semi's LM75 */
+#define CONFIG_DTT_SENSORS	{0, 1, 2, 3}	/* Sensor addresses */
+#define CONFIG_SYS_DTT_MAX_TEMP	70
+#define CONFIG_SYS_DTT_LOW_TEMP	-30
+#define CONFIG_SYS_DTT_HYSTERESIS	3
+#define CONFIG_SYS_DTT_BUS_NUM		(CONFIG_SYS_MAX_I2C_BUS)
+
+#if defined(CONFIG_CMD_NAND)
+#define CONFIG_NAND_KMETER1
+#define CONFIG_SYS_MAX_NAND_DEVICE	1
+#define CONFIG_SYS_NAND_BASE		CONFIG_SYS_KMBEC_FPGA_BASE
+#endif
+
+#if defined(CONFIG_PCI)
+#define CONFIG_CMD_PCI
+#endif
+
+/*
+ * For booting Linux, the board info and command line data
+ * have to be in the first 8 MB of memory, since this is
+ * the maximum mapped by the Linux kernel during initialization.
+ */
+#define CONFIG_SYS_BOOTMAPSZ		(8 << 20)
+
+/*
+ * Core HID Setup
+ */
+#define CONFIG_SYS_HID0_INIT		0x000000000
+#define CONFIG_SYS_HID0_FINAL		(HID0_ENABLE_MACHINE_CHECK | \
+					 HID0_ENABLE_INSTRUCTION_CACHE)
+#define CONFIG_SYS_HID2			HID2_HBE
+
+/*
+ * MMU Setup
+ */
+
+#define CONFIG_HIGH_BATS	1	/* High BATs supported */
+
+/* DDR: cache cacheable */
+#define CONFIG_SYS_IBAT0L	(CONFIG_SYS_SDRAM_BASE | BATL_PP_10 | \
+				BATL_CACHEINHIBIT | BATL_GUARDEDSTORAGE)
+#define CONFIG_SYS_IBAT0U	(CONFIG_SYS_SDRAM_BASE | BATU_BL_256M | \
+					BATU_VS | BATU_VP)
+#define CONFIG_SYS_DBAT0L	CONFIG_SYS_IBAT0L
+#define CONFIG_SYS_DBAT0U	CONFIG_SYS_IBAT0U
+
+/* IMMRBAR & PCI IO: cache-inhibit and guarded */
+#define CONFIG_SYS_IBAT1L	(CONFIG_SYS_IMMR | BATL_PP_10 | \
+				BATL_CACHEINHIBIT | BATL_GUARDEDSTORAGE)
+#define CONFIG_SYS_IBAT1U	(CONFIG_SYS_IMMR | BATU_BL_4M | BATU_VS \
+					| BATU_VP)
+#define CONFIG_SYS_DBAT1L	CONFIG_SYS_IBAT1L
+#define CONFIG_SYS_DBAT1U	CONFIG_SYS_IBAT1U
+
+/* PRIO1, PIGGY:  icache cacheable, but dcache-inhibit and guarded */
+#define CONFIG_SYS_IBAT2L	(CONFIG_SYS_KMBEC_FPGA_BASE | BATL_PP_10 | \
+				BATL_MEMCOHERENCE)
+#define CONFIG_SYS_IBAT2U	(CONFIG_SYS_KMBEC_FPGA_BASE | BATU_BL_128M | \
+				BATU_VS | BATU_VP)
+#define CONFIG_SYS_DBAT2L	(CONFIG_SYS_KMBEC_FPGA_BASE | BATL_PP_10 | \
+				 BATL_CACHEINHIBIT | BATL_GUARDEDSTORAGE)
+#define CONFIG_SYS_DBAT2U	CONFIG_SYS_IBAT2U
+
+/* FLASH: icache cacheable, but dcache-inhibit and guarded */
+#define CONFIG_SYS_IBAT3L	(CONFIG_SYS_FLASH_BASE | BATL_PP_10 | \
+					BATL_MEMCOHERENCE)
+#define CONFIG_SYS_IBAT3U	(CONFIG_SYS_FLASH_BASE | BATU_BL_256M | \
+					BATU_VS | BATU_VP)
+#define CONFIG_SYS_DBAT3L	(CONFIG_SYS_FLASH_BASE | BATL_PP_10 | \
+				 BATL_CACHEINHIBIT | BATL_GUARDEDSTORAGE)
+#define CONFIG_SYS_DBAT3U	CONFIG_SYS_IBAT3U
+
+/* Stack in dcache: cacheable, no memory coherence */
+#define CONFIG_SYS_IBAT4L	(CONFIG_SYS_INIT_RAM_ADDR | BATL_PP_10)
+#define CONFIG_SYS_IBAT4U	(CONFIG_SYS_INIT_RAM_ADDR | BATU_BL_128K | \
+					BATU_VS | BATU_VP)
+#define CONFIG_SYS_DBAT4L	CONFIG_SYS_IBAT4L
+#define CONFIG_SYS_DBAT4U	CONFIG_SYS_IBAT4U
+
+/*
+ * Internal Definitions
+ *
+ * Boot Flags
+ */
+#define BOOTFLAG_COLD	0x01 /* Normal Power-On: Boot from FLASH */
+#define BOOTFLAG_WARM	0x02 /* Software reboot */
+
+#define BOOTFLASH_START	0xF0000000
+
+#define CONFIG_KM_CONSOLE_TTY	"ttyS0"
+
+/*
+ * Environment Configuration
+ */
+#define CONFIG_ENV_OVERWRITE
+#ifndef CONFIG_KM_DEF_ENV		/* if not set by keymile-common.h */
+#define CONFIG_KM_DEF_ENV "km-common=empty\0"
+#endif
+
+#ifndef CONFIG_KM_DEF_ROOTPATH
+#define CONFIG_KM_DEF_ROOTPATH		\
+	"rootpath=/opt/eldk/ppc_82xx\0"
+#endif
+
+#define CONFIG_EXTRA_ENV_SETTINGS \
+	CONFIG_KM_DEF_ENV						\
+	CONFIG_KM_DEF_ROOTPATH						\
+	"dtt_bus=pca9547:70:a\0"					\
+	"EEprom_ivm=pca9547:70:9\0"					\
+	"newenv="							\
+		"prot off 0xF00C0000 +0x40000 && "			\
+		"era 0xF00C0000 +0x40000\0"				\
+	"unlock=yes\0"							\
+	""
+
+#if defined(CONFIG_UEC_ETH)
+#define CONFIG_HAS_ETH0
+#endif
+
+#endif /* __CONFIG_KM83XX_H */
diff --git a/include/configs/km_arm.h b/include/configs/km_arm.h
index bf77cc0..70113d4 100644
--- a/include/configs/km_arm.h
+++ b/include/configs/km_arm.h
@@ -6,6 +6,9 @@
  * (C) Copyright 2009
  * Stefan Roese, DENX Software Engineering, sr@denx.de.
  *
+ * (C) Copyright 2010-2011
+ * Heiko Schocher, DENX Software Engineering, hs@denx.de.
+ *
  * See file CREDITS for list of people who contributed to this
  * project.
  *
@@ -25,7 +28,10 @@
  * MA 02110-1301 USA
  */
 
-/* for linking errors see http://lists.denx.de/pipermail/u-boot/2009-July/057350.html */
+/*
+ * for linking errors see
+ * http://lists.denx.de/pipermail/u-boot/2009-July/057350.html
+ */
 
 #ifndef _CONFIG_KM_ARM_H
 #define _CONFIG_KM_ARM_H
@@ -38,12 +44,34 @@
 #define CONFIG_FEROCEON_88FR131		/* CPU Core subversion */
 #define CONFIG_KIRKWOOD			/* SOC Family Name */
 #define CONFIG_KW88F6281		/* SOC Name */
-#define CONFIG_MACH_SUEN3		/* Machine type */
+#define CONFIG_MACH_KM_KIRKWOOD		/* Machine type */
 
 /* include common defines/options for all Keymile boards */
 #include "keymile-common.h"
-#undef CONFIG_CMD_DTT
-#undef CONFIG_BOOTCOUNT_LIMIT
+
+#define CONFIG_SYS_TEXT_BASE	0x04000000	/* code address after reloc */
+#define CONFIG_ENV_SIZE		(128 << 10)	/* NAND chip block size	*/
+#define CONFIG_SYS_MEMTEST_START 0x00400000	/* 4M */
+#define CONFIG_SYS_MEMTEST_END	0x007fffff	/*(_8M -1) */
+#define CONFIG_SYS_LOAD_ADDR	0x00800000	/* default load adr- 8M */
+
+/* pseudo-non volatile RAM [hex] */
+#define CONFIG_KM_PNVRAM	0x80000
+/* physical RAM MTD size [hex] */
+#define CONFIG_KM_PHRAM		0x17F000
+
+#define CONFIG_KM_CRAMFS_ADDR	0x2400000
+#define CONFIG_KM_KERNEL_ADDR	0x2000000	/* 4096KBytes */
+
+#define CONFIG_KM_DEF_ENV_CPU						\
+	"addmtdparts=setenv bootargs ${bootargs} ${mtdparts}\0"		\
+	"boot=bootm ${actual_kernel_addr} - -\0"			\
+	"cramfsloadfdt=echo \\\\c\0"					\
+	"tftpfdt=echo \\\\c\0"						\
+	CONFIG_KM_DEF_ENV_UPDATE					\
+	""
+
+
 
 #define CONFIG_MD5	/* get_random_hex on krikwood needs MD5 support */
 #define CONFIG_SKIP_LOWLEVEL_INIT	/* disable board lowlevel_init */
@@ -152,15 +180,15 @@
 void set_scl (int state);
 int get_sda (void);
 int get_scl (void);
-#define SUEN3_SDA_PIN	8
-#define SUEN3_SCL_PIN	9
-#define SUEN3_ENV_WP	38
+#define KM_KIRKWOOD_SDA_PIN	8
+#define KM_KIRKWOOD_SCL_PIN	9
+#define KM_KIRKWOOD_ENV_WP	38
 
-#define I2C_ACTIVE	__set_direction(SUEN3_SDA_PIN, 0)
-#define I2C_TRISTATE	__set_direction(SUEN3_SDA_PIN, 1)
-#define I2C_READ	(kw_gpio_get_value(SUEN3_SDA_PIN) ? 1 : 0)
-#define I2C_SDA(bit)	kw_gpio_set_value(SUEN3_SDA_PIN, bit);
-#define I2C_SCL(bit)	kw_gpio_set_value(SUEN3_SCL_PIN, bit);
+#define I2C_ACTIVE	__set_direction(KM_KIRKWOOD_SDA_PIN, 0)
+#define I2C_TRISTATE	__set_direction(KM_KIRKWOOD_SDA_PIN, 1)
+#define I2C_READ	(kw_gpio_get_value(KM_KIRKWOOD_SDA_PIN) ? 1 : 0)
+#define I2C_SDA(bit)	kw_gpio_set_value(KM_KIRKWOOD_SDA_PIN, bit)
+#define I2C_SCL(bit)	kw_gpio_set_value(KM_KIRKWOOD_SCL_PIN, bit)
 #endif
 
 #define I2C_DELAY	udelay(3)	/* 1/4 I2C clock duration */
@@ -173,6 +201,47 @@
 #define CONFIG_SYS_I2C_EEPROM_ADDR	0x50
 #define CONFIG_SYS_I2C_EEPROM_ADDR_LEN	2
 
+/*
+ *  Environment variables configurations
+ */
+#define CONFIG_ENV_IS_IN_EEPROM		/* use EEPROM for environment vars */
+#define CONFIG_SYS_DEF_EEPROM_ADDR	0x50
+#define CONFIG_ENV_EEPROM_IS_ON_I2C
+#define CONFIG_SYS_EEPROM_WREN
+#define CONFIG_ENV_OFFSET		0x0 /* no bracets! */
+#undef	CONFIG_ENV_SIZE
+#define CONFIG_ENV_SIZE			(0x2000 - CONFIG_ENV_OFFSET)
+#define CONFIG_I2C_ENV_EEPROM_BUS	"pca9547:70:d\0"
+
+/* offset redund: (CONFIG_ENV_OFFSET + CONFIG_ENV_SIZE) */
+#define CONFIG_SYS_REDUNDAND_ENVIRONMENT
+#define CONFIG_ENV_OFFSET_REDUND	0x2000 /* no bracets! */
+#define CONFIG_ENV_SIZE_REDUND		(CONFIG_ENV_SIZE)
+
+#define CONFIG_CMD_SF
+
+#define CONFIG_SPI_FLASH
+#define CONFIG_HARD_SPI
+#define CONFIG_KIRKWOOD_SPI
+#define CONFIG_SPI_FLASH_STMICRO
+#define CONFIG_ENV_SPI_BUS		0
+#define CONFIG_ENV_SPI_CS		0
+#define CONFIG_ENV_SPI_MAX_HZ		50000000	/* 50Mhz */
+
+#define FLASH_GPIO_PIN			0x00010000
+
+#define MTDIDS_DEFAULT		"nand0=orion_nand"
+/* test-only: partitioning needs some tuning, this is just for tests */
+#define MTDPARTS_DEFAULT	"mtdparts="				\
+	"orion_nand:"							\
+		"-(" CONFIG_KM_UBI_PARTITION_NAME ")"
+
+#define	CONFIG_KM_DEF_ENV_UPDATE					\
+	"update="							\
+		"spi on;sf probe 0;sf erase 0 50000;"			\
+		"sf write ${u-boot_addr_r} 0 ${filesize};"		\
+		"spi off\0"
+
 #if defined(CONFIG_SYS_NO_FLASH)
 #define CONFIG_KM_UBI_PARTITION_NAME   "ubi0"
 #undef	CONFIG_FLASH_CFI_MTD
@@ -185,4 +254,13 @@
 #define CONFIG_SYS_INIT_SP_ADDR		0xC8012000
 /* Do early setups now in board_init_f() */
 #define CONFIG_BOARD_EARLY_INIT_F
+
+/*
+ * resereved pram area at the end of memroy [hex]
+ * 8Mbytes for switch + 4Kbytes for bootcount
+ */
+#define CONFIG_KM_RESERVED_PRAM 0x801000
+/* address for the bootcount (taken from end of RAM) */
+#define BOOTCOUNT_ADDR          (CONFIG_KM_RESERVED_PRAM)
+
 #endif /* _CONFIG_KM_ARM_H */
diff --git a/include/configs/kmeter1.h b/include/configs/kmeter1.h
index b98e6a1..2fcecaf 100644
--- a/include/configs/kmeter1.h
+++ b/include/configs/kmeter1.h
@@ -8,7 +8,7 @@
  * Copyright (C) 2007 MontaVista Software, Inc.
  *                    Anton Vorontsov <avorontsov@ru.mvista.com>
  *
- * (C) Copyright 2008
+ * (C) Copyright 2008-2011
  * Heiko Schocher, DENX Software Engineering, hs@denx.de.
  *
  * This program is free software; you can redistribute it and/or
@@ -23,32 +23,24 @@
 /*
  * High Level Configuration Options
  */
-#define CONFIG_E300		1 /* E300 family */
-#define CONFIG_QE		1 /* Has QE */
-#define CONFIG_MPC83xx		1 /* MPC83xx family */
-#define CONFIG_MPC8360		1 /* MPC8360 CPU specific */
-#define CONFIG_KMETER1		1 /* KMETER1 board specific */
+#define CONFIG_QE		/* Has QE */
+#define CONFIG_MPC8360		/* MPC8360 CPU specific */
+#define CONFIG_KMETER1		/* KMETER1 board specific */
 #define CONFIG_HOSTNAME		kmeter1
+#define CONFIG_KM_BOARD_NAME   "kmeter1"
 
 #define	CONFIG_SYS_TEXT_BASE	0xF0000000
+#define CONFIG_KM_DEF_NETDEV	\
+	"netdev=eth2\0"		\
 
-/* include common defines/options for all Keymile boards */
-#include "keymile-common.h"
+/* include common defines/options for all 83xx Keymile boards */
+#include "km83xx-common.h"
 
-#define CONFIG_KM_UBI_PARTITION_NAME	"ubi0"
-
-#define MTDIDS_DEFAULT		"nor0=boot"
-#define MTDPARTS_DEFAULT	\
-	"mtdparts=boot:768k(u-boot),128k(env),128k(envred),"	\
-	"-(" CONFIG_KM_UBI_PARTITION_NAME ")"
-
-#define CONFIG_MISC_INIT_R	1
+#define CONFIG_MISC_INIT_R
 /*
- * System Clock Setup
+ * System IO Setup
  */
-#define CONFIG_83XX_CLKIN		66000000
-#define CONFIG_SYS_CLK_FREQ		66000000
-#define CONFIG_83XX_PCICLK		66000000
+#define CONFIG_SYS_SICRH		(SICRH_UC1EOBI | SICRH_UC2E1OBI)
 
 /*
  * Hardware Reset Configuration Word
@@ -69,54 +61,7 @@
 	HRCWH_LALE_EARLY | \
 	HRCWH_LDP_CLEAR )
 
-/*
- * System IO Config
- */
-#define CONFIG_SYS_SICRH		0x00000006
-#define CONFIG_SYS_SICRL		0x00000000
-
-/*
- * IMMR new address
- */
-#define CONFIG_SYS_IMMR		0xE0000000
-
-/*
- * Bus Arbitration Configuration Register (ACR)
- */
-#define CONFIG_SYS_ACR_PIPE_DEP 3       /* pipeline depth 4 transactions */
-#define CONFIG_SYS_ACR_RPTCNT   3       /* 4 consecutive transactions */
-#define CONFIG_SYS_ACR_APARK    0       /* park bus to master (below) */
-#define CONFIG_SYS_ACR_PARKM    3       /* parking master = QuiccEngine */
-
-/*
- * DDR Setup
- */
-#define CONFIG_SYS_DDR_BASE		0x00000000 /* DDR is system memory */
-#define CONFIG_SYS_SDRAM_BASE		CONFIG_SYS_DDR_BASE
-#define CONFIG_SYS_DDR_SDRAM_BASE	CONFIG_SYS_DDR_BASE
-#define CONFIG_SYS_DDR_SDRAM_CLK_CNTL	(DDR_SDRAM_CLK_CNTL_SS_EN | \
-					DDR_SDRAM_CLK_CNTL_CLK_ADJUST_05)
-
-#define CFG_83XX_DDR_USES_CS0
-
-#undef CONFIG_DDR_ECC
-
-/*
- * DDRCDR - DDR Control Driver Register
- */
-
-#undef CONFIG_SPD_EEPROM	/* Do not use SPD EEPROM for DDR setup */
-
-/*
- * Manually set up DDR parameters
- */
-#define CONFIG_DDR_II
-#define CONFIG_SYS_DDR_SIZE		2048 /* MB */
 #define CONFIG_SYS_DDR_CS0_BNDS		0x0000007f
-#define CONFIG_SYS_DDR_CS0_CONFIG	(CSCONFIG_EN | CSCONFIG_AP | \
-					 CSCONFIG_ROW_BIT_13 | \
-					 CSCONFIG_COL_BIT_10 | CSCONFIG_ODT_WR_ACS)
-
 #define CONFIG_SYS_DDR_SDRAM_CFG	(SDRAM_CFG_SDRAM_TYPE_DDR2 | \
 					 SDRAM_CFG_SREN)
 #define CONFIG_SYS_DDR_SDRAM_CFG2	0x00401000
@@ -124,6 +69,11 @@
 #define CONFIG_SYS_DDR_INTERVAL	((0x080 << SDRAM_INTERVAL_BSTOPRE_SHIFT) | \
 				 (0x3cf << SDRAM_INTERVAL_REFINT_SHIFT))
 
+#define CONFIG_SYS_DDR_CS0_CONFIG	(CSCONFIG_EN | CSCONFIG_AP | \
+					 CSCONFIG_ROW_BIT_13 | \
+					 CSCONFIG_COL_BIT_10 | \
+					 CSCONFIG_ODT_WR_ACS)
+
 #define	CONFIG_SYS_DDRCDR		0x40000001
 #define CONFIG_SYS_DDR_MODE		0x47860452
 #define CONFIG_SYS_DDR_MODE2		0x8080c000
@@ -137,14 +87,14 @@
 				 (0 << TIMING_CFG0_WRT_SHIFT) | \
 				 (0 << TIMING_CFG0_RWT_SHIFT))
 
-#define CONFIG_SYS_DDR_TIMING_1	((      TIMING_CFG1_CASLAT_50) | \
-				 ( 2 << TIMING_CFG1_WRTORD_SHIFT) | \
-				 ( 2 << TIMING_CFG1_ACTTOACT_SHIFT) | \
-				 ( 3 << TIMING_CFG1_WRREC_SHIFT) | \
-				 ( 7 << TIMING_CFG1_REFREC_SHIFT) | \
-				 ( 3 << TIMING_CFG1_ACTTORW_SHIFT) | \
-				 ( 8 << TIMING_CFG1_ACTTOPRE_SHIFT) | \
-				 ( 3 << TIMING_CFG1_PRETOACT_SHIFT))
+#define CONFIG_SYS_DDR_TIMING_1	((TIMING_CFG1_CASLAT_50) | \
+				 (2 << TIMING_CFG1_WRTORD_SHIFT) | \
+				 (2 << TIMING_CFG1_ACTTOACT_SHIFT) | \
+				 (3 << TIMING_CFG1_WRREC_SHIFT) | \
+				 (7 << TIMING_CFG1_REFREC_SHIFT) | \
+				 (3 << TIMING_CFG1_ACTTORW_SHIFT) | \
+				 (8 << TIMING_CFG1_ACTTOPRE_SHIFT) | \
+				 (3 << TIMING_CFG1_PRETOACT_SHIFT))
 
 #define CONFIG_SYS_DDR_TIMING_2	((8 << TIMING_CFG2_FOUR_ACT_SHIFT) | \
 				 (3 << TIMING_CFG2_CKE_PLS_SHIFT) | \
@@ -156,31 +106,15 @@
 
 #define CONFIG_SYS_DDR_TIMING_3	0x00000000
 
-/*
- * The reserved memory
- */
-#define CONFIG_SYS_MONITOR_BASE	CONFIG_SYS_TEXT_BASE /* start of monitor */
-#define CONFIG_SYS_FLASH_BASE		0xF0000000
-#define CONFIG_SYS_PIGGY_BASE		0xE8000000
-#define	CONFIG_SYS_PIGGY_SIZE		128
-#define CONFIG_SYS_PAXE_BASE		0xA0000000
+/* PRIO FPGA */
+#define	CONFIG_SYS_KMBEC_FPGA_BASE	0xE8000000
+#define	CONFIG_SYS_KMBEC_FPGA_SIZE	128
+/* PAXE FPGA */
+#define	CONFIG_SYS_PAXE_BASE		0xA0000000
 #define	CONFIG_SYS_PAXE_SIZE		512
 
-#if (CONFIG_SYS_MONITOR_BASE < CONFIG_SYS_FLASH_BASE)
-#define CONFIG_SYS_RAMBOOT
-#else
-#undef	CONFIG_SYS_RAMBOOT
-#endif
-
-#define CONFIG_SYS_MONITOR_LEN		(384 * 1024) /* Reserve 384 kB for Mon */
-
-/*
- * Initial RAM Base Address Setup
- */
-#define CONFIG_SYS_INIT_RAM_LOCK	1
-#define CONFIG_SYS_INIT_RAM_ADDR	0xE6000000 /* Initial RAM address */
-#define CONFIG_SYS_INIT_RAM_SIZE	0x1000 /* Size of used area in RAM */
-#define CONFIG_SYS_GBL_DATA_OFFSET	(CONFIG_SYS_INIT_RAM_SIZE - GENERATED_GBL_DATA_SIZE)
+/* EEprom support */
+#define CONFIG_SYS_I2C_EEPROM_ADDR_LEN	2
 
 /*
  * Local Bus Configuration & Clock Setup
@@ -194,56 +128,14 @@
  *
  * Bank Bus     Machine PortSz  Size  Device
  * ---- ---     ------- ------  -----  ------
- *  0   Local   GPCM    16 bit  256MB FLASH
- *  1   Local   GPCM     8 bit  128MB GPIO/PIGGY
  *  3   Local   GPCM     8 bit  512MB PAXE
  *
  */
-/*
- * FLASH on the Local Bus
- */
-#define CONFIG_SYS_FLASH_CFI		/* use the Common Flash Interface */
-#define CONFIG_FLASH_CFI_DRIVER		/* use the CFI driver */
-#define CONFIG_SYS_FLASH_SIZE		256 /* max FLASH size is 256M */
-#define CONFIG_SYS_FLASH_PROTECTION	1
-#define CONFIG_SYS_FLASH_USE_BUFFER_WRITE	1
-
-#define CONFIG_SYS_LBLAWBAR0_PRELIM	CONFIG_SYS_FLASH_BASE /* Window base at flash base */
-#define CONFIG_SYS_LBLAWAR0_PRELIM	0x8000001b /* 256MB window size */
-
-#define CONFIG_SYS_BR0_PRELIM	(CONFIG_SYS_FLASH_BASE | \
-				(2 << BR_PS_SHIFT) | /* 16 bit port size */ \
-				BR_V)
-
-#define CONFIG_SYS_OR0_PRELIM	(MEG_TO_AM(CONFIG_SYS_FLASH_SIZE) | \
-				OR_GPCM_CSNT | OR_GPCM_ACS_DIV2 | \
-				OR_GPCM_SCY_5 | \
-				OR_GPCM_TRLX | OR_GPCM_EAD)
-
-#define CONFIG_SYS_MAX_FLASH_BANKS	1	/* max num of flash banks	*/
-#define CONFIG_SYS_MAX_FLASH_SECT	512	/* max num of sects on one chip */
-#define CONFIG_SYS_FLASH_BANKS_LIST { CONFIG_SYS_FLASH_BASE }
-
-#undef	CONFIG_SYS_FLASH_CHECKSUM
-
-/*
- * PRIO1/PIGGY on the local bus CS1
- */
-#define CONFIG_SYS_LBLAWBAR1_PRELIM	CONFIG_SYS_PIGGY_BASE /* Window base at flash base */
-#define CONFIG_SYS_LBLAWAR1_PRELIM	0x8000001A /* 128MB window size */
-
-#define CONFIG_SYS_BR1_PRELIM	(CONFIG_SYS_PIGGY_BASE | \
-				(1 << BR_PS_SHIFT) | /* 8 bit port size */ \
-				BR_V)
-#define CONFIG_SYS_OR1_PRELIM		(MEG_TO_AM(CONFIG_SYS_PIGGY_SIZE) | /* 128MB */ \
-				OR_GPCM_CSNT | OR_GPCM_ACS_DIV2 | \
-				OR_GPCM_SCY_2 | \
-				OR_GPCM_TRLX | OR_GPCM_EAD)
 
 /*
  * PAXE on the local bus CS3
  */
-#define CONFIG_SYS_LBLAWBAR3_PRELIM	CONFIG_SYS_PAXE_BASE /* Window base at flash base */
+#define CONFIG_SYS_LBLAWBAR3_PRELIM	CONFIG_SYS_PAXE_BASE
 #define CONFIG_SYS_LBLAWAR3_PRELIM	0x8000001C /* 512MB window size */
 
 #define CONFIG_SYS_BR3_PRELIM	(CONFIG_SYS_PAXE_BASE | \
@@ -255,165 +147,14 @@
 				OR_GPCM_TRLX | OR_GPCM_EAD)
 
 /*
- * Serial Port
- */
-#define CONFIG_CONS_INDEX	1
-#define CONFIG_SYS_NS16550
-#define CONFIG_SYS_NS16550_SERIAL
-#define CONFIG_SYS_NS16550_REG_SIZE	1
-#define CONFIG_SYS_NS16550_CLK		get_bus_freq(0)
-
-#define CONFIG_SYS_NS16550_COM1	(CONFIG_SYS_IMMR+0x4500)
-#define CONFIG_SYS_NS16550_COM2	(CONFIG_SYS_IMMR+0x4600)
-
-/* Pass open firmware flat tree */
-#define CONFIG_OF_LIBFDT	1
-#define CONFIG_OF_BOARD_SETUP	1
-#define CONFIG_OF_STDOUT_VIA_ALIAS
-
-/*
- * General PCI
- * Addresses are mapped 1-1.
- */
-#undef CONFIG_PCI		/* No PCI */
-
-#ifndef CONFIG_NET_MULTI
-#define CONFIG_NET_MULTI	1
-#endif
-/*
- * QE UEC ethernet configuration
- */
-#define CONFIG_UEC_ETH
-#define CONFIG_ETHPRIME		"UEC0"
-
-#define CONFIG_UEC_ETH1		/* GETH1 */
-#define UEC_VERBOSE_DEBUG	1
-
-#ifdef CONFIG_UEC_ETH1
-#define CONFIG_SYS_UEC1_UCC_NUM	3	/* UCC4 */
-#define CONFIG_SYS_UEC1_RX_CLK		QE_CLK_NONE	/* not used in RMII Mode */
-#define CONFIG_SYS_UEC1_TX_CLK		QE_CLK17
-#define CONFIG_SYS_UEC1_ETH_TYPE	FAST_ETH
-#define CONFIG_SYS_UEC1_PHY_ADDR	0
-#define CONFIG_SYS_UEC1_INTERFACE_TYPE PHY_INTERFACE_MODE_RMII
-#define CONFIG_SYS_UEC1_INTERFACE_SPEED 100
-#endif
-
-/*
- * Environment
- */
-
-#ifndef CONFIG_SYS_RAMBOOT
-#define CONFIG_ENV_IS_IN_FLASH	1
-#define CONFIG_ENV_ADDR		(CONFIG_SYS_MONITOR_BASE + CONFIG_SYS_MONITOR_LEN)
-#define CONFIG_ENV_SECT_SIZE	0x20000 /* 128K(one sector) for env */
-#define CONFIG_ENV_OFFSET	(CONFIG_SYS_MONITOR_LEN)
-
-/* Address and size of Redundant Environment Sector	*/
-#define CONFIG_ENV_OFFSET_REDUND	(CONFIG_ENV_OFFSET+CONFIG_ENV_SECT_SIZE)
-#define CONFIG_ENV_SIZE_REDUND	(CONFIG_ENV_SIZE)
-
-#else /* CFG_RAMBOOT */
-#define CONFIG_SYS_NO_FLASH		1	/* Flash is not usable now */
-#define CONFIG_ENV_IS_NOWHERE	1	/* Store ENV in memory only */
-#define CONFIG_ENV_ADDR		(CONFIG_SYS_MONITOR_BASE - 0x1000)
-#define CONFIG_ENV_SIZE		0x2000
-#endif /* CFG_RAMBOOT */
-
-/* I2C */
-#define CONFIG_HARD_I2C		/* I2C with hardware support */
-#undef	CONFIG_SOFT_I2C		/* I2C bit-banged */
-#define CONFIG_FSL_I2C
-#define CONFIG_SYS_I2C_SPEED	200000	/* I2C speed and slave address */
-#define CONFIG_SYS_I2C_SLAVE	0x7F
-#define CONFIG_SYS_I2C_OFFSET	0x3000
-#define CONFIG_I2C_MULTI_BUS	1
-#define CONFIG_I2C_MUX		1
-
-/* EEprom support */
-#define CONFIG_SYS_I2C_EEPROM_ADDR_LEN	2
-
-/* I2C SYSMON (LM75, AD7414 is almost compatible)			*/
-#define CONFIG_DTT_LM75		1	/* ON Semi's LM75		*/
-#define CONFIG_DTT_SENSORS	{0, 1, 2, 3}	/* Sensor addresses		*/
-#define CONFIG_SYS_DTT_MAX_TEMP	70
-#define CONFIG_SYS_DTT_LOW_TEMP	-30
-#define CONFIG_SYS_DTT_HYSTERESIS	3
-#define CONFIG_SYS_DTT_BUS_NUM		(CONFIG_SYS_MAX_I2C_BUS)
-
-#if defined(CONFIG_CMD_NAND)
-#define CONFIG_NAND_KMETER1
-#define CONFIG_SYS_MAX_NAND_DEVICE	1
-#define CONFIG_SYS_NAND_BASE		CONFIG_SYS_PIGGY_BASE
-#endif
-
-#if defined(CONFIG_PCI)
-#define CONFIG_CMD_PCI
-#endif
-
-#if defined(CFG_RAMBOOT)
-#undef CONFIG_CMD_SAVEENV
-#undef CONFIG_CMD_LOADS
-#endif
-
-/*
- * For booting Linux, the board info and command line data
- * have to be in the first 256 MB of memory, since this is
- * the maximum mapped by the Linux kernel during initialization.
- */
-#define CONFIG_SYS_BOOTMAPSZ		(256 << 20) /* Initial Memory map for Linux */
-
-/*
- * Core HID Setup
- */
-#define CONFIG_SYS_HID0_INIT		0x000000000
-#define CONFIG_SYS_HID0_FINAL		(HID0_ENABLE_MACHINE_CHECK | \
-					 HID0_ENABLE_INSTRUCTION_CACHE)
-#define CONFIG_SYS_HID2			HID2_HBE
-
-/*
  * MMU Setup
  */
 
-#define CONFIG_HIGH_BATS	1	/* High BATs supported */
-
-/* DDR: cache cacheable */
-#define CONFIG_SYS_IBAT0L	(CONFIG_SYS_SDRAM_BASE | BATL_PP_10 | \
-				BATL_CACHEINHIBIT | BATL_GUARDEDSTORAGE)
-#define CONFIG_SYS_IBAT0U	(CONFIG_SYS_SDRAM_BASE | BATU_BL_256M | BATU_VS | BATU_VP)
-#define CONFIG_SYS_DBAT0L	CONFIG_SYS_IBAT0L
-#define CONFIG_SYS_DBAT0U	CONFIG_SYS_IBAT0U
-
-/* IMMRBAR & PCI IO: cache-inhibit and guarded */
-#define CONFIG_SYS_IBAT1L	(CONFIG_SYS_IMMR | BATL_PP_10 | \
-				BATL_CACHEINHIBIT | BATL_GUARDEDSTORAGE)
-#define CONFIG_SYS_IBAT1U	(CONFIG_SYS_IMMR | BATU_BL_4M | BATU_VS | BATU_VP)
-#define CONFIG_SYS_DBAT1L	CONFIG_SYS_IBAT1L
-#define CONFIG_SYS_DBAT1U	CONFIG_SYS_IBAT1U
-
-/* PRIO1, PIGGY:  icache cacheable, but dcache-inhibit and guarded */
-#define CONFIG_SYS_IBAT2L	(CONFIG_SYS_PIGGY_BASE | BATL_PP_10 | BATL_MEMCOHERENCE)
-#define CONFIG_SYS_IBAT2U	(CONFIG_SYS_PIGGY_BASE | BATU_BL_128M | BATU_VS | BATU_VP)
-#define CONFIG_SYS_DBAT2L	(CONFIG_SYS_PIGGY_BASE | BATL_PP_10 | \
-				 BATL_CACHEINHIBIT | BATL_GUARDEDSTORAGE)
-#define CONFIG_SYS_DBAT2U	CONFIG_SYS_IBAT2U
-
-/* FLASH: icache cacheable, but dcache-inhibit and guarded */
-#define CONFIG_SYS_IBAT3L	(CONFIG_SYS_FLASH_BASE | BATL_PP_10 | BATL_MEMCOHERENCE)
-#define CONFIG_SYS_IBAT3U	(CONFIG_SYS_FLASH_BASE | BATU_BL_256M | BATU_VS | BATU_VP)
-#define CONFIG_SYS_DBAT3L	(CONFIG_SYS_FLASH_BASE | BATL_PP_10 | \
-				 BATL_CACHEINHIBIT | BATL_GUARDEDSTORAGE)
-#define CONFIG_SYS_DBAT3U	CONFIG_SYS_IBAT3U
-
-/* Stack in dcache: cacheable, no memory coherence */
-#define CONFIG_SYS_IBAT4L	(CONFIG_SYS_INIT_RAM_ADDR | BATL_PP_10)
-#define CONFIG_SYS_IBAT4U	(CONFIG_SYS_INIT_RAM_ADDR | BATU_BL_128K | BATU_VS | BATU_VP)
-#define CONFIG_SYS_DBAT4L	CONFIG_SYS_IBAT4L
-#define CONFIG_SYS_DBAT4U	CONFIG_SYS_IBAT4U
-
 /* PAXE:  icache cacheable, but dcache-inhibit and guarded */
-#define CONFIG_SYS_IBAT5L	(CONFIG_SYS_PAXE_BASE | BATL_PP_10 | BATL_MEMCOHERENCE)
-#define CONFIG_SYS_IBAT5U	(CONFIG_SYS_PAXE_BASE | BATU_BL_256M | BATU_VS | BATU_VP)
+#define CONFIG_SYS_IBAT5L	(CONFIG_SYS_PAXE_BASE | BATL_PP_10 | \
+				 BATL_MEMCOHERENCE)
+#define CONFIG_SYS_IBAT5U	(CONFIG_SYS_PAXE_BASE | BATU_BL_256M | \
+				 BATU_VS | BATU_VP)
 #define CONFIG_SYS_DBAT5L	(CONFIG_SYS_PAXE_BASE | BATL_PP_10 | \
 				 BATL_CACHEINHIBIT | BATL_GUARDEDSTORAGE)
 #define CONFIG_SYS_DBAT5U	CONFIG_SYS_IBAT5U
@@ -441,39 +182,4 @@
 #define CONFIG_SYS_DBAT7U	CONFIG_SYS_IBAT7U
 #endif /* CONFIG_PCI */
 
-#define BOOTFLASH_START	F0000000
-
-#define CONFIG_PRAM	512	/* protected RAM [KBytes] */
-
-/*
- * Environment Configuration
- */
-#define CONFIG_ENV_OVERWRITE
-#ifndef CONFIG_KM_DEF_ENV		/* if not set by keymile-common.h */
-#define CONFIG_KM_DEF_ENV "km-common=empty\0"
-#endif
-
-#define CONFIG_EXTRA_ENV_SETTINGS \
-       CONFIG_KM_DEF_ENV						\
-	"rootpath=/opt/eldk/ppc_82xx\0"					\
-	"addcon=setenv bootargs ${bootargs} console=ttyS0,${baudrate}\0"\
-	"ramdisk_file=/tftpboot/kmeter1/uRamdisk\0"			\
-	"loadram=tftp ${ramdisk_addr_r} ${ramdisk_file}\0"		\
-	"loadfdt=tftp ${fdt_addr_r} ${fdt_file}\0"			\
-	"loadkernel=tftp ${kernel_addr_r} ${bootfile}\0"		\
-	"unlock=yes\0"							\
-	"fdt_addr=F0080000\0"						\
-	"kernel_addr=F00a0000\0"					\
-	"ramdisk_addr=F03a0000\0"					\
-	"ramdisk_addr_r=F10000\0"					\
-	"EEprom_ivm=pca9547:70:9\0"					\
-	"dtt_bus=pca9547:70:a\0"					\
-	"mtdids=nor0=app \0"						\
-	"mtdparts=" MK_STR(MTDPARTS_DEFAULT) "\0"			\
-   ""
-
-#if defined(CONFIG_UEC_ETH)
-#define CONFIG_HAS_ETH0
-#endif
-
 #endif /* __CONFIG_H */
diff --git a/include/configs/kmsupx5.h b/include/configs/kmsupx5.h
new file mode 100644
index 0000000..55ed3f6
--- /dev/null
+++ b/include/configs/kmsupx5.h
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2006 Freescale Semiconductor, Inc.
+ *                    Dave Liu <daveliu@freescale.com>
+ *
+ * Copyright (C) 2007 Logic Product Development, Inc.
+ *                    Peter Barada <peterb@logicpd.com>
+ *
+ * Copyright (C) 2007 MontaVista Software, Inc.
+ *                    Anton Vorontsov <avorontsov@ru.mvista.com>
+ *
+ * (C) Copyright 2008
+ * Heiko Schocher, DENX Software Engineering, hs@denx.de.
+ *
+ * (C) Copyright 2010
+ * Lukas Roggli, KEYMILE Ltd, lukas.roggli@keymile.com
+ *
+ * (C) Copyright 2010-2011
+ * Thomas Reufer, KEYMILE Ltd, thomas.reufer@keymile.com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+/*
+ * High Level Configuration Options
+ */
+#define CONFIG_KMSUPX5		1 /* Keymile PBEC8321 board specific */
+#define CONFIG_HOSTNAME		supx5
+#define CONFIG_KM_BOARD_NAME	"supx5"
+
+#define	CONFIG_SYS_TEXT_BASE	0xF0000000
+
+/* include common defines/options for all 8321 Keymile boards */
+#include "km8321-common.h"
+
+/*
+ * Init Local Bus Memory Controller:
+ *
+ * Bank Bus     Machine PortSz  Size  Device
+ * ---- ---     ------- ------  -----  ------
+ *  2   Local   GPCM    8 bit  256MB	LPXF
+ *  3   Local   not used
+ *
+ */
+
+/*
+ * LPXF on the local bus CS2
+ * Window base at flash base
+ * Window size: 256 MB
+ */
+
+#define	CONFIG_SYS_LPXF_BASE		0xA0000000    /* LPXF */
+#define	CONFIG_SYS_LPXF_SIZE		256 /* Megabytes */
+
+#define CONFIG_SYS_LBLAWBAR2_PRELIM	CONFIG_SYS_LPXF_BASE
+#define CONFIG_SYS_LBLAWAR2_PRELIM	(LBLAWAR_EN | LBLAWAR_256MB)
+
+#define CONFIG_SYS_BR2_PRELIM	(CONFIG_SYS_LPXF_BASE | \
+				 BR_PS_8 | \
+				 BR_MS_GPCM | \
+				 BR_V)
+
+#define CONFIG_SYS_OR2_PRELIM	(MEG_TO_AM(CONFIG_SYS_LPXF_SIZE) | \
+				 OR_GPCM_CSNT | \
+				 OR_GPCM_ACS_DIV4 | \
+				 OR_GPCM_SCY_2 | \
+				 (OR_GPCM_TRLX & \
+				 (~OR_GPCM_EHTR)) |  /* EHTR = 0 */ \
+				 OR_GPCM_EAD)
+
+/* LPXF:  icache cacheable, but dcache-inhibit and guarded */
+#define CONFIG_SYS_IBAT5L	(CONFIG_SYS_LPXF_BASE | BATL_PP_10 | \
+				 BATL_MEMCOHERENCE)
+#define CONFIG_SYS_IBAT5U	(CONFIG_SYS_LPXF_BASE | BATU_BL_256M | \
+				 BATU_VS | BATU_VP)
+#define CONFIG_SYS_DBAT5L	(CONFIG_SYS_LPXF_BASE | BATL_PP_10 | \
+				 BATL_CACHEINHIBIT | BATL_GUARDEDSTORAGE)
+#define CONFIG_SYS_DBAT5U	CONFIG_SYS_IBAT5U
+
+/* Bank 3 not used */
+#define CONFIG_SYS_IBAT6L       (0)
+#define CONFIG_SYS_IBAT6U       (0)
+#define CONFIG_SYS_DBAT6L       CONFIG_SYS_IBAT6L
+#define CONFIG_SYS_DBAT6U       CONFIG_SYS_IBAT6U
+
+#endif /* __CONFIG_H */
diff --git a/include/configs/mgcoge.h b/include/configs/mgcoge.h
index f1bd32a..dcde76c 100644
--- a/include/configs/mgcoge.h
+++ b/include/configs/mgcoge.h
@@ -1,5 +1,5 @@
 /*
- * (C) Copyright 2007
+ * (C) Copyright 2007-2011
  * Heiko Schocher, DENX Software Engineering, hs@denx.de.
  *
  * See file CREDITS for list of people who contributed to this
@@ -29,92 +29,24 @@
  * (easy to change)
  */
 
-#define CONFIG_MPC8247		1
-#define CONFIG_MPC8272_FAMILY   1
-#define CONFIG_MGCOGE		1
+#define CONFIG_MPC8247
+#define CONFIG_MGCOGE
 #define CONFIG_HOSTNAME		mgcoge
 
 #define	CONFIG_SYS_TEXT_BASE	0xFE000000
 
-#define CONFIG_CPM2		1	/* Has a CPM2 */
-
 /* include common defines/options for all Keymile boards */
 #include "keymile-common.h"
-
-/*
- * Select serial console configuration
- *
- * If either CONFIG_CONS_ON_SMC or CONFIG_CONS_ON_SCC is selected, then
- * CONFIG_CONS_INDEX must be set to the channel number (1-2 for SMC, 1-4
- * for SCC).
- */
-#define	CONFIG_CONS_ON_SMC		/* Console is on SMC         */
-#undef  CONFIG_CONS_ON_SCC		/* It's not on SCC           */
-#undef	CONFIG_CONS_NONE		/* It's not on external UART */
-#define CONFIG_CONS_INDEX	2	/* SMC2 is used for console  */
-#define CONFIG_SYS_SMC_RXBUFLEN	128
-#define CONFIG_SYS_MAXIDLE	10
-
-/*
- * Select ethernet configuration
- *
- * If either CONFIG_ETHER_ON_SCC or CONFIG_ETHER_ON_FCC is selected,
- * then CONFIG_ETHER_INDEX must be set to the channel number (1-4 for
- * SCC, 1-3 for FCC)
- *
- * If CONFIG_ETHER_NONE is defined, then either the ethernet routines
- * must be defined elsewhere (as for the console), or CONFIG_CMD_NET
- * must be unset.
- */
-#define	CONFIG_ETHER_ON_SCC		/* Ethernet is on SCC */
-#undef	CONFIG_ETHER_ON_FCC		/* Ethernet is not on FCC     */
-#undef	CONFIG_ETHER_NONE		/* No external Ethernet   */
-#define CONFIG_NET_MULTI	1
-
-#define CONFIG_ETHER_INDEX	4
-#define CONFIG_HAS_ETH0
-#define CONFIG_SYS_SCC_TOUT_LOOP	10000000
-
-# define CONFIG_SYS_CMXSCR_VALUE	(CMXSCR_RS4CS_CLK7 | CMXSCR_TS4CS_CLK8)
-
-#ifndef CONFIG_8260_CLKIN
-#define CONFIG_8260_CLKIN	66000000	/* in Hz */
-#endif
-
-#define BOOTFLASH_START	FE000000
-#define CONFIG_PRAM	512	/* protected RAM [KBytes] */
-
-#define MTDIDS_DEFAULT		"nor0=boot,nor1=app"
-#define MTDPARTS_DEFAULT	\
-	"mtdparts=boot:384k(u-boot),128k(env),128k(envred),3456k(free);" \
-	"app:3m(esw0),10m(rootfs0),3m(esw1),10m(rootfs1),1m(var),5m(cfg)"
-
-#ifndef CONFIG_KM_DEF_ENV		/* if not set by keymile-common.h */
-#define CONFIG_KM_DEF_ENV "km-common=empty\0"
-#endif
-/*
- * Default environment settings
- */
-#define	CONFIG_EXTRA_ENV_SETTINGS	\
-	CONFIG_KM_DEF_ENV						\
-	"rootpath=/opt/eldk/ppc_82xx\0"					\
-	"addcon=setenv bootargs ${bootargs} "				\
-		"console=ttyCPM0,${baudrate}\0"				\
-	"mtdids=nor0=boot,nor1=app \0"					\
-	"partition=nor1,5 \0"						\
-	"new_env=prot off FE060000 FE09FFFF; era FE060000 FE09FFFF \0" 	\
-	"EEprom_ivm=pca9544a:70:4 \0"					\
-	"mtdparts=" MK_STR(MTDPARTS_DEFAULT) "\0"			\
-	"unlock=yes\0"							\
-	""
+#include "km-powerpc.h"
 
 #define CONFIG_SYS_SDRAM_BASE		0x00000000
 #define CONFIG_SYS_FLASH_BASE		0xFE000000
 #define CONFIG_SYS_FLASH_SIZE		32
 #define CONFIG_SYS_FLASH_CFI
 #define CONFIG_FLASH_CFI_DRIVER
-#define CONFIG_SYS_MAX_FLASH_BANKS	3	/* max num of flash banks	*/
-#define CONFIG_SYS_MAX_FLASH_SECT	512	/* max num of sects on one chip */
+#define CONFIG_SYS_MAX_FLASH_BANKS	3
+/* max num of sects on one chip */
+#define CONFIG_SYS_MAX_FLASH_SECT	512
 
 #define CONFIG_SYS_FLASH_BASE_1	0x50000000
 #define CONFIG_SYS_FLASH_SIZE_1	32
@@ -124,232 +56,11 @@
 #define CONFIG_SYS_FLASH_BANKS_LIST { CONFIG_SYS_FLASH_BASE, \
 					CONFIG_SYS_FLASH_BASE_1, \
 					CONFIG_SYS_FLASH_BASE_2 }
+#define MTDIDS_DEFAULT		"nor3=app"
 
-#define CONFIG_SYS_MONITOR_BASE	CONFIG_SYS_TEXT_BASE
-#if (CONFIG_SYS_MONITOR_BASE < CONFIG_SYS_FLASH_BASE)
-#define CONFIG_SYS_RAMBOOT
-#endif
+/* include further common stuff for all keymile 82xx boards */
+#include "km82xx-common.h"
 
-#define CONFIG_SYS_MONITOR_LEN		(384 << 10)	/* Reserve 384KB for Monitor */
-
-#define CONFIG_ENV_IS_IN_FLASH
-
-#ifdef CONFIG_ENV_IS_IN_FLASH
-#define CONFIG_ENV_SECT_SIZE	0x20000
-#define CONFIG_ENV_ADDR		(CONFIG_SYS_MONITOR_BASE + CONFIG_SYS_MONITOR_LEN)
-#define CONFIG_ENV_OFFSET	CONFIG_SYS_MONITOR_LEN
-
-/* Address and size of Redundant Environment Sector	*/
-#define CONFIG_ENV_OFFSET_REDUND	(CONFIG_ENV_OFFSET + CONFIG_ENV_SECT_SIZE)
-#define CONFIG_ENV_SIZE_REDUND		(CONFIG_ENV_SIZE)
-#endif /* CONFIG_ENV_IS_IN_FLASH */
-#define CONFIG_ENV_BUFFER_PRINT		1
-
-/* enable I2C and select the hardware/software driver */
-#undef	CONFIG_HARD_I2C			/* I2C with hardware support	*/
-#define	CONFIG_SOFT_I2C		1	/* I2C bit-banged		*/
-#define CONFIG_SYS_I2C_SPEED		50000	/* I2C speed and slave address	*/
-#define CONFIG_SYS_I2C_SLAVE		0x7F
-
-/*
- * Software (bit-bang) I2C driver configuration
- */
-
-#define I2C_PORT	3		/* Port A=0, B=1, C=2, D=3 */
-#define I2C_ACTIVE	(iop->pdir |=  0x00010000)
-#define I2C_TRISTATE	(iop->pdir &= ~0x00010000)
-#define I2C_READ	((iop->pdat & 0x00010000) != 0)
-#define I2C_SDA(bit)	if(bit) iop->pdat |=  0x00010000; \
-			else    iop->pdat &= ~0x00010000
-#define I2C_SCL(bit)	if(bit) iop->pdat |=  0x00020000; \
-			else    iop->pdat &= ~0x00020000
-#define I2C_DELAY	udelay(5)	/* 1/4 I2C clock duration */
-
-/* I2C SYSMON (LM75, AD7414 is almost compatible)			*/
-#define CONFIG_DTT_LM75		1	/* ON Semi's LM75		*/
-#define CONFIG_DTT_SENSORS	{0}	/* Sensor addresses		*/
-#define CONFIG_SYS_DTT_MAX_TEMP	70
-#define CONFIG_SYS_DTT_LOW_TEMP	-30
-#define CONFIG_SYS_DTT_HYSTERESIS	3
-#define CONFIG_SYS_DTT_BUS_NUM		(CONFIG_SYS_MAX_I2C_BUS)
-
-#define CONFIG_SYS_I2C_EEPROM_ADDR_LEN	1
-
-#define CONFIG_SYS_IMMR		0xF0000000
-
-#define CONFIG_SYS_INIT_RAM_ADDR	CONFIG_SYS_IMMR
-#define CONFIG_SYS_INIT_RAM_SIZE	0x2000	/* Size of used area in DPRAM	*/
-#define CONFIG_SYS_GBL_DATA_OFFSET	(CONFIG_SYS_INIT_RAM_SIZE - GENERATED_GBL_DATA_SIZE)
-#define CONFIG_SYS_INIT_SP_OFFSET	CONFIG_SYS_GBL_DATA_OFFSET
-
-/* Hard reset configuration word */
-#define CONFIG_SYS_HRCW_MASTER		0x0604b211
-
-/* No slaves */
-#define CONFIG_SYS_HRCW_SLAVE1		0
-#define CONFIG_SYS_HRCW_SLAVE2		0
-#define CONFIG_SYS_HRCW_SLAVE3		0
-#define CONFIG_SYS_HRCW_SLAVE4		0
-#define CONFIG_SYS_HRCW_SLAVE5		0
-#define CONFIG_SYS_HRCW_SLAVE6		0
-#define CONFIG_SYS_HRCW_SLAVE7		0
-
-#define CONFIG_SYS_BOOTMAPSZ		(8 << 20)	/* Initial Memory map for Linux */
-
-#define CONFIG_SYS_CACHELINE_SIZE	32	/* For MPC8260 CPUs */
-#if defined(CONFIG_CMD_KGDB)
-#  define CONFIG_SYS_CACHELINE_SHIFT	5	/* log base 2 of the above value */
-#endif
-
-#define CONFIG_SYS_HID0_INIT		0
-#define CONFIG_SYS_HID0_FINAL		(HID0_ICE | HID0_IFEM | HID0_ABE)
-
-#define CONFIG_SYS_HID2		0
-
-#define CONFIG_SYS_SIUMCR		0x4020c200
-#define CONFIG_SYS_SYPCR		0xFFFFFFC3
-#define CONFIG_SYS_BCR			0x10000000
-#define CONFIG_SYS_SCCR		(SCCR_PCI_MODE | SCCR_PCI_MODCK)
-
-/*-----------------------------------------------------------------------
- * RMR - Reset Mode Register                                     5-5
- *-----------------------------------------------------------------------
- * turn on Checkstop Reset Enable
- */
-#define CONFIG_SYS_RMR         0
-
-/*-----------------------------------------------------------------------
- * TMCNTSC - Time Counter Status and Control                     4-40
- *-----------------------------------------------------------------------
- * Clear once per Second and Alarm Interrupt Status, Set 32KHz timersclk,
- * and enable Time Counter
- */
-#define CONFIG_SYS_TMCNTSC     (TMCNTSC_SEC|TMCNTSC_ALR|TMCNTSC_TCF|TMCNTSC_TCE)
-
-/*-----------------------------------------------------------------------
- * PISCR - Periodic Interrupt Status and Control                 4-42
- *-----------------------------------------------------------------------
- * Clear Periodic Interrupt Status, Set 32KHz timersclk, and enable
- * Periodic timer
- */
-#define CONFIG_SYS_PISCR       (PISCR_PS|PISCR_PTF|PISCR_PTE)
-
-/*-----------------------------------------------------------------------
- * RCCR - RISC Controller Configuration                         13-7
- *-----------------------------------------------------------------------
- */
-#define CONFIG_SYS_RCCR        0
-
-/*
- * Init Memory Controller:
- *
- * Bank Bus     Machine PortSz  Device
- * ---- ---     ------- ------  ------
- *  0   60x     GPCM     8 bit  FLASH
- *  1   60x     SDRAM   32 bit  SDRAM
- *  3   60x     GPCM     8 bit  GPIO/PIGGY
- *  5   60x     GPCM    16 bit  CFG-Flash
- *
- */
-/* Bank 0 - FLASH
- */
-#define CONFIG_SYS_BR0_PRELIM  ((CONFIG_SYS_FLASH_BASE & BRx_BA_MSK)	|\
-			 BRx_PS_8			|\
-			 BRx_MS_GPCM_P			|\
-			 BRx_V)
-
-#define CONFIG_SYS_OR0_PRELIM  (MEG_TO_AM(CONFIG_SYS_FLASH_SIZE)	|\
-			 ORxG_CSNT			|\
-			 ORxG_ACS_DIV2			|\
-			 ORxG_SCY_5_CLK			|\
-			 ORxG_TRLX )
-
-
-/* Bank 1 - 60x bus SDRAM
- */
-#define SDRAM_MAX_SIZE	0x08000000	/* max. 128 MB		*/
-#define CONFIG_SYS_GLOBAL_SDRAM_LIMIT	(256 << 20)	/* less than 256 MB */
-
-#define CONFIG_SYS_MPTPR       0x1800
-
-/*-----------------------------------------------------------------------------
- * Address for Mode Register Set (MRS) command
- *-----------------------------------------------------------------------------
- */
-#define CONFIG_SYS_MRS_OFFS	0x00000110
-#define CONFIG_SYS_PSRT        0x0e
-
-#define CONFIG_SYS_BR1_PRELIM  ((CONFIG_SYS_SDRAM_BASE & BRx_BA_MSK)  |\
-			 BRx_PS_64                      |\
-			 BRx_MS_SDRAM_P                 |\
-			 BRx_V)
-
-#define CONFIG_SYS_OR1_PRELIM	CONFIG_SYS_OR1
-
-/* SDRAM initialization values
-*/
-
-#define CONFIG_SYS_OR1    ((~(CONFIG_SYS_GLOBAL_SDRAM_LIMIT-1) & ORxS_SDAM_MSK) |\
-			 ORxS_BPD_8                     |\
-			 ORxS_ROWST_PBI0_A7		|\
-			 ORxS_NUMR_13)
-
-#define CONFIG_SYS_PSDMR  (PSDMR_SDAM_A14_IS_A5 |\
-			 PSDMR_BSMA_A14_A16           |\
-			 PSDMR_SDA10_PBI0_A9		|\
-			 PSDMR_RFRC_5_CLK               |\
-			 PSDMR_PRETOACT_2W              |\
-			 PSDMR_ACTTORW_2W               |\
-			 PSDMR_LDOTOPRE_1C              |\
-			 PSDMR_WRC_1C                   |\
-			 PSDMR_CL_2)
-
-/* GPIO/PIGGY on CS3 initialization values
-*/
-#define CONFIG_SYS_PIGGY_BASE	0x30000000
-#define CONFIG_SYS_PIGGY_SIZE	128
-
-#define CONFIG_SYS_BR3_PRELIM	((CONFIG_SYS_PIGGY_BASE & BRx_BA_MSK) |\
-			 BRx_PS_8 | BRx_MS_GPCM_P | BRx_V)
-
-#define CONFIG_SYS_OR3_PRELIM	(MEG_TO_AM(CONFIG_SYS_PIGGY_SIZE) |\
-			 ORxG_CSNT | ORxG_ACS_DIV2 |\
-			 ORxG_SCY_3_CLK | ORxG_TRLX )
-
-/* Board FPGA on CS4 initialization values
-*/
-#define CONFIG_SYS_FPGA_BASE	0x40000000
-#define CONFIG_SYS_FPGA_SIZE	1 /*1KB*/
-
-#define CONFIG_SYS_BR4_PRELIM ((CONFIG_SYS_FPGA_BASE & BRx_BA_MSK) |\
-			BRx_PS_8 | BRx_MS_GPCM_P | BRx_V)
-
-#define CONFIG_SYS_OR4_PRELIM (P2SZ_TO_AM(CONFIG_SYS_FPGA_SIZE << 10) |\
-			 ORxG_CSNT | ORxG_ACS_DIV2 |\
-			 ORxG_SCY_3_CLK | ORxG_TRLX )
-
-/* CFG-Flash on CS5 initialization values
-*/
-#define CONFIG_SYS_BR5_PRELIM	((CONFIG_SYS_FLASH_BASE_1 & BRx_BA_MSK) |\
-			 BRx_PS_16 | BRx_MS_GPCM_P | BRx_V)
-
-#define CONFIG_SYS_OR5_PRELIM	(MEG_TO_AM(CONFIG_SYS_FLASH_SIZE_1 + \
-				 CONFIG_SYS_FLASH_SIZE_2) |\
-				 ORxG_CSNT | ORxG_ACS_DIV2 |\
-				 ORxG_SCY_5_CLK | ORxG_TRLX )
-
-#define	CONFIG_SYS_RESET_ADDRESS 0xFDFFFFFC	/* "bad" address		*/
-
-/* pass open firmware flat tree */
-#define CONFIG_FIT		1
-#define CONFIG_OF_LIBFDT	1
-#define CONFIG_OF_BOARD_SETUP	1
-
-#define OF_TBCLK		(bd->bi_busfreq / 4)
-#define OF_STDOUT_PATH		"/soc/cpm/serial@11a90"
-
-/* enable last_stage_init */
-#define CONFIG_LAST_STAGE_INIT          1
 /* bfticu address */
 #define CONFIG_SYS_BFTICU_BASE          0x40000000
 
diff --git a/include/configs/mgcoge2ne.h b/include/configs/mgcoge2ne.h
new file mode 100644
index 0000000..287b717
--- /dev/null
+++ b/include/configs/mgcoge2ne.h
@@ -0,0 +1,64 @@
+/*
+ * (C) Copyright 2007-2010
+ * Heiko Schocher, DENX Software Engineering, hs@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.
+ *
+ * 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
+ */
+
+#ifndef __MGCOGE2NE
+#define __MGCOGE2NE
+
+/*
+ * High Level Configuration Options
+ * (easy to change)
+ */
+#define CONFIG_MPC8247
+#define CONFIG_MGCOGE
+#define CONFIG_HOSTNAME		mgcoge2ne
+
+#define	CONFIG_SYS_TEXT_BASE	0xFE000000
+
+/* include common defines/options for all Keymile boards */
+#include "keymile-common.h"
+#include "km-powerpc.h"
+
+#define CONFIG_SYS_SDRAM_BASE		0x00000000
+#define CONFIG_SYS_FLASH_BASE		0xFE000000
+#define CONFIG_SYS_FLASH_SIZE		32
+#define CONFIG_SYS_FLASH_CFI
+#define CONFIG_FLASH_CFI_DRIVER
+#define CONFIG_SYS_MAX_FLASH_BANKS	3	/* max num of flash banks */
+#define CONFIG_SYS_MAX_FLASH_SECT	512	/*
+						 * max num of sects on one
+						 * chip
+						 */
+
+#define CONFIG_SYS_FLASH_BASE_1	0x50000000
+#define CONFIG_SYS_FLASH_SIZE_1	64
+#define CONFIG_SYS_FLASH_SIZE_2	0
+
+#define CONFIG_SYS_FLASH_BANKS_LIST { CONFIG_SYS_FLASH_BASE, \
+					CONFIG_SYS_FLASH_BASE_1 }
+
+#define MTDIDS_DEFAULT		"nor2=app"
+
+/* include further common stuff for all keymile 82xx boards */
+#include "km82xx-common.h"
+
+#endif /* __MGCOGE2NE */
diff --git a/include/configs/mgcoge2un.h b/include/configs/mgcoge2un.h
new file mode 100644
index 0000000..d3c7bdc
--- /dev/null
+++ b/include/configs/mgcoge2un.h
@@ -0,0 +1,65 @@
+/*
+ * (C) Copyright 2009
+ * Marvell Semiconductor <www.marvell.com>
+ * Prafulla Wadaskar <prafulla@marvell.com>
+ *
+ * (C) Copyright 2009
+ * Stefan Roese, DENX Software Engineering, sr@denx.de.
+ *
+ * (C) Copyright 2010-2011
+ * Holger Brunck, Keymile GmbH Hannover, holger.brunck@keymile.com
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+
+/* for linking errors see
+ * http://lists.denx.de/pipermail/u-boot/2009-July/057350.html */
+
+#ifndef _CONFIG_MGCOGE2UN_H
+#define _CONFIG_MGCOGE2UN_H
+
+/* include common defines/options for all arm based Keymile boards */
+#include "km_arm.h"
+
+/*
+ * Version number information
+ */
+#define CONFIG_IDENT_STRING	"\nKeymile MGCOGE2UN"
+
+#define CONFIG_HOSTNAME			mgcoge2un
+
+#define KM_IVM_BUS	"pca9547:70:9" /* I2C2 (Mux-Port 1)*/
+#define KM_ENV_BUS	"pca9547:70:d" /* I2C2 (Mux-Port 5)*/
+
+/*
+ * Default environment variables
+ */
+#define CONFIG_EXTRA_ENV_SETTINGS					\
+	CONFIG_KM_DEF_ENV						\
+	"newenv=setenv addr 0x100000 && "				\
+		"i2c dev 1; mw.b ${addr} 0 4 && "			\
+		"eeprom write " xstr(CONFIG_SYS_DEF_EEPROM_ADDR)	\
+		" ${addr} " xstr(CONFIG_ENV_OFFSET) " 4 && "		\
+		"eeprom write " xstr(CONFIG_SYS_DEF_EEPROM_ADDR)	\
+		" ${addr} " xstr(CONFIG_ENV_OFFSET_REDUND) " 4\0"	\
+	"rootpath=/opt/eldk/arm\0"					\
+	"EEprom_ivm=" KM_IVM_BUS "\0"					\
+	""
+
+#endif /* _CONFIG_MGCOGE2UN_H */
diff --git a/include/configs/mx51evk.h b/include/configs/mx51evk.h
index 50caacd..6a785f8 100644
--- a/include/configs/mx51evk.h
+++ b/include/configs/mx51evk.h
@@ -48,6 +48,8 @@
 #define CONFIG_SETUP_MEMORY_TAGS	1
 #define CONFIG_INITRD_TAG		1
 
+#define CONFIG_OF_LIBFDT		1
+
 /*
  * Size of malloc() pool
  */
diff --git a/include/configs/mx53evk.h b/include/configs/mx53evk.h
index 6ac910b..5749a08 100644
--- a/include/configs/mx53evk.h
+++ b/include/configs/mx53evk.h
@@ -38,6 +38,8 @@
 #define CONFIG_SETUP_MEMORY_TAGS	1
 #define CONFIG_INITRD_TAG		1
 
+#define CONFIG_OF_LIBFDT		1
+
 /* Size of malloc() pool */
 #define CONFIG_SYS_MALLOC_LEN		(CONFIG_ENV_SIZE + 2 * 1024 * 1024)
 
diff --git a/include/configs/omap3_overo.h b/include/configs/omap3_overo.h
index 44a6eb7..c5e997c 100644
--- a/include/configs/omap3_overo.h
+++ b/include/configs/omap3_overo.h
@@ -52,6 +52,8 @@
 #define CONFIG_INITRD_TAG		1
 #define CONFIG_REVISION_TAG		1
 
+#define CONFIG_OF_LIBFDT		1
+
 /*
  * Size of malloc() pool
  */
diff --git a/include/configs/omap3_pandora.h b/include/configs/omap3_pandora.h
index 7b6883c..39c87a8 100644
--- a/include/configs/omap3_pandora.h
+++ b/include/configs/omap3_pandora.h
@@ -55,6 +55,8 @@
 #define CONFIG_INITRD_TAG		1
 #define CONFIG_REVISION_TAG		1
 
+#define CONFIG_OF_LIBFDT		1
+
 /*
  * Size of malloc() pool
  */
diff --git a/include/configs/omap3_sdp3430.h b/include/configs/omap3_sdp3430.h
index 5ddf920..1d6ba7f 100644
--- a/include/configs/omap3_sdp3430.h
+++ b/include/configs/omap3_sdp3430.h
@@ -71,6 +71,8 @@
 #define CONFIG_INITRD_TAG		1
 #define CONFIG_REVISION_TAG		1
 
+#define CONFIG_OF_LIBFDT		1
+
 /*
  * Size of malloc() pool
  * Total Size Environment - 256k
diff --git a/include/configs/omap3_zoom1.h b/include/configs/omap3_zoom1.h
index 2bfda4b..5adffb5 100644
--- a/include/configs/omap3_zoom1.h
+++ b/include/configs/omap3_zoom1.h
@@ -61,6 +61,8 @@
 #define CONFIG_INITRD_TAG		1
 #define CONFIG_REVISION_TAG		1
 
+#define CONFIG_OF_LIBFDT		1
+
 /*
  * Size of malloc() pool
  */
diff --git a/include/configs/omap3_zoom2.h b/include/configs/omap3_zoom2.h
index dadca28..747c69d 100644
--- a/include/configs/omap3_zoom2.h
+++ b/include/configs/omap3_zoom2.h
@@ -62,6 +62,8 @@
 #define CONFIG_INITRD_TAG		1
 #define CONFIG_REVISION_TAG		1
 
+#define CONFIG_OF_LIBFDT		1
+
 /*
  * Size of malloc() pool
  */
diff --git a/include/configs/omap4_panda.h b/include/configs/omap4_panda.h
index 2b03b0f..ffcc9aa 100644
--- a/include/configs/omap4_panda.h
+++ b/include/configs/omap4_panda.h
@@ -60,6 +60,8 @@
 #define CONFIG_INITRD_TAG		1
 #define CONFIG_REVISION_TAG		1
 
+#define CONFIG_OF_LIBFDT		1
+
 /*
  * Size of malloc() pool
  * Total Size Environment - 256k
diff --git a/include/configs/omap4_sdp4430.h b/include/configs/omap4_sdp4430.h
index 9a8bb73..8d04d07 100644
--- a/include/configs/omap4_sdp4430.h
+++ b/include/configs/omap4_sdp4430.h
@@ -56,6 +56,8 @@
 #undef CONFIG_USE_IRQ				/* no support for IRQs */
 #define CONFIG_MISC_INIT_R
 
+#define CONFIG_OF_LIBFDT		1
+
 #define CONFIG_CMDLINE_TAG		1	/* enable passing of ATAGs */
 #define CONFIG_SETUP_MEMORY_TAGS	1
 #define CONFIG_INITRD_TAG		1
diff --git a/include/configs/pdm360ng.h b/include/configs/pdm360ng.h
index 37a22a7..831af6a 100644
--- a/include/configs/pdm360ng.h
+++ b/include/configs/pdm360ng.h
@@ -64,8 +64,6 @@
 #define CONFIG_SPLASH_SCREEN
 #define CONFIG_VIDEO_LOGO
 #define CONFIG_VIDEO_BMP_RLE8
-#define CONFIG_VIDEO_XRES	800
-#define CONFIG_VIDEO_YRES	480
 #endif
 
 #define CONFIG_SYS_MPC512X_CLKIN	33333333	/* in Hz */
diff --git a/include/configs/suen3.h b/include/configs/suen3.h
index b2730a3..2b6f19e 100644
--- a/include/configs/suen3.h
+++ b/include/configs/suen3.h
@@ -43,53 +43,14 @@
 
 #define CONFIG_HOSTNAME			suen3
 
-/*
- *  Environment variables configurations
- */
-#define CONFIG_ENV_IS_IN_EEPROM		/* use EEPROM for environment vars */
-#define CONFIG_SYS_DEF_EEPROM_ADDR	0x50
-#define CONFIG_ENV_EEPROM_IS_ON_I2C	1
-#define CONFIG_SYS_EEPROM_WREN		1
-#define CONFIG_ENV_OFFSET		0x0 /* no bracets! */
-#undef	CONFIG_ENV_SIZE
-#define CONFIG_ENV_SIZE			(0x2000 - CONFIG_ENV_OFFSET)
-#define CONFIG_I2C_ENV_EEPROM_BUS	"pca9547:70:d\0"
-
-/* offset redund: (CONFIG_ENV_OFFSET + CONFIG_ENV_SIZE) */
-#define CONFIG_SYS_REDUNDAND_ENVIRONMENT
-#define CONFIG_ENV_OFFSET_REDUND	0x2000 /* no bracets! */
-#define CONFIG_ENV_SIZE_REDUND		(CONFIG_ENV_SIZE)
-
-#define CONFIG_CMD_SF
-
-#define CONFIG_SPI_FLASH
-#define CONFIG_HARD_SPI
-#define CONFIG_KIRKWOOD_SPI
-#define CONFIG_SPI_FLASH_STMICRO
-#define CONFIG_ENV_SPI_BUS		0
-#define CONFIG_ENV_SPI_CS		0
-#define CONFIG_ENV_SPI_MAX_HZ		50000000	/* 50Mhz */
-
-#define FLASH_GPIO_PIN			0x00010000
-
-#define MTDIDS_DEFAULT		"nand0=orion_nand"
-/* test-only: partitioning needs some tuning, this is just for tests */
-#define MTDPARTS_DEFAULT	"mtdparts="				\
-	"orion_nand:"							\
-		"-(" CONFIG_KM_UBI_PARTITION_NAME ")"
-
-#define	CONFIG_KM_DEF_ENV_UPDATE					\
-	"update="							\
-		"spi on;sf probe 0;sf erase 0 50000;"			\
-		"sf write ${u-boot_addr_r} 0 ${filesize};"		\
-		"spi off\0"
+#define KM_IVM_BUS	"pca9544a:70:9"	/* I2C2 (Mux-Port 1)*/
+#define KM_ENV_BUS	"pca9544a:70:d"	/* I2C2 (Mux-Port 5)*/
 
 /*
  * Default environment variables
  */
 #define CONFIG_EXTRA_ENV_SETTINGS					\
 	CONFIG_KM_DEF_ENV						\
-	"memsize=0x8000000\0"						\
 	"newenv=setenv addr 0x100000 && "				\
 		"i2c dev 1; mw.b ${addr} 0 4 && "			\
 		"eeprom write " xstr(CONFIG_SYS_DEF_EEPROM_ADDR)	\
@@ -97,7 +58,7 @@
 		"eeprom write " xstr(CONFIG_SYS_DEF_EEPROM_ADDR)	\
 		" ${addr} " xstr(CONFIG_ENV_OFFSET_REDUND) " 4\0"	\
 	"rootpath=/opt/eldk/arm\0"					\
-	"EEprom_ivm=pca9544a:70:9\0"					\
+	"EEprom_ivm=" KM_IVM_BUS "\0"					\
 	""
 
 #endif /* _CONFIG_SUEN3_H */
diff --git a/include/configs/suen8.h b/include/configs/suen8.h
new file mode 100644
index 0000000..3f60bc3
--- /dev/null
+++ b/include/configs/suen8.h
@@ -0,0 +1,65 @@
+/*
+ * (C) Copyright 2009
+ * Marvell Semiconductor <www.marvell.com>
+ * Prafulla Wadaskar <prafulla@marvell.com>
+ *
+ * (C) Copyright 2009
+ * Stefan Roese, DENX Software Engineering, sr@denx.de.
+ *
+ * (C) Copyright 2010-2011
+ * Holger Brunck, Keymile GmbH Hannover, holger.brunck@keymile.com.
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+
+/* for linking errors see
+ * http://lists.denx.de/pipermail/u-boot/2009-July/057350.html */
+
+#ifndef _CONFIG_SUEN8_H
+#define _CONFIG_SUEN8_H
+
+/* include common defines/options for all arm based Keymile boards */
+#include "km_arm.h"
+
+/*
+ * Version number information
+ */
+#define CONFIG_IDENT_STRING	"\nKeymile SUEN8"
+
+#define CONFIG_HOSTNAME			suen8
+
+#define KM_IVM_BUS	"pca9544a:70:9" /* I2C2 (Mux-Port 1)*/
+#define KM_ENV_BUS	"pca9544a:70:d" /* I2C2 (Mux-Port 5)*/
+
+/*
+ * Default environment variables
+ */
+#define CONFIG_EXTRA_ENV_SETTINGS					\
+	CONFIG_KM_DEF_ENV						\
+	"newenv=setenv addr 0x100000 && "				\
+		"i2c dev 1; mw.b ${addr} 0 4 && "			\
+		"eeprom write " xstr(CONFIG_SYS_DEF_EEPROM_ADDR)	\
+		" ${addr} " xstr(CONFIG_ENV_OFFSET) " 4 && "		\
+		"eeprom write " xstr(CONFIG_SYS_DEF_EEPROM_ADDR)	\
+		" ${addr} " xstr(CONFIG_ENV_OFFSET_REDUND) " 4\0"	\
+	"rootpath=/opt/eldk/arm\0"					\
+	"EEprom_ivm=" KM_IVM_BUS "\0"					\
+	""
+
+#endif /* _CONFIG_SUEN8_H */
diff --git a/include/configs/suvd3.h b/include/configs/suvd3.h
new file mode 100644
index 0000000..d9eb201
--- /dev/null
+++ b/include/configs/suvd3.h
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2006 Freescale Semiconductor, Inc.
+ *                    Dave Liu <daveliu@freescale.com>
+ *
+ * Copyright (C) 2007 Logic Product Development, Inc.
+ *                    Peter Barada <peterb@logicpd.com>
+ *
+ * Copyright (C) 2007 MontaVista Software, Inc.
+ *                    Anton Vorontsov <avorontsov@ru.mvista.com>
+ *
+ * (C) Copyright 2010
+ * Heiko Schocher, DENX Software Engineering, hs@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.
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+/*
+ * High Level Configuration Options
+ */
+#define CONFIG_SUVD3		/* SUVD3 board specific */
+#define CONFIG_HOSTNAME		suvd3
+#define CONFIG_KM_BOARD_NAME   "suvd3"
+
+#define	CONFIG_SYS_TEXT_BASE	0xF0000000
+
+/* include common defines/options for all 8321 Keymile boards */
+#include "km8321-common.h"
+
+#define CONFIG_SYS_APP1_BASE		0xA0000000
+#define	CONFIG_SYS_APP1_SIZE		256 /* Megabytes */
+#define CONFIG_SYS_APP2_BASE		0xB0000000
+#define	CONFIG_SYS_APP2_SIZE		256 /* Megabytes */
+
+/* EEprom support */
+#define CONFIG_SYS_I2C_EEPROM_ADDR_LEN	1
+
+/*
+ * Init Local Bus Memory Controller:
+ *
+ * Bank Bus     Machine PortSz  Size  Device
+ * ---- ---     ------- ------  -----  ------
+ *  2   Local   UPMA    16 bit  256MB APP1
+ *  3   Local   GPCM    16 bit  256MB APP2
+ *
+ */
+
+/*
+ * APP1 on the local bus CS2
+ */
+#define CONFIG_SYS_LBLAWBAR2_PRELIM	CONFIG_SYS_APP1_BASE
+#define CONFIG_SYS_LBLAWAR2_PRELIM	(LBLAWAR_EN | LBLAWAR_256MB)
+
+#define CONFIG_SYS_BR2_PRELIM	(CONFIG_SYS_APP1_BASE | \
+				 BR_PS_16 | \
+				 BR_MS_UPMA | \
+				 BR_V)
+#define CONFIG_SYS_OR2_PRELIM	(MEG_TO_AM(CONFIG_SYS_APP1_SIZE))
+
+#define CONFIG_SYS_BR3_PRELIM	(CONFIG_SYS_APP2_BASE | \
+				 BR_PS_16 | \
+				 BR_V)
+
+#define CONFIG_SYS_OR3_PRELIM	(MEG_TO_AM(CONFIG_SYS_APP2_SIZE) | \
+				 OR_GPCM_CSNT | \
+				 OR_GPCM_ACS_DIV4 | \
+				 OR_GPCM_SCY_3 | \
+				 OR_GPCM_TRLX)
+
+#define CONFIG_SYS_MAMR	(MxMR_GPL_x4DIS | \
+			 0x0000c000 | \
+			 MxMR_WLFx_2X)
+
+#define CONFIG_SYS_LBLAWBAR3_PRELIM	CONFIG_SYS_APP2_BASE
+#define CONFIG_SYS_LBLAWAR3_PRELIM	(LBLAWAR_EN | LBLAWAR_256MB)
+
+/*
+ * MMU Setup
+ */
+
+
+/* APP1:  icache cacheable, but dcache-inhibit and guarded */
+#define CONFIG_SYS_IBAT5L	(CONFIG_SYS_APP1_BASE | BATL_PP_10 | \
+				 BATL_MEMCOHERENCE)
+#define CONFIG_SYS_IBAT5U	(CONFIG_SYS_APP1_BASE | BATU_BL_256M | \
+				 BATU_VS | BATU_VP)
+#define CONFIG_SYS_DBAT5L	(CONFIG_SYS_APP1_BASE | BATL_PP_10 | \
+				 BATL_CACHEINHIBIT | BATL_GUARDEDSTORAGE)
+#define CONFIG_SYS_DBAT5U	CONFIG_SYS_IBAT5U
+
+#define CONFIG_SYS_IBAT6L	(CONFIG_SYS_APP2_BASE | BATL_PP_10 | \
+				 BATL_MEMCOHERENCE)
+#define CONFIG_SYS_IBAT6U	(CONFIG_SYS_APP2_BASE | BATU_BL_256M | \
+				 BATU_VS | BATU_VP)
+#define CONFIG_SYS_DBAT6L	(CONFIG_SYS_APP2_BASE | BATL_PP_10 | \
+				 BATL_CACHEINHIBIT | BATL_GUARDEDSTORAGE)
+#define CONFIG_SYS_DBAT6U	CONFIG_SYS_IBAT6U
+
+#endif /* __CONFIG_H */
diff --git a/include/configs/tegra2-common.h b/include/configs/tegra2-common.h
index 2924325..febce35 100644
--- a/include/configs/tegra2-common.h
+++ b/include/configs/tegra2-common.h
@@ -47,6 +47,7 @@
 #define CONFIG_SKIP_LOWLEVEL_INIT
 
 #define CONFIG_CMDLINE_TAG		/* enable passing of ATAGs */
+#define CONFIG_OF_LIBFDT		/* enable passing of devicetree */
 
 /* Environment */
 #define CONFIG_ENV_IS_NOWHERE
diff --git a/include/configs/tuda1.h b/include/configs/tuda1.h
new file mode 100644
index 0000000..1c0b3e0
--- /dev/null
+++ b/include/configs/tuda1.h
@@ -0,0 +1,141 @@
+/*
+ * Copyright (C) 2006 Freescale Semiconductor, Inc.
+ *                    Dave Liu <daveliu@freescale.com>
+ *
+ * Copyright (C) 2007 Logic Product Development, Inc.
+ *                    Peter Barada <peterb@logicpd.com>
+ *
+ * Copyright (C) 2007 MontaVista Software, Inc.
+ *                    Anton Vorontsov <avorontsov@ru.mvista.com>
+ *
+ * (C) Copyright 2008
+ * Heiko Schocher, DENX Software Engineering, hs@denx.de.
+ *
+ * (C) Copyright 2010-2011
+ * Lukas Roggli, KEYMILE Ltd, lukas.roggli@keymile.com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+/*
+ * High Level Configuration Options
+ */
+#define CONFIG_TUDA1		/* TUDA1 board specific */
+#define CONFIG_HOSTNAME		tuda1
+#define CONFIG_KM_BOARD_NAME   "tuda1"
+
+#define	CONFIG_SYS_TEXT_BASE	0xF0000000
+
+/* include common defines/options for all 8321 Keymile boards */
+#include "km8321-common.h"
+
+#define CONFIG_SYS_APP1_BASE	0xA0000000    /* PAXG */
+#define	CONFIG_SYS_APP1_SIZE	256 /* Megabytes */
+#define CONFIG_SYS_APP2_BASE	0xB0000000    /* PINC3 */
+#define	CONFIG_SYS_APP2_SIZE	256 /* Megabytes */
+
+/*
+ * Local Bus Configuration & Clock Setup
+ */
+#define CONFIG_SYS_LCRR		(LCRR_DBYP | LCRR_EADC_1 | LCRR_CLKDIV_2)
+#define CONFIG_SYS_LBC_LBCR	0x00000000
+
+/*
+ * Init Local Bus Memory Controller:
+ *
+ * Bank Bus     Machine PortSz  Size  Device
+ * ---- ---     ------- ------  -----  ------
+ *  2   Local   GPCM    8 bit  256MB	PAXG
+ *  3   Local   GPCM    8 bit  256MB	PINC3
+ *
+ */
+
+/*
+ * PAXG on the local bus CS2
+ */
+/* Window base at flash base */
+#define CONFIG_SYS_LBLAWBAR2_PRELIM	CONFIG_SYS_APP1_BASE
+/* Window size: 256 MB */
+#define CONFIG_SYS_LBLAWAR2_PRELIM	(LBLAWAR_EN | LBLAWAR_256MB)
+
+#define CONFIG_SYS_BR2_PRELIM	(CONFIG_SYS_APP1_BASE | \
+				 BR_PS_8 | \
+				 BR_MS_GPCM | \
+				 BR_V)
+
+#define CONFIG_SYS_OR2_PRELIM	(MEG_TO_AM(CONFIG_SYS_APP1_SIZE) | \
+				 OR_GPCM_CSNT | \
+				 OR_GPCM_ACS_DIV4 | \
+				 OR_GPCM_SCY_2 | \
+				 (OR_GPCM_TRLX & \
+				 (~OR_GPCM_EHTR)) |  /* EHTR = 0 */ \
+				 OR_GPCM_EAD)
+/*
+ * PINC3 on the local bus CS3
+ */
+/* Access window base at PINC3 base */
+#define CONFIG_SYS_LBLAWBAR3_PRELIM	CONFIG_SYS_APP2_BASE
+/* Window size: 256 MB */
+#define CONFIG_SYS_LBLAWAR3_PRELIM	(LBLAWAR_EN | LBLAWAR_256MB)
+
+#define CONFIG_SYS_BR3_PRELIM	(CONFIG_SYS_APP2_BASE | \
+				 BR_PS_8 |		\
+				 BR_MS_GPCM |		\
+				 BR_V)
+
+#define CONFIG_SYS_OR3_PRELIM	(MEG_TO_AM(CONFIG_SYS_APP2_SIZE) | \
+				 OR_GPCM_CSNT |	\
+				 (OR_GPCM_ACS_DIV2 & /* ACS = 11 */\
+				 (~OR_GPCM_XACS)) |  /* XACS = 0 */\
+				 (OR_GPCM_SCY_2 & \
+				 (~OR_GPCM_EHTR)) |  /* EHTR = 0 */ \
+				 OR_GPCM_TRLX)
+
+#define CONFIG_SYS_MAMR		(MxMR_GPL_x4DIS | \
+				 0x0000c000 | \
+				 MxMR_WLFx_2X)
+
+/*
+ * MMU Setup
+ */
+/* PAXG:  icache cacheable, but dcache-inhibit and guarded */
+#define CONFIG_SYS_IBAT5L	(CONFIG_SYS_APP1_BASE | \
+				 BATL_PP_10 | \
+				 BATL_MEMCOHERENCE)
+/* 512M should also include APP2... */
+#define CONFIG_SYS_IBAT5U	(CONFIG_SYS_APP1_BASE | \
+				 BATU_BL_256M | \
+				 BATU_VS | \
+				 BATU_VP)
+#define CONFIG_SYS_DBAT5L	(CONFIG_SYS_APP1_BASE | \
+				 BATL_PP_10 | \
+				 BATL_CACHEINHIBIT | \
+				 BATL_GUARDEDSTORAGE)
+#define CONFIG_SYS_DBAT5U	CONFIG_SYS_IBAT5U
+
+/* PINC3:  icache cacheable, but dcache-inhibit and guarded */
+#define CONFIG_SYS_IBAT6L	(CONFIG_SYS_APP2_BASE | \
+				 BATL_PP_10 | \
+				 BATL_MEMCOHERENCE)
+#define CONFIG_SYS_IBAT6U	(CONFIG_SYS_APP2_BASE | \
+				 BATU_BL_256M | \
+				 BATU_VS | \
+				 BATU_VP)
+#define CONFIG_SYS_DBAT6L	(CONFIG_SYS_APP2_BASE | \
+				 BATL_PP_10 | \
+				 BATL_CACHEINHIBIT | \
+				 BATL_GUARDEDSTORAGE)
+#define CONFIG_SYS_DBAT6U	CONFIG_SYS_IBAT6U
+
+#define CONFIG_SYS_IBAT7L	(0)
+#define CONFIG_SYS_IBAT7U	(0)
+#define CONFIG_SYS_DBAT7L	CONFIG_SYS_IBAT7L
+#define CONFIG_SYS_DBAT7U	CONFIG_SYS_IBAT7U
+
+#endif /* __CONFIG_H */
diff --git a/include/configs/tuxa1.h b/include/configs/tuxa1.h
new file mode 100644
index 0000000..012db96
--- /dev/null
+++ b/include/configs/tuxa1.h
@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) 2006 Freescale Semiconductor, Inc.
+ *                    Dave Liu <daveliu@freescale.com>
+ *
+ * Copyright (C) 2007 Logic Product Development, Inc.
+ *                    Peter Barada <peterb@logicpd.com>
+ *
+ * Copyright (C) 2007 MontaVista Software, Inc.
+ *                    Anton Vorontsov <avorontsov@ru.mvista.com>
+ *
+ * (C) Copyright 2008
+ * Heiko Schocher, DENX Software Engineering, hs@denx.de.
+ *
+ * (C) Copyright 2010
+ * Yan Bin, Lukas Roggli, KEYMILE Ltd, lukas.roggli@keymile.com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+/*
+ * High Level Configuration Options
+ */
+#define CONFIG_TUXA1		/* TUXA1 board specific */
+#define CONFIG_HOSTNAME		tuxa1
+#define CONFIG_KM_BOARD_NAME   "tuxa1"
+
+#define	CONFIG_SYS_TEXT_BASE	0xF0000000
+
+/* include common defines/options for all 8321 Keymile boards */
+#include "km8321-common.h"
+
+#define	CONFIG_SYS_LPXF_BASE		0xA0000000    /* LPXF */
+#define	CONFIG_SYS_LPXF_SIZE		256 /* Megabytes */
+#define	CONFIG_SYS_PINC2_BASE		0xB0000000    /* PINC2 */
+#define	CONFIG_SYS_PINC2_SIZE		256 /* Megabytes */
+
+/*
+ * Init Local Bus Memory Controller:
+ *
+ * Bank Bus     Machine PortSz  Size  Device
+ * ---- ---     ------- ------  -----  ------
+ *  2   Local   GPCM    8 bit  256MB	LPXF
+ *  3   Local   GPCM    8 bit  256MB	PINC2
+ *
+ */
+
+/*
+ * LPXF on the local bus CS2
+ * Window base at flash base
+ * Window size: 256 MB
+ */
+#define CONFIG_SYS_LBLAWBAR2_PRELIM	CONFIG_SYS_LPXF_BASE
+#define CONFIG_SYS_LBLAWAR2_PRELIM	(LBLAWAR_EN | LBLAWAR_256MB)
+
+#define CONFIG_SYS_BR2_PRELIM       (CONFIG_SYS_LPXF_BASE | \
+				BR_PS_8 | \
+				BR_MS_GPCM | \
+				BR_V)
+
+#define CONFIG_SYS_OR2_PRELIM	(MEG_TO_AM(CONFIG_SYS_LPXF_SIZE) | \
+				 OR_GPCM_CSNT | \
+				 OR_GPCM_ACS_DIV4 | \
+				 OR_GPCM_SCY_2 | \
+				 (OR_GPCM_TRLX & \
+				 (~OR_GPCM_EHTR)) |  /* EHTR = 0 */ \
+				 OR_GPCM_EAD)
+/*
+ * PINC2 on the local bus CS3
+ * Access window base at PINC2 base
+ * Window size: 256 MB
+ */
+#define CONFIG_SYS_LBLAWBAR3_PRELIM	CONFIG_SYS_PINC2_BASE
+#define CONFIG_SYS_LBLAWAR3_PRELIM	(LBLAWAR_EN | LBLAWAR_256MB)
+
+#define CONFIG_SYS_BR3_PRELIM	(CONFIG_SYS_PINC2_BASE | \
+				 BR_PS_8 | \
+				 BR_MS_GPCM | \
+				 BR_V)
+
+#define CONFIG_SYS_OR3_PRELIM	(MEG_TO_AM(CONFIG_SYS_PINC2_SIZE) | \
+				 OR_GPCM_CSNT | \
+				 (OR_GPCM_ACS_DIV2 & /* ACS = 11 */ \
+				 (~OR_GPCM_XACS)) |  /* XACS = 0 */ \
+				 (OR_GPCM_SCY_2 & \
+				 (~OR_GPCM_EHTR)) |  /* EHTR = 0 */ \
+				 OR_GPCM_TRLX)
+
+#define CONFIG_SYS_MAMR		(MxMR_GPL_x4DIS | \
+				 0x0000c000 | \
+				 MxMR_WLFx_2X)
+
+/*
+ * MMU Setup
+ */
+/* LPXF:  icache cacheable, but dcache-inhibit and guarded */
+#define CONFIG_SYS_IBAT5L	(CONFIG_SYS_LPXF_BASE | BATL_PP_10 | \
+				 BATL_MEMCOHERENCE)
+#define CONFIG_SYS_IBAT5U	(CONFIG_SYS_LPXF_BASE | BATU_BL_256M | \
+				 BATU_VS | BATU_VP)
+#define CONFIG_SYS_DBAT5L	(CONFIG_SYS_LPXF_BASE | BATL_PP_10 | \
+				 BATL_CACHEINHIBIT | BATL_GUARDEDSTORAGE)
+#define CONFIG_SYS_DBAT5U	CONFIG_SYS_IBAT5U
+
+/* PINC2:  icache cacheable, but dcache-inhibit and guarded */
+#define CONFIG_SYS_IBAT6L	(CONFIG_SYS_PINC2_BASE | BATL_PP_10 | \
+				 BATL_MEMCOHERENCE)
+#define CONFIG_SYS_IBAT6U	(CONFIG_SYS_PINC2_BASE | BATU_BL_256M | \
+				 BATU_VS | BATU_VP)
+#define CONFIG_SYS_DBAT6L	(CONFIG_SYS_PINC2_BASE | BATL_PP_10 | \
+				 BATL_CACHEINHIBIT | BATL_GUARDEDSTORAGE)
+#define CONFIG_SYS_DBAT6U	CONFIG_SYS_IBAT6U
+
+#define CONFIG_SYS_IBAT7L	(0)
+#define CONFIG_SYS_IBAT7U	(0)
+#define CONFIG_SYS_DBAT7L	CONFIG_SYS_IBAT7L
+#define CONFIG_SYS_DBAT7U	CONFIG_SYS_IBAT7U
+
+#endif /* __CONFIG_H */
diff --git a/include/fsl_diu_fb.h b/include/fsl_diu_fb.h
index 87443e1..4c89f4b 100644
--- a/include/fsl_diu_fb.h
+++ b/include/fsl_diu_fb.h
@@ -1,6 +1,7 @@
 /*
- * Copyright 2007 Freescale Semiconductor, Inc.
- * York Sun <yorksun@freescale.com>
+ * Copyright 2007, 2011 Freescale Semiconductor, Inc.
+ * Authors: York Sun <yorksun@freescale.com>
+ *          Timur Tabi <timur@freescale.com>
  *
  * FSL DIU Framebuffer driver
  *
@@ -23,38 +24,8 @@
  * MA 02111-1307 USA
  */
 
-struct fb_var_screeninfo {
-	unsigned int xres;		/* visible resolution		*/
-	unsigned int yres;
+int fsl_diu_init(int xres, u32 pixel_format, int gamma_fix);
 
-	unsigned int bits_per_pixel;	/* guess what			*/
-
-	/* Timing: All values in pixclocks, except pixclock (of course) */
-	unsigned int pixclock;		/* pixel clock in ps (pico seconds) */
-	unsigned int left_margin;	/* time from sync to picture	*/
-	unsigned int right_margin;	/* time from picture to sync	*/
-	unsigned int upper_margin;	/* time from sync to picture	*/
-	unsigned int lower_margin;
-	unsigned int hsync_len;		/* length of horizontal sync	*/
-	unsigned int vsync_len;		/* length of vertical sync	*/
-	unsigned int sync;		/* see FB_SYNC_*		*/
-	unsigned int vmode;		/* see FB_VMODE_*		*/
-	unsigned int rotate;		/* angle we rotate counter clockwise */
-};
-
-struct fb_info {
-	struct fb_var_screeninfo var;	/* Current var */
-	unsigned long smem_start;	/* Start of frame buffer mem */
-					/* (physical address) */
-	unsigned int smem_len;		/* Length of frame buffer mem */
-	unsigned int type;		/* see FB_TYPE_*		*/
-	unsigned int line_length;	/* length of a line in bytes    */
-
-	char *screen_base;
-	unsigned long screen_size;
-};
-
-
-extern char *fsl_fb_open(struct fb_info **info);
-int fsl_diu_init(int xres, unsigned int pixel_format, int gamma_fix);
-int platform_diu_init(unsigned int *xres, unsigned int *yres);
+/* Prototypes for external board-specific functions */
+int platform_diu_init(unsigned int xres, unsigned int yres, const char *port);
+void diu_set_pixel_clock(unsigned int pixclock);
diff --git a/include/i2c.h b/include/i2c.h
index cd23c8a..8ceb4c8 100644
--- a/include/i2c.h
+++ b/include/i2c.h
@@ -108,9 +108,7 @@
  * repeatedly to change the speed and slave addresses.
  */
 void i2c_init(int speed, int slaveaddr);
-#ifdef CONFIG_SYS_I2C_INIT_BOARD
 void i2c_init_board(void);
-#endif
 #ifdef CONFIG_SYS_I2C_BOARD_LATE_INIT
 void i2c_board_late_init(void);
 #endif
diff --git a/include/ide.h b/include/ide.h
index 6a1b7ae..80a10f4 100644
--- a/include/ide.h
+++ b/include/ide.h
@@ -57,4 +57,11 @@
 #if defined(CONFIG_OF_IDE_FIXUP)
 int ide_device_present(int dev);
 #endif
+
+#if defined(CONFIG_IDE_AHB)
+unsigned char ide_read_register(int dev, unsigned int port);
+void ide_write_register(int dev, unsigned int port, unsigned char val);
+void ide_read_data(int dev, ulong *sect_buf, int words);
+void ide_write_data(int dev, ulong *sect_buf, int words);
+#endif
 #endif /* _IDE_H */
diff --git a/include/mmc.h b/include/mmc.h
index e0a56d9..f7f2286 100644
--- a/include/mmc.h
+++ b/include/mmc.h
@@ -14,7 +14,7 @@
  *
  * 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
+ * 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
@@ -94,14 +94,14 @@
 #define MMC_HS_TIMING		0x00000100
 #define MMC_HS_52MHZ		0x2
 
-#define OCR_BUSY	0x80000000
-#define OCR_HCS		0x40000000
+#define OCR_BUSY		0x80000000
+#define OCR_HCS			0x40000000
 #define OCR_VOLTAGE_MASK	0x007FFF80
 #define OCR_ACCESS_MODE		0x60000000
 
 #define MMC_STATUS_MASK		(~0x0206BF7F)
-#define MMC_STATUS_RDY_FOR_DATA (1<<8)
-#define MMC_STATUS_CURR_STATE	(0xf<<9)
+#define MMC_STATUS_RDY_FOR_DATA (1 << 8)
+#define MMC_STATUS_CURR_STATE	(0xf << 9)
 
 #define MMC_VDD_165_195		0x00000080	/* VDD voltage 1.65 - 1.95 */
 #define MMC_VDD_20_21		0x00000100	/* VDD voltage 2.0 ~ 2.1 */
@@ -147,12 +147,12 @@
  * EXT_CSD field definitions
  */
 
-#define EXT_CSD_CMD_SET_NORMAL		(1<<0)
-#define EXT_CSD_CMD_SET_SECURE		(1<<1)
-#define EXT_CSD_CMD_SET_CPSECURE	(1<<2)
+#define EXT_CSD_CMD_SET_NORMAL		(1 << 0)
+#define EXT_CSD_CMD_SET_SECURE		(1 << 1)
+#define EXT_CSD_CMD_SET_CPSECURE	(1 << 2)
 
-#define EXT_CSD_CARD_TYPE_26	(1<<0)	/* Card can run at 26MHz */
-#define EXT_CSD_CARD_TYPE_52	(1<<1)	/* Card can run at 52MHz */
+#define EXT_CSD_CARD_TYPE_26	(1 << 0)	/* Card can run at 26MHz */
+#define EXT_CSD_CARD_TYPE_52	(1 << 1)	/* Card can run at 52MHz */
 
 #define EXT_CSD_BUS_WIDTH_1	0	/* Card is in 1 bit mode */
 #define EXT_CSD_BUS_WIDTH_4	1	/* Card is in 4 bit mode */
@@ -162,21 +162,21 @@
 #define R1_APP_CMD			(1 << 5)
 
 #define MMC_RSP_PRESENT (1 << 0)
-#define MMC_RSP_136     (1 << 1)                /* 136 bit response */
-#define MMC_RSP_CRC     (1 << 2)                /* expect valid crc */
-#define MMC_RSP_BUSY    (1 << 3)                /* card may send busy */
-#define MMC_RSP_OPCODE  (1 << 4)                /* response contains opcode */
+#define MMC_RSP_136	(1 << 1)		/* 136 bit response */
+#define MMC_RSP_CRC	(1 << 2)		/* expect valid crc */
+#define MMC_RSP_BUSY	(1 << 3)		/* card may send busy */
+#define MMC_RSP_OPCODE	(1 << 4)		/* response contains opcode */
 
-#define MMC_RSP_NONE    (0)
-#define MMC_RSP_R1      (MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE)
+#define MMC_RSP_NONE	(0)
+#define MMC_RSP_R1	(MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE)
 #define MMC_RSP_R1b	(MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE| \
 			MMC_RSP_BUSY)
-#define MMC_RSP_R2      (MMC_RSP_PRESENT|MMC_RSP_136|MMC_RSP_CRC)
-#define MMC_RSP_R3      (MMC_RSP_PRESENT)
-#define MMC_RSP_R4      (MMC_RSP_PRESENT)
-#define MMC_RSP_R5      (MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE)
-#define MMC_RSP_R6      (MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE)
-#define MMC_RSP_R7      (MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE)
+#define MMC_RSP_R2	(MMC_RSP_PRESENT|MMC_RSP_136|MMC_RSP_CRC)
+#define MMC_RSP_R3	(MMC_RSP_PRESENT)
+#define MMC_RSP_R4	(MMC_RSP_PRESENT)
+#define MMC_RSP_R5	(MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE)
+#define MMC_RSP_R6	(MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE)
+#define MMC_RSP_R7	(MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE)
 
 
 struct mmc_cid {
@@ -283,9 +283,7 @@
 			struct mmc_cmd *cmd, struct mmc_data *data);
 	void (*set_ios)(struct mmc *mmc);
 	int (*init)(struct mmc *mmc);
-#ifdef CONFIG_MMC_MBLOCK
 	uint b_max;
-#endif
 };
 
 int mmc_register(struct mmc *mmc);
diff --git a/lib/Makefile b/lib/Makefile
index fcfe351..afa6914 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -52,7 +52,6 @@
 COBJS-y	+= strmhz.o
 COBJS-y += time.o
 COBJS-y += vsprintf.o
-COBJS-$(CONFIG_ZLIB) += zlib.o
 COBJS-$(CONFIG_RBTREE)	+= rbtree.o
 
 COBJS	:= $(COBJS-y)
diff --git a/lib/zlib.c b/lib/zlib.c
deleted file mode 100644
index e19484a..0000000
--- a/lib/zlib.c
+++ /dev/null
@@ -1,2218 +0,0 @@
-/*
- * This file is derived from various .h and .c files from the zlib-1.2.3
- * distribution by Jean-loup Gailly and Mark Adler, with some additions
- * by Paul Mackerras to aid in implementing Deflate compression and
- * decompression for PPP packets.  See zlib.h for conditions of
- * distribution and use.
- *
- * Changes that have been made include:
- * - changed functions not used outside this file to "local"
- * - added minCompression parameter to deflateInit2
- * - added Z_PACKET_FLUSH (see zlib.h for details)
- * - added inflateIncomp
- */
-
-/*+++++*/
-/* zutil.h -- internal interface and configuration of the compression library
- * Copyright (C) 1995-2005 Jean-loup Gailly.
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* WARNING: this file should *not* be used by applications. It is
-   part of the implementation of the compression library and is
-   subject to change. Applications should only use zlib.h.
- */
-
-#define ZUTIL_H
-#define ZLIB_INTERNAL
-
-#include <common.h>
-#include <compiler.h>
-#include <asm/unaligned.h>
-#include <watchdog.h>
-#include "u-boot/zlib.h"
-#undef	OFF				/* avoid conflicts */
-
-/* To avoid a build time warning */
-#ifdef STDC
-#include <malloc.h>
-#endif
-
-#ifndef local
-#define local static
-#endif
-/* compile with -Dlocal if your debugger can't find static symbols */
-
-typedef unsigned char uch;
-typedef uch FAR uchf;
-typedef unsigned short ush;
-typedef ush FAR ushf;
-typedef unsigned long ulg;
-
-#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)]
-#define ERR_RETURN(strm,err) return (strm->msg = (char*)ERR_MSG(err), (err))
-/* To be used only when the state is known to be valid */
-
-#ifndef NULL
-#define NULL	((void *) 0)
-#endif
-
-	/* common constants */
-
-#ifndef DEF_WBITS
-#define DEF_WBITS MAX_WBITS
-#endif
-/* default windowBits for decompression. MAX_WBITS is for compression only */
-
-#if MAX_MEM_LEVEL >= 8
-#define DEF_MEM_LEVEL 8
-#else
-#define DEF_MEM_LEVEL  MAX_MEM_LEVEL
-#endif
-/* default memLevel */
-
-#define STORED_BLOCK 0
-#define STATIC_TREES 1
-#define DYN_TREES    2
-/* The three kinds of block type */
-
-#define MIN_MATCH 3
-#define MAX_MATCH 258
-/* The minimum and maximum match lengths */
-
-	 /* functions */
-
-#include <linux/string.h>
-#define zmemcpy memcpy
-#define zmemcmp memcmp
-#define zmemzero(dest, len) memset(dest, 0, len)
-
-/* Diagnostic functions */
-#ifdef DEBUG
-	extern int z_verbose;
-	extern void z_error    OF((char *m));
-#define Assert(cond,msg) {if(!(cond)) z_error(msg);}
-#define fprintf(fp,...)	printf(__VA_ARGS__)
-#define Trace(x) {if (z_verbose>=0) fprintf x ;}
-#define Tracev(x) {if (z_verbose>0) fprintf x ;}
-#define Tracevv(x) {if (z_verbose>1) fprintf x ;}
-#define Tracec(c,x) {if (z_verbose>0 && (c)) fprintf x ;}
-#define Tracecv(c,x) {if (z_verbose>1 && (c)) fprintf x ;}
-#else
-#define Assert(cond,msg)
-#define Trace(x)
-#define Tracev(x)
-#define Tracevv(x)
-#define Tracec(c,x)
-#define Tracecv(c,x)
-#endif
-
-voidpf zcalloc OF((voidpf opaque, unsigned items, unsigned size));
-void zcfree  OF((voidpf opaque, voidpf ptr, unsigned size));
-
-#define ZALLOC(strm, items, size) \
-	(*((strm)->zalloc))((strm)->opaque, (items), (size))
-#define ZFREE(strm, addr)  (*((strm)->zfree))((strm)->opaque, (voidpf)(addr), 0)
-
-/*+++++*/
-/* inftrees.h -- header to use inftrees.c
- * Copyright (C) 1995-2005 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* WARNING: this file should *not* be used by applications. It is
-   part of the implementation of the compression library and is
-   subject to change. Applications should only use zlib.h.
- */
-
-/* Structure for decoding tables.  Each entry provides either the
-   information needed to do the operation requested by the code that
-   indexed that table entry, or it provides a pointer to another
-   table that indexes more bits of the code.  op indicates whether
-   the entry is a pointer to another table, a literal, a length or
-   distance, an end-of-block, or an invalid code.  For a table
-   pointer, the low four bits of op is the number of index bits of
-   that table.  For a length or distance, the low four bits of op
-   is the number of extra bits to get after the code.  bits is
-   the number of bits in this code or part of the code to drop off
-   of the bit buffer.  val is the actual byte to output in the case
-   of a literal, the base length or distance, or the offset from
-   the current table to the next table.  Each entry is four bytes. */
-
-typedef struct {
-	unsigned char op;           /* operation, extra bits, table bits */
-	unsigned char bits;         /* bits in this part of the code */
-	unsigned short val;         /* offset in table or code value */
-} code;
-
-/* Maximum size of dynamic tree.  The maximum found in a long but non-
-   exhaustive search was 1444 code structures (852 for length/literals
-   and 592 for distances, the latter actually the result of an
-   exhaustive search).  The true maximum is not known, but the value
-   below is more than safe. */
-#define ENOUGH 2048
-#define MAXD 592
-
-/* Type of code to build for inftable() */
-typedef enum {
-	CODES,
-	LENS,
-	DISTS
-} codetype;
-
-extern int inflate_table OF((codetype type, unsigned short FAR *lens,
-				unsigned codes, code FAR * FAR *table,
-				unsigned FAR *bits, unsigned short FAR *work));
-/*+++++*/
-/* inflate.h -- internal inflate state definition
- * Copyright (C) 1995-2004 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* WARNING: this file should *not* be used by applications. It is
-   part of the implementation of the compression library and is
-   subject to change. Applications should only use zlib.h.
- */
-
-#define GUNZIP
-
-/* Possible inflate modes between inflate() calls */
-typedef enum {
-	HEAD, /* i: waiting for magic header */
-	FLAGS, /* i: waiting for method and flags (gzip) */
-	TIME, /* i: waiting for modification time (gzip) */
-	OS, /* i: waiting for extra flags and operating system (gzip) */
-	EXLEN, /* i: waiting for extra length (gzip) */
-	EXTRA, /* i: waiting for extra bytes (gzip) */
-	NAME, /* i: waiting for end of file name (gzip) */
-	COMMENT, /* i: waiting for end of comment (gzip) */
-	HCRC, /* i: waiting for header crc (gzip) */
-	DICTID, /* i: waiting for dictionary check value */
-	DICT, /* waiting for inflateSetDictionary() call */
-	TYPE, /* i: waiting for type bits, including last-flag bit */
-	TYPEDO, /* i: same, but skip check to exit inflate on new block */
-	STORED, /* i: waiting for stored size (length and complement) */
-	COPY, /* i/o: waiting for input or output to copy stored block */
-	TABLE, /* i: waiting for dynamic block table lengths */
-	LENLENS, /* i: waiting for code length code lengths */
-	CODELENS, /* i: waiting for length/lit and distance code lengths */
-	LEN, /* i: waiting for length/lit code */
-	LENEXT, /* i: waiting for length extra bits */
-	DIST, /* i: waiting for distance code */
-	DISTEXT, /* i: waiting for distance extra bits */
-	MATCH, /* o: waiting for output space to copy string */
-	LIT, /* o: waiting for output space to write literal */
-	CHECK, /* i: waiting for 32-bit check value */
-	LENGTH, /* i: waiting for 32-bit length (gzip) */
-	DONE, /* finished check, done -- remain here until reset */
-	BAD, /* got a data error -- remain here until reset */
-	MEM, /* got an inflate() memory error -- remain here until reset */
-	SYNC, /* looking for synchronization bytes to restart inflate() */
-	START,
-	WASH,
-	END,
-	BADCODE
-} inflate_mode;
-
-/*
-    State transitions between above modes -
-
-    (most modes can go to the BAD or MEM mode -- not shown for clarity)
-
-    Process header:
-        HEAD -> (gzip) or (zlib)
-        (gzip) -> FLAGS -> TIME -> OS -> EXLEN -> EXTRA -> NAME
-        NAME -> COMMENT -> HCRC -> TYPE
-        (zlib) -> DICTID or TYPE
-        DICTID -> DICT -> TYPE
-    Read deflate blocks:
-            TYPE -> STORED or TABLE or LEN or CHECK
-            STORED -> COPY -> TYPE
-            TABLE -> LENLENS -> CODELENS -> LEN
-    Read deflate codes:
-                LEN -> LENEXT or LIT or TYPE
-                LENEXT -> DIST -> DISTEXT -> MATCH -> LEN
-                LIT -> LEN
-    Process trailer:
-        CHECK -> LENGTH -> DONE
- */
-
-/* state maintained between inflate() calls.  Approximately 7K bytes. */
-struct inflate_state {
-	inflate_mode mode; /* current inflate mode */
-	int last; /* true if processing last block */
-	int wrap; /* bit 0 true for zlib, bit 1 true for gzip */
-	int havedict; /* true if dictionary provided */
-	int flags; /* gzip header method and flags (0 if zlib) */
-	unsigned dmax; /* zlib header max distance (INFLATE_STRICT) */
-	unsigned long check; /* protected copy of check value */
-	unsigned long total; /* protected copy of output count */
-	gz_headerp head; /* where to save gzip header information */
-        /* sliding window */
-	unsigned wbits; /* log base 2 of requested window size */
-	unsigned wsize; /* window size or zero if not using window */
-	unsigned whave; /* valid bytes in the window */
-	unsigned write; /* window write index */
-	unsigned char FAR *window; /* allocated sliding window, if needed */
-        /* bit accumulator */
-	unsigned long hold; /* input bit accumulator */
-	unsigned bits; /* number of bits in "in" */
-        /* for string and stored block copying */
-	unsigned length; /* literal or length of data to copy */
-	unsigned offset; /* distance back to copy string from */
-        /* for table and code decoding */
-	unsigned extra; /* extra bits needed */
-        /* fixed and dynamic code tables */
-	code const FAR *lencode; /* starting table for length/literal codes */
-	code const FAR *distcode; /* starting table for distance codes */
-	unsigned lenbits; /* index bits for lencode */
-	unsigned distbits; /* index bits for distcode */
-        /* dynamic table building */
-	unsigned ncode; /* number of code length code lengths */
-	unsigned nlen; /* number of length code lengths */
-	unsigned ndist; /* number of distance code lengths */
-	unsigned have; /* number of code lengths in lens[] */
-	code FAR *next; /* next available space in codes[] */
-	unsigned short lens[320]; /* temporary storage for code lengths */
-	unsigned short work[288]; /* work area for code table building */
-	code codes[ENOUGH]; /* space for code tables */
-};
-
-/*+++++*/
-/* inffast.h -- header to use inffast.c
- * Copyright (C) 1995-2003 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* WARNING: this file should *not* be used by applications. It is
-   part of the implementation of the compression library and is
-   subject to change. Applications should only use zlib.h.
- */
-
-void inflate_fast OF((z_streamp strm, unsigned start));
-/*+++++*/
-    /* inffixed.h -- table for decoding fixed codes
-     * Generated automatically by makefixed().
-     */
-
-    /* WARNING: this file should *not* be used by applications. It
-       is part of the implementation of the compression library and
-       is subject to change. Applications should only use zlib.h.
-     */
-
-	static const code lenfix[512] = {
-	{96,7,0},{0,8,80},{0,8,16},{20,8,115},{18,7,31},{0,8,112},{0,8,48},
-	{0,9,192},{16,7,10},{0,8,96},{0,8,32},{0,9,160},{0,8,0},{0,8,128},
-	{0,8,64},{0,9,224},{16,7,6},{0,8,88},{0,8,24},{0,9,144},{19,7,59},
-	{0,8,120},{0,8,56},{0,9,208},{17,7,17},{0,8,104},{0,8,40},{0,9,176},
-	{0,8,8},{0,8,136},{0,8,72},{0,9,240},{16,7,4},{0,8,84},{0,8,20},
-	{21,8,227},{19,7,43},{0,8,116},{0,8,52},{0,9,200},{17,7,13},{0,8,100},
-	{0,8,36},{0,9,168},{0,8,4},{0,8,132},{0,8,68},{0,9,232},{16,7,8},
-	{0,8,92},{0,8,28},{0,9,152},{20,7,83},{0,8,124},{0,8,60},{0,9,216},
-	{18,7,23},{0,8,108},{0,8,44},{0,9,184},{0,8,12},{0,8,140},{0,8,76},
-	{0,9,248},{16,7,3},{0,8,82},{0,8,18},{21,8,163},{19,7,35},{0,8,114},
-	{0,8,50},{0,9,196},{17,7,11},{0,8,98},{0,8,34},{0,9,164},{0,8,2},
-	{0,8,130},{0,8,66},{0,9,228},{16,7,7},{0,8,90},{0,8,26},{0,9,148},
-	{20,7,67},{0,8,122},{0,8,58},{0,9,212},{18,7,19},{0,8,106},{0,8,42},
-	{0,9,180},{0,8,10},{0,8,138},{0,8,74},{0,9,244},{16,7,5},{0,8,86},
-	{0,8,22},{64,8,0},{19,7,51},{0,8,118},{0,8,54},{0,9,204},{17,7,15},
-	{0,8,102},{0,8,38},{0,9,172},{0,8,6},{0,8,134},{0,8,70},{0,9,236},
-	{16,7,9},{0,8,94},{0,8,30},{0,9,156},{20,7,99},{0,8,126},{0,8,62},
-	{0,9,220},{18,7,27},{0,8,110},{0,8,46},{0,9,188},{0,8,14},{0,8,142},
-	{0,8,78},{0,9,252},{96,7,0},{0,8,81},{0,8,17},{21,8,131},{18,7,31},
-	{0,8,113},{0,8,49},{0,9,194},{16,7,10},{0,8,97},{0,8,33},{0,9,162},
-	{0,8,1},{0,8,129},{0,8,65},{0,9,226},{16,7,6},{0,8,89},{0,8,25},
-	{0,9,146},{19,7,59},{0,8,121},{0,8,57},{0,9,210},{17,7,17},{0,8,105},
-	{0,8,41},{0,9,178},{0,8,9},{0,8,137},{0,8,73},{0,9,242},{16,7,4},
-	{0,8,85},{0,8,21},{16,8,258},{19,7,43},{0,8,117},{0,8,53},{0,9,202},
-	{17,7,13},{0,8,101},{0,8,37},{0,9,170},{0,8,5},{0,8,133},{0,8,69},
-	{0,9,234},{16,7,8},{0,8,93},{0,8,29},{0,9,154},{20,7,83},{0,8,125},
-	{0,8,61},{0,9,218},{18,7,23},{0,8,109},{0,8,45},{0,9,186},{0,8,13},
-	{0,8,141},{0,8,77},{0,9,250},{16,7,3},{0,8,83},{0,8,19},{21,8,195},
-	{19,7,35},{0,8,115},{0,8,51},{0,9,198},{17,7,11},{0,8,99},{0,8,35},
-	{0,9,166},{0,8,3},{0,8,131},{0,8,67},{0,9,230},{16,7,7},{0,8,91},
-	{0,8,27},{0,9,150},{20,7,67},{0,8,123},{0,8,59},{0,9,214},{18,7,19},
-	{0,8,107},{0,8,43},{0,9,182},{0,8,11},{0,8,139},{0,8,75},{0,9,246},
-	{16,7,5},{0,8,87},{0,8,23},{64,8,0},{19,7,51},{0,8,119},{0,8,55},
-	{0,9,206},{17,7,15},{0,8,103},{0,8,39},{0,9,174},{0,8,7},{0,8,135},
-	{0,8,71},{0,9,238},{16,7,9},{0,8,95},{0,8,31},{0,9,158},{20,7,99},
-	{0,8,127},{0,8,63},{0,9,222},{18,7,27},{0,8,111},{0,8,47},{0,9,190},
-	{0,8,15},{0,8,143},{0,8,79},{0,9,254},{96,7,0},{0,8,80},{0,8,16},
-	{20,8,115},{18,7,31},{0,8,112},{0,8,48},{0,9,193},{16,7,10},{0,8,96},
-	{0,8,32},{0,9,161},{0,8,0},{0,8,128},{0,8,64},{0,9,225},{16,7,6},
-	{0,8,88},{0,8,24},{0,9,145},{19,7,59},{0,8,120},{0,8,56},{0,9,209},
-	{17,7,17},{0,8,104},{0,8,40},{0,9,177},{0,8,8},{0,8,136},{0,8,72},
-	{0,9,241},{16,7,4},{0,8,84},{0,8,20},{21,8,227},{19,7,43},{0,8,116},
-	{0,8,52},{0,9,201},{17,7,13},{0,8,100},{0,8,36},{0,9,169},{0,8,4},
-	{0,8,132},{0,8,68},{0,9,233},{16,7,8},{0,8,92},{0,8,28},{0,9,153},
-	{20,7,83},{0,8,124},{0,8,60},{0,9,217},{18,7,23},{0,8,108},{0,8,44},
-	{0,9,185},{0,8,12},{0,8,140},{0,8,76},{0,9,249},{16,7,3},{0,8,82},
-	{0,8,18},{21,8,163},{19,7,35},{0,8,114},{0,8,50},{0,9,197},{17,7,11},
-	{0,8,98},{0,8,34},{0,9,165},{0,8,2},{0,8,130},{0,8,66},{0,9,229},
-	{16,7,7},{0,8,90},{0,8,26},{0,9,149},{20,7,67},{0,8,122},{0,8,58},
-	{0,9,213},{18,7,19},{0,8,106},{0,8,42},{0,9,181},{0,8,10},{0,8,138},
-	{0,8,74},{0,9,245},{16,7,5},{0,8,86},{0,8,22},{64,8,0},{19,7,51},
-	{0,8,118},{0,8,54},{0,9,205},{17,7,15},{0,8,102},{0,8,38},{0,9,173},
-	{0,8,6},{0,8,134},{0,8,70},{0,9,237},{16,7,9},{0,8,94},{0,8,30},
-	{0,9,157},{20,7,99},{0,8,126},{0,8,62},{0,9,221},{18,7,27},{0,8,110},
-	{0,8,46},{0,9,189},{0,8,14},{0,8,142},{0,8,78},{0,9,253},{96,7,0},
-	{0,8,81},{0,8,17},{21,8,131},{18,7,31},{0,8,113},{0,8,49},{0,9,195},
-	{16,7,10},{0,8,97},{0,8,33},{0,9,163},{0,8,1},{0,8,129},{0,8,65},
-	{0,9,227},{16,7,6},{0,8,89},{0,8,25},{0,9,147},{19,7,59},{0,8,121},
-	{0,8,57},{0,9,211},{17,7,17},{0,8,105},{0,8,41},{0,9,179},{0,8,9},
-	{0,8,137},{0,8,73},{0,9,243},{16,7,4},{0,8,85},{0,8,21},{16,8,258},
-	{19,7,43},{0,8,117},{0,8,53},{0,9,203},{17,7,13},{0,8,101},{0,8,37},
-	{0,9,171},{0,8,5},{0,8,133},{0,8,69},{0,9,235},{16,7,8},{0,8,93},
-	{0,8,29},{0,9,155},{20,7,83},{0,8,125},{0,8,61},{0,9,219},{18,7,23},
-	{0,8,109},{0,8,45},{0,9,187},{0,8,13},{0,8,141},{0,8,77},{0,9,251},
-	{16,7,3},{0,8,83},{0,8,19},{21,8,195},{19,7,35},{0,8,115},{0,8,51},
-	{0,9,199},{17,7,11},{0,8,99},{0,8,35},{0,9,167},{0,8,3},{0,8,131},
-	{0,8,67},{0,9,231},{16,7,7},{0,8,91},{0,8,27},{0,9,151},{20,7,67},
-	{0,8,123},{0,8,59},{0,9,215},{18,7,19},{0,8,107},{0,8,43},{0,9,183},
-	{0,8,11},{0,8,139},{0,8,75},{0,9,247},{16,7,5},{0,8,87},{0,8,23},
-	{64,8,0},{19,7,51},{0,8,119},{0,8,55},{0,9,207},{17,7,15},{0,8,103},
-	{0,8,39},{0,9,175},{0,8,7},{0,8,135},{0,8,71},{0,9,239},{16,7,9},
-	{0,8,95},{0,8,31},{0,9,159},{20,7,99},{0,8,127},{0,8,63},{0,9,223},
-	{18,7,27},{0,8,111},{0,8,47},{0,9,191},{0,8,15},{0,8,143},{0,8,79},
-	{0,9,255}
-	};
-
-	static const code distfix[32] = {
-	{16,5,1},{23,5,257},{19,5,17},{27,5,4097},{17,5,5},{25,5,1025},
-	{21,5,65},{29,5,16385},{16,5,3},{24,5,513},{20,5,33},{28,5,8193},
-	{18,5,9},{26,5,2049},{22,5,129},{64,5,0},{16,5,2},{23,5,385},
-	{19,5,25},{27,5,6145},{17,5,7},{25,5,1537},{21,5,97},{29,5,24577},
-	{16,5,4},{24,5,769},{20,5,49},{28,5,12289},{18,5,13},{26,5,3073},
-	{22,5,193},{64,5,0}
-	};
-
-/*+++++*/
-/* inffast.c -- fast decoding
- * Copyright (C) 1995-2004 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* Allow machine dependent optimization for post-increment or pre-increment.
-   Based on testing to date,
-   Pre-increment preferred for:
-   - PowerPC G3 (Adler)
-   - MIPS R5000 (Randers-Pehrson)
-   Post-increment preferred for:
-   - none
-   No measurable difference:
-   - Pentium III (Anderson)
-   - M68060 (Nikl)
- */
-#define OFF 1
-#define PUP(a) *++(a)
-#define UP_UNALIGNED(a) get_unaligned(++(a))
-
-/*
-   Decode literal, length, and distance codes and write out the resulting
-   literal and match bytes until either not enough input or output is
-   available, an end-of-block is encountered, or a data error is encountered.
-   When large enough input and output buffers are supplied to inflate(), for
-   example, a 16K input buffer and a 64K output buffer, more than 95% of the
-   inflate execution time is spent in this routine.
-
-   Entry assumptions:
-
-        state->mode == LEN
-        strm->avail_in >= 6
-        strm->avail_out >= 258
-        start >= strm->avail_out
-        state->bits < 8
-
-   On return, state->mode is one of:
-
-        LEN -- ran out of enough output space or enough available input
-        TYPE -- reached end of block code, inflate() to interpret next block
-        BAD -- error in block data
-
-   Notes:
-
-    - The maximum input bits used by a length/distance pair is 15 bits for the
-      length code, 5 bits for the length extra, 15 bits for the distance code,
-      and 13 bits for the distance extra.  This totals 48 bits, or six bytes.
-      Therefore if strm->avail_in >= 6, then there is enough input to avoid
-      checking for available input while decoding.
-
-    - The maximum bytes that a single length/distance pair can output is 258
-      bytes, which is the maximum length that can be coded.  inflate_fast()
-      requires strm->avail_out >= 258 for each loop to avoid checking for
-      output space.
- */
-void inflate_fast(strm, start)
-z_streamp strm;
-unsigned start;         /* inflate()'s starting value for strm->avail_out */
-{
-    struct inflate_state FAR *state;
-    unsigned char FAR *in;      /* local strm->next_in */
-    unsigned char FAR *last;    /* while in < last, enough input available */
-    unsigned char FAR *out;     /* local strm->next_out */
-    unsigned char FAR *beg;     /* inflate()'s initial strm->next_out */
-    unsigned char FAR *end;     /* while out < end, enough space available */
-#ifdef INFLATE_STRICT
-    unsigned dmax;              /* maximum distance from zlib header */
-#endif
-    unsigned wsize;             /* window size or zero if not using window */
-    unsigned whave;             /* valid bytes in the window */
-    unsigned write;             /* window write index */
-    unsigned char FAR *window;  /* allocated sliding window, if wsize != 0 */
-    unsigned long hold;         /* local strm->hold */
-    unsigned bits;              /* local strm->bits */
-    code const FAR *lcode;      /* local strm->lencode */
-    code const FAR *dcode;      /* local strm->distcode */
-    unsigned lmask;             /* mask for first level of length codes */
-    unsigned dmask;             /* mask for first level of distance codes */
-    code this;                  /* retrieved table entry */
-    unsigned op;                /* code bits, operation, extra bits, or */
-                                /*  window position, window bytes to copy */
-    unsigned len;               /* match length, unused bytes */
-    unsigned dist;              /* match distance */
-    unsigned char FAR *from;    /* where to copy match from */
-
-    /* copy state to local variables */
-    state = (struct inflate_state FAR *)strm->state;
-    in = strm->next_in - OFF;
-    last = in + (strm->avail_in - 5);
-    out = strm->next_out - OFF;
-    beg = out - (start - strm->avail_out);
-    end = out + (strm->avail_out - 257);
-#ifdef INFLATE_STRICT
-    dmax = state->dmax;
-#endif
-    wsize = state->wsize;
-    whave = state->whave;
-    write = state->write;
-    window = state->window;
-    hold = state->hold;
-    bits = state->bits;
-    lcode = state->lencode;
-    dcode = state->distcode;
-    lmask = (1U << state->lenbits) - 1;
-    dmask = (1U << state->distbits) - 1;
-
-    /* decode literals and length/distances until end-of-block or not enough
-       input data or output space */
-    do {
-        if (bits < 15) {
-            hold += (unsigned long)(PUP(in)) << bits;
-            bits += 8;
-            hold += (unsigned long)(PUP(in)) << bits;
-            bits += 8;
-        }
-        this = lcode[hold & lmask];
-      dolen:
-        op = (unsigned)(this.bits);
-        hold >>= op;
-        bits -= op;
-        op = (unsigned)(this.op);
-        if (op == 0) {                          /* literal */
-            Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ?
-                    "inflate:         literal '%c'\n" :
-                    "inflate:         literal 0x%02x\n", this.val));
-            PUP(out) = (unsigned char)(this.val);
-        }
-        else if (op & 16) {                     /* length base */
-            len = (unsigned)(this.val);
-            op &= 15;                           /* number of extra bits */
-            if (op) {
-                if (bits < op) {
-                    hold += (unsigned long)(PUP(in)) << bits;
-                    bits += 8;
-                }
-                len += (unsigned)hold & ((1U << op) - 1);
-                hold >>= op;
-                bits -= op;
-            }
-            Tracevv((stderr, "inflate:         length %u\n", len));
-            if (bits < 15) {
-                hold += (unsigned long)(PUP(in)) << bits;
-                bits += 8;
-                hold += (unsigned long)(PUP(in)) << bits;
-                bits += 8;
-            }
-            this = dcode[hold & dmask];
-          dodist:
-            op = (unsigned)(this.bits);
-            hold >>= op;
-            bits -= op;
-            op = (unsigned)(this.op);
-            if (op & 16) {                      /* distance base */
-                dist = (unsigned)(this.val);
-                op &= 15;                       /* number of extra bits */
-                if (bits < op) {
-                    hold += (unsigned long)(PUP(in)) << bits;
-                    bits += 8;
-                    if (bits < op) {
-                        hold += (unsigned long)(PUP(in)) << bits;
-                        bits += 8;
-                    }
-                }
-                dist += (unsigned)hold & ((1U << op) - 1);
-#ifdef INFLATE_STRICT
-                if (dist > dmax) {
-                    strm->msg = (char *)"invalid distance too far back";
-                    state->mode = BAD;
-                    break;
-                }
-#endif
-                hold >>= op;
-                bits -= op;
-                Tracevv((stderr, "inflate:         distance %u\n", dist));
-                op = (unsigned)(out - beg);     /* max distance in output */
-                if (dist > op) {                /* see if copy from window */
-                    op = dist - op;             /* distance back in window */
-                    if (op > whave) {
-                        strm->msg = (char *)"invalid distance too far back";
-                        state->mode = BAD;
-                        break;
-                    }
-                    from = window - OFF;
-                    if (write == 0) {           /* very common case */
-                        from += wsize - op;
-                        if (op < len) {         /* some from window */
-                            len -= op;
-                            do {
-                                PUP(out) = PUP(from);
-                            } while (--op);
-                            from = out - dist;  /* rest from output */
-                        }
-                    }
-                    else if (write < op) {      /* wrap around window */
-                        from += wsize + write - op;
-                        op -= write;
-                        if (op < len) {         /* some from end of window */
-                            len -= op;
-                            do {
-                                PUP(out) = PUP(from);
-                            } while (--op);
-                            from = window - OFF;
-                            if (write < len) {  /* some from start of window */
-                                op = write;
-                                len -= op;
-                                do {
-                                    PUP(out) = PUP(from);
-                                } while (--op);
-                                from = out - dist;      /* rest from output */
-                            }
-                        }
-                    }
-                    else {                      /* contiguous in window */
-                        from += write - op;
-                        if (op < len) {         /* some from window */
-                            len -= op;
-                            do {
-                                PUP(out) = PUP(from);
-                            } while (--op);
-                            from = out - dist;  /* rest from output */
-                        }
-                    }
-                    while (len > 2) {
-                        PUP(out) = PUP(from);
-                        PUP(out) = PUP(from);
-                        PUP(out) = PUP(from);
-                        len -= 3;
-                    }
-                    if (len) {
-                        PUP(out) = PUP(from);
-                        if (len > 1)
-                            PUP(out) = PUP(from);
-                    }
-                }
-                else {
-		    unsigned short *sout;
-		    unsigned long loops;
-
-                    from = out - dist;          /* copy direct from output */
-                    /* minimum length is three */
-		    /* Align out addr */
-		    if (!((long)(out - 1 + OFF) & 1)) {
-			PUP(out) = PUP(from);
-			len--;
-		    }
-		    sout = (unsigned short *)(out - OFF);
-		    if (dist > 2 ) {
-			unsigned short *sfrom;
-
-			sfrom = (unsigned short *)(from - OFF);
-			loops = len >> 1;
-			do
-			    PUP(sout) = UP_UNALIGNED(sfrom);
-			while (--loops);
-			out = (unsigned char *)sout + OFF;
-			from = (unsigned char *)sfrom + OFF;
-		    } else { /* dist == 1 or dist == 2 */
-			unsigned short pat16;
-
-			pat16 = *(sout-2+2*OFF);
-			if (dist == 1)
-#if defined(__BIG_ENDIAN)
-			    pat16 = (pat16 & 0xff) | ((pat16 & 0xff ) << 8);
-#elif defined(__LITTLE_ENDIAN)
-			    pat16 = (pat16 & 0xff00) | ((pat16 & 0xff00 ) >> 8);
-#else
-#error __BIG_ENDIAN nor __LITTLE_ENDIAN is defined
-#endif
-			loops = len >> 1;
-			do
-			    PUP(sout) = pat16;
-			while (--loops);
-			out = (unsigned char *)sout + OFF;
-		    }
-		    if (len & 1)
-			PUP(out) = PUP(from);
-                }
-            }
-            else if ((op & 64) == 0) {          /* 2nd level distance code */
-                this = dcode[this.val + (hold & ((1U << op) - 1))];
-                goto dodist;
-            }
-            else {
-                strm->msg = (char *)"invalid distance code";
-                state->mode = BAD;
-                break;
-            }
-        }
-        else if ((op & 64) == 0) {              /* 2nd level length code */
-            this = lcode[this.val + (hold & ((1U << op) - 1))];
-            goto dolen;
-        }
-        else if (op & 32) {                     /* end-of-block */
-            Tracevv((stderr, "inflate:         end of block\n"));
-            state->mode = TYPE;
-            break;
-        }
-        else {
-            strm->msg = (char *)"invalid literal/length code";
-            state->mode = BAD;
-            break;
-        }
-    } while (in < last && out < end);
-
-    /* return unused bytes (on entry, bits < 8, so in won't go too far back) */
-    len = bits >> 3;
-    in -= len;
-    bits -= len << 3;
-    hold &= (1U << bits) - 1;
-
-    /* update state and return */
-    strm->next_in = in + OFF;
-    strm->next_out = out + OFF;
-    strm->avail_in = (unsigned)(in < last ? 5 + (last - in) : 5 - (in - last));
-    strm->avail_out = (unsigned)(out < end ?
-                                 257 + (end - out) : 257 - (out - end));
-    state->hold = hold;
-    state->bits = bits;
-    return;
-}
-
-/*
-   inflate_fast() speedups that turned out slower (on a PowerPC G3 750CXe):
-   - Using bit fields for code structure
-   - Different op definition to avoid & for extra bits (do & for table bits)
-   - Three separate decoding do-loops for direct, window, and write == 0
-   - Special case for distance > 1 copies to do overlapped load and store copy
-   - Explicit branch predictions (based on measured branch probabilities)
-   - Deferring match copy and interspersed it with decoding subsequent codes
-   - Swapping literal/length else
-   - Swapping window/direct else
-   - Larger unrolled copy loops (three is about right)
-   - Moving len -= 3 statement into middle of loop
- */
-
-/*+++++*/
-/* inftrees.c -- generate Huffman trees for efficient decoding
- * Copyright (C) 1995-2005 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-#define MAXBITS 15
-/*
-  If you use the zlib library in a product, an acknowledgment is welcome
-  in the documentation of your product. If for some reason you cannot
-  include such an acknowledgment, I would appreciate that you keep this
-  copyright string in the executable of your product.
- */
-
-/*
-   Build a set of tables to decode the provided canonical Huffman code.
-   The code lengths are lens[0..codes-1].  The result starts at *table,
-   whose indices are 0..2^bits-1.  work is a writable array of at least
-   lens shorts, which is used as a work area.  type is the type of code
-   to be generated, CODES, LENS, or DISTS.  On return, zero is success,
-   -1 is an invalid code, and +1 means that ENOUGH isn't enough.  table
-   on return points to the next available entry's address.  bits is the
-   requested root table index bits, and on return it is the actual root
-   table index bits.  It will differ if the request is greater than the
-   longest code or if it is less than the shortest code.
- */
-int inflate_table(type, lens, codes, table, bits, work)
-codetype type;
-unsigned short FAR *lens;
-unsigned codes;
-code FAR * FAR *table;
-unsigned FAR *bits;
-unsigned short FAR *work;
-{
-    unsigned len;               /* a code's length in bits */
-    unsigned sym;               /* index of code symbols */
-    unsigned min, max;          /* minimum and maximum code lengths */
-    unsigned root;              /* number of index bits for root table */
-    unsigned curr;              /* number of index bits for current table */
-    unsigned drop;              /* code bits to drop for sub-table */
-    int left;                   /* number of prefix codes available */
-    unsigned used;              /* code entries in table used */
-    unsigned huff;              /* Huffman code */
-    unsigned incr;              /* for incrementing code, index */
-    unsigned fill;              /* index for replicating entries */
-    unsigned low;               /* low bits for current root entry */
-    unsigned mask;              /* mask for low root bits */
-    code this;                  /* table entry for duplication */
-    code FAR *next;             /* next available space in table */
-    const unsigned short FAR *base;     /* base value table to use */
-    const unsigned short FAR *extra;    /* extra bits table to use */
-    int end;                    /* use base and extra for symbol > end */
-    unsigned short count[MAXBITS+1];    /* number of codes of each length */
-    unsigned short offs[MAXBITS+1];     /* offsets in table for each length */
-    static const unsigned short lbase[31] = { /* Length codes 257..285 base */
-        3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
-        35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
-    static const unsigned short lext[31] = { /* Length codes 257..285 extra */
-        16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18,
-        19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 201, 196};
-    static const unsigned short dbase[32] = { /* Distance codes 0..29 base */
-        1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
-        257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
-        8193, 12289, 16385, 24577, 0, 0};
-    static const unsigned short dext[32] = { /* Distance codes 0..29 extra */
-        16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22,
-        23, 23, 24, 24, 25, 25, 26, 26, 27, 27,
-        28, 28, 29, 29, 64, 64};
-
-    /*
-       Process a set of code lengths to create a canonical Huffman code.  The
-       code lengths are lens[0..codes-1].  Each length corresponds to the
-       symbols 0..codes-1.  The Huffman code is generated by first sorting the
-       symbols by length from short to long, and retaining the symbol order
-       for codes with equal lengths.  Then the code starts with all zero bits
-       for the first code of the shortest length, and the codes are integer
-       increments for the same length, and zeros are appended as the length
-       increases.  For the deflate format, these bits are stored backwards
-       from their more natural integer increment ordering, and so when the
-       decoding tables are built in the large loop below, the integer codes
-       are incremented backwards.
-
-       This routine assumes, but does not check, that all of the entries in
-       lens[] are in the range 0..MAXBITS.  The caller must assure this.
-       1..MAXBITS is interpreted as that code length.  zero means that that
-       symbol does not occur in this code.
-
-       The codes are sorted by computing a count of codes for each length,
-       creating from that a table of starting indices for each length in the
-       sorted table, and then entering the symbols in order in the sorted
-       table.  The sorted table is work[], with that space being provided by
-       the caller.
-
-       The length counts are used for other purposes as well, i.e. finding
-       the minimum and maximum length codes, determining if there are any
-       codes at all, checking for a valid set of lengths, and looking ahead
-       at length counts to determine sub-table sizes when building the
-       decoding tables.
-     */
-
-    /* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */
-    for (len = 0; len <= MAXBITS; len++)
-        count[len] = 0;
-    for (sym = 0; sym < codes; sym++)
-        count[lens[sym]]++;
-
-    /* bound code lengths, force root to be within code lengths */
-    root = *bits;
-    for (max = MAXBITS; max >= 1; max--)
-        if (count[max] != 0) break;
-    if (root > max) root = max;
-    if (max == 0) {                     /* no symbols to code at all */
-        this.op = (unsigned char)64;    /* invalid code marker */
-        this.bits = (unsigned char)1;
-        this.val = (unsigned short)0;
-        *(*table)++ = this;             /* make a table to force an error */
-        *(*table)++ = this;
-        *bits = 1;
-        return 0;     /* no symbols, but wait for decoding to report error */
-    }
-    for (min = 1; min <= MAXBITS; min++)
-        if (count[min] != 0) break;
-    if (root < min) root = min;
-
-    /* check for an over-subscribed or incomplete set of lengths */
-    left = 1;
-    for (len = 1; len <= MAXBITS; len++) {
-        left <<= 1;
-        left -= count[len];
-        if (left < 0) return -1;        /* over-subscribed */
-    }
-    if (left > 0 && (type == CODES || max != 1))
-        return -1;                      /* incomplete set */
-
-    /* generate offsets into symbol table for each length for sorting */
-    offs[1] = 0;
-    for (len = 1; len < MAXBITS; len++)
-        offs[len + 1] = offs[len] + count[len];
-
-    /* sort symbols by length, by symbol order within each length */
-    for (sym = 0; sym < codes; sym++)
-        if (lens[sym] != 0) work[offs[lens[sym]]++] = (unsigned short)sym;
-
-    /*
-       Create and fill in decoding tables.  In this loop, the table being
-       filled is at next and has curr index bits.  The code being used is huff
-       with length len.  That code is converted to an index by dropping drop
-       bits off of the bottom.  For codes where len is less than drop + curr,
-       those top drop + curr - len bits are incremented through all values to
-       fill the table with replicated entries.
-
-       root is the number of index bits for the root table.  When len exceeds
-       root, sub-tables are created pointed to by the root entry with an index
-       of the low root bits of huff.  This is saved in low to check for when a
-       new sub-table should be started.  drop is zero when the root table is
-       being filled, and drop is root when sub-tables are being filled.
-
-       When a new sub-table is needed, it is necessary to look ahead in the
-       code lengths to determine what size sub-table is needed.  The length
-       counts are used for this, and so count[] is decremented as codes are
-       entered in the tables.
-
-       used keeps track of how many table entries have been allocated from the
-       provided *table space.  It is checked when a LENS table is being made
-       against the space in *table, ENOUGH, minus the maximum space needed by
-       the worst case distance code, MAXD.  This should never happen, but the
-       sufficiency of ENOUGH has not been proven exhaustively, hence the check.
-       This assumes that when type == LENS, bits == 9.
-
-       sym increments through all symbols, and the loop terminates when
-       all codes of length max, i.e. all codes, have been processed.  This
-       routine permits incomplete codes, so another loop after this one fills
-       in the rest of the decoding tables with invalid code markers.
-     */
-
-    /* set up for code type */
-    switch (type) {
-    case CODES:
-        base = extra = work;    /* dummy value--not used */
-        end = 19;
-        break;
-    case LENS:
-        base = lbase;
-        base -= 257;
-        extra = lext;
-        extra -= 257;
-        end = 256;
-        break;
-    default:            /* DISTS */
-        base = dbase;
-        extra = dext;
-        end = -1;
-    }
-
-    /* initialize state for loop */
-    huff = 0;                   /* starting code */
-    sym = 0;                    /* starting code symbol */
-    len = min;                  /* starting code length */
-    next = *table;              /* current table to fill in */
-    curr = root;                /* current table index bits */
-    drop = 0;                   /* current bits to drop from code for index */
-    low = (unsigned)(-1);       /* trigger new sub-table when len > root */
-    used = 1U << root;          /* use root table entries */
-    mask = used - 1;            /* mask for comparing low */
-
-    /* check available table space */
-    if (type == LENS && used >= ENOUGH - MAXD)
-        return 1;
-
-    /* process all codes and make table entries */
-    for (;;) {
-        /* create table entry */
-        this.bits = (unsigned char)(len - drop);
-        if ((int)(work[sym]) < end) {
-            this.op = (unsigned char)0;
-            this.val = work[sym];
-        }
-        else if ((int)(work[sym]) > end) {
-            this.op = (unsigned char)(extra[work[sym]]);
-            this.val = base[work[sym]];
-        }
-        else {
-            this.op = (unsigned char)(32 + 64);         /* end of block */
-            this.val = 0;
-        }
-
-        /* replicate for those indices with low len bits equal to huff */
-        incr = 1U << (len - drop);
-        fill = 1U << curr;
-        min = fill;                 /* save offset to next table */
-        do {
-            fill -= incr;
-            next[(huff >> drop) + fill] = this;
-        } while (fill != 0);
-
-        /* backwards increment the len-bit code huff */
-        incr = 1U << (len - 1);
-        while (huff & incr)
-            incr >>= 1;
-        if (incr != 0) {
-            huff &= incr - 1;
-            huff += incr;
-        }
-        else
-            huff = 0;
-
-        /* go to next symbol, update count, len */
-        sym++;
-        if (--(count[len]) == 0) {
-            if (len == max) break;
-            len = lens[work[sym]];
-        }
-
-        /* create new sub-table if needed */
-        if (len > root && (huff & mask) != low) {
-            /* if first time, transition to sub-tables */
-            if (drop == 0)
-                drop = root;
-
-            /* increment past last table */
-            next += min;            /* here min is 1 << curr */
-
-            /* determine length of next table */
-            curr = len - drop;
-            left = (int)(1 << curr);
-            while (curr + drop < max) {
-                left -= count[curr + drop];
-                if (left <= 0) break;
-                curr++;
-                left <<= 1;
-            }
-
-            /* check for enough space */
-            used += 1U << curr;
-            if (type == LENS && used >= ENOUGH - MAXD)
-                return 1;
-
-            /* point entry in root table to sub-table */
-            low = huff & mask;
-            (*table)[low].op = (unsigned char)curr;
-            (*table)[low].bits = (unsigned char)root;
-            (*table)[low].val = (unsigned short)(next - *table);
-        }
-    }
-
-    /*
-       Fill in rest of table for incomplete codes.  This loop is similar to the
-       loop above in incrementing huff for table indices.  It is assumed that
-       len is equal to curr + drop, so there is no loop needed to increment
-       through high index bits.  When the current sub-table is filled, the loop
-       drops back to the root table to fill in any remaining entries there.
-     */
-    this.op = (unsigned char)64;                /* invalid code marker */
-    this.bits = (unsigned char)(len - drop);
-    this.val = (unsigned short)0;
-    while (huff != 0) {
-        /* when done with sub-table, drop back to root table */
-        if (drop != 0 && (huff & mask) != low) {
-            drop = 0;
-            len = root;
-            next = *table;
-            this.bits = (unsigned char)len;
-        }
-
-        /* put invalid code marker in table */
-        next[huff >> drop] = this;
-
-        /* backwards increment the len-bit code huff */
-        incr = 1U << (len - 1);
-        while (huff & incr)
-            incr >>= 1;
-        if (incr != 0) {
-            huff &= incr - 1;
-            huff += incr;
-        }
-        else
-            huff = 0;
-    }
-
-    /* set return parameters */
-    *table += used;
-    *bits = root;
-    return 0;
-}
-
-/*+++++*/
-/* inflate.c -- zlib decompression
- * Copyright (C) 1995-2005 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-local void fixedtables OF((struct inflate_state FAR *state));
-local int updatewindow OF((z_streamp strm, unsigned out));
-
-int ZEXPORT inflateReset(strm)
-z_streamp strm;
-{
-    struct inflate_state FAR *state;
-
-    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
-    state = (struct inflate_state FAR *)strm->state;
-    strm->total_in = strm->total_out = state->total = 0;
-    strm->msg = Z_NULL;
-    strm->adler = 1;        /* to support ill-conceived Java test suite */
-    state->mode = HEAD;
-    state->last = 0;
-    state->havedict = 0;
-    state->dmax = 32768U;
-    state->head = Z_NULL;
-    state->wsize = 0;
-    state->whave = 0;
-    state->write = 0;
-    state->hold = 0;
-    state->bits = 0;
-    state->lencode = state->distcode = state->next = state->codes;
-    WATCHDOG_RESET();
-    Tracev((stderr, "inflate: reset\n"));
-    return Z_OK;
-}
-
-int ZEXPORT inflateInit2_(strm, windowBits, version, stream_size)
-z_streamp strm;
-int windowBits;
-const char *version;
-int stream_size;
-{
-    struct inflate_state FAR *state;
-
-    if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||
-        stream_size != (int)(sizeof(z_stream)))
-        return Z_VERSION_ERROR;
-    if (strm == Z_NULL) return Z_STREAM_ERROR;
-    strm->msg = Z_NULL;                 /* in case we return an error */
-    if (strm->zalloc == (alloc_func)0) {
-        strm->zalloc = zcalloc;
-        strm->opaque = (voidpf)0;
-    }
-    if (strm->zfree == (free_func)0) strm->zfree = zcfree;
-    state = (struct inflate_state FAR *)
-            ZALLOC(strm, 1, sizeof(struct inflate_state));
-    if (state == Z_NULL) return Z_MEM_ERROR;
-    Tracev((stderr, "inflate: allocated\n"));
-    strm->state = (struct internal_state FAR *)state;
-    if (windowBits < 0) {
-        state->wrap = 0;
-        windowBits = -windowBits;
-    }
-    else {
-        state->wrap = (windowBits >> 4) + 1;
-#ifdef GUNZIP
-        if (windowBits < 48) windowBits &= 15;
-#endif
-    }
-    if (windowBits < 8 || windowBits > 15) {
-        ZFREE(strm, state);
-        strm->state = Z_NULL;
-        return Z_STREAM_ERROR;
-    }
-    state->wbits = (unsigned)windowBits;
-    state->window = Z_NULL;
-    return inflateReset(strm);
-}
-
-int ZEXPORT inflateInit_(strm, version, stream_size)
-z_streamp strm;
-const char *version;
-int stream_size;
-{
-    return inflateInit2_(strm, DEF_WBITS, version, stream_size);
-}
-
-local void fixedtables(state)
-struct inflate_state FAR *state;
-{
-    state->lencode = lenfix;
-    state->lenbits = 9;
-    state->distcode = distfix;
-    state->distbits = 5;
-}
-
-/*
-   Update the window with the last wsize (normally 32K) bytes written before
-   returning.  If window does not exist yet, create it.  This is only called
-   when a window is already in use, or when output has been written during this
-   inflate call, but the end of the deflate stream has not been reached yet.
-   It is also called to create a window for dictionary data when a dictionary
-   is loaded.
-
-   Providing output buffers larger than 32K to inflate() should provide a speed
-   advantage, since only the last 32K of output is copied to the sliding window
-   upon return from inflate(), and since all distances after the first 32K of
-   output will fall in the output data, making match copies simpler and faster.
-   The advantage may be dependent on the size of the processor's data caches.
- */
-local int updatewindow(strm, out)
-z_streamp strm;
-unsigned out;
-{
-    struct inflate_state FAR *state;
-    unsigned copy, dist;
-
-    state = (struct inflate_state FAR *)strm->state;
-
-    /* if it hasn't been done already, allocate space for the window */
-    if (state->window == Z_NULL) {
-        state->window = (unsigned char FAR *)
-                        ZALLOC(strm, 1U << state->wbits,
-                               sizeof(unsigned char));
-        if (state->window == Z_NULL) return 1;
-    }
-
-    /* if window not in use yet, initialize */
-    if (state->wsize == 0) {
-        state->wsize = 1U << state->wbits;
-        state->write = 0;
-        state->whave = 0;
-    }
-
-    /* copy state->wsize or less output bytes into the circular window */
-    copy = out - strm->avail_out;
-    if (copy >= state->wsize) {
-        zmemcpy(state->window, strm->next_out - state->wsize, state->wsize);
-        state->write = 0;
-        state->whave = state->wsize;
-    }
-    else {
-        dist = state->wsize - state->write;
-        if (dist > copy) dist = copy;
-        zmemcpy(state->window + state->write, strm->next_out - copy, dist);
-        copy -= dist;
-        if (copy) {
-            zmemcpy(state->window, strm->next_out - copy, copy);
-            state->write = copy;
-            state->whave = state->wsize;
-        }
-        else {
-            state->write += dist;
-            if (state->write == state->wsize) state->write = 0;
-            if (state->whave < state->wsize) state->whave += dist;
-        }
-    }
-    return 0;
-}
-
-/* Macros for inflate(): */
-
-/* check function to use adler32() for zlib or crc32() for gzip */
-#define UPDATE(check, buf, len) \
-	(state->flags ? crc32(check, buf, len) : adler32(check, buf, len))
-
-/* check macros for header crc */
-#define CRC2(check, word) \
-	do { \
-		hbuf[0] = (unsigned char)(word); \
-		hbuf[1] = (unsigned char)((word) >> 8); \
-		check = crc32(check, hbuf, 2); \
-	} while (0)
-
-#define CRC4(check, word) \
-	do { \
-		hbuf[0] = (unsigned char)(word); \
-		hbuf[1] = (unsigned char)((word) >> 8); \
-		hbuf[2] = (unsigned char)((word) >> 16); \
-		hbuf[3] = (unsigned char)((word) >> 24); \
-		check = crc32(check, hbuf, 4); \
-	} while (0)
-
-/* Load registers with state in inflate() for speed */
-#define LOAD() \
-	do { \
-		put = strm->next_out; \
-		left = strm->avail_out; \
-		next = strm->next_in; \
-		have = strm->avail_in; \
-		hold = state->hold; \
-		bits = state->bits; \
-	} while (0)
-
-/* Restore state from registers in inflate() */
-#define RESTORE() \
-	do { \
-		strm->next_out = put; \
-		strm->avail_out = left; \
-		strm->next_in = next; \
-		strm->avail_in = have; \
-		state->hold = hold; \
-		state->bits = bits; \
-	} while (0)
-
-/* Clear the input bit accumulator */
-#define INITBITS() \
-	do { \
-		hold = 0; \
-		bits = 0; \
-	} while (0)
-
-/* Get a byte of input into the bit accumulator, or return from inflate()
-   if there is no input available. */
-#define PULLBYTE() \
-	do { \
-		if (have == 0) goto inf_leave; \
-		have--; \
-		hold += (unsigned long)(*next++) << bits; \
-		bits += 8; \
-	} while (0)
-
-/* Assure that there are at least n bits in the bit accumulator.  If there is
-   not enough available input to do that, then return from inflate(). */
-#define NEEDBITS(n) \
-	do { \
-		while (bits < (unsigned)(n)) \
-			PULLBYTE(); \
-	} while (0)
-
-/* Return the low n bits of the bit accumulator (n < 16) */
-#define BITS(n) \
-	((unsigned)hold & ((1U << (n)) - 1))
-
-/* Remove n bits from the bit accumulator */
-#define DROPBITS(n) \
-	do { \
-		hold >>= (n); \
-		bits -= (unsigned)(n); \
-	} while (0)
-
-/* Remove zero to seven bits as needed to go to a byte boundary */
-#define BYTEBITS() \
-	do { \
-		hold >>= bits & 7; \
-		bits -= bits & 7; \
-	} while (0)
-
-/* Reverse the bytes in a 32-bit value */
-#define REVERSE(q) \
-	((((q) >> 24) & 0xff) + (((q) >> 8) & 0xff00) + \
-		(((q) & 0xff00) << 8) + (((q) & 0xff) << 24))
-
-/*
-   inflate() uses a state machine to process as much input data and generate as
-   much output data as possible before returning.  The state machine is
-   structured roughly as follows:
-
-    for (;;) switch (state) {
-    ...
-    case STATEn:
-        if (not enough input data or output space to make progress)
-            return;
-        ... make progress ...
-        state = STATEm;
-        break;
-    ...
-    }
-
-   so when inflate() is called again, the same case is attempted again, and
-   if the appropriate resources are provided, the machine proceeds to the
-   next state.  The NEEDBITS() macro is usually the way the state evaluates
-   whether it can proceed or should return.  NEEDBITS() does the return if
-   the requested bits are not available.  The typical use of the BITS macros
-   is:
-
-        NEEDBITS(n);
-        ... do something with BITS(n) ...
-        DROPBITS(n);
-
-   where NEEDBITS(n) either returns from inflate() if there isn't enough
-   input left to load n bits into the accumulator, or it continues.  BITS(n)
-   gives the low n bits in the accumulator.  When done, DROPBITS(n) drops
-   the low n bits off the accumulator.  INITBITS() clears the accumulator
-   and sets the number of available bits to zero.  BYTEBITS() discards just
-   enough bits to put the accumulator on a byte boundary.  After BYTEBITS()
-   and a NEEDBITS(8), then BITS(8) would return the next byte in the stream.
-
-   NEEDBITS(n) uses PULLBYTE() to get an available byte of input, or to return
-   if there is no input available.  The decoding of variable length codes uses
-   PULLBYTE() directly in order to pull just enough bytes to decode the next
-   code, and no more.
-
-   Some states loop until they get enough input, making sure that enough
-   state information is maintained to continue the loop where it left off
-   if NEEDBITS() returns in the loop.  For example, want, need, and keep
-   would all have to actually be part of the saved state in case NEEDBITS()
-   returns:
-
-    case STATEw:
-        while (want < need) {
-            NEEDBITS(n);
-            keep[want++] = BITS(n);
-            DROPBITS(n);
-        }
-        state = STATEx;
-    case STATEx:
-
-   As shown above, if the next state is also the next case, then the break
-   is omitted.
-
-   A state may also return if there is not enough output space available to
-   complete that state.  Those states are copying stored data, writing a
-   literal byte, and copying a matching string.
-
-   When returning, a "goto inf_leave" is used to update the total counters,
-   update the check value, and determine whether any progress has been made
-   during that inflate() call in order to return the proper return code.
-   Progress is defined as a change in either strm->avail_in or strm->avail_out.
-   When there is a window, goto inf_leave will update the window with the last
-   output written.  If a goto inf_leave occurs in the middle of decompression
-   and there is no window currently, goto inf_leave will create one and copy
-   output to the window for the next call of inflate().
-
-   In this implementation, the flush parameter of inflate() only affects the
-   return code (per zlib.h).  inflate() always writes as much as possible to
-   strm->next_out, given the space available and the provided input--the effect
-   documented in zlib.h of Z_SYNC_FLUSH.  Furthermore, inflate() always defers
-   the allocation of and copying into a sliding window until necessary, which
-   provides the effect documented in zlib.h for Z_FINISH when the entire input
-   stream available.  So the only thing the flush parameter actually does is:
-   when flush is set to Z_FINISH, inflate() cannot return Z_OK.  Instead it
-   will return Z_BUF_ERROR if it has not reached the end of the stream.
- */
-int ZEXPORT inflate(strm, flush)
-z_streamp strm;
-int flush;
-{
-    struct inflate_state FAR *state;
-    unsigned char FAR *next;    /* next input */
-    unsigned char FAR *put;     /* next output */
-    unsigned have, left;        /* available input and output */
-    unsigned long hold;         /* bit buffer */
-    unsigned bits;              /* bits in bit buffer */
-    unsigned in, out;           /* save starting available input and output */
-    unsigned copy;              /* number of stored or match bytes to copy */
-    unsigned char FAR *from;    /* where to copy match bytes from */
-    code this;                  /* current decoding table entry */
-    code last;                  /* parent table entry */
-    unsigned len;               /* length to copy for repeats, bits to drop */
-    int ret;                    /* return code */
-#ifdef GUNZIP
-    unsigned char hbuf[4];      /* buffer for gzip header crc calculation */
-#endif
-    static const unsigned short order[19] = /* permutation of code lengths */
-        {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
-
-    if (strm == Z_NULL || strm->state == Z_NULL ||
-        (strm->next_in == Z_NULL && strm->avail_in != 0))
-        return Z_STREAM_ERROR;
-
-    state = (struct inflate_state FAR *)strm->state;
-    if (state->mode == TYPE) state->mode = TYPEDO;      /* skip check */
-    LOAD();
-    in = have;
-    out = left;
-    ret = Z_OK;
-    for (;;)
-        switch (state->mode) {
-        case HEAD:
-            if (state->wrap == 0) {
-                state->mode = TYPEDO;
-                break;
-            }
-            NEEDBITS(16);
-#ifdef GUNZIP
-            if ((state->wrap & 2) && hold == 0x8b1f) {  /* gzip header */
-                state->check = crc32(0L, Z_NULL, 0);
-                CRC2(state->check, hold);
-                INITBITS();
-                state->mode = FLAGS;
-                break;
-            }
-            state->flags = 0;           /* expect zlib header */
-            if (state->head != Z_NULL)
-                state->head->done = -1;
-            if (!(state->wrap & 1) ||   /* check if zlib header allowed */
-#else
-            if (
-#endif
-                ((BITS(8) << 8) + (hold >> 8)) % 31) {
-                strm->msg = (char *)"incorrect header check";
-                state->mode = BAD;
-                break;
-            }
-            if (BITS(4) != Z_DEFLATED) {
-                strm->msg = (char *)"unknown compression method";
-                state->mode = BAD;
-                break;
-            }
-            DROPBITS(4);
-            len = BITS(4) + 8;
-            if (len > state->wbits) {
-                strm->msg = (char *)"invalid window size";
-                state->mode = BAD;
-                break;
-            }
-            state->dmax = 1U << len;
-            Tracev((stderr, "inflate:   zlib header ok\n"));
-            strm->adler = state->check = adler32(0L, Z_NULL, 0);
-            state->mode = hold & 0x200 ? DICTID : TYPE;
-            INITBITS();
-            break;
-#ifdef GUNZIP
-        case FLAGS:
-            NEEDBITS(16);
-            state->flags = (int)(hold);
-            if ((state->flags & 0xff) != Z_DEFLATED) {
-                strm->msg = (char *)"unknown compression method";
-                state->mode = BAD;
-                break;
-            }
-            if (state->flags & 0xe000) {
-                strm->msg = (char *)"unknown header flags set";
-                state->mode = BAD;
-                break;
-            }
-            if (state->head != Z_NULL)
-                state->head->text = (int)((hold >> 8) & 1);
-            if (state->flags & 0x0200) CRC2(state->check, hold);
-            INITBITS();
-            state->mode = TIME;
-        case TIME:
-            NEEDBITS(32);
-            if (state->head != Z_NULL)
-                state->head->time = hold;
-            if (state->flags & 0x0200) CRC4(state->check, hold);
-            INITBITS();
-            state->mode = OS;
-        case OS:
-            NEEDBITS(16);
-            if (state->head != Z_NULL) {
-                state->head->xflags = (int)(hold & 0xff);
-                state->head->os = (int)(hold >> 8);
-            }
-            if (state->flags & 0x0200) CRC2(state->check, hold);
-            INITBITS();
-            state->mode = EXLEN;
-        case EXLEN:
-            if (state->flags & 0x0400) {
-                NEEDBITS(16);
-                state->length = (unsigned)(hold);
-                if (state->head != Z_NULL)
-                    state->head->extra_len = (unsigned)hold;
-                if (state->flags & 0x0200) CRC2(state->check, hold);
-                INITBITS();
-            }
-            else if (state->head != Z_NULL)
-                state->head->extra = Z_NULL;
-            state->mode = EXTRA;
-        case EXTRA:
-            if (state->flags & 0x0400) {
-                copy = state->length;
-                if (copy > have) copy = have;
-                if (copy) {
-                    if (state->head != Z_NULL &&
-                        state->head->extra != Z_NULL) {
-                        len = state->head->extra_len - state->length;
-                        zmemcpy(state->head->extra + len, next,
-                                len + copy > state->head->extra_max ?
-                                state->head->extra_max - len : copy);
-                    }
-                    if (state->flags & 0x0200)
-                        state->check = crc32(state->check, next, copy);
-                    have -= copy;
-                    next += copy;
-                    state->length -= copy;
-                }
-                if (state->length) goto inf_leave;
-            }
-            state->length = 0;
-            state->mode = NAME;
-        case NAME:
-            if (state->flags & 0x0800) {
-                if (have == 0) goto inf_leave;
-                copy = 0;
-                do {
-                    len = (unsigned)(next[copy++]);
-                    if (state->head != Z_NULL &&
-                            state->head->name != Z_NULL &&
-                            state->length < state->head->name_max)
-                        state->head->name[state->length++] = len;
-                } while (len && copy < have);
-                if (state->flags & 0x0200)
-                    state->check = crc32(state->check, next, copy);
-                have -= copy;
-                next += copy;
-                if (len) goto inf_leave;
-            }
-            else if (state->head != Z_NULL)
-                state->head->name = Z_NULL;
-            state->length = 0;
-            state->mode = COMMENT;
-        case COMMENT:
-            if (state->flags & 0x1000) {
-                if (have == 0) goto inf_leave;
-                copy = 0;
-                do {
-                    len = (unsigned)(next[copy++]);
-                    if (state->head != Z_NULL &&
-                            state->head->comment != Z_NULL &&
-                            state->length < state->head->comm_max)
-                        state->head->comment[state->length++] = len;
-                } while (len && copy < have);
-                if (state->flags & 0x0200)
-                    state->check = crc32(state->check, next, copy);
-                have -= copy;
-                next += copy;
-                if (len) goto inf_leave;
-            }
-            else if (state->head != Z_NULL)
-                state->head->comment = Z_NULL;
-            state->mode = HCRC;
-        case HCRC:
-            if (state->flags & 0x0200) {
-                NEEDBITS(16);
-                if (hold != (state->check & 0xffff)) {
-                    strm->msg = (char *)"header crc mismatch";
-                    state->mode = BAD;
-                    break;
-                }
-                INITBITS();
-            }
-            if (state->head != Z_NULL) {
-                state->head->hcrc = (int)((state->flags >> 9) & 1);
-                state->head->done = 1;
-            }
-            strm->adler = state->check = crc32(0L, Z_NULL, 0);
-            state->mode = TYPE;
-            break;
-#endif
-        case DICTID:
-            NEEDBITS(32);
-            strm->adler = state->check = REVERSE(hold);
-            INITBITS();
-            state->mode = DICT;
-        case DICT:
-            if (state->havedict == 0) {
-                RESTORE();
-                return Z_NEED_DICT;
-            }
-            strm->adler = state->check = adler32(0L, Z_NULL, 0);
-            state->mode = TYPE;
-        case TYPE:
-	    WATCHDOG_RESET();
-            if (flush == Z_BLOCK) goto inf_leave;
-        case TYPEDO:
-            if (state->last) {
-                BYTEBITS();
-                state->mode = CHECK;
-                break;
-            }
-            NEEDBITS(3);
-            state->last = BITS(1);
-            DROPBITS(1);
-            switch (BITS(2)) {
-            case 0:                             /* stored block */
-                Tracev((stderr, "inflate:     stored block%s\n",
-                        state->last ? " (last)" : ""));
-                state->mode = STORED;
-                break;
-            case 1:                             /* fixed block */
-                fixedtables(state);
-                Tracev((stderr, "inflate:     fixed codes block%s\n",
-                        state->last ? " (last)" : ""));
-                state->mode = LEN;              /* decode codes */
-                break;
-            case 2:                             /* dynamic block */
-                Tracev((stderr, "inflate:     dynamic codes block%s\n",
-                        state->last ? " (last)" : ""));
-                state->mode = TABLE;
-                break;
-            case 3:
-                strm->msg = (char *)"invalid block type";
-                state->mode = BAD;
-            }
-            DROPBITS(2);
-            break;
-        case STORED:
-            BYTEBITS();                         /* go to byte boundary */
-            NEEDBITS(32);
-            if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) {
-                strm->msg = (char *)"invalid stored block lengths";
-                state->mode = BAD;
-                break;
-            }
-            state->length = (unsigned)hold & 0xffff;
-            Tracev((stderr, "inflate:       stored length %u\n",
-                    state->length));
-            INITBITS();
-            state->mode = COPY;
-        case COPY:
-            copy = state->length;
-            if (copy) {
-                if (copy > have) copy = have;
-                if (copy > left) copy = left;
-                if (copy == 0) goto inf_leave;
-                zmemcpy(put, next, copy);
-                have -= copy;
-                next += copy;
-                left -= copy;
-                put += copy;
-                state->length -= copy;
-                break;
-            }
-            Tracev((stderr, "inflate:       stored end\n"));
-            state->mode = TYPE;
-            break;
-        case TABLE:
-            NEEDBITS(14);
-            state->nlen = BITS(5) + 257;
-            DROPBITS(5);
-            state->ndist = BITS(5) + 1;
-            DROPBITS(5);
-            state->ncode = BITS(4) + 4;
-            DROPBITS(4);
-#ifndef PKZIP_BUG_WORKAROUND
-            if (state->nlen > 286 || state->ndist > 30) {
-                strm->msg = (char *)"too many length or distance symbols";
-                state->mode = BAD;
-                break;
-            }
-#endif
-            Tracev((stderr, "inflate:       table sizes ok\n"));
-            state->have = 0;
-            state->mode = LENLENS;
-        case LENLENS:
-            while (state->have < state->ncode) {
-                NEEDBITS(3);
-                state->lens[order[state->have++]] = (unsigned short)BITS(3);
-                DROPBITS(3);
-            }
-            while (state->have < 19)
-                state->lens[order[state->have++]] = 0;
-            state->next = state->codes;
-            state->lencode = (code const FAR *)(state->next);
-            state->lenbits = 7;
-            ret = inflate_table(CODES, state->lens, 19, &(state->next),
-                                &(state->lenbits), state->work);
-            if (ret) {
-                strm->msg = (char *)"invalid code lengths set";
-                state->mode = BAD;
-                break;
-            }
-            Tracev((stderr, "inflate:       code lengths ok\n"));
-            state->have = 0;
-            state->mode = CODELENS;
-        case CODELENS:
-            while (state->have < state->nlen + state->ndist) {
-                for (;;) {
-                    this = state->lencode[BITS(state->lenbits)];
-                    if ((unsigned)(this.bits) <= bits) break;
-                    PULLBYTE();
-                }
-                if (this.val < 16) {
-                    NEEDBITS(this.bits);
-                    DROPBITS(this.bits);
-                    state->lens[state->have++] = this.val;
-                }
-                else {
-                    if (this.val == 16) {
-                        NEEDBITS(this.bits + 2);
-                        DROPBITS(this.bits);
-                        if (state->have == 0) {
-                            strm->msg = (char *)"invalid bit length repeat";
-                            state->mode = BAD;
-                            break;
-                        }
-                        len = state->lens[state->have - 1];
-                        copy = 3 + BITS(2);
-                        DROPBITS(2);
-                    }
-                    else if (this.val == 17) {
-                        NEEDBITS(this.bits + 3);
-                        DROPBITS(this.bits);
-                        len = 0;
-                        copy = 3 + BITS(3);
-                        DROPBITS(3);
-                    }
-                    else {
-                        NEEDBITS(this.bits + 7);
-                        DROPBITS(this.bits);
-                        len = 0;
-                        copy = 11 + BITS(7);
-                        DROPBITS(7);
-                    }
-                    if (state->have + copy > state->nlen + state->ndist) {
-                        strm->msg = (char *)"invalid bit length repeat";
-                        state->mode = BAD;
-                        break;
-                    }
-                    while (copy--)
-                        state->lens[state->have++] = (unsigned short)len;
-                }
-            }
-
-            /* handle error breaks in while */
-            if (state->mode == BAD) break;
-
-            /* build code tables */
-            state->next = state->codes;
-            state->lencode = (code const FAR *)(state->next);
-            state->lenbits = 9;
-            ret = inflate_table(LENS, state->lens, state->nlen, &(state->next),
-                                &(state->lenbits), state->work);
-            if (ret) {
-                strm->msg = (char *)"invalid literal/lengths set";
-                state->mode = BAD;
-                break;
-            }
-            state->distcode = (code const FAR *)(state->next);
-            state->distbits = 6;
-            ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist,
-                            &(state->next), &(state->distbits), state->work);
-            if (ret) {
-                strm->msg = (char *)"invalid distances set";
-                state->mode = BAD;
-                break;
-            }
-            Tracev((stderr, "inflate:       codes ok\n"));
-            state->mode = LEN;
-        case LEN:
-	    WATCHDOG_RESET();
-            if (have >= 6 && left >= 258) {
-                RESTORE();
-                inflate_fast(strm, out);
-                LOAD();
-                break;
-            }
-            for (;;) {
-                this = state->lencode[BITS(state->lenbits)];
-                if ((unsigned)(this.bits) <= bits) break;
-                PULLBYTE();
-            }
-            if (this.op && (this.op & 0xf0) == 0) {
-                last = this;
-                for (;;) {
-                    this = state->lencode[last.val +
-                            (BITS(last.bits + last.op) >> last.bits)];
-                    if ((unsigned)(last.bits + this.bits) <= bits) break;
-                    PULLBYTE();
-                }
-                DROPBITS(last.bits);
-            }
-            DROPBITS(this.bits);
-            state->length = (unsigned)this.val;
-            if ((int)(this.op) == 0) {
-                Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ?
-                        "inflate:         literal '%c'\n" :
-                        "inflate:         literal 0x%02x\n", this.val));
-                state->mode = LIT;
-                break;
-            }
-            if (this.op & 32) {
-                Tracevv((stderr, "inflate:         end of block\n"));
-                state->mode = TYPE;
-                break;
-            }
-            if (this.op & 64) {
-                strm->msg = (char *)"invalid literal/length code";
-                state->mode = BAD;
-                break;
-            }
-            state->extra = (unsigned)(this.op) & 15;
-            state->mode = LENEXT;
-        case LENEXT:
-            if (state->extra) {
-                NEEDBITS(state->extra);
-                state->length += BITS(state->extra);
-                DROPBITS(state->extra);
-            }
-            Tracevv((stderr, "inflate:         length %u\n", state->length));
-            state->mode = DIST;
-        case DIST:
-            for (;;) {
-                this = state->distcode[BITS(state->distbits)];
-                if ((unsigned)(this.bits) <= bits) break;
-                PULLBYTE();
-            }
-            if ((this.op & 0xf0) == 0) {
-                last = this;
-                for (;;) {
-                    this = state->distcode[last.val +
-                            (BITS(last.bits + last.op) >> last.bits)];
-                    if ((unsigned)(last.bits + this.bits) <= bits) break;
-                    PULLBYTE();
-                }
-                DROPBITS(last.bits);
-            }
-            DROPBITS(this.bits);
-            if (this.op & 64) {
-                strm->msg = (char *)"invalid distance code";
-                state->mode = BAD;
-                break;
-            }
-            state->offset = (unsigned)this.val;
-            state->extra = (unsigned)(this.op) & 15;
-            state->mode = DISTEXT;
-        case DISTEXT:
-            if (state->extra) {
-                NEEDBITS(state->extra);
-                state->offset += BITS(state->extra);
-                DROPBITS(state->extra);
-            }
-#ifdef INFLATE_STRICT
-            if (state->offset > state->dmax) {
-                strm->msg = (char *)"invalid distance too far back";
-                state->mode = BAD;
-                break;
-            }
-#endif
-            if (state->offset > state->whave + out - left) {
-                strm->msg = (char *)"invalid distance too far back";
-                state->mode = BAD;
-                break;
-            }
-            Tracevv((stderr, "inflate:         distance %u\n", state->offset));
-            state->mode = MATCH;
-        case MATCH:
-            if (left == 0) goto inf_leave;
-            copy = out - left;
-            if (state->offset > copy) {         /* copy from window */
-                copy = state->offset - copy;
-                if (copy > state->write) {
-                    copy -= state->write;
-                    from = state->window + (state->wsize - copy);
-                }
-                else
-                    from = state->window + (state->write - copy);
-                if (copy > state->length) copy = state->length;
-            }
-            else {                              /* copy from output */
-                from = put - state->offset;
-                copy = state->length;
-            }
-            if (copy > left) copy = left;
-            left -= copy;
-            state->length -= copy;
-            do {
-                *put++ = *from++;
-            } while (--copy);
-            if (state->length == 0) state->mode = LEN;
-            break;
-        case LIT:
-            if (left == 0) goto inf_leave;
-            *put++ = (unsigned char)(state->length);
-            left--;
-            state->mode = LEN;
-            break;
-        case CHECK:
-            if (state->wrap) {
-                NEEDBITS(32);
-                out -= left;
-                strm->total_out += out;
-                state->total += out;
-                if (out)
-                    strm->adler = state->check =
-                        UPDATE(state->check, put - out, out);
-                out = left;
-                if ((
-#ifdef GUNZIP
-                     state->flags ? hold :
-#endif
-                     REVERSE(hold)) != state->check) {
-                    strm->msg = (char *)"incorrect data check";
-                    state->mode = BAD;
-                    break;
-                }
-                INITBITS();
-                Tracev((stderr, "inflate:   check matches trailer\n"));
-            }
-#ifdef GUNZIP
-            state->mode = LENGTH;
-        case LENGTH:
-            if (state->wrap && state->flags) {
-                NEEDBITS(32);
-                if (hold != (state->total & 0xffffffffUL)) {
-                    strm->msg = (char *)"incorrect length check";
-                    state->mode = BAD;
-                    break;
-                }
-                INITBITS();
-                Tracev((stderr, "inflate:   length matches trailer\n"));
-            }
-#endif
-            state->mode = DONE;
-        case DONE:
-            ret = Z_STREAM_END;
-            goto inf_leave;
-        case BAD:
-            ret = Z_DATA_ERROR;
-            goto inf_leave;
-        case MEM:
-            return Z_MEM_ERROR;
-        case SYNC:
-        default:
-            return Z_STREAM_ERROR;
-        }
-
-    /*
-       Return from inflate(), updating the total counts and the check value.
-       If there was no progress during the inflate() call, return a buffer
-       error.  Call updatewindow() to create and/or update the window state.
-       Note: a memory error from inflate() is non-recoverable.
-     */
-  inf_leave:
-    RESTORE();
-    if (state->wsize || (state->mode < CHECK && out != strm->avail_out))
-        if (updatewindow(strm, out)) {
-            state->mode = MEM;
-            return Z_MEM_ERROR;
-        }
-    in -= strm->avail_in;
-    out -= strm->avail_out;
-    strm->total_in += in;
-    strm->total_out += out;
-    state->total += out;
-    if (state->wrap && out)
-        strm->adler = state->check =
-            UPDATE(state->check, strm->next_out - out, out);
-    strm->data_type = state->bits + (state->last ? 64 : 0) +
-                      (state->mode == TYPE ? 128 : 0);
-    if (((in == 0 && out == 0) || flush == Z_FINISH) && ret == Z_OK)
-        ret = Z_BUF_ERROR;
-    return ret;
-}
-
-int ZEXPORT inflateEnd(strm)
-z_streamp strm;
-{
-    struct inflate_state FAR *state;
-    if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0)
-        return Z_STREAM_ERROR;
-    state = (struct inflate_state FAR *)strm->state;
-    if (state->window != Z_NULL) {
-	WATCHDOG_RESET();
-	ZFREE(strm, state->window);
-    }
-    ZFREE(strm, strm->state);
-    strm->state = Z_NULL;
-    Tracev((stderr, "inflate: end\n"));
-    return Z_OK;
-}
-
-/*+++++*/
-/* zutil.c -- target dependent utility functions for the compression library
- * Copyright (C) 1995-2005 Jean-loup Gailly.
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* @(#) $Id$ */
-
-#ifndef NO_DUMMY_DECL
-struct internal_state	{int dummy;}; /* for buggy compilers */
-#endif
-
-const char * const z_errmsg[10] = {
-"need dictionary",     /* Z_NEED_DICT       2  */
-"stream end",          /* Z_STREAM_END      1  */
-"",                    /* Z_OK              0  */
-"file error",          /* Z_ERRNO         (-1) */
-"stream error",        /* Z_STREAM_ERROR  (-2) */
-"data error",          /* Z_DATA_ERROR    (-3) */
-"insufficient memory", /* Z_MEM_ERROR     (-4) */
-"buffer error",        /* Z_BUF_ERROR     (-5) */
-"incompatible version",/* Z_VERSION_ERROR (-6) */
-""};
-
-#ifdef DEBUG
-
-#ifndef verbose
-#define verbose 0
-#endif
-int z_verbose = verbose;
-
-void z_error (m)
-    char *m;
-{
-	fprintf(stderr, "%s\n", m);
-	hang ();
-}
-#endif
-
-/* exported to allow conversion of error code to string for compress() and
- * uncompress()
- */
-#ifndef MY_ZCALLOC /* Any system without a special alloc function */
-
-#ifndef STDC
-extern voidp    malloc OF((uInt size));
-extern voidp    calloc OF((uInt items, uInt size));
-extern void     free   OF((voidpf ptr));
-#endif
-
-voidpf zcalloc (opaque, items, size)
-	voidpf opaque;
-	unsigned items;
-	unsigned size;
-{
-	if (opaque)
-		items += size - size; /* make compiler happy */
-	return sizeof(uInt) > 2 ? (voidpf)malloc(items * size) :
-		(voidpf)calloc(items, size);
-}
-
-void  zcfree (opaque, ptr, nb)
-	voidpf opaque;
-	voidpf ptr;
-	unsigned nb;
-{
-	free(ptr);
-	if (opaque)
-		return; /* make compiler happy */
-}
-
-#endif /* MY_ZCALLOC */
-/*+++++*/
-/* adler32.c -- compute the Adler-32 checksum of a data stream
- * Copyright (C) 1995-2004 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-/* @(#) $Id$ */
-
-#define BASE 65521UL    /* largest prime smaller than 65536 */
-#define NMAX 5552
-/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
-
-#define DO1(buf,i)  {adler += (buf)[i]; sum2 += adler;}
-#define DO2(buf,i)  DO1(buf,i); DO1(buf,i+1);
-#define DO4(buf,i)  DO2(buf,i); DO2(buf,i+2);
-#define DO8(buf,i)  DO4(buf,i); DO4(buf,i+4);
-#define DO16(buf)   DO8(buf,0); DO8(buf,8);
-
-/* use NO_DIVIDE if your processor does not do division in hardware */
-#ifdef NO_DIVIDE
-#define MOD(a) \
-	do { \
-		if (a >= (BASE << 16)) \
-			a -= (BASE << 16); \
-		if (a >= (BASE << 15)) \
-			a -= (BASE << 15); \
-		if (a >= (BASE << 14)) \
-			a -= (BASE << 14); \
-		if (a >= (BASE << 13)) \
-			a -= (BASE << 13); \
-		if (a >= (BASE << 12)) \
-			a -= (BASE << 12); \
-		if (a >= (BASE << 11)) \
-			a -= (BASE << 11); \
-		if (a >= (BASE << 10)) \
-			a -= (BASE << 10); \
-		if (a >= (BASE << 9)) \
-			a -= (BASE << 9); \
-		if (a >= (BASE << 8)) \
-			a -= (BASE << 8); \
-		if (a >= (BASE << 7)) \
-			a -= (BASE << 7); \
-		if (a >= (BASE << 6)) \
-			a -= (BASE << 6); \
-		if (a >= (BASE << 5)) \
-			a -= (BASE << 5); \
-		if (a >= (BASE << 4)) \
-			a -= (BASE << 4); \
-		if (a >= (BASE << 3)) \
-			a -= (BASE << 3); \
-		if (a >= (BASE << 2)) \
-			a -= (BASE << 2); \
-		if (a >= (BASE << 1)) \
-			a -= (BASE << 1); \
-		if (a >= BASE) \
-			a -= BASE; \
-	} while (0)
-#define MOD4(a) \
-	do { \
-		if (a >= (BASE << 4)) \
-			a -= (BASE << 4); \
-		if (a >= (BASE << 3)) \
-			a -= (BASE << 3); \
-		if (a >= (BASE << 2)) \
-			a -= (BASE << 2); \
-		if (a >= (BASE << 1)) \
-			a -= (BASE << 1); \
-		if (a >= BASE) \
-			a -= BASE; \
-	} while (0)
-#else
-#define MOD(a) a %= BASE
-#define MOD4(a) a %= BASE
-#endif
-
-/* ========================================================================= */
-uLong ZEXPORT adler32(adler, buf, len)
-    uLong adler;
-    const Bytef *buf;
-    uInt len;
-{
-    unsigned long sum2;
-    unsigned n;
-
-    /* split Adler-32 into component sums */
-    sum2 = (adler >> 16) & 0xffff;
-    adler &= 0xffff;
-
-    /* in case user likes doing a byte at a time, keep it fast */
-    if (len == 1) {
-        adler += buf[0];
-        if (adler >= BASE)
-            adler -= BASE;
-        sum2 += adler;
-        if (sum2 >= BASE)
-            sum2 -= BASE;
-        return adler | (sum2 << 16);
-    }
-
-    /* initial Adler-32 value (deferred check for len == 1 speed) */
-    if (buf == Z_NULL)
-        return 1L;
-
-    /* in case short lengths are provided, keep it somewhat fast */
-    if (len < 16) {
-        while (len--) {
-            adler += *buf++;
-            sum2 += adler;
-        }
-        if (adler >= BASE)
-            adler -= BASE;
-        MOD4(sum2);             /* only added so many BASE's */
-        return adler | (sum2 << 16);
-    }
-
-    /* do length NMAX blocks -- requires just one modulo operation */
-    while (len >= NMAX) {
-        len -= NMAX;
-        n = NMAX / 16;          /* NMAX is divisible by 16 */
-        do {
-            DO16(buf);          /* 16 sums unrolled */
-            buf += 16;
-        } while (--n);
-        MOD(adler);
-        MOD(sum2);
-    }
-
-    /* do remaining bytes (less than NMAX, still just one modulo) */
-    if (len) {                  /* avoid modulos if none remaining */
-        while (len >= 16) {
-            len -= 16;
-            DO16(buf);
-            buf += 16;
-        }
-        while (len--) {
-            adler += *buf++;
-            sum2 += adler;
-        }
-        MOD(adler);
-        MOD(sum2);
-    }
-
-    /* return recombined sums */
-    return adler | (sum2 << 16);
-}
diff --git a/lib/zlib/Makefile b/lib/zlib/Makefile
new file mode 100644
index 0000000..1596302
--- /dev/null
+++ b/lib/zlib/Makefile
@@ -0,0 +1,44 @@
+#
+# (C) Copyright 2000-2006
+# Wolfgang Denk, DENX Software Engineering, wd@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.
+#
+# 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 $(TOPDIR)/config.mk
+
+LIB	= $(obj)libz.o
+
+COBJS-$(CONFIG_ZLIB) += zlib.o
+
+COBJS	:= $(COBJS-y)
+SRCS	:= $(COBJS:.o=.c)
+OBJS	:= $(addprefix $(obj),$(COBJS))
+
+$(LIB):	$(obj).depend $(OBJS)
+	$(call cmd_link_o_target, $(OBJS))
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/lib/zlib/adler32.c b/lib/zlib/adler32.c
new file mode 100644
index 0000000..dc9480d
--- /dev/null
+++ b/lib/zlib/adler32.c
@@ -0,0 +1,125 @@
+/* adler32.c -- compute the Adler-32 checksum of a data stream
+ * Copyright (C) 1995-2004 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* @(#) $Id$ */
+
+#define ZLIB_INTERNAL
+#include "zlib.h"
+
+#define BASE 65521UL    /* largest prime smaller than 65536 */
+#define NMAX 5552
+/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
+
+#define DO1(buf,i)  {adler += (buf)[i]; sum2 += adler;}
+#define DO2(buf,i)  DO1(buf,i); DO1(buf,i+1);
+#define DO4(buf,i)  DO2(buf,i); DO2(buf,i+2);
+#define DO8(buf,i)  DO4(buf,i); DO4(buf,i+4);
+#define DO16(buf)   DO8(buf,0); DO8(buf,8);
+
+/* use NO_DIVIDE if your processor does not do division in hardware */
+#ifdef NO_DIVIDE
+#  define MOD(a) \
+    do { \
+        if (a >= (BASE << 16)) a -= (BASE << 16); \
+        if (a >= (BASE << 15)) a -= (BASE << 15); \
+        if (a >= (BASE << 14)) a -= (BASE << 14); \
+        if (a >= (BASE << 13)) a -= (BASE << 13); \
+        if (a >= (BASE << 12)) a -= (BASE << 12); \
+        if (a >= (BASE << 11)) a -= (BASE << 11); \
+        if (a >= (BASE << 10)) a -= (BASE << 10); \
+        if (a >= (BASE << 9)) a -= (BASE << 9); \
+        if (a >= (BASE << 8)) a -= (BASE << 8); \
+        if (a >= (BASE << 7)) a -= (BASE << 7); \
+        if (a >= (BASE << 6)) a -= (BASE << 6); \
+        if (a >= (BASE << 5)) a -= (BASE << 5); \
+        if (a >= (BASE << 4)) a -= (BASE << 4); \
+        if (a >= (BASE << 3)) a -= (BASE << 3); \
+        if (a >= (BASE << 2)) a -= (BASE << 2); \
+        if (a >= (BASE << 1)) a -= (BASE << 1); \
+        if (a >= BASE) a -= BASE; \
+    } while (0)
+#  define MOD4(a) \
+    do { \
+        if (a >= (BASE << 4)) a -= (BASE << 4); \
+        if (a >= (BASE << 3)) a -= (BASE << 3); \
+        if (a >= (BASE << 2)) a -= (BASE << 2); \
+        if (a >= (BASE << 1)) a -= (BASE << 1); \
+        if (a >= BASE) a -= BASE; \
+    } while (0)
+#else
+#  define MOD(a) a %= BASE
+#  define MOD4(a) a %= BASE
+#endif
+
+/* ========================================================================= */
+uLong ZEXPORT adler32(adler, buf, len)
+    uLong adler;
+    const Bytef *buf;
+    uInt len;
+{
+    unsigned long sum2;
+    unsigned n;
+
+    /* split Adler-32 into component sums */
+    sum2 = (adler >> 16) & 0xffff;
+    adler &= 0xffff;
+
+    /* in case user likes doing a byte at a time, keep it fast */
+    if (len == 1) {
+        adler += buf[0];
+        if (adler >= BASE)
+            adler -= BASE;
+        sum2 += adler;
+        if (sum2 >= BASE)
+            sum2 -= BASE;
+        return adler | (sum2 << 16);
+    }
+
+    /* initial Adler-32 value (deferred check for len == 1 speed) */
+    if (buf == Z_NULL)
+        return 1L;
+
+    /* in case short lengths are provided, keep it somewhat fast */
+    if (len < 16) {
+        while (len--) {
+            adler += *buf++;
+            sum2 += adler;
+        }
+        if (adler >= BASE)
+            adler -= BASE;
+        MOD4(sum2);             /* only added so many BASE's */
+        return adler | (sum2 << 16);
+    }
+
+    /* do length NMAX blocks -- requires just one modulo operation */
+    while (len >= NMAX) {
+        len -= NMAX;
+        n = NMAX / 16;          /* NMAX is divisible by 16 */
+        do {
+            DO16(buf);          /* 16 sums unrolled */
+            buf += 16;
+        } while (--n);
+        MOD(adler);
+        MOD(sum2);
+    }
+
+    /* do remaining bytes (less than NMAX, still just one modulo) */
+    if (len) {                  /* avoid modulos if none remaining */
+        while (len >= 16) {
+            len -= 16;
+            DO16(buf);
+            buf += 16;
+        }
+        while (len--) {
+            adler += *buf++;
+            sum2 += adler;
+        }
+        MOD(adler);
+        MOD(sum2);
+    }
+
+    /* return recombined sums */
+    return adler | (sum2 << 16);
+}
diff --git a/lib/zlib/inffast.c b/lib/zlib/inffast.c
new file mode 100644
index 0000000..8e823df
--- /dev/null
+++ b/lib/zlib/inffast.c
@@ -0,0 +1,349 @@
+/* inffast.c -- fast decoding
+ * Copyright (C) 1995-2004 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* U-boot: we already included these
+#include "zutil.h"
+#include "inftrees.h"
+#include "inflate.h"
+#include "inffast.h"
+*/
+
+#ifndef ASMINF
+
+/* Allow machine dependent optimization for post-increment or pre-increment.
+   Based on testing to date,
+   Pre-increment preferred for:
+   - PowerPC G3 (Adler)
+   - MIPS R5000 (Randers-Pehrson)
+   Post-increment preferred for:
+   - none
+   No measurable difference:
+   - Pentium III (Anderson)
+   - M68060 (Nikl)
+ */
+#ifdef POSTINC
+#  define OFF 0
+#  define PUP(a) *(a)++
+#else
+#  define OFF 1
+#  define PUP(a) *++(a)
+#endif
+
+/*
+   Decode literal, length, and distance codes and write out the resulting
+   literal and match bytes until either not enough input or output is
+   available, an end-of-block is encountered, or a data error is encountered.
+   When large enough input and output buffers are supplied to inflate(), for
+   example, a 16K input buffer and a 64K output buffer, more than 95% of the
+   inflate execution time is spent in this routine.
+
+   Entry assumptions:
+
+        state->mode == LEN
+        strm->avail_in >= 6
+        strm->avail_out >= 258
+        start >= strm->avail_out
+        state->bits < 8
+
+   On return, state->mode is one of:
+
+        LEN -- ran out of enough output space or enough available input
+        TYPE -- reached end of block code, inflate() to interpret next block
+        BAD -- error in block data
+
+   Notes:
+
+    - The maximum input bits used by a length/distance pair is 15 bits for the
+      length code, 5 bits for the length extra, 15 bits for the distance code,
+      and 13 bits for the distance extra.  This totals 48 bits, or six bytes.
+      Therefore if strm->avail_in >= 6, then there is enough input to avoid
+      checking for available input while decoding.
+
+    - The maximum bytes that a single length/distance pair can output is 258
+      bytes, which is the maximum length that can be coded.  inflate_fast()
+      requires strm->avail_out >= 258 for each loop to avoid checking for
+      output space.
+ */
+void inflate_fast(strm, start)
+z_streamp strm;
+unsigned start;         /* inflate()'s starting value for strm->avail_out */
+{
+    struct inflate_state FAR *state;
+    unsigned char FAR *in;      /* local strm->next_in */
+    unsigned char FAR *last;    /* while in < last, enough input available */
+    unsigned char FAR *out;     /* local strm->next_out */
+    unsigned char FAR *beg;     /* inflate()'s initial strm->next_out */
+    unsigned char FAR *end;     /* while out < end, enough space available */
+#ifdef INFLATE_STRICT
+    unsigned dmax;              /* maximum distance from zlib header */
+#endif
+    unsigned wsize;             /* window size or zero if not using window */
+    unsigned whave;             /* valid bytes in the window */
+    unsigned write;             /* window write index */
+    unsigned char FAR *window;  /* allocated sliding window, if wsize != 0 */
+    unsigned long hold;         /* local strm->hold */
+    unsigned bits;              /* local strm->bits */
+    code const FAR *lcode;      /* local strm->lencode */
+    code const FAR *dcode;      /* local strm->distcode */
+    unsigned lmask;             /* mask for first level of length codes */
+    unsigned dmask;             /* mask for first level of distance codes */
+    code this;                  /* retrieved table entry */
+    unsigned op;                /* code bits, operation, extra bits, or */
+                                /*  window position, window bytes to copy */
+    unsigned len;               /* match length, unused bytes */
+    unsigned dist;              /* match distance */
+    unsigned char FAR *from;    /* where to copy match from */
+
+    /* copy state to local variables */
+    state = (struct inflate_state FAR *)strm->state;
+    in = strm->next_in - OFF;
+    last = in + (strm->avail_in - 5);
+    out = strm->next_out - OFF;
+    beg = out - (start - strm->avail_out);
+    end = out + (strm->avail_out - 257);
+#ifdef INFLATE_STRICT
+    dmax = state->dmax;
+#endif
+    wsize = state->wsize;
+    whave = state->whave;
+    write = state->write;
+    window = state->window;
+    hold = state->hold;
+    bits = state->bits;
+    lcode = state->lencode;
+    dcode = state->distcode;
+    lmask = (1U << state->lenbits) - 1;
+    dmask = (1U << state->distbits) - 1;
+
+    /* decode literals and length/distances until end-of-block or not enough
+       input data or output space */
+    do {
+        if (bits < 15) {
+            hold += (unsigned long)(PUP(in)) << bits;
+            bits += 8;
+            hold += (unsigned long)(PUP(in)) << bits;
+            bits += 8;
+        }
+        this = lcode[hold & lmask];
+      dolen:
+        op = (unsigned)(this.bits);
+        hold >>= op;
+        bits -= op;
+        op = (unsigned)(this.op);
+        if (op == 0) {                          /* literal */
+            Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ?
+                    "inflate:         literal '%c'\n" :
+                    "inflate:         literal 0x%02x\n", this.val));
+            PUP(out) = (unsigned char)(this.val);
+        }
+        else if (op & 16) {                     /* length base */
+            len = (unsigned)(this.val);
+            op &= 15;                           /* number of extra bits */
+            if (op) {
+                if (bits < op) {
+                    hold += (unsigned long)(PUP(in)) << bits;
+                    bits += 8;
+                }
+                len += (unsigned)hold & ((1U << op) - 1);
+                hold >>= op;
+                bits -= op;
+            }
+            Tracevv((stderr, "inflate:         length %u\n", len));
+            if (bits < 15) {
+                hold += (unsigned long)(PUP(in)) << bits;
+                bits += 8;
+                hold += (unsigned long)(PUP(in)) << bits;
+                bits += 8;
+            }
+            this = dcode[hold & dmask];
+          dodist:
+            op = (unsigned)(this.bits);
+            hold >>= op;
+            bits -= op;
+            op = (unsigned)(this.op);
+            if (op & 16) {                      /* distance base */
+                dist = (unsigned)(this.val);
+                op &= 15;                       /* number of extra bits */
+                if (bits < op) {
+                    hold += (unsigned long)(PUP(in)) << bits;
+                    bits += 8;
+                    if (bits < op) {
+                        hold += (unsigned long)(PUP(in)) << bits;
+                        bits += 8;
+                    }
+                }
+                dist += (unsigned)hold & ((1U << op) - 1);
+#ifdef INFLATE_STRICT
+                if (dist > dmax) {
+                    strm->msg = (char *)"invalid distance too far back";
+                    state->mode = BAD;
+                    break;
+                }
+#endif
+                hold >>= op;
+                bits -= op;
+                Tracevv((stderr, "inflate:         distance %u\n", dist));
+                op = (unsigned)(out - beg);     /* max distance in output */
+                if (dist > op) {                /* see if copy from window */
+                    op = dist - op;             /* distance back in window */
+                    if (op > whave) {
+                        strm->msg = (char *)"invalid distance too far back";
+                        state->mode = BAD;
+                        break;
+                    }
+                    from = window - OFF;
+                    if (write == 0) {           /* very common case */
+                        from += wsize - op;
+                        if (op < len) {         /* some from window */
+                            len -= op;
+                            do {
+                                PUP(out) = PUP(from);
+                            } while (--op);
+                            from = out - dist;  /* rest from output */
+                        }
+                    }
+                    else if (write < op) {      /* wrap around window */
+                        from += wsize + write - op;
+                        op -= write;
+                        if (op < len) {         /* some from end of window */
+                            len -= op;
+                            do {
+                                PUP(out) = PUP(from);
+                            } while (--op);
+                            from = window - OFF;
+                            if (write < len) {  /* some from start of window */
+                                op = write;
+                                len -= op;
+                                do {
+                                    PUP(out) = PUP(from);
+                                } while (--op);
+                                from = out - dist;      /* rest from output */
+                            }
+                        }
+                    }
+                    else {                      /* contiguous in window */
+                        from += write - op;
+                        if (op < len) {         /* some from window */
+                            len -= op;
+                            do {
+                                PUP(out) = PUP(from);
+                            } while (--op);
+                            from = out - dist;  /* rest from output */
+                        }
+                    }
+                    while (len > 2) {
+                        PUP(out) = PUP(from);
+                        PUP(out) = PUP(from);
+                        PUP(out) = PUP(from);
+                        len -= 3;
+                    }
+                    if (len) {
+                        PUP(out) = PUP(from);
+                        if (len > 1)
+                            PUP(out) = PUP(from);
+                    }
+                }
+                else {
+		    unsigned short *sout;
+		    unsigned long loops;
+
+                    from = out - dist;          /* copy direct from output */
+                    /* minimum length is three */
+		    /* Align out addr */
+		    if (!((long)(out - 1 + OFF) & 1)) {
+			PUP(out) = PUP(from);
+			len--;
+		    }
+		    sout = (unsigned short *)(out - OFF);
+		    if (dist > 2 ) {
+			unsigned short *sfrom;
+
+			sfrom = (unsigned short *)(from - OFF);
+			loops = len >> 1;
+			do
+			    PUP(sout) = get_unaligned(++sfrom);
+			while (--loops);
+			out = (unsigned char *)sout + OFF;
+			from = (unsigned char *)sfrom + OFF;
+		    } else { /* dist == 1 or dist == 2 */
+			unsigned short pat16;
+
+			pat16 = *(sout-2+2*OFF);
+			if (dist == 1)
+#if defined(__BIG_ENDIAN)
+			    pat16 = (pat16 & 0xff) | ((pat16 & 0xff ) << 8);
+#elif defined(__LITTLE_ENDIAN)
+			    pat16 = (pat16 & 0xff00) | ((pat16 & 0xff00 ) >> 8);
+#else
+#error __BIG_ENDIAN nor __LITTLE_ENDIAN is defined
+#endif
+			loops = len >> 1;
+			do
+			    PUP(sout) = pat16;
+			while (--loops);
+			out = (unsigned char *)sout + OFF;
+		    }
+		    if (len & 1)
+			PUP(out) = PUP(from);
+                }
+            }
+            else if ((op & 64) == 0) {          /* 2nd level distance code */
+                this = dcode[this.val + (hold & ((1U << op) - 1))];
+                goto dodist;
+            }
+            else {
+                strm->msg = (char *)"invalid distance code";
+                state->mode = BAD;
+                break;
+            }
+        }
+        else if ((op & 64) == 0) {              /* 2nd level length code */
+            this = lcode[this.val + (hold & ((1U << op) - 1))];
+            goto dolen;
+        }
+        else if (op & 32) {                     /* end-of-block */
+            Tracevv((stderr, "inflate:         end of block\n"));
+            state->mode = TYPE;
+            break;
+        }
+        else {
+            strm->msg = (char *)"invalid literal/length code";
+            state->mode = BAD;
+            break;
+        }
+    } while (in < last && out < end);
+
+    /* return unused bytes (on entry, bits < 8, so in won't go too far back) */
+    len = bits >> 3;
+    in -= len;
+    bits -= len << 3;
+    hold &= (1U << bits) - 1;
+
+    /* update state and return */
+    strm->next_in = in + OFF;
+    strm->next_out = out + OFF;
+    strm->avail_in = (unsigned)(in < last ? 5 + (last - in) : 5 - (in - last));
+    strm->avail_out = (unsigned)(out < end ?
+                                 257 + (end - out) : 257 - (out - end));
+    state->hold = hold;
+    state->bits = bits;
+    return;
+}
+
+/*
+   inflate_fast() speedups that turned out slower (on a PowerPC G3 750CXe):
+   - Using bit fields for code structure
+   - Different op definition to avoid & for extra bits (do & for table bits)
+   - Three separate decoding do-loops for direct, window, and write == 0
+   - Special case for distance > 1 copies to do overlapped load and store copy
+   - Explicit branch predictions (based on measured branch probabilities)
+   - Deferring match copy and interspersed it with decoding subsequent codes
+   - Swapping literal/length else
+   - Swapping window/direct else
+   - Larger unrolled copy loops (three is about right)
+   - Moving len -= 3 statement into middle of loop
+ */
+
+#endif /* !ASMINF */
diff --git a/lib/zlib/inffast.h b/lib/zlib/inffast.h
new file mode 100644
index 0000000..1e88d2d
--- /dev/null
+++ b/lib/zlib/inffast.h
@@ -0,0 +1,11 @@
+/* inffast.h -- header to use inffast.c
+ * Copyright (C) 1995-2003 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+   part of the implementation of the compression library and is
+   subject to change. Applications should only use zlib.h.
+ */
+
+void inflate_fast OF((z_streamp strm, unsigned start));
diff --git a/lib/zlib/inffixed.h b/lib/zlib/inffixed.h
new file mode 100644
index 0000000..75ed4b5
--- /dev/null
+++ b/lib/zlib/inffixed.h
@@ -0,0 +1,94 @@
+    /* inffixed.h -- table for decoding fixed codes
+     * Generated automatically by makefixed().
+     */
+
+    /* WARNING: this file should *not* be used by applications. It
+       is part of the implementation of the compression library and
+       is subject to change. Applications should only use zlib.h.
+     */
+
+    static const code lenfix[512] = {
+        {96,7,0},{0,8,80},{0,8,16},{20,8,115},{18,7,31},{0,8,112},{0,8,48},
+        {0,9,192},{16,7,10},{0,8,96},{0,8,32},{0,9,160},{0,8,0},{0,8,128},
+        {0,8,64},{0,9,224},{16,7,6},{0,8,88},{0,8,24},{0,9,144},{19,7,59},
+        {0,8,120},{0,8,56},{0,9,208},{17,7,17},{0,8,104},{0,8,40},{0,9,176},
+        {0,8,8},{0,8,136},{0,8,72},{0,9,240},{16,7,4},{0,8,84},{0,8,20},
+        {21,8,227},{19,7,43},{0,8,116},{0,8,52},{0,9,200},{17,7,13},{0,8,100},
+        {0,8,36},{0,9,168},{0,8,4},{0,8,132},{0,8,68},{0,9,232},{16,7,8},
+        {0,8,92},{0,8,28},{0,9,152},{20,7,83},{0,8,124},{0,8,60},{0,9,216},
+        {18,7,23},{0,8,108},{0,8,44},{0,9,184},{0,8,12},{0,8,140},{0,8,76},
+        {0,9,248},{16,7,3},{0,8,82},{0,8,18},{21,8,163},{19,7,35},{0,8,114},
+        {0,8,50},{0,9,196},{17,7,11},{0,8,98},{0,8,34},{0,9,164},{0,8,2},
+        {0,8,130},{0,8,66},{0,9,228},{16,7,7},{0,8,90},{0,8,26},{0,9,148},
+        {20,7,67},{0,8,122},{0,8,58},{0,9,212},{18,7,19},{0,8,106},{0,8,42},
+        {0,9,180},{0,8,10},{0,8,138},{0,8,74},{0,9,244},{16,7,5},{0,8,86},
+        {0,8,22},{64,8,0},{19,7,51},{0,8,118},{0,8,54},{0,9,204},{17,7,15},
+        {0,8,102},{0,8,38},{0,9,172},{0,8,6},{0,8,134},{0,8,70},{0,9,236},
+        {16,7,9},{0,8,94},{0,8,30},{0,9,156},{20,7,99},{0,8,126},{0,8,62},
+        {0,9,220},{18,7,27},{0,8,110},{0,8,46},{0,9,188},{0,8,14},{0,8,142},
+        {0,8,78},{0,9,252},{96,7,0},{0,8,81},{0,8,17},{21,8,131},{18,7,31},
+        {0,8,113},{0,8,49},{0,9,194},{16,7,10},{0,8,97},{0,8,33},{0,9,162},
+        {0,8,1},{0,8,129},{0,8,65},{0,9,226},{16,7,6},{0,8,89},{0,8,25},
+        {0,9,146},{19,7,59},{0,8,121},{0,8,57},{0,9,210},{17,7,17},{0,8,105},
+        {0,8,41},{0,9,178},{0,8,9},{0,8,137},{0,8,73},{0,9,242},{16,7,4},
+        {0,8,85},{0,8,21},{16,8,258},{19,7,43},{0,8,117},{0,8,53},{0,9,202},
+        {17,7,13},{0,8,101},{0,8,37},{0,9,170},{0,8,5},{0,8,133},{0,8,69},
+        {0,9,234},{16,7,8},{0,8,93},{0,8,29},{0,9,154},{20,7,83},{0,8,125},
+        {0,8,61},{0,9,218},{18,7,23},{0,8,109},{0,8,45},{0,9,186},{0,8,13},
+        {0,8,141},{0,8,77},{0,9,250},{16,7,3},{0,8,83},{0,8,19},{21,8,195},
+        {19,7,35},{0,8,115},{0,8,51},{0,9,198},{17,7,11},{0,8,99},{0,8,35},
+        {0,9,166},{0,8,3},{0,8,131},{0,8,67},{0,9,230},{16,7,7},{0,8,91},
+        {0,8,27},{0,9,150},{20,7,67},{0,8,123},{0,8,59},{0,9,214},{18,7,19},
+        {0,8,107},{0,8,43},{0,9,182},{0,8,11},{0,8,139},{0,8,75},{0,9,246},
+        {16,7,5},{0,8,87},{0,8,23},{64,8,0},{19,7,51},{0,8,119},{0,8,55},
+        {0,9,206},{17,7,15},{0,8,103},{0,8,39},{0,9,174},{0,8,7},{0,8,135},
+        {0,8,71},{0,9,238},{16,7,9},{0,8,95},{0,8,31},{0,9,158},{20,7,99},
+        {0,8,127},{0,8,63},{0,9,222},{18,7,27},{0,8,111},{0,8,47},{0,9,190},
+        {0,8,15},{0,8,143},{0,8,79},{0,9,254},{96,7,0},{0,8,80},{0,8,16},
+        {20,8,115},{18,7,31},{0,8,112},{0,8,48},{0,9,193},{16,7,10},{0,8,96},
+        {0,8,32},{0,9,161},{0,8,0},{0,8,128},{0,8,64},{0,9,225},{16,7,6},
+        {0,8,88},{0,8,24},{0,9,145},{19,7,59},{0,8,120},{0,8,56},{0,9,209},
+        {17,7,17},{0,8,104},{0,8,40},{0,9,177},{0,8,8},{0,8,136},{0,8,72},
+        {0,9,241},{16,7,4},{0,8,84},{0,8,20},{21,8,227},{19,7,43},{0,8,116},
+        {0,8,52},{0,9,201},{17,7,13},{0,8,100},{0,8,36},{0,9,169},{0,8,4},
+        {0,8,132},{0,8,68},{0,9,233},{16,7,8},{0,8,92},{0,8,28},{0,9,153},
+        {20,7,83},{0,8,124},{0,8,60},{0,9,217},{18,7,23},{0,8,108},{0,8,44},
+        {0,9,185},{0,8,12},{0,8,140},{0,8,76},{0,9,249},{16,7,3},{0,8,82},
+        {0,8,18},{21,8,163},{19,7,35},{0,8,114},{0,8,50},{0,9,197},{17,7,11},
+        {0,8,98},{0,8,34},{0,9,165},{0,8,2},{0,8,130},{0,8,66},{0,9,229},
+        {16,7,7},{0,8,90},{0,8,26},{0,9,149},{20,7,67},{0,8,122},{0,8,58},
+        {0,9,213},{18,7,19},{0,8,106},{0,8,42},{0,9,181},{0,8,10},{0,8,138},
+        {0,8,74},{0,9,245},{16,7,5},{0,8,86},{0,8,22},{64,8,0},{19,7,51},
+        {0,8,118},{0,8,54},{0,9,205},{17,7,15},{0,8,102},{0,8,38},{0,9,173},
+        {0,8,6},{0,8,134},{0,8,70},{0,9,237},{16,7,9},{0,8,94},{0,8,30},
+        {0,9,157},{20,7,99},{0,8,126},{0,8,62},{0,9,221},{18,7,27},{0,8,110},
+        {0,8,46},{0,9,189},{0,8,14},{0,8,142},{0,8,78},{0,9,253},{96,7,0},
+        {0,8,81},{0,8,17},{21,8,131},{18,7,31},{0,8,113},{0,8,49},{0,9,195},
+        {16,7,10},{0,8,97},{0,8,33},{0,9,163},{0,8,1},{0,8,129},{0,8,65},
+        {0,9,227},{16,7,6},{0,8,89},{0,8,25},{0,9,147},{19,7,59},{0,8,121},
+        {0,8,57},{0,9,211},{17,7,17},{0,8,105},{0,8,41},{0,9,179},{0,8,9},
+        {0,8,137},{0,8,73},{0,9,243},{16,7,4},{0,8,85},{0,8,21},{16,8,258},
+        {19,7,43},{0,8,117},{0,8,53},{0,9,203},{17,7,13},{0,8,101},{0,8,37},
+        {0,9,171},{0,8,5},{0,8,133},{0,8,69},{0,9,235},{16,7,8},{0,8,93},
+        {0,8,29},{0,9,155},{20,7,83},{0,8,125},{0,8,61},{0,9,219},{18,7,23},
+        {0,8,109},{0,8,45},{0,9,187},{0,8,13},{0,8,141},{0,8,77},{0,9,251},
+        {16,7,3},{0,8,83},{0,8,19},{21,8,195},{19,7,35},{0,8,115},{0,8,51},
+        {0,9,199},{17,7,11},{0,8,99},{0,8,35},{0,9,167},{0,8,3},{0,8,131},
+        {0,8,67},{0,9,231},{16,7,7},{0,8,91},{0,8,27},{0,9,151},{20,7,67},
+        {0,8,123},{0,8,59},{0,9,215},{18,7,19},{0,8,107},{0,8,43},{0,9,183},
+        {0,8,11},{0,8,139},{0,8,75},{0,9,247},{16,7,5},{0,8,87},{0,8,23},
+        {64,8,0},{19,7,51},{0,8,119},{0,8,55},{0,9,207},{17,7,15},{0,8,103},
+        {0,8,39},{0,9,175},{0,8,7},{0,8,135},{0,8,71},{0,9,239},{16,7,9},
+        {0,8,95},{0,8,31},{0,9,159},{20,7,99},{0,8,127},{0,8,63},{0,9,223},
+        {18,7,27},{0,8,111},{0,8,47},{0,9,191},{0,8,15},{0,8,143},{0,8,79},
+        {0,9,255}
+    };
+
+    static const code distfix[32] = {
+        {16,5,1},{23,5,257},{19,5,17},{27,5,4097},{17,5,5},{25,5,1025},
+        {21,5,65},{29,5,16385},{16,5,3},{24,5,513},{20,5,33},{28,5,8193},
+        {18,5,9},{26,5,2049},{22,5,129},{64,5,0},{16,5,2},{23,5,385},
+        {19,5,25},{27,5,6145},{17,5,7},{25,5,1537},{21,5,97},{29,5,24577},
+        {16,5,4},{24,5,769},{20,5,49},{28,5,12289},{18,5,13},{26,5,3073},
+        {22,5,193},{64,5,0}
+    };
diff --git a/lib/zlib/inflate.c b/lib/zlib/inflate.c
new file mode 100644
index 0000000..1eef609
--- /dev/null
+++ b/lib/zlib/inflate.c
@@ -0,0 +1,956 @@
+/* inflate.c -- zlib decompression
+ * Copyright (C) 1995-2005 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+local void fixedtables OF((struct inflate_state FAR *state));
+local int updatewindow OF((z_streamp strm, unsigned out));
+
+int ZEXPORT inflateReset(strm)
+z_streamp strm;
+{
+    struct inflate_state FAR *state;
+
+    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+    state = (struct inflate_state FAR *)strm->state;
+    strm->total_in = strm->total_out = state->total = 0;
+    strm->msg = Z_NULL;
+    strm->adler = 1;        /* to support ill-conceived Java test suite */
+    state->mode = HEAD;
+    state->last = 0;
+    state->havedict = 0;
+    state->dmax = 32768U;
+    state->head = Z_NULL;
+    state->wsize = 0;
+    state->whave = 0;
+    state->write = 0;
+    state->hold = 0;
+    state->bits = 0;
+    state->lencode = state->distcode = state->next = state->codes;
+    WATCHDOG_RESET();
+    Tracev((stderr, "inflate: reset\n"));
+    return Z_OK;
+}
+
+int ZEXPORT inflateInit2_(strm, windowBits, version, stream_size)
+z_streamp strm;
+int windowBits;
+const char *version;
+int stream_size;
+{
+    struct inflate_state FAR *state;
+
+    if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||
+        stream_size != (int)(sizeof(z_stream)))
+        return Z_VERSION_ERROR;
+    if (strm == Z_NULL) return Z_STREAM_ERROR;
+    strm->msg = Z_NULL;                 /* in case we return an error */
+    if (strm->zalloc == (alloc_func)0) {
+        strm->zalloc = zcalloc;
+        strm->opaque = (voidpf)0;
+    }
+    if (strm->zfree == (free_func)0) strm->zfree = zcfree;
+    state = (struct inflate_state FAR *)
+            ZALLOC(strm, 1, sizeof(struct inflate_state));
+    if (state == Z_NULL) return Z_MEM_ERROR;
+    Tracev((stderr, "inflate: allocated\n"));
+    strm->state = (struct internal_state FAR *)state;
+    if (windowBits < 0) {
+        state->wrap = 0;
+        windowBits = -windowBits;
+    }
+    else {
+        state->wrap = (windowBits >> 4) + 1;
+#ifdef GUNZIP
+        if (windowBits < 48) windowBits &= 15;
+#endif
+    }
+    if (windowBits < 8 || windowBits > 15) {
+        ZFREE(strm, state);
+        strm->state = Z_NULL;
+        return Z_STREAM_ERROR;
+    }
+    state->wbits = (unsigned)windowBits;
+    state->window = Z_NULL;
+    return inflateReset(strm);
+}
+
+int ZEXPORT inflateInit_(strm, version, stream_size)
+z_streamp strm;
+const char *version;
+int stream_size;
+{
+    return inflateInit2_(strm, DEF_WBITS, version, stream_size);
+}
+
+local void fixedtables(state)
+struct inflate_state FAR *state;
+{
+    state->lencode = lenfix;
+    state->lenbits = 9;
+    state->distcode = distfix;
+    state->distbits = 5;
+}
+
+/*
+   Update the window with the last wsize (normally 32K) bytes written before
+   returning.  If window does not exist yet, create it.  This is only called
+   when a window is already in use, or when output has been written during this
+   inflate call, but the end of the deflate stream has not been reached yet.
+   It is also called to create a window for dictionary data when a dictionary
+   is loaded.
+
+   Providing output buffers larger than 32K to inflate() should provide a speed
+   advantage, since only the last 32K of output is copied to the sliding window
+   upon return from inflate(), and since all distances after the first 32K of
+   output will fall in the output data, making match copies simpler and faster.
+   The advantage may be dependent on the size of the processor's data caches.
+ */
+local int updatewindow(strm, out)
+z_streamp strm;
+unsigned out;
+{
+    struct inflate_state FAR *state;
+    unsigned copy, dist;
+
+    state = (struct inflate_state FAR *)strm->state;
+
+    /* if it hasn't been done already, allocate space for the window */
+    if (state->window == Z_NULL) {
+        state->window = (unsigned char FAR *)
+                        ZALLOC(strm, 1U << state->wbits,
+                               sizeof(unsigned char));
+        if (state->window == Z_NULL) return 1;
+    }
+
+    /* if window not in use yet, initialize */
+    if (state->wsize == 0) {
+        state->wsize = 1U << state->wbits;
+        state->write = 0;
+        state->whave = 0;
+    }
+
+    /* copy state->wsize or less output bytes into the circular window */
+    copy = out - strm->avail_out;
+    if (copy >= state->wsize) {
+        zmemcpy(state->window, strm->next_out - state->wsize, state->wsize);
+        state->write = 0;
+        state->whave = state->wsize;
+    }
+    else {
+        dist = state->wsize - state->write;
+        if (dist > copy) dist = copy;
+        zmemcpy(state->window + state->write, strm->next_out - copy, dist);
+        copy -= dist;
+        if (copy) {
+            zmemcpy(state->window, strm->next_out - copy, copy);
+            state->write = copy;
+            state->whave = state->wsize;
+        }
+        else {
+            state->write += dist;
+            if (state->write == state->wsize) state->write = 0;
+            if (state->whave < state->wsize) state->whave += dist;
+        }
+    }
+    return 0;
+}
+
+/* Macros for inflate(): */
+
+/* check function to use adler32() for zlib or crc32() for gzip */
+#ifdef GUNZIP
+#  define UPDATE(check, buf, len) \
+    (state->flags ? crc32(check, buf, len) : adler32(check, buf, len))
+#else
+#  define UPDATE(check, buf, len) adler32(check, buf, len)
+#endif
+
+/* check macros for header crc */
+#ifdef GUNZIP
+#  define CRC2(check, word) \
+    do { \
+        hbuf[0] = (unsigned char)(word); \
+        hbuf[1] = (unsigned char)((word) >> 8); \
+        check = crc32(check, hbuf, 2); \
+    } while (0)
+
+#  define CRC4(check, word) \
+    do { \
+        hbuf[0] = (unsigned char)(word); \
+        hbuf[1] = (unsigned char)((word) >> 8); \
+        hbuf[2] = (unsigned char)((word) >> 16); \
+        hbuf[3] = (unsigned char)((word) >> 24); \
+        check = crc32(check, hbuf, 4); \
+    } while (0)
+#endif
+
+/* Load registers with state in inflate() for speed */
+#define LOAD() \
+    do { \
+        put = strm->next_out; \
+        left = strm->avail_out; \
+        next = strm->next_in; \
+        have = strm->avail_in; \
+        hold = state->hold; \
+        bits = state->bits; \
+    } while (0)
+
+/* Restore state from registers in inflate() */
+#define RESTORE() \
+    do { \
+        strm->next_out = put; \
+        strm->avail_out = left; \
+        strm->next_in = next; \
+        strm->avail_in = have; \
+        state->hold = hold; \
+        state->bits = bits; \
+    } while (0)
+
+/* Clear the input bit accumulator */
+#define INITBITS() \
+    do { \
+        hold = 0; \
+        bits = 0; \
+    } while (0)
+
+/* Get a byte of input into the bit accumulator, or return from inflate()
+   if there is no input available. */
+#define PULLBYTE() \
+    do { \
+        if (have == 0) goto inf_leave; \
+        have--; \
+        hold += (unsigned long)(*next++) << bits; \
+        bits += 8; \
+    } while (0)
+
+/* Assure that there are at least n bits in the bit accumulator.  If there is
+   not enough available input to do that, then return from inflate(). */
+#define NEEDBITS(n) \
+    do { \
+        while (bits < (unsigned)(n)) \
+            PULLBYTE(); \
+    } while (0)
+
+/* Return the low n bits of the bit accumulator (n < 16) */
+#define BITS(n) \
+    ((unsigned)hold & ((1U << (n)) - 1))
+
+/* Remove n bits from the bit accumulator */
+#define DROPBITS(n) \
+    do { \
+        hold >>= (n); \
+        bits -= (unsigned)(n); \
+    } while (0)
+
+/* Remove zero to seven bits as needed to go to a byte boundary */
+#define BYTEBITS() \
+    do { \
+        hold >>= bits & 7; \
+        bits -= bits & 7; \
+    } while (0)
+
+/* Reverse the bytes in a 32-bit value */
+#define REVERSE(q) \
+    ((((q) >> 24) & 0xff) + (((q) >> 8) & 0xff00) + \
+     (((q) & 0xff00) << 8) + (((q) & 0xff) << 24))
+
+/*
+   inflate() uses a state machine to process as much input data and generate as
+   much output data as possible before returning.  The state machine is
+   structured roughly as follows:
+
+    for (;;) switch (state) {
+    ...
+    case STATEn:
+        if (not enough input data or output space to make progress)
+            return;
+        ... make progress ...
+        state = STATEm;
+        break;
+    ...
+    }
+
+   so when inflate() is called again, the same case is attempted again, and
+   if the appropriate resources are provided, the machine proceeds to the
+   next state.  The NEEDBITS() macro is usually the way the state evaluates
+   whether it can proceed or should return.  NEEDBITS() does the return if
+   the requested bits are not available.  The typical use of the BITS macros
+   is:
+
+        NEEDBITS(n);
+        ... do something with BITS(n) ...
+        DROPBITS(n);
+
+   where NEEDBITS(n) either returns from inflate() if there isn't enough
+   input left to load n bits into the accumulator, or it continues.  BITS(n)
+   gives the low n bits in the accumulator.  When done, DROPBITS(n) drops
+   the low n bits off the accumulator.  INITBITS() clears the accumulator
+   and sets the number of available bits to zero.  BYTEBITS() discards just
+   enough bits to put the accumulator on a byte boundary.  After BYTEBITS()
+   and a NEEDBITS(8), then BITS(8) would return the next byte in the stream.
+
+   NEEDBITS(n) uses PULLBYTE() to get an available byte of input, or to return
+   if there is no input available.  The decoding of variable length codes uses
+   PULLBYTE() directly in order to pull just enough bytes to decode the next
+   code, and no more.
+
+   Some states loop until they get enough input, making sure that enough
+   state information is maintained to continue the loop where it left off
+   if NEEDBITS() returns in the loop.  For example, want, need, and keep
+   would all have to actually be part of the saved state in case NEEDBITS()
+   returns:
+
+    case STATEw:
+        while (want < need) {
+            NEEDBITS(n);
+            keep[want++] = BITS(n);
+            DROPBITS(n);
+        }
+        state = STATEx;
+    case STATEx:
+
+   As shown above, if the next state is also the next case, then the break
+   is omitted.
+
+   A state may also return if there is not enough output space available to
+   complete that state.  Those states are copying stored data, writing a
+   literal byte, and copying a matching string.
+
+   When returning, a "goto inf_leave" is used to update the total counters,
+   update the check value, and determine whether any progress has been made
+   during that inflate() call in order to return the proper return code.
+   Progress is defined as a change in either strm->avail_in or strm->avail_out.
+   When there is a window, goto inf_leave will update the window with the last
+   output written.  If a goto inf_leave occurs in the middle of decompression
+   and there is no window currently, goto inf_leave will create one and copy
+   output to the window for the next call of inflate().
+
+   In this implementation, the flush parameter of inflate() only affects the
+   return code (per zlib.h).  inflate() always writes as much as possible to
+   strm->next_out, given the space available and the provided input--the effect
+   documented in zlib.h of Z_SYNC_FLUSH.  Furthermore, inflate() always defers
+   the allocation of and copying into a sliding window until necessary, which
+   provides the effect documented in zlib.h for Z_FINISH when the entire input
+   stream available.  So the only thing the flush parameter actually does is:
+   when flush is set to Z_FINISH, inflate() cannot return Z_OK.  Instead it
+   will return Z_BUF_ERROR if it has not reached the end of the stream.
+ */
+int ZEXPORT inflate(strm, flush)
+z_streamp strm;
+int flush;
+{
+    struct inflate_state FAR *state;
+    unsigned char FAR *next;    /* next input */
+    unsigned char FAR *put;     /* next output */
+    unsigned have, left;        /* available input and output */
+    unsigned long hold;         /* bit buffer */
+    unsigned bits;              /* bits in bit buffer */
+    unsigned in, out;           /* save starting available input and output */
+    unsigned copy;              /* number of stored or match bytes to copy */
+    unsigned char FAR *from;    /* where to copy match bytes from */
+    code this;                  /* current decoding table entry */
+    code last;                  /* parent table entry */
+    unsigned len;               /* length to copy for repeats, bits to drop */
+    int ret;                    /* return code */
+#ifdef GUNZIP
+    unsigned char hbuf[4];      /* buffer for gzip header crc calculation */
+#endif
+    static const unsigned short order[19] = /* permutation of code lengths */
+        {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
+
+    if (strm == Z_NULL || strm->state == Z_NULL ||
+        (strm->next_in == Z_NULL && strm->avail_in != 0))
+        return Z_STREAM_ERROR;
+
+    state = (struct inflate_state FAR *)strm->state;
+    if (state->mode == TYPE) state->mode = TYPEDO;      /* skip check */
+    LOAD();
+    in = have;
+    out = left;
+    ret = Z_OK;
+    for (;;)
+        switch (state->mode) {
+        case HEAD:
+            if (state->wrap == 0) {
+                state->mode = TYPEDO;
+                break;
+            }
+            NEEDBITS(16);
+#ifdef GUNZIP
+            if ((state->wrap & 2) && hold == 0x8b1f) {  /* gzip header */
+                state->check = crc32(0L, Z_NULL, 0);
+                CRC2(state->check, hold);
+                INITBITS();
+                state->mode = FLAGS;
+                break;
+            }
+            state->flags = 0;           /* expect zlib header */
+            if (state->head != Z_NULL)
+                state->head->done = -1;
+            if (!(state->wrap & 1) ||   /* check if zlib header allowed */
+#else
+            if (
+#endif
+                ((BITS(8) << 8) + (hold >> 8)) % 31) {
+                strm->msg = (char *)"incorrect header check";
+                state->mode = BAD;
+                break;
+            }
+            if (BITS(4) != Z_DEFLATED) {
+                strm->msg = (char *)"unknown compression method";
+                state->mode = BAD;
+                break;
+            }
+            DROPBITS(4);
+            len = BITS(4) + 8;
+            if (len > state->wbits) {
+                strm->msg = (char *)"invalid window size";
+                state->mode = BAD;
+                break;
+            }
+            state->dmax = 1U << len;
+            Tracev((stderr, "inflate:   zlib header ok\n"));
+            strm->adler = state->check = adler32(0L, Z_NULL, 0);
+            state->mode = hold & 0x200 ? DICTID : TYPE;
+            INITBITS();
+            break;
+#ifdef GUNZIP
+        case FLAGS:
+            NEEDBITS(16);
+            state->flags = (int)(hold);
+            if ((state->flags & 0xff) != Z_DEFLATED) {
+                strm->msg = (char *)"unknown compression method";
+                state->mode = BAD;
+                break;
+            }
+            if (state->flags & 0xe000) {
+                strm->msg = (char *)"unknown header flags set";
+                state->mode = BAD;
+                break;
+            }
+            if (state->head != Z_NULL)
+                state->head->text = (int)((hold >> 8) & 1);
+            if (state->flags & 0x0200) CRC2(state->check, hold);
+            INITBITS();
+            state->mode = TIME;
+        case TIME:
+            NEEDBITS(32);
+            if (state->head != Z_NULL)
+                state->head->time = hold;
+            if (state->flags & 0x0200) CRC4(state->check, hold);
+            INITBITS();
+            state->mode = OS;
+        case OS:
+            NEEDBITS(16);
+            if (state->head != Z_NULL) {
+                state->head->xflags = (int)(hold & 0xff);
+                state->head->os = (int)(hold >> 8);
+            }
+            if (state->flags & 0x0200) CRC2(state->check, hold);
+            INITBITS();
+            state->mode = EXLEN;
+        case EXLEN:
+            if (state->flags & 0x0400) {
+                NEEDBITS(16);
+                state->length = (unsigned)(hold);
+                if (state->head != Z_NULL)
+                    state->head->extra_len = (unsigned)hold;
+                if (state->flags & 0x0200) CRC2(state->check, hold);
+                INITBITS();
+            }
+            else if (state->head != Z_NULL)
+                state->head->extra = Z_NULL;
+            state->mode = EXTRA;
+        case EXTRA:
+            if (state->flags & 0x0400) {
+                copy = state->length;
+                if (copy > have) copy = have;
+                if (copy) {
+                    if (state->head != Z_NULL &&
+                        state->head->extra != Z_NULL) {
+                        len = state->head->extra_len - state->length;
+                        zmemcpy(state->head->extra + len, next,
+                                len + copy > state->head->extra_max ?
+                                state->head->extra_max - len : copy);
+                    }
+                    if (state->flags & 0x0200)
+                        state->check = crc32(state->check, next, copy);
+                    have -= copy;
+                    next += copy;
+                    state->length -= copy;
+                }
+                if (state->length) goto inf_leave;
+            }
+            state->length = 0;
+            state->mode = NAME;
+        case NAME:
+            if (state->flags & 0x0800) {
+                if (have == 0) goto inf_leave;
+                copy = 0;
+                do {
+                    len = (unsigned)(next[copy++]);
+                    if (state->head != Z_NULL &&
+                            state->head->name != Z_NULL &&
+                            state->length < state->head->name_max)
+                        state->head->name[state->length++] = len;
+                } while (len && copy < have);
+                if (state->flags & 0x0200)
+                    state->check = crc32(state->check, next, copy);
+                have -= copy;
+                next += copy;
+                if (len) goto inf_leave;
+            }
+            else if (state->head != Z_NULL)
+                state->head->name = Z_NULL;
+            state->length = 0;
+            state->mode = COMMENT;
+        case COMMENT:
+            if (state->flags & 0x1000) {
+                if (have == 0) goto inf_leave;
+                copy = 0;
+                do {
+                    len = (unsigned)(next[copy++]);
+                    if (state->head != Z_NULL &&
+                            state->head->comment != Z_NULL &&
+                            state->length < state->head->comm_max)
+                        state->head->comment[state->length++] = len;
+                } while (len && copy < have);
+                if (state->flags & 0x0200)
+                    state->check = crc32(state->check, next, copy);
+                have -= copy;
+                next += copy;
+                if (len) goto inf_leave;
+            }
+            else if (state->head != Z_NULL)
+                state->head->comment = Z_NULL;
+            state->mode = HCRC;
+        case HCRC:
+            if (state->flags & 0x0200) {
+                NEEDBITS(16);
+                if (hold != (state->check & 0xffff)) {
+                    strm->msg = (char *)"header crc mismatch";
+                    state->mode = BAD;
+                    break;
+                }
+                INITBITS();
+            }
+            if (state->head != Z_NULL) {
+                state->head->hcrc = (int)((state->flags >> 9) & 1);
+                state->head->done = 1;
+            }
+            strm->adler = state->check = crc32(0L, Z_NULL, 0);
+            state->mode = TYPE;
+            break;
+#endif
+        case DICTID:
+            NEEDBITS(32);
+            strm->adler = state->check = REVERSE(hold);
+            INITBITS();
+            state->mode = DICT;
+        case DICT:
+            if (state->havedict == 0) {
+                RESTORE();
+                return Z_NEED_DICT;
+            }
+            strm->adler = state->check = adler32(0L, Z_NULL, 0);
+            state->mode = TYPE;
+        case TYPE:
+	    WATCHDOG_RESET();
+            if (flush == Z_BLOCK) goto inf_leave;
+        case TYPEDO:
+            if (state->last) {
+                BYTEBITS();
+                state->mode = CHECK;
+                break;
+            }
+            NEEDBITS(3);
+            state->last = BITS(1);
+            DROPBITS(1);
+            switch (BITS(2)) {
+            case 0:                             /* stored block */
+                Tracev((stderr, "inflate:     stored block%s\n",
+                        state->last ? " (last)" : ""));
+                state->mode = STORED;
+                break;
+            case 1:                             /* fixed block */
+                fixedtables(state);
+                Tracev((stderr, "inflate:     fixed codes block%s\n",
+                        state->last ? " (last)" : ""));
+                state->mode = LEN;              /* decode codes */
+                break;
+            case 2:                             /* dynamic block */
+                Tracev((stderr, "inflate:     dynamic codes block%s\n",
+                        state->last ? " (last)" : ""));
+                state->mode = TABLE;
+                break;
+            case 3:
+                strm->msg = (char *)"invalid block type";
+                state->mode = BAD;
+            }
+            DROPBITS(2);
+            break;
+        case STORED:
+            BYTEBITS();                         /* go to byte boundary */
+            NEEDBITS(32);
+            if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) {
+                strm->msg = (char *)"invalid stored block lengths";
+                state->mode = BAD;
+                break;
+            }
+            state->length = (unsigned)hold & 0xffff;
+            Tracev((stderr, "inflate:       stored length %u\n",
+                    state->length));
+            INITBITS();
+            state->mode = COPY;
+        case COPY:
+            copy = state->length;
+            if (copy) {
+                if (copy > have) copy = have;
+                if (copy > left) copy = left;
+                if (copy == 0) goto inf_leave;
+                zmemcpy(put, next, copy);
+                have -= copy;
+                next += copy;
+                left -= copy;
+                put += copy;
+                state->length -= copy;
+                break;
+            }
+            Tracev((stderr, "inflate:       stored end\n"));
+            state->mode = TYPE;
+            break;
+        case TABLE:
+            NEEDBITS(14);
+            state->nlen = BITS(5) + 257;
+            DROPBITS(5);
+            state->ndist = BITS(5) + 1;
+            DROPBITS(5);
+            state->ncode = BITS(4) + 4;
+            DROPBITS(4);
+#ifndef PKZIP_BUG_WORKAROUND
+            if (state->nlen > 286 || state->ndist > 30) {
+                strm->msg = (char *)"too many length or distance symbols";
+                state->mode = BAD;
+                break;
+            }
+#endif
+            Tracev((stderr, "inflate:       table sizes ok\n"));
+            state->have = 0;
+            state->mode = LENLENS;
+        case LENLENS:
+            while (state->have < state->ncode) {
+                NEEDBITS(3);
+                state->lens[order[state->have++]] = (unsigned short)BITS(3);
+                DROPBITS(3);
+            }
+            while (state->have < 19)
+                state->lens[order[state->have++]] = 0;
+            state->next = state->codes;
+            state->lencode = (code const FAR *)(state->next);
+            state->lenbits = 7;
+            ret = inflate_table(CODES, state->lens, 19, &(state->next),
+                                &(state->lenbits), state->work);
+            if (ret) {
+                strm->msg = (char *)"invalid code lengths set";
+                state->mode = BAD;
+                break;
+            }
+            Tracev((stderr, "inflate:       code lengths ok\n"));
+            state->have = 0;
+            state->mode = CODELENS;
+        case CODELENS:
+            while (state->have < state->nlen + state->ndist) {
+                for (;;) {
+                    this = state->lencode[BITS(state->lenbits)];
+                    if ((unsigned)(this.bits) <= bits) break;
+                    PULLBYTE();
+                }
+                if (this.val < 16) {
+                    NEEDBITS(this.bits);
+                    DROPBITS(this.bits);
+                    state->lens[state->have++] = this.val;
+                }
+                else {
+                    if (this.val == 16) {
+                        NEEDBITS(this.bits + 2);
+                        DROPBITS(this.bits);
+                        if (state->have == 0) {
+                            strm->msg = (char *)"invalid bit length repeat";
+                            state->mode = BAD;
+                            break;
+                        }
+                        len = state->lens[state->have - 1];
+                        copy = 3 + BITS(2);
+                        DROPBITS(2);
+                    }
+                    else if (this.val == 17) {
+                        NEEDBITS(this.bits + 3);
+                        DROPBITS(this.bits);
+                        len = 0;
+                        copy = 3 + BITS(3);
+                        DROPBITS(3);
+                    }
+                    else {
+                        NEEDBITS(this.bits + 7);
+                        DROPBITS(this.bits);
+                        len = 0;
+                        copy = 11 + BITS(7);
+                        DROPBITS(7);
+                    }
+                    if (state->have + copy > state->nlen + state->ndist) {
+                        strm->msg = (char *)"invalid bit length repeat";
+                        state->mode = BAD;
+                        break;
+                    }
+                    while (copy--)
+                        state->lens[state->have++] = (unsigned short)len;
+                }
+            }
+
+            /* handle error breaks in while */
+            if (state->mode == BAD) break;
+
+            /* build code tables */
+            state->next = state->codes;
+            state->lencode = (code const FAR *)(state->next);
+            state->lenbits = 9;
+            ret = inflate_table(LENS, state->lens, state->nlen, &(state->next),
+                                &(state->lenbits), state->work);
+            if (ret) {
+                strm->msg = (char *)"invalid literal/lengths set";
+                state->mode = BAD;
+                break;
+            }
+            state->distcode = (code const FAR *)(state->next);
+            state->distbits = 6;
+            ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist,
+                            &(state->next), &(state->distbits), state->work);
+            if (ret) {
+                strm->msg = (char *)"invalid distances set";
+                state->mode = BAD;
+                break;
+            }
+            Tracev((stderr, "inflate:       codes ok\n"));
+            state->mode = LEN;
+        case LEN:
+	    WATCHDOG_RESET();
+            if (have >= 6 && left >= 258) {
+                RESTORE();
+                inflate_fast(strm, out);
+                LOAD();
+                break;
+            }
+            for (;;) {
+                this = state->lencode[BITS(state->lenbits)];
+                if ((unsigned)(this.bits) <= bits) break;
+                PULLBYTE();
+            }
+            if (this.op && (this.op & 0xf0) == 0) {
+                last = this;
+                for (;;) {
+                    this = state->lencode[last.val +
+                            (BITS(last.bits + last.op) >> last.bits)];
+                    if ((unsigned)(last.bits + this.bits) <= bits) break;
+                    PULLBYTE();
+                }
+                DROPBITS(last.bits);
+            }
+            DROPBITS(this.bits);
+            state->length = (unsigned)this.val;
+            if ((int)(this.op) == 0) {
+                Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ?
+                        "inflate:         literal '%c'\n" :
+                        "inflate:         literal 0x%02x\n", this.val));
+                state->mode = LIT;
+                break;
+            }
+            if (this.op & 32) {
+                Tracevv((stderr, "inflate:         end of block\n"));
+                state->mode = TYPE;
+                break;
+            }
+            if (this.op & 64) {
+                strm->msg = (char *)"invalid literal/length code";
+                state->mode = BAD;
+                break;
+            }
+            state->extra = (unsigned)(this.op) & 15;
+            state->mode = LENEXT;
+        case LENEXT:
+            if (state->extra) {
+                NEEDBITS(state->extra);
+                state->length += BITS(state->extra);
+                DROPBITS(state->extra);
+            }
+            Tracevv((stderr, "inflate:         length %u\n", state->length));
+            state->mode = DIST;
+        case DIST:
+            for (;;) {
+                this = state->distcode[BITS(state->distbits)];
+                if ((unsigned)(this.bits) <= bits) break;
+                PULLBYTE();
+            }
+            if ((this.op & 0xf0) == 0) {
+                last = this;
+                for (;;) {
+                    this = state->distcode[last.val +
+                            (BITS(last.bits + last.op) >> last.bits)];
+                    if ((unsigned)(last.bits + this.bits) <= bits) break;
+                    PULLBYTE();
+                }
+                DROPBITS(last.bits);
+            }
+            DROPBITS(this.bits);
+            if (this.op & 64) {
+                strm->msg = (char *)"invalid distance code";
+                state->mode = BAD;
+                break;
+            }
+            state->offset = (unsigned)this.val;
+            state->extra = (unsigned)(this.op) & 15;
+            state->mode = DISTEXT;
+        case DISTEXT:
+            if (state->extra) {
+                NEEDBITS(state->extra);
+                state->offset += BITS(state->extra);
+                DROPBITS(state->extra);
+            }
+#ifdef INFLATE_STRICT
+            if (state->offset > state->dmax) {
+                strm->msg = (char *)"invalid distance too far back";
+                state->mode = BAD;
+                break;
+            }
+#endif
+            if (state->offset > state->whave + out - left) {
+                strm->msg = (char *)"invalid distance too far back";
+                state->mode = BAD;
+                break;
+            }
+            Tracevv((stderr, "inflate:         distance %u\n", state->offset));
+            state->mode = MATCH;
+        case MATCH:
+            if (left == 0) goto inf_leave;
+            copy = out - left;
+            if (state->offset > copy) {         /* copy from window */
+                copy = state->offset - copy;
+                if (copy > state->write) {
+                    copy -= state->write;
+                    from = state->window + (state->wsize - copy);
+                }
+                else
+                    from = state->window + (state->write - copy);
+                if (copy > state->length) copy = state->length;
+            }
+            else {                              /* copy from output */
+                from = put - state->offset;
+                copy = state->length;
+            }
+            if (copy > left) copy = left;
+            left -= copy;
+            state->length -= copy;
+            do {
+                *put++ = *from++;
+            } while (--copy);
+            if (state->length == 0) state->mode = LEN;
+            break;
+        case LIT:
+            if (left == 0) goto inf_leave;
+            *put++ = (unsigned char)(state->length);
+            left--;
+            state->mode = LEN;
+            break;
+        case CHECK:
+            if (state->wrap) {
+                NEEDBITS(32);
+                out -= left;
+                strm->total_out += out;
+                state->total += out;
+                if (out)
+                    strm->adler = state->check =
+                        UPDATE(state->check, put - out, out);
+                out = left;
+                if ((
+#ifdef GUNZIP
+                     state->flags ? hold :
+#endif
+                     REVERSE(hold)) != state->check) {
+                    strm->msg = (char *)"incorrect data check";
+                    state->mode = BAD;
+                    break;
+                }
+                INITBITS();
+                Tracev((stderr, "inflate:   check matches trailer\n"));
+            }
+#ifdef GUNZIP
+            state->mode = LENGTH;
+        case LENGTH:
+            if (state->wrap && state->flags) {
+                NEEDBITS(32);
+                if (hold != (state->total & 0xffffffffUL)) {
+                    strm->msg = (char *)"incorrect length check";
+                    state->mode = BAD;
+                    break;
+                }
+                INITBITS();
+                Tracev((stderr, "inflate:   length matches trailer\n"));
+            }
+#endif
+            state->mode = DONE;
+        case DONE:
+            ret = Z_STREAM_END;
+            goto inf_leave;
+        case BAD:
+            ret = Z_DATA_ERROR;
+            goto inf_leave;
+        case MEM:
+            return Z_MEM_ERROR;
+        case SYNC:
+        default:
+            return Z_STREAM_ERROR;
+        }
+
+    /*
+       Return from inflate(), updating the total counts and the check value.
+       If there was no progress during the inflate() call, return a buffer
+       error.  Call updatewindow() to create and/or update the window state.
+       Note: a memory error from inflate() is non-recoverable.
+     */
+  inf_leave:
+    RESTORE();
+    if (state->wsize || (state->mode < CHECK && out != strm->avail_out))
+        if (updatewindow(strm, out)) {
+            state->mode = MEM;
+            return Z_MEM_ERROR;
+        }
+    in -= strm->avail_in;
+    out -= strm->avail_out;
+    strm->total_in += in;
+    strm->total_out += out;
+    state->total += out;
+    if (state->wrap && out)
+        strm->adler = state->check =
+            UPDATE(state->check, strm->next_out - out, out);
+    strm->data_type = state->bits + (state->last ? 64 : 0) +
+                      (state->mode == TYPE ? 128 : 0);
+    if (((in == 0 && out == 0) || flush == Z_FINISH) && ret == Z_OK)
+        ret = Z_BUF_ERROR;
+    return ret;
+}
+
+int ZEXPORT inflateEnd(strm)
+z_streamp strm;
+{
+    struct inflate_state FAR *state;
+    if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0)
+        return Z_STREAM_ERROR;
+    state = (struct inflate_state FAR *)strm->state;
+    if (state->window != Z_NULL) {
+	WATCHDOG_RESET();
+	ZFREE(strm, state->window);
+    }
+    ZFREE(strm, strm->state);
+    strm->state = Z_NULL;
+    Tracev((stderr, "inflate: end\n"));
+    return Z_OK;
+}
diff --git a/lib/zlib/inflate.h b/lib/zlib/inflate.h
new file mode 100644
index 0000000..07bd3e7
--- /dev/null
+++ b/lib/zlib/inflate.h
@@ -0,0 +1,115 @@
+/* inflate.h -- internal inflate state definition
+ * Copyright (C) 1995-2004 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+   part of the implementation of the compression library and is
+   subject to change. Applications should only use zlib.h.
+ */
+
+/* define NO_GZIP when compiling if you want to disable gzip header and
+   trailer decoding by inflate().  NO_GZIP would be used to avoid linking in
+   the crc code when it is not needed.  For shared libraries, gzip decoding
+   should be left enabled. */
+#ifndef NO_GZIP
+#  define GUNZIP
+#endif
+
+/* Possible inflate modes between inflate() calls */
+typedef enum {
+    HEAD,       /* i: waiting for magic header */
+    FLAGS,      /* i: waiting for method and flags (gzip) */
+    TIME,       /* i: waiting for modification time (gzip) */
+    OS,         /* i: waiting for extra flags and operating system (gzip) */
+    EXLEN,      /* i: waiting for extra length (gzip) */
+    EXTRA,      /* i: waiting for extra bytes (gzip) */
+    NAME,       /* i: waiting for end of file name (gzip) */
+    COMMENT,    /* i: waiting for end of comment (gzip) */
+    HCRC,       /* i: waiting for header crc (gzip) */
+    DICTID,     /* i: waiting for dictionary check value */
+    DICT,       /* waiting for inflateSetDictionary() call */
+        TYPE,       /* i: waiting for type bits, including last-flag bit */
+        TYPEDO,     /* i: same, but skip check to exit inflate on new block */
+        STORED,     /* i: waiting for stored size (length and complement) */
+        COPY,       /* i/o: waiting for input or output to copy stored block */
+        TABLE,      /* i: waiting for dynamic block table lengths */
+        LENLENS,    /* i: waiting for code length code lengths */
+        CODELENS,   /* i: waiting for length/lit and distance code lengths */
+            LEN,        /* i: waiting for length/lit code */
+            LENEXT,     /* i: waiting for length extra bits */
+            DIST,       /* i: waiting for distance code */
+            DISTEXT,    /* i: waiting for distance extra bits */
+            MATCH,      /* o: waiting for output space to copy string */
+            LIT,        /* o: waiting for output space to write literal */
+    CHECK,      /* i: waiting for 32-bit check value */
+    LENGTH,     /* i: waiting for 32-bit length (gzip) */
+    DONE,       /* finished check, done -- remain here until reset */
+    BAD,        /* got a data error -- remain here until reset */
+    MEM,        /* got an inflate() memory error -- remain here until reset */
+    SYNC        /* looking for synchronization bytes to restart inflate() */
+} inflate_mode;
+
+/*
+    State transitions between above modes -
+
+    (most modes can go to the BAD or MEM mode -- not shown for clarity)
+
+    Process header:
+        HEAD -> (gzip) or (zlib)
+        (gzip) -> FLAGS -> TIME -> OS -> EXLEN -> EXTRA -> NAME
+        NAME -> COMMENT -> HCRC -> TYPE
+        (zlib) -> DICTID or TYPE
+        DICTID -> DICT -> TYPE
+    Read deflate blocks:
+            TYPE -> STORED or TABLE or LEN or CHECK
+            STORED -> COPY -> TYPE
+            TABLE -> LENLENS -> CODELENS -> LEN
+    Read deflate codes:
+                LEN -> LENEXT or LIT or TYPE
+                LENEXT -> DIST -> DISTEXT -> MATCH -> LEN
+                LIT -> LEN
+    Process trailer:
+        CHECK -> LENGTH -> DONE
+ */
+
+/* state maintained between inflate() calls.  Approximately 7K bytes. */
+struct inflate_state {
+    inflate_mode mode;          /* current inflate mode */
+    int last;                   /* true if processing last block */
+    int wrap;                   /* bit 0 true for zlib, bit 1 true for gzip */
+    int havedict;               /* true if dictionary provided */
+    int flags;                  /* gzip header method and flags (0 if zlib) */
+    unsigned dmax;              /* zlib header max distance (INFLATE_STRICT) */
+    unsigned long check;        /* protected copy of check value */
+    unsigned long total;        /* protected copy of output count */
+    gz_headerp head;            /* where to save gzip header information */
+        /* sliding window */
+    unsigned wbits;             /* log base 2 of requested window size */
+    unsigned wsize;             /* window size or zero if not using window */
+    unsigned whave;             /* valid bytes in the window */
+    unsigned write;             /* window write index */
+    unsigned char FAR *window;  /* allocated sliding window, if needed */
+        /* bit accumulator */
+    unsigned long hold;         /* input bit accumulator */
+    unsigned bits;              /* number of bits in "in" */
+        /* for string and stored block copying */
+    unsigned length;            /* literal or length of data to copy */
+    unsigned offset;            /* distance back to copy string from */
+        /* for table and code decoding */
+    unsigned extra;             /* extra bits needed */
+        /* fixed and dynamic code tables */
+    code const FAR *lencode;    /* starting table for length/literal codes */
+    code const FAR *distcode;   /* starting table for distance codes */
+    unsigned lenbits;           /* index bits for lencode */
+    unsigned distbits;          /* index bits for distcode */
+        /* dynamic table building */
+    unsigned ncode;             /* number of code length code lengths */
+    unsigned nlen;              /* number of length code lengths */
+    unsigned ndist;             /* number of distance code lengths */
+    unsigned have;              /* number of code lengths in lens[] */
+    code FAR *next;             /* next available space in codes[] */
+    unsigned short lens[320];   /* temporary storage for code lengths */
+    unsigned short work[288];   /* work area for code table building */
+    code codes[ENOUGH];         /* space for code tables */
+};
diff --git a/lib/zlib/inftrees.c b/lib/zlib/inftrees.c
new file mode 100644
index 0000000..c6d4c03
--- /dev/null
+++ b/lib/zlib/inftrees.c
@@ -0,0 +1,329 @@
+/* inftrees.c -- generate Huffman trees for efficient decoding
+ * Copyright (C) 1995-2005 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* U-boot: we already included these
+#include "zutil.h"
+#include "inftrees.h"
+*/
+
+#define MAXBITS 15
+
+/*
+  If you use the zlib library in a product, an acknowledgment is welcome
+  in the documentation of your product. If for some reason you cannot
+  include such an acknowledgment, I would appreciate that you keep this
+  copyright string in the executable of your product.
+ */
+
+/*
+   Build a set of tables to decode the provided canonical Huffman code.
+   The code lengths are lens[0..codes-1].  The result starts at *table,
+   whose indices are 0..2^bits-1.  work is a writable array of at least
+   lens shorts, which is used as a work area.  type is the type of code
+   to be generated, CODES, LENS, or DISTS.  On return, zero is success,
+   -1 is an invalid code, and +1 means that ENOUGH isn't enough.  table
+   on return points to the next available entry's address.  bits is the
+   requested root table index bits, and on return it is the actual root
+   table index bits.  It will differ if the request is greater than the
+   longest code or if it is less than the shortest code.
+ */
+int inflate_table(type, lens, codes, table, bits, work)
+codetype type;
+unsigned short FAR *lens;
+unsigned codes;
+code FAR * FAR *table;
+unsigned FAR *bits;
+unsigned short FAR *work;
+{
+    unsigned len;               /* a code's length in bits */
+    unsigned sym;               /* index of code symbols */
+    unsigned min, max;          /* minimum and maximum code lengths */
+    unsigned root;              /* number of index bits for root table */
+    unsigned curr;              /* number of index bits for current table */
+    unsigned drop;              /* code bits to drop for sub-table */
+    int left;                   /* number of prefix codes available */
+    unsigned used;              /* code entries in table used */
+    unsigned huff;              /* Huffman code */
+    unsigned incr;              /* for incrementing code, index */
+    unsigned fill;              /* index for replicating entries */
+    unsigned low;               /* low bits for current root entry */
+    unsigned mask;              /* mask for low root bits */
+    code this;                  /* table entry for duplication */
+    code FAR *next;             /* next available space in table */
+    const unsigned short FAR *base;     /* base value table to use */
+    const unsigned short FAR *extra;    /* extra bits table to use */
+    int end;                    /* use base and extra for symbol > end */
+    unsigned short count[MAXBITS+1];    /* number of codes of each length */
+    unsigned short offs[MAXBITS+1];     /* offsets in table for each length */
+    static const unsigned short lbase[31] = { /* Length codes 257..285 base */
+        3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
+        35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
+    static const unsigned short lext[31] = { /* Length codes 257..285 extra */
+        16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18,
+        19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 201, 196};
+    static const unsigned short dbase[32] = { /* Distance codes 0..29 base */
+        1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
+        257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
+        8193, 12289, 16385, 24577, 0, 0};
+    static const unsigned short dext[32] = { /* Distance codes 0..29 extra */
+        16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22,
+        23, 23, 24, 24, 25, 25, 26, 26, 27, 27,
+        28, 28, 29, 29, 64, 64};
+
+    /*
+       Process a set of code lengths to create a canonical Huffman code.  The
+       code lengths are lens[0..codes-1].  Each length corresponds to the
+       symbols 0..codes-1.  The Huffman code is generated by first sorting the
+       symbols by length from short to long, and retaining the symbol order
+       for codes with equal lengths.  Then the code starts with all zero bits
+       for the first code of the shortest length, and the codes are integer
+       increments for the same length, and zeros are appended as the length
+       increases.  For the deflate format, these bits are stored backwards
+       from their more natural integer increment ordering, and so when the
+       decoding tables are built in the large loop below, the integer codes
+       are incremented backwards.
+
+       This routine assumes, but does not check, that all of the entries in
+       lens[] are in the range 0..MAXBITS.  The caller must assure this.
+       1..MAXBITS is interpreted as that code length.  zero means that that
+       symbol does not occur in this code.
+
+       The codes are sorted by computing a count of codes for each length,
+       creating from that a table of starting indices for each length in the
+       sorted table, and then entering the symbols in order in the sorted
+       table.  The sorted table is work[], with that space being provided by
+       the caller.
+
+       The length counts are used for other purposes as well, i.e. finding
+       the minimum and maximum length codes, determining if there are any
+       codes at all, checking for a valid set of lengths, and looking ahead
+       at length counts to determine sub-table sizes when building the
+       decoding tables.
+     */
+
+    /* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */
+    for (len = 0; len <= MAXBITS; len++)
+        count[len] = 0;
+    for (sym = 0; sym < codes; sym++)
+        count[lens[sym]]++;
+
+    /* bound code lengths, force root to be within code lengths */
+    root = *bits;
+    for (max = MAXBITS; max >= 1; max--)
+        if (count[max] != 0) break;
+    if (root > max) root = max;
+    if (max == 0) {                     /* no symbols to code at all */
+        this.op = (unsigned char)64;    /* invalid code marker */
+        this.bits = (unsigned char)1;
+        this.val = (unsigned short)0;
+        *(*table)++ = this;             /* make a table to force an error */
+        *(*table)++ = this;
+        *bits = 1;
+        return 0;     /* no symbols, but wait for decoding to report error */
+    }
+    for (min = 1; min <= MAXBITS; min++)
+        if (count[min] != 0) break;
+    if (root < min) root = min;
+
+    /* check for an over-subscribed or incomplete set of lengths */
+    left = 1;
+    for (len = 1; len <= MAXBITS; len++) {
+        left <<= 1;
+        left -= count[len];
+        if (left < 0) return -1;        /* over-subscribed */
+    }
+    if (left > 0 && (type == CODES || max != 1))
+        return -1;                      /* incomplete set */
+
+    /* generate offsets into symbol table for each length for sorting */
+    offs[1] = 0;
+    for (len = 1; len < MAXBITS; len++)
+        offs[len + 1] = offs[len] + count[len];
+
+    /* sort symbols by length, by symbol order within each length */
+    for (sym = 0; sym < codes; sym++)
+        if (lens[sym] != 0) work[offs[lens[sym]]++] = (unsigned short)sym;
+
+    /*
+       Create and fill in decoding tables.  In this loop, the table being
+       filled is at next and has curr index bits.  The code being used is huff
+       with length len.  That code is converted to an index by dropping drop
+       bits off of the bottom.  For codes where len is less than drop + curr,
+       those top drop + curr - len bits are incremented through all values to
+       fill the table with replicated entries.
+
+       root is the number of index bits for the root table.  When len exceeds
+       root, sub-tables are created pointed to by the root entry with an index
+       of the low root bits of huff.  This is saved in low to check for when a
+       new sub-table should be started.  drop is zero when the root table is
+       being filled, and drop is root when sub-tables are being filled.
+
+       When a new sub-table is needed, it is necessary to look ahead in the
+       code lengths to determine what size sub-table is needed.  The length
+       counts are used for this, and so count[] is decremented as codes are
+       entered in the tables.
+
+       used keeps track of how many table entries have been allocated from the
+       provided *table space.  It is checked when a LENS table is being made
+       against the space in *table, ENOUGH, minus the maximum space needed by
+       the worst case distance code, MAXD.  This should never happen, but the
+       sufficiency of ENOUGH has not been proven exhaustively, hence the check.
+       This assumes that when type == LENS, bits == 9.
+
+       sym increments through all symbols, and the loop terminates when
+       all codes of length max, i.e. all codes, have been processed.  This
+       routine permits incomplete codes, so another loop after this one fills
+       in the rest of the decoding tables with invalid code markers.
+     */
+
+    /* set up for code type */
+    switch (type) {
+    case CODES:
+        base = extra = work;    /* dummy value--not used */
+        end = 19;
+        break;
+    case LENS:
+        base = lbase;
+        base -= 257;
+        extra = lext;
+        extra -= 257;
+        end = 256;
+        break;
+    default:            /* DISTS */
+        base = dbase;
+        extra = dext;
+        end = -1;
+    }
+
+    /* initialize state for loop */
+    huff = 0;                   /* starting code */
+    sym = 0;                    /* starting code symbol */
+    len = min;                  /* starting code length */
+    next = *table;              /* current table to fill in */
+    curr = root;                /* current table index bits */
+    drop = 0;                   /* current bits to drop from code for index */
+    low = (unsigned)(-1);       /* trigger new sub-table when len > root */
+    used = 1U << root;          /* use root table entries */
+    mask = used - 1;            /* mask for comparing low */
+
+    /* check available table space */
+    if (type == LENS && used >= ENOUGH - MAXD)
+        return 1;
+
+    /* process all codes and make table entries */
+    for (;;) {
+        /* create table entry */
+        this.bits = (unsigned char)(len - drop);
+        if ((int)(work[sym]) < end) {
+            this.op = (unsigned char)0;
+            this.val = work[sym];
+        }
+        else if ((int)(work[sym]) > end) {
+            this.op = (unsigned char)(extra[work[sym]]);
+            this.val = base[work[sym]];
+        }
+        else {
+            this.op = (unsigned char)(32 + 64);         /* end of block */
+            this.val = 0;
+        }
+
+        /* replicate for those indices with low len bits equal to huff */
+        incr = 1U << (len - drop);
+        fill = 1U << curr;
+        min = fill;                 /* save offset to next table */
+        do {
+            fill -= incr;
+            next[(huff >> drop) + fill] = this;
+        } while (fill != 0);
+
+        /* backwards increment the len-bit code huff */
+        incr = 1U << (len - 1);
+        while (huff & incr)
+            incr >>= 1;
+        if (incr != 0) {
+            huff &= incr - 1;
+            huff += incr;
+        }
+        else
+            huff = 0;
+
+        /* go to next symbol, update count, len */
+        sym++;
+        if (--(count[len]) == 0) {
+            if (len == max) break;
+            len = lens[work[sym]];
+        }
+
+        /* create new sub-table if needed */
+        if (len > root && (huff & mask) != low) {
+            /* if first time, transition to sub-tables */
+            if (drop == 0)
+                drop = root;
+
+            /* increment past last table */
+            next += min;            /* here min is 1 << curr */
+
+            /* determine length of next table */
+            curr = len - drop;
+            left = (int)(1 << curr);
+            while (curr + drop < max) {
+                left -= count[curr + drop];
+                if (left <= 0) break;
+                curr++;
+                left <<= 1;
+            }
+
+            /* check for enough space */
+            used += 1U << curr;
+            if (type == LENS && used >= ENOUGH - MAXD)
+                return 1;
+
+            /* point entry in root table to sub-table */
+            low = huff & mask;
+            (*table)[low].op = (unsigned char)curr;
+            (*table)[low].bits = (unsigned char)root;
+            (*table)[low].val = (unsigned short)(next - *table);
+        }
+    }
+
+    /*
+       Fill in rest of table for incomplete codes.  This loop is similar to the
+       loop above in incrementing huff for table indices.  It is assumed that
+       len is equal to curr + drop, so there is no loop needed to increment
+       through high index bits.  When the current sub-table is filled, the loop
+       drops back to the root table to fill in any remaining entries there.
+     */
+    this.op = (unsigned char)64;                /* invalid code marker */
+    this.bits = (unsigned char)(len - drop);
+    this.val = (unsigned short)0;
+    while (huff != 0) {
+        /* when done with sub-table, drop back to root table */
+        if (drop != 0 && (huff & mask) != low) {
+            drop = 0;
+            len = root;
+            next = *table;
+            this.bits = (unsigned char)len;
+        }
+
+        /* put invalid code marker in table */
+        next[huff >> drop] = this;
+
+        /* backwards increment the len-bit code huff */
+        incr = 1U << (len - 1);
+        while (huff & incr)
+            incr >>= 1;
+        if (incr != 0) {
+            huff &= incr - 1;
+            huff += incr;
+        }
+        else
+            huff = 0;
+    }
+
+    /* set return parameters */
+    *table += used;
+    *bits = root;
+    return 0;
+}
diff --git a/lib/zlib/inftrees.h b/lib/zlib/inftrees.h
new file mode 100644
index 0000000..b1104c8
--- /dev/null
+++ b/lib/zlib/inftrees.h
@@ -0,0 +1,55 @@
+/* inftrees.h -- header to use inftrees.c
+ * Copyright (C) 1995-2005 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+   part of the implementation of the compression library and is
+   subject to change. Applications should only use zlib.h.
+ */
+
+/* Structure for decoding tables.  Each entry provides either the
+   information needed to do the operation requested by the code that
+   indexed that table entry, or it provides a pointer to another
+   table that indexes more bits of the code.  op indicates whether
+   the entry is a pointer to another table, a literal, a length or
+   distance, an end-of-block, or an invalid code.  For a table
+   pointer, the low four bits of op is the number of index bits of
+   that table.  For a length or distance, the low four bits of op
+   is the number of extra bits to get after the code.  bits is
+   the number of bits in this code or part of the code to drop off
+   of the bit buffer.  val is the actual byte to output in the case
+   of a literal, the base length or distance, or the offset from
+   the current table to the next table.  Each entry is four bytes. */
+typedef struct {
+    unsigned char op;           /* operation, extra bits, table bits */
+    unsigned char bits;         /* bits in this part of the code */
+    unsigned short val;         /* offset in table or code value */
+} code;
+
+/* op values as set by inflate_table():
+    00000000 - literal
+    0000tttt - table link, tttt != 0 is the number of table index bits
+    0001eeee - length or distance, eeee is the number of extra bits
+    01100000 - end of block
+    01000000 - invalid code
+ */
+
+/* Maximum size of dynamic tree.  The maximum found in a long but non-
+   exhaustive search was 1444 code structures (852 for length/literals
+   and 592 for distances, the latter actually the result of an
+   exhaustive search).  The true maximum is not known, but the value
+   below is more than safe. */
+#define ENOUGH 2048
+#define MAXD 592
+
+/* Type of code to build for inftable() */
+typedef enum {
+    CODES,
+    LENS,
+    DISTS
+} codetype;
+
+extern int inflate_table OF((codetype type, unsigned short FAR *lens,
+                             unsigned codes, code FAR * FAR *table,
+                             unsigned FAR *bits, unsigned short FAR *work));
diff --git a/lib/zlib/zlib.c b/lib/zlib/zlib.c
new file mode 100644
index 0000000..230d0df
--- /dev/null
+++ b/lib/zlib/zlib.c
@@ -0,0 +1,24 @@
+/*
+ * This file is derived from various .h and .c files from the zlib-1.2.3
+ * distribution by Jean-loup Gailly and Mark Adler, with some additions
+ * by Paul Mackerras to aid in implementing Deflate compression and
+ * decompression for PPP packets.  See zlib.h for conditions of
+ * distribution and use.
+ *
+ * Changes that have been made include:
+ * - changed functions not used outside this file to "local"
+ * - added minCompression parameter to deflateInit2
+ * - added Z_PACKET_FLUSH (see zlib.h for details)
+ * - added inflateIncomp
+ */
+
+#include "zutil.h"
+#include "inftrees.h"
+#include "inflate.h"
+#include "inffast.h"
+#include "inffixed.h"
+#include "inffast.c"
+#include "inftrees.c"
+#include "inflate.c"
+#include "zutil.c"
+#include "adler32.c"
diff --git a/lib/zlib/zlib.h b/lib/zlib/zlib.h
new file mode 100644
index 0000000..556be32
--- /dev/null
+++ b/lib/zlib/zlib.h
@@ -0,0 +1,20 @@
+/* Glue between u-boot and upstream zlib */
+#ifndef __GLUE_ZLIB_H__
+#define __GLUE_ZLIB_H__
+
+#include <common.h>
+#include <compiler.h>
+#include <asm/unaligned.h>
+#include <watchdog.h>
+#include "u-boot/zlib.h"
+
+/* avoid conflicts */
+#undef OFF
+#undef ASMINF
+#undef POSTINC
+#undef NO_GZIP
+#define GUNZIP
+#undef STDC
+#undef NO_ERRNO_H
+
+#endif
diff --git a/lib/zlib/zutil.c b/lib/zlib/zutil.c
new file mode 100644
index 0000000..65f9554
--- /dev/null
+++ b/lib/zlib/zutil.c
@@ -0,0 +1,73 @@
+/* zutil.c -- target dependent utility functions for the compression library
+ * Copyright (C) 1995-2005 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* @(#) $Id$ */
+
+#include "zutil.h"
+
+#ifndef NO_DUMMY_DECL
+struct internal_state      {int dummy;}; /* for buggy compilers */
+#endif
+
+const char * const z_errmsg[10] = {
+"need dictionary",     /* Z_NEED_DICT       2  */
+"stream end",          /* Z_STREAM_END      1  */
+"",                    /* Z_OK              0  */
+"file error",          /* Z_ERRNO         (-1) */
+"stream error",        /* Z_STREAM_ERROR  (-2) */
+"data error",          /* Z_DATA_ERROR    (-3) */
+"insufficient memory", /* Z_MEM_ERROR     (-4) */
+"buffer error",        /* Z_BUF_ERROR     (-5) */
+"incompatible version",/* Z_VERSION_ERROR (-6) */
+""};
+
+#ifdef DEBUG
+
+#ifndef verbose
+#define verbose 0
+#endif
+int z_verbose = verbose;
+
+void z_error (m)
+    char *m;
+{
+	fprintf(stderr, "%s\n", m);
+	hang ();
+}
+#endif
+
+/* exported to allow conversion of error code to string for compress() and
+ * uncompress()
+ */
+#ifndef MY_ZCALLOC /* Any system without a special alloc function */
+
+#ifndef STDC
+extern voidp    malloc OF((uInt size));
+extern voidp    calloc OF((uInt items, uInt size));
+extern void     free   OF((voidpf ptr));
+#endif
+
+voidpf zcalloc (opaque, items, size)
+	voidpf opaque;
+	unsigned items;
+	unsigned size;
+{
+	if (opaque)
+		items += size - size; /* make compiler happy */
+	return sizeof(uInt) > 2 ? (voidpf)malloc(items * size) :
+		(voidpf)calloc(items, size);
+}
+
+void  zcfree (opaque, ptr, nb)
+	voidpf opaque;
+	voidpf ptr;
+	unsigned nb;
+{
+	free(ptr);
+	if (opaque)
+		return; /* make compiler happy */
+}
+
+#endif /* MY_ZCALLOC */
diff --git a/lib/zlib/zutil.h b/lib/zlib/zutil.h
new file mode 100644
index 0000000..46522c8
--- /dev/null
+++ b/lib/zlib/zutil.h
@@ -0,0 +1,121 @@
+/* zutil.h -- internal interface and configuration of the compression library
+ * Copyright (C) 1995-2005 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+   part of the implementation of the compression library and is
+   subject to change. Applications should only use zlib.h.
+ */
+
+/* @(#) $Id$ */
+
+#ifndef ZUTIL_H
+#define ZUTIL_H
+
+#define ZLIB_INTERNAL
+#include "zlib.h"
+
+#ifdef STDC
+#  ifndef _WIN32_WCE
+#    include <stddef.h>
+#  endif
+#  include <string.h>
+#  include <stdlib.h>
+#endif
+#ifdef NO_ERRNO_H
+#   ifdef _WIN32_WCE
+      /* The Microsoft C Run-Time Library for Windows CE doesn't have
+       * errno.  We define it as a global variable to simplify porting.
+       * Its value is always 0 and should not be used.  We rename it to
+       * avoid conflict with other libraries that use the same workaround.
+       */
+#     define errno z_errno
+#   endif
+    extern int errno;
+#else
+#  ifndef _WIN32_WCE
+#    include <errno.h>
+#  endif
+#endif
+
+#ifndef local
+#  define local static
+#endif
+/* compile with -Dlocal if your debugger can't find static symbols */
+
+typedef unsigned char  uch;
+typedef uch FAR uchf;
+typedef unsigned short ush;
+typedef ush FAR ushf;
+typedef unsigned long  ulg;
+
+extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */
+/* (size given to avoid silly warnings with Visual C++) */
+
+#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)]
+
+#define ERR_RETURN(strm,err) \
+  return (strm->msg = (char*)ERR_MSG(err), (err))
+/* To be used only when the state is known to be valid */
+
+        /* common constants */
+
+#ifndef DEF_WBITS
+#  define DEF_WBITS MAX_WBITS
+#endif
+/* default windowBits for decompression. MAX_WBITS is for compression only */
+
+#if MAX_MEM_LEVEL >= 8
+#  define DEF_MEM_LEVEL 8
+#else
+#  define DEF_MEM_LEVEL  MAX_MEM_LEVEL
+#endif
+/* default memLevel */
+
+#define STORED_BLOCK 0
+#define STATIC_TREES 1
+#define DYN_TREES    2
+/* The three kinds of block type */
+
+#define MIN_MATCH  3
+#define MAX_MATCH  258
+/* The minimum and maximum match lengths */
+
+	 /* functions */
+
+#include <linux/string.h>
+#define zmemcpy memcpy
+#define zmemcmp memcmp
+#define zmemzero(dest, len) memset(dest, 0, len)
+
+/* Diagnostic functions */
+#ifdef DEBUG
+#  include <stdio.h>
+   extern int z_verbose;
+   extern void z_error    OF((char *m));
+#  define Assert(cond,msg) {if(!(cond)) z_error(msg);}
+#  define Trace(x) {if (z_verbose>=0) fprintf x ;}
+#  define Tracev(x) {if (z_verbose>0) fprintf x ;}
+#  define Tracevv(x) {if (z_verbose>1) fprintf x ;}
+#  define Tracec(c,x) {if (z_verbose>0 && (c)) fprintf x ;}
+#  define Tracecv(c,x) {if (z_verbose>1 && (c)) fprintf x ;}
+#else
+#  define Assert(cond,msg)
+#  define Trace(x)
+#  define Tracev(x)
+#  define Tracevv(x)
+#  define Tracec(c,x)
+#  define Tracecv(c,x)
+#endif
+
+
+voidpf zcalloc OF((voidpf opaque, unsigned items, unsigned size));
+void   zcfree  OF((voidpf opaque, voidpf ptr, unsigned size));
+
+#define ZALLOC(strm, items, size) \
+           (*((strm)->zalloc))((strm)->opaque, (items), (size))
+#define ZFREE(strm, addr)  (*((strm)->zfree))((strm)->opaque, (voidpf)(addr), 0)
+#define TRY_FREE(s, p) {if (p) ZFREE(s, p);}
+
+#endif /* ZUTIL_H */
diff --git a/tools/env/README b/tools/env/README
index 91e679a..d5f228f 100644
--- a/tools/env/README
+++ b/tools/env/README
@@ -2,6 +2,12 @@
 This is a demo implementation of a Linux command line tool to access
 the U-Boot's environment variables.
 
+In the current version, there is an issue in cross-compilation.
+In order to cross-compile fw_printenv, run
+    make HOSTCC=<your CC cross-compiler> env
+in the root directory of the U-Boot distribution. For example,
+    make HOSTCC=arm-linux-gcc env
+
 For the run-time utiltity configuration uncomment the line
 #define CONFIG_FILE  "/etc/fw_env.config"
 in fw_env.h.